On Fri, Jun 28, 2024 at 11:17 AM Vlastimil Babka <vbabka@xxxxxxx> wrote: > > On 6/28/24 11:06 AM, Alice Ryhl wrote: > >> >> > >> > > >> > I took a quick look as what kmem_buckets is, and seems to me that align > >> > doesn't make sense here (and probably not useful in Rust as well) > >> > because a kmem_buckets is a set of kmem_caches, each has its own object > >> > size, making them share the same alignment is probably not what you > >> > want. But I could be missing something. > >> > >> How flexible do you need those alignments to be? Besides the power-of-two > >> guarantees, we currently have only two odd sizes with 96 and 192. If those > >> were guaranteed to be aligned 32 bytes, would that be sufficient? Also do > >> you ever allocate anything smaller than 32 bytes then? > >> > >> To summarize, if Rust's requirements can be summarized by some rules and > >> it's not completely ad-hoc per-allocation alignment requirement (or if it > >> is, does it have an upper bound?) we could perhaps figure out the creation > >> of rust-specific kmem_buckets to give it what's needed? > > > > Rust's allocator API can take any size and alignment as long as: > > > > 1. The alignment is a power of two. > > 2. The size is non-zero. > > 3. When you round up the size to the next multiple of the alignment, > > then it must not overflow the signed type isize / ssize_t. > > > > What happens right now is that when Rust wants an allocation with a > > higher alignment than ARCH_SLAB_MINALIGN, then it will increase size > > until it becomes a power of two so that the power-of-two guarantee > > gives a properly aligned allocation. > > So am I correct thinking that, if the cache of size 96 bytes guaranteed a > 32byte alignment, and 192 bytes guaranteed 64byte alignment, and the rest of > sizes with the already guaranteed power-of-two alignment, then on rust side > you would only have to round up sizes to the next multiples of the alignemnt > (rule 3 above) and that would be sufficient? > Abstracting from the specific sizes of 96 and 192, the guarantee on kmalloc > side would have to be - guarantee alignment to the largest power-of-two > divisor of the size. Does that sound right? > > Then I think we could have some flag for kmem_buckets creation that would do > the right thing. If kmalloc/krealloc guarantee that an allocation is aligned according to the largest power-of-two divisor of the size, then the Rust allocator would definitely be simplified as we would not longer need this part: if layout.align() > bindings::ARCH_SLAB_MINALIGN { // The alignment requirement exceeds the slab guarantee, thus try to enlarge the size // to use the "power-of-two" size/alignment guarantee (see comments in `kmalloc()` for // more information). // // Note that `layout.size()` (after padding) is guaranteed to be a multiple of // `layout.align()`, so `next_power_of_two` gives enough alignment guarantee. size = size.next_power_of_two(); } We would only need to keep the part that rounds up the size to a multiple of the alignment. Alice