Re: [PATCH v4 1/4] mm/zsmalloc: encode class index in obj value for lockless class lookup
From: Wenchao Hao
Date: Tue Jun 09 2026 - 23:20:13 EST
On Wed, Jun 10, 2026 at 1:56 AM Nhat Pham <nphamcs@xxxxxxxxx> wrote:
>
> On Tue, Jun 9, 2026 at 4:35 AM Wenchao Hao <haowenchao22@xxxxxxxxx> wrote:
> >
> > From: Wenchao Hao <haowenchao@xxxxxxxxxx>
> >
> > + * ceil(log2(ZS_MAX_PAGES_PER_ZSPAGE)) at preprocessor time, for use
> > + * in #if below. Kconfig restricts ZSMALLOC_CHAIN_SIZE to [4, 16].
> > + */
> > +#if ZS_MAX_PAGES_PER_ZSPAGE <= 4
> > +#define ZS_CHAIN_LOG2 2
> > +#elif ZS_MAX_PAGES_PER_ZSPAGE <= 8
> > +#define ZS_CHAIN_LOG2 3
> > +#elif ZS_MAX_PAGES_PER_ZSPAGE <= 16
> > +#define ZS_CHAIN_LOG2 4
>
> Do we not have log2 macro to use here?
const_ilog2() in <linux/log2.h> wraps everything in __builtin_constant_p(),
which is not a preprocessor expression and so cannot be used in an
#if condition. Since we need this value at the preprocessor stage
(to decide ZS_OBJ_CLASS_BITS in the next #if), the manual cascade
seems unavoidable.
>
> > +#else
> > +#error "ZSMALLOC_CHAIN_SIZE out of expected range [4,16]"
> > +#endif
> > +
> > +/* PAGE_SHIFT - 5 = log2(PAGE_SIZE / 32); 32 = ZS_MIN_ALLOC_SIZE floor. */
> > +#define ZS_MAX_OBJ_PER_PAGE_LOG2 (PAGE_SHIFT - 5)
> > +
> > +/*
> > + * obj_idx width that keeps ZS_MIN_ALLOC_SIZE at its 32-byte floor.
> > + * Below this, ZS_MIN_ALLOC_SIZE is auto-raised by the MAX(32, ...)
> > + * formula -- still correct, but objects are coarser.
> > + */
> > +#define ZS_OBJ_IDX_DENSE_BITS (ZS_CHAIN_LOG2 + ZS_MAX_OBJ_PER_PAGE_LOG2)
>
> ZS_CHAIN_LOG2 is (roughly) number of bits to represent the zpage index
> in the zspage, and ZS_MAX_OBJ_PER_PAGE_LOG2 is roughly the number of
> bits to represent the object index within the zpage, correct?
>
Exactly. Both are really "how many bits are needed to represent X",
just expressed as log2(X):
ZS_CHAIN_LOG2
= ceil(log2(ZS_MAX_PAGES_PER_ZSPAGE))
= bits to index a page within a zspage.
ZS_MAX_OBJ_PER_PAGE_LOG2
= log2(PAGE_SIZE / 32)
= bits to index an object within a single page, at the smallest
possible object size (32 bytes).
The "_LOG2" suffix names the math but hides the intent. How about
renaming them as:
ZS_CHAIN_LOG2 -> ZS_MAX_BITS_PAGES_PER_ZSPAGE
ZS_MAX_OBJ_PER_PAGE_LOG2 -> ZS_MAX_BITS_OBJS_PER_PAGE
ZS_OBJ_IDX_DENSE_BITS -> ZS_MAX_BITS_OBJS_PER_ZSPAGE
Then the third one reads as the sum of the first two: "bits to index
any object in the densest zspage", and the ZS_OBJ_CLASS_BITS predicate
gets easier to follow.
Does that work for you?
Wenchao