Re: [PATCH 1/2] mm/shrinker: size shrinker_info_unit to a power of two

From: Konstantin Khorenko

Date: Wed Oct 14 2026 - 09:41:18 EST


On 10/13/26 04:52, Qi Zheng wrote:
> On 10/13/26 3:02 AM, Konstantin Khorenko wrote:
>> Every memory cgroup allocates, per NUMA node, one shrinker_info_unit
>> for every SHRINKER_UNIT_BITS shrinker ids up to shrinker_nr_max. The
>> unit holds BITS_PER_LONG atomic_long_t of deferred work, a power of
>> two, plus the one-word bitmap of shrinkers with objects charged to the
>> cgroup. That word takes the unit just past the power of two, to 520
>> bytes on 64-bit, so every unit comes from kmalloc-1k and almost half of
>> it is padding.
>>
>> The units are allocated when the cgroup goes online and freed when it is
>> freed, so a dying cgroup keeps them until the last reference to it is
>> gone. Their number is the number of memory cgroups, times the NUMA
>> nodes, times shrinker_nr_max / SHRINKER_UNIT_BITS. shrinker_nr_max is
>> the peak number of memcg-aware shrinkers registered at once, and every
>> superblock registers one, so a host that mounts many filesystems and
>> runs many cgroups carries the padding as unreclaimable slab, and keeps
>> paying it for new cgroups after the mounts are gone.
>>
>> Let a unit cover one id less than a word holds. The bitmap still fits
>> one word, and nr_deferred[] plus that word add up to BITS_PER_LONG
>> longs, so the unit fills a power-of-two kmalloc slot exactly and, on
>> 64-bit, the memory taken by units halves, for about one unit more in
>> BITS_PER_LONG.
>> round_up() in expand_shrinker_info() needs a power-of-two step and
>> becomes roundup(); the other uses of SHRINKER_UNIT_BITS are divisions,
>> modulos and multiplications that do not care. Assert the unit size at
>> build time, since the layout depends on it.
>>
>> Assisted-by: LLM
>> Signed-off-by: Konstantin Khorenko <khorenko@xxxxxxxxxxxxx>
>> ---
<skipped>

>
> Acked-by: Qi Zheng <qi.zheng@xxxxxxxxx>

Qi, thank you for the review!

>
> Thanks,
> Qi
>
>
>