* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
[not found] <cover.1786003779.git.xueyuan.chen@vivo.com>
@ 2026-08-07 3:56 ` Sergey Senozhatsky
2026-08-07 10:57 ` Xueyuan Chen
0 siblings, 1 reply; 22+ messages in thread
From: Sergey Senozhatsky @ 2026-08-07 3:56 UTC (permalink / raw)
To: xueyuan.chen
Cc: Minchan Kim, Sergey Senozhatsky, Andrew Morton, linux-mm,
linux-kernel, xueyuan.chen21
On (26/08/06 16:27), xueyuan.chen@vivo.com wrote:
> On an Android device with 12 GB of RAM, observed zsmalloc compaction
> durations had a p95 of 38.86 ms and a maximum of 269.68 ms, motivating a
> per-scan reclaim goal.
Would it be possible to give a little more data? What was the
fragmentation ratio, how much memory was saved during that
auto-compaction, etc. If possible.
Somewhere in the back of my mind I was thinking about, maybe,
disabling (removing) zsmalloc shrinker callbacks, in other words
disabling auto-compaction. We have a sysfs knob for pool compaction
for system that still want to run compaction. So I'm leaning towards
removal of shrinker callbacks from zsmalloc.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-08-07 3:56 ` [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware Sergey Senozhatsky
@ 2026-08-07 10:57 ` Xueyuan Chen
2026-08-07 12:12 ` Sergey Senozhatsky
0 siblings, 1 reply; 22+ messages in thread
From: Xueyuan Chen @ 2026-08-07 10:57 UTC (permalink / raw)
To: Sergey Senozhatsky
Cc: Minchan Kim, Andrew Morton, linux-mm, linux-kernel, xueyuan.chen21
Hi Sergey,
Here is some additional data:
I used the following definitions:
compactable ratio = freeable_pages / total_pages
memory reclaimed = pages_freed * PAGE_SIZE
freeable_pages is the estimate before compaction, based on the same
calculation as zs_shrinker_count(), while pages_freed is the actual
number of backing pages released.
There were 264 callbacks in the trace:
callback elapsed time:
median: 5.77 ms
p95: 55.82 ms
maximum: 271.36 ms
compactable ratio before compaction:
median: 0.32%
p95: 2.86%
maximum: 8.33%
memory reclaimed per callback:
median: 3.80 MiB
p95: 30.45 MiB
maximum: 92.73 MiB
The longest callback took 271.36 ms. Its compactable ratio was 3.25%,
and it released 7,650 pages, or about 29.88 MiB.
There was also a 241.91 ms callback (with 30 schedule-outs) with a
compactable ratio of 0.44%. It released 1,019 pages, or about
3.98 MiB.
Based on this data, it seems better to remove the shrinker.
Would you prefer that I change v2 to remove the zsmalloc shrinker
callbacks directly?
Thanks,
Xueyuan
On 8/7/2026 11:56 AM, Sergey Senozhatsky wrote:
> On (26/08/06 16:27), xueyuan.chen@vivo.com wrote:
>> On an Android device with 12 GB of RAM, observed zsmalloc compaction
>> durations had a p95 of 38.86 ms and a maximum of 269.68 ms, motivating a
>> per-scan reclaim goal.
> Would it be possible to give a little more data? What was the
> fragmentation ratio, how much memory was saved during that
> auto-compaction, etc. If possible.
>
> Somewhere in the back of my mind I was thinking about, maybe,
> disabling (removing) zsmalloc shrinker callbacks, in other words
> disabling auto-compaction. We have a sysfs knob for pool compaction
> for system that still want to run compaction. So I'm leaning towards
> removal of shrinker callbacks from zsmalloc.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-08-07 10:57 ` Xueyuan Chen
@ 2026-08-07 12:12 ` Sergey Senozhatsky
2026-08-07 16:25 ` Nhat Pham
0 siblings, 1 reply; 22+ messages in thread
From: Sergey Senozhatsky @ 2026-08-07 12:12 UTC (permalink / raw)
To: Xueyuan Chen, Nhat Pham, Barry Song, Yosry Ahmed,
Johannes Weiner, Brian Geffon
Cc: Sergey Senozhatsky, Minchan Kim, Andrew Morton, linux-mm,
linux-kernel, xueyuan.chen21
On (26/08/07 18:57), Xueyuan Chen wrote:
> Hi Sergey,
>
> Here is some additional data:
>
> I used the following definitions:
> compactable ratio = freeable_pages / total_pages
> memory reclaimed = pages_freed * PAGE_SIZE
>
> freeable_pages is the estimate before compaction, based on the same
> calculation as zs_shrinker_count(), while pages_freed is the actual
> number of backing pages released.
>
> There were 264 callbacks in the trace:
> callback elapsed time:
> median: 5.77 ms
> p95: 55.82 ms
> maximum: 271.36 ms
>
> compactable ratio before compaction:
> median: 0.32%
> p95: 2.86%
> maximum: 8.33%
>
> memory reclaimed per callback:
> median: 3.80 MiB
> p95: 30.45 MiB
> maximum: 92.73 MiB
>
> The longest callback took 271.36 ms. Its compactable ratio was 3.25%,
> and it released 7,650 pages, or about 29.88 MiB.
>
> There was also a 241.91 ms callback (with 30 schedule-outs) with a
> compactable ratio of 0.44%. It released 1,019 pages, or about
> 3.98 MiB.
>
> Based on this data, it seems better to remove the shrinker.
>
> Would you prefer that I change v2 to remove the zsmalloc shrinker
> callbacks directly?
Let's bring in heavy artillery to this discussion, in addition to Andrew
and Minchan, adding Nhat, Yosry, Barry, Johannes, Brian (random order).
Folks, I'm bullish on removal of zsmalloc shrinker callbacks.
I don't think those buy us much apart from memcpy-s and lock
contention. Systems that want to compact zsmalloc have a sysfs
knob (and API) to do so (based on zram mm_stat numbers).
Any thoughts?
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-08-07 12:12 ` Sergey Senozhatsky
@ 2026-08-07 16:25 ` Nhat Pham
2026-08-11 9:03 ` Xueyuan Chen
` (2 more replies)
0 siblings, 3 replies; 22+ messages in thread
From: Nhat Pham @ 2026-08-07 16:25 UTC (permalink / raw)
To: Sergey Senozhatsky
Cc: Xueyuan Chen, Barry Song, Yosry Ahmed, Johannes Weiner,
Brian Geffon, Minchan Kim, Andrew Morton, linux-mm, linux-kernel,
xueyuan.chen21
On Fri, Aug 7, 2026 at 5:12 AM Sergey Senozhatsky
<senozhatsky@chromium.org> wrote:
>
> On (26/08/07 18:57), Xueyuan Chen wrote:
> > Hi Sergey,
> >
> > Here is some additional data:
> >
> > I used the following definitions:
> > compactable ratio = freeable_pages / total_pages
> > memory reclaimed = pages_freed * PAGE_SIZE
> >
> > freeable_pages is the estimate before compaction, based on the same
> > calculation as zs_shrinker_count(), while pages_freed is the actual
> > number of backing pages released.
> >
> > There were 264 callbacks in the trace:
> > callback elapsed time:
> > median: 5.77 ms
> > p95: 55.82 ms
> > maximum: 271.36 ms
> >
> > compactable ratio before compaction:
> > median: 0.32%
> > p95: 2.86%
> > maximum: 8.33%
> >
> > memory reclaimed per callback:
> > median: 3.80 MiB
> > p95: 30.45 MiB
> > maximum: 92.73 MiB
> >
> > The longest callback took 271.36 ms. Its compactable ratio was 3.25%,
> > and it released 7,650 pages, or about 29.88 MiB.
> >
> > There was also a 241.91 ms callback (with 30 schedule-outs) with a
> > compactable ratio of 0.44%. It released 1,019 pages, or about
> > 3.98 MiB.
> >
> > Based on this data, it seems better to remove the shrinker.
> >
> > Would you prefer that I change v2 to remove the zsmalloc shrinker
> > callbacks directly?
>
> Let's bring in heavy artillery to this discussion, in addition to Andrew
> and Minchan, adding Nhat, Yosry, Barry, Johannes, Brian (random order).
>
> Folks, I'm bullish on removal of zsmalloc shrinker callbacks.
> I don't think those buy us much apart from memcpy-s and lock
> contention. Systems that want to compact zsmalloc have a sysfs
> knob (and API) to do so (based on zram mm_stat numbers).
Hmm we'd need to collect more data in our workloads to determine, but
if we can compute compactable ratio (freeable_pages / total_pages) on
a per size class basis, can we just skip the size class whose ratio is
too bad? Would that at least cut down on the vast majority of
fruitless memcpys and lock acquisitions etc?
I'm always a bit hesitant to over-rely on userspace, especially when
kernel has information to do something smart about it. It might not
react in time, and many proactive reclaiming schemes back off under
heavy memory pressure.
>
> Any thoughts?
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-08-07 16:25 ` Nhat Pham
@ 2026-08-11 9:03 ` Xueyuan Chen
2026-08-11 16:25 ` Nhat Pham
2026-10-29 1:43 ` Sergey Senozhatsky
2026-10-29 2:26 ` Sergey Senozhatsky
2 siblings, 1 reply; 22+ messages in thread
From: Xueyuan Chen @ 2026-08-11 9:03 UTC (permalink / raw)
To: Nhat Pham, Sergey Senozhatsky
Cc: Barry Song, Yosry Ahmed, Johannes Weiner, Brian Geffon,
Minchan Kim, Andrew Morton, linux-mm, linux-kernel,
xueyuan.chen21
On 8/8/2026 12:25 AM, Nhat Pham wrote:
> On Fri, Aug 7, 2026 at 5:12 AM Sergey Senozhatsky
> <senozhatsky@chromium.org> wrote:
>> On (26/08/07 18:57), Xueyuan Chen wrote:
>>> Hi Sergey,
>>>
>>> Here is some additional data:
>>>
>>> I used the following definitions:
>>> compactable ratio = freeable_pages / total_pages
>>> memory reclaimed = pages_freed * PAGE_SIZE
>>>
>>> freeable_pages is the estimate before compaction, based on the same
>>> calculation as zs_shrinker_count(), while pages_freed is the actual
>>> number of backing pages released.
>>>
>>> There were 264 callbacks in the trace:
>>> callback elapsed time:
>>> median: 5.77 ms
>>> p95: 55.82 ms
>>> maximum: 271.36 ms
>>>
>>> compactable ratio before compaction:
>>> median: 0.32%
>>> p95: 2.86%
>>> maximum: 8.33%
>>>
>>> memory reclaimed per callback:
>>> median: 3.80 MiB
>>> p95: 30.45 MiB
>>> maximum: 92.73 MiB
>>>
>>> The longest callback took 271.36 ms. Its compactable ratio was 3.25%,
>>> and it released 7,650 pages, or about 29.88 MiB.
>>>
>>> There was also a 241.91 ms callback (with 30 schedule-outs) with a
>>> compactable ratio of 0.44%. It released 1,019 pages, or about
>>> 3.98 MiB.
>>>
>>> Based on this data, it seems better to remove the shrinker.
>>>
>>> Would you prefer that I change v2 to remove the zsmalloc shrinker
>>> callbacks directly?
>> Let's bring in heavy artillery to this discussion, in addition to Andrew
>> and Minchan, adding Nhat, Yosry, Barry, Johannes, Brian (random order).
>>
>> Folks, I'm bullish on removal of zsmalloc shrinker callbacks.
>> I don't think those buy us much apart from memcpy-s and lock
>> contention. Systems that want to compact zsmalloc have a sysfs
>> knob (and API) to do so (based on zram mm_stat numbers).
> Hmm we'd need to collect more data in our workloads to determine, but
> if we can compute compactable ratio (freeable_pages / total_pages) on
> a per size class basis, can we just skip the size class whose ratio is
> too bad? Would that at least cut down on the vast majority of
> fruitless memcpys and lock acquisitions etc?
>
> I'm always a bit hesitant to over-rely on userspace, especially when
> kernel has information to do something smart about it. It might not
> react in time, and many proactive reclaiming schemes back off under
> heavy memory pressure.
Hi Nhat,
I collected per size-class data. 53.7% of size classes have freeable==0,
so skipping them saves some time. However, 94.7% of zs_compact() time is
spent on classes where freeable > 0 — meaning the cost is dominated by
the actual compaction work, not by scanning empty classes.
That said, skipping freeable == 0 classes is still a worthwhile
optimization on its own — it avoids unnecessary write_lock,spin_lock.
But it would not meaningfully reduce the worst-case latency.
Thanks,
Xueyuan
>> Any thoughts?
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-08-11 9:03 ` Xueyuan Chen
@ 2026-08-11 16:25 ` Nhat Pham
2026-08-14 16:50 ` Xueyuan Chen
2026-08-18 12:11 ` Xueyuan Chen
0 siblings, 2 replies; 22+ messages in thread
From: Nhat Pham @ 2026-08-11 16:25 UTC (permalink / raw)
To: Xueyuan Chen
Cc: Sergey Senozhatsky, Barry Song, Yosry Ahmed, Johannes Weiner,
Brian Geffon, Minchan Kim, Andrew Morton, linux-mm, linux-kernel,
xueyuan.chen21
On Tue, Aug 11, 2026 at 2:04 AM Xueyuan Chen <xueyuan.chen@vivo.com> wrote:
>
>
> On 8/8/2026 12:25 AM, Nhat Pham wrote:
> > On Fri, Aug 7, 2026 at 5:12 AM Sergey Senozhatsky
> > <senozhatsky@chromium.org> wrote:
> >> On (26/08/07 18:57), Xueyuan Chen wrote:
> >>> Hi Sergey,
> >>>
> >>> Here is some additional data:
> >>>
> >>> I used the following definitions:
> >>> compactable ratio = freeable_pages / total_pages
> >>> memory reclaimed = pages_freed * PAGE_SIZE
> >>>
> >>> freeable_pages is the estimate before compaction, based on the same
> >>> calculation as zs_shrinker_count(), while pages_freed is the actual
> >>> number of backing pages released.
> >>>
> >>> There were 264 callbacks in the trace:
> >>> callback elapsed time:
> >>> median: 5.77 ms
> >>> p95: 55.82 ms
> >>> maximum: 271.36 ms
> >>>
> >>> compactable ratio before compaction:
> >>> median: 0.32%
> >>> p95: 2.86%
> >>> maximum: 8.33%
> >>>
> >>> memory reclaimed per callback:
> >>> median: 3.80 MiB
> >>> p95: 30.45 MiB
> >>> maximum: 92.73 MiB
> >>>
> >>> The longest callback took 271.36 ms. Its compactable ratio was 3.25%,
> >>> and it released 7,650 pages, or about 29.88 MiB.
> >>>
> >>> There was also a 241.91 ms callback (with 30 schedule-outs) with a
> >>> compactable ratio of 0.44%. It released 1,019 pages, or about
> >>> 3.98 MiB.
> >>>
> >>> Based on this data, it seems better to remove the shrinker.
> >>>
> >>> Would you prefer that I change v2 to remove the zsmalloc shrinker
> >>> callbacks directly?
> >> Let's bring in heavy artillery to this discussion, in addition to Andrew
> >> and Minchan, adding Nhat, Yosry, Barry, Johannes, Brian (random order).
> >>
> >> Folks, I'm bullish on removal of zsmalloc shrinker callbacks.
> >> I don't think those buy us much apart from memcpy-s and lock
> >> contention. Systems that want to compact zsmalloc have a sysfs
> >> knob (and API) to do so (based on zram mm_stat numbers).
> > Hmm we'd need to collect more data in our workloads to determine, but
> > if we can compute compactable ratio (freeable_pages / total_pages) on
> > a per size class basis, can we just skip the size class whose ratio is
> > too bad? Would that at least cut down on the vast majority of
> > fruitless memcpys and lock acquisitions etc?
> >
> > I'm always a bit hesitant to over-rely on userspace, especially when
> > kernel has information to do something smart about it. It might not
> > react in time, and many proactive reclaiming schemes back off under
> > heavy memory pressure.
>
> Hi Nhat,
>
> I collected per size-class data. 53.7% of size classes have freeable==0,
> so skipping them saves some time. However, 94.7% of zs_compact() time is
> spent on classes where freeable > 0 — meaning the cost is dominated by
> the actual compaction work, not by scanning empty classes.
What's the distribution of these? Say if I were to skip all size class
with compactable ratio below 20%, or those where we can free at least
one full zspage? (IIUC, we only free any memory at all if a zspage got
freed up from our internal compaction, correct?).
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-08-11 16:25 ` Nhat Pham
@ 2026-08-14 16:50 ` Xueyuan Chen
2026-08-18 12:11 ` Xueyuan Chen
1 sibling, 0 replies; 22+ messages in thread
From: Xueyuan Chen @ 2026-08-14 16:50 UTC (permalink / raw)
To: Nhat Pham
Cc: Xueyuan Chen, Sergey Senozhatsky, Barry Song, Yosry Ahmed,
Johannes Weiner, Brian Geffon, Minchan Kim, Andrew Morton,
linux-mm, linux-kernel
On Wed, Aug 12, 2026 at 12:25 AM Nhat Pham <nphamcs@gmail.com> wrote:
>
> On Tue, Aug 11, 2026 at 2:04 AM Xueyuan Chen <xueyuan.chen@vivo.com> wrote:
> >
> >
> > On 8/8/2026 12:25 AM, Nhat Pham wrote:
> > > On Fri, Aug 7, 2026 at 5:12 AM Sergey Senozhatsky
> > > <senozhatsky@chromium.org> wrote:
> > >> On (26/08/07 18:57), Xueyuan Chen wrote:
> > >>> Hi Sergey,
> > >>>
> > >>> Here is some additional data:
> > >>>
> > >>> I used the following definitions:
> > >>> compactable ratio = freeable_pages / total_pages
> > >>> memory reclaimed = pages_freed * PAGE_SIZE
> > >>>
> > >>> freeable_pages is the estimate before compaction, based on the same
> > >>> calculation as zs_shrinker_count(), while pages_freed is the actual
> > >>> number of backing pages released.
> > >>>
> > >>> There were 264 callbacks in the trace:
> > >>> callback elapsed time:
> > >>> median: 5.77 ms
> > >>> p95: 55.82 ms
> > >>> maximum: 271.36 ms
> > >>>
> > >>> compactable ratio before compaction:
> > >>> median: 0.32%
> > >>> p95: 2.86%
> > >>> maximum: 8.33%
> > >>>
> > >>> memory reclaimed per callback:
> > >>> median: 3.80 MiB
> > >>> p95: 30.45 MiB
> > >>> maximum: 92.73 MiB
> > >>>
> > >>> The longest callback took 271.36 ms. Its compactable ratio was 3.25%,
> > >>> and it released 7,650 pages, or about 29.88 MiB.
> > >>>
> > >>> There was also a 241.91 ms callback (with 30 schedule-outs) with a
> > >>> compactable ratio of 0.44%. It released 1,019 pages, or about
> > >>> 3.98 MiB.
> > >>>
> > >>> Based on this data, it seems better to remove the shrinker.
> > >>>
> > >>> Would you prefer that I change v2 to remove the zsmalloc shrinker
> > >>> callbacks directly?
> > >> Let's bring in heavy artillery to this discussion, in addition to Andrew
> > >> and Minchan, adding Nhat, Yosry, Barry, Johannes, Brian (random order).
> > >>
> > >> Folks, I'm bullish on removal of zsmalloc shrinker callbacks.
> > >> I don't think those buy us much apart from memcpy-s and lock
> > >> contention. Systems that want to compact zsmalloc have a sysfs
> > >> knob (and API) to do so (based on zram mm_stat numbers).
> > > Hmm we'd need to collect more data in our workloads to determine, but
> > > if we can compute compactable ratio (freeable_pages / total_pages) on
> > > a per size class basis, can we just skip the size class whose ratio is
> > > too bad? Would that at least cut down on the vast majority of
> > > fruitless memcpys and lock acquisitions etc?
> > >
> > > I'm always a bit hesitant to over-rely on userspace, especially when
> > > kernel has information to do something smart about it. It might not
> > > react in time, and many proactive reclaiming schemes back off under
> > > heavy memory pressure.
> >
> > Hi Nhat,
> >
> > I collected per size-class data. 53.7% of size classes have freeable==0,
> > so skipping them saves some time. However, 94.7% of zs_compact() time is
> > spent on classes where freeable > 0 — meaning the cost is dominated by
> > the actual compaction work, not by scanning empty classes.
>
Hi Nhat,
Sorry for the late reply.
> What's the distribution of these? Say if I were to skip all size class
> with compactable ratio below 20%, or those where we can free at least
> one full zspage? (IIUC, we only free any memory at all if a zspage got
> freed up from our internal compaction, correct?).
You are right, we only free the backing pages when a full zspage is emptied
by compaction.
My test device had some problems, I need some time to collect new data.
The good news is the per-size-class distribution should be ready next week.
Thanks
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-08-11 16:25 ` Nhat Pham
2026-08-14 16:50 ` Xueyuan Chen
@ 2026-08-18 12:11 ` Xueyuan Chen
1 sibling, 0 replies; 22+ messages in thread
From: Xueyuan Chen @ 2026-08-18 12:11 UTC (permalink / raw)
To: Nhat Pham
Cc: Sergey Senozhatsky, Barry Song, Yosry Ahmed, Johannes Weiner,
Brian Geffon, Minchan Kim, Andrew Morton, linux-mm, linux-kernel,
xueyuan.chen21
On 8/12/2026 12:25 AM, Nhat Pham wrote:
> On Tue, Aug 11, 2026 at 2:04 AM Xueyuan Chen <xueyuan.chen@vivo.com> wrote:
>>
>> On 8/8/2026 12:25 AM, Nhat Pham wrote:
>>> On Fri, Aug 7, 2026 at 5:12 AM Sergey Senozhatsky
>>> <senozhatsky@chromium.org> wrote:
>>>> On (26/08/07 18:57), Xueyuan Chen wrote:
>>>>> Hi Sergey,
>>>>>
>>>>> Here is some additional data:
>>>>>
>>>>> I used the following definitions:
>>>>> compactable ratio = freeable_pages / total_pages
>>>>> memory reclaimed = pages_freed * PAGE_SIZE
>>>>>
>>>>> freeable_pages is the estimate before compaction, based on the same
>>>>> calculation as zs_shrinker_count(), while pages_freed is the actual
>>>>> number of backing pages released.
>>>>>
>>>>> There were 264 callbacks in the trace:
>>>>> callback elapsed time:
>>>>> median: 5.77 ms
>>>>> p95: 55.82 ms
>>>>> maximum: 271.36 ms
>>>>>
>>>>> compactable ratio before compaction:
>>>>> median: 0.32%
>>>>> p95: 2.86%
>>>>> maximum: 8.33%
>>>>>
>>>>> memory reclaimed per callback:
>>>>> median: 3.80 MiB
>>>>> p95: 30.45 MiB
>>>>> maximum: 92.73 MiB
>>>>>
>>>>> The longest callback took 271.36 ms. Its compactable ratio was 3.25%,
>>>>> and it released 7,650 pages, or about 29.88 MiB.
>>>>>
>>>>> There was also a 241.91 ms callback (with 30 schedule-outs) with a
>>>>> compactable ratio of 0.44%. It released 1,019 pages, or about
>>>>> 3.98 MiB.
>>>>>
>>>>> Based on this data, it seems better to remove the shrinker.
>>>>>
>>>>> Would you prefer that I change v2 to remove the zsmalloc shrinker
>>>>> callbacks directly?
>>>> Let's bring in heavy artillery to this discussion, in addition to Andrew
>>>> and Minchan, adding Nhat, Yosry, Barry, Johannes, Brian (random order).
>>>>
>>>> Folks, I'm bullish on removal of zsmalloc shrinker callbacks.
>>>> I don't think those buy us much apart from memcpy-s and lock
>>>> contention. Systems that want to compact zsmalloc have a sysfs
>>>> knob (and API) to do so (based on zram mm_stat numbers).
>>> Hmm we'd need to collect more data in our workloads to determine, but
>>> if we can compute compactable ratio (freeable_pages / total_pages) on
>>> a per size class basis, can we just skip the size class whose ratio is
>>> too bad? Would that at least cut down on the vast majority of
>>> fruitless memcpys and lock acquisitions etc?
>>>
>>> I'm always a bit hesitant to over-rely on userspace, especially when
>>> kernel has information to do something smart about it. It might not
>>> react in time, and many proactive reclaiming schemes back off under
>>> heavy memory pressure.
>> Hi Nhat,
>>
>> I collected per size-class data. 53.7% of size classes have freeable==0,
>> so skipping them saves some time. However, 94.7% of zs_compact() time is
>> spent on classes where freeable > 0 — meaning the cost is dominated by
>> the actual compaction work, not by scanning empty classes.
> What's the distribution of these? Say if I were to skip all size class
> with compactable ratio below 20%, or those where we can free at least
> one full zspage? (IIUC, we only free any memory at all if a zspage got
> freed up from our internal compaction, correct?).
Hi Nhat,
Across 106 zram0 compaction callbacks, there were 6,246 per-class
events with freeable > 0, covering 118 size classes.
The data by object size was:
| object size (bytes) | classes | events | total pages | freeable pages |
| [0, 256) | 14 | 570 | 182297 | 6728 |
| [256, 512) | 16 | 748 | 480127 | 14526 |
| [512, 1024) | 30 | 1586 | 2677075 | 71934 |
| [1024, 2048) | 36 | 2180 | 11990170 | 294133 |
| [2048, 3072) | 15 | 821 | 5089301 | 106204 |
| [3072, 4096] | 7 | 341 | 1170843 | 20012 |
The compactable-ratio distribution at class-compaction entry was:
p25: 0.75%
median: 1.65%
p90: 6.76%
p95: 9.42%
p99: 14.52%
maximum: 30.99%
Only 12 out of 6,246 events had a ratio of 20% or higher, so a 20%
threshold would skip nearly all of them.
| freeable pages | total pages | compactable ratio |
class A | 10 | 20 | 50% |
class B | 20 | 50 | 40% |
In this example, class B has more freeable pages even though its ratio
is lower. So I don't think the ratio alone is enough to decide whether
to compact a class.
Thanks,
Xueyuan
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-08-07 16:25 ` Nhat Pham
2026-08-11 9:03 ` Xueyuan Chen
@ 2026-10-29 1:43 ` Sergey Senozhatsky
2026-10-29 1:48 ` Sergey Senozhatsky
2026-10-30 2:05 ` Xueyuan Chen
2026-10-29 2:26 ` Sergey Senozhatsky
2 siblings, 2 replies; 22+ messages in thread
From: Sergey Senozhatsky @ 2026-10-29 1:43 UTC (permalink / raw)
To: Nhat Pham
Cc: Sergey Senozhatsky, Xueyuan Chen, Barry Song, Yosry Ahmed,
Johannes Weiner, Brian Geffon, Minchan Kim, Andrew Morton,
linux-mm, linux-kernel, xueyuan.chen21
On (26/08/07 09:25), Nhat Pham wrote:
> > On (26/08/07 18:57), Xueyuan Chen wrote:
> > > Hi Sergey,
> > >
> > > Here is some additional data:
> > >
> > > I used the following definitions:
> > > compactable ratio = freeable_pages / total_pages
> > > memory reclaimed = pages_freed * PAGE_SIZE
> > >
> > > freeable_pages is the estimate before compaction, based on the same
> > > calculation as zs_shrinker_count(), while pages_freed is the actual
> > > number of backing pages released.
> > >
> > > There were 264 callbacks in the trace:
> > > callback elapsed time:
> > > median: 5.77 ms
> > > p95: 55.82 ms
> > > maximum: 271.36 ms
> > >
> > > compactable ratio before compaction:
> > > median: 0.32%
> > > p95: 2.86%
> > > maximum: 8.33%
> > >
> > > memory reclaimed per callback:
> > > median: 3.80 MiB
> > > p95: 30.45 MiB
> > > maximum: 92.73 MiB
> > >
> > > The longest callback took 271.36 ms. Its compactable ratio was 3.25%,
> > > and it released 7,650 pages, or about 29.88 MiB.
> > >
> > > There was also a 241.91 ms callback (with 30 schedule-outs) with a
> > > compactable ratio of 0.44%. It released 1,019 pages, or about
> > > 3.98 MiB.
> > >
> > > Based on this data, it seems better to remove the shrinker.
> > >
> > > Would you prefer that I change v2 to remove the zsmalloc shrinker
> > > callbacks directly?
> >
> > Let's bring in heavy artillery to this discussion, in addition to Andrew
> > and Minchan, adding Nhat, Yosry, Barry, Johannes, Brian (random order).
> >
> > Folks, I'm bullish on removal of zsmalloc shrinker callbacks.
> > I don't think those buy us much apart from memcpy-s and lock
> > contention. Systems that want to compact zsmalloc have a sysfs
> > knob (and API) to do so (based on zram mm_stat numbers).
>
> Hmm we'd need to collect more data in our workloads to determine, but
> if we can compute compactable ratio (freeable_pages / total_pages) on
> a per size class basis, can we just skip the size class whose ratio is
> too bad? Would that at least cut down on the vast majority of
> fruitless memcpys and lock acquisitions etc?
>
> I'm always a bit hesitant to over-rely on userspace, especially when
> kernel has information to do something smart about it. It might not
> react in time, and many proactive reclaiming schemes back off under
> heavy memory pressure.
Apologies for the delay.
The thing about shrinker compaction is that it's sort of on the
wrong end. It doesn't trigger compaction when memory is plentiful,
no matter the internal fragmentation rate, and start firing compaction
scans when memory pressure hits. The problem with this is that, now
compaction moves objects (if can compact zspages) and releases empty
zspages, in parallel with potentially heavy swapping out activities,
which can simply allocate those released pages back. Which seems like
a useless exercise and needless memcpy-s. So I was thinking about
either putting it under config or just removing it (this might be a
harder decision).
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-10-29 1:43 ` Sergey Senozhatsky
@ 2026-10-29 1:48 ` Sergey Senozhatsky
2026-11-02 2:58 ` Xueyuan Chen
2026-11-04 18:06 ` Nhat Pham
2026-10-30 2:05 ` Xueyuan Chen
1 sibling, 2 replies; 22+ messages in thread
From: Sergey Senozhatsky @ 2026-10-29 1:48 UTC (permalink / raw)
To: Nhat Pham
Cc: Xueyuan Chen, Barry Song, Yosry Ahmed, Johannes Weiner,
Brian Geffon, Minchan Kim, Andrew Morton, linux-mm, linux-kernel,
xueyuan.chen21, Sergey Senozhatsky
On (26/10/29 10:43), Sergey Senozhatsky wrote:
[..]
> > Hmm we'd need to collect more data in our workloads to determine, but
> > if we can compute compactable ratio (freeable_pages / total_pages) on
> > a per size class basis, can we just skip the size class whose ratio is
> > too bad? Would that at least cut down on the vast majority of
> > fruitless memcpys and lock acquisitions etc?
> >
> > I'm always a bit hesitant to over-rely on userspace, especially when
> > kernel has information to do something smart about it. It might not
> > react in time, and many proactive reclaiming schemes back off under
> > heavy memory pressure.
>
> Apologies for the delay.
>
> The thing about shrinker compaction is that it's sort of on the
> wrong end. It doesn't trigger compaction when memory is plentiful,
> no matter the internal fragmentation rate, and start firing compaction
> scans when memory pressure hits. The problem with this is that, now
> compaction moves objects (if can compact zspages) and releases empty
> zspages, in parallel with potentially heavy swapping out activities,
> which can simply allocate those released pages back. Which seems like
> a useless exercise and needless memcpy-s. So I was thinking about
> either putting it under config or just removing it (this might be a
> harder decision).
In embedded (android/bookOS/etc.) there is a daemon, that triggers
various zram activities. We can wire in pool-compaction (once under
memory pressure), which is a zram sysfs device attribute, instead
of pondering zsmalloc with scan callbacks.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-08-07 16:25 ` Nhat Pham
2026-08-11 9:03 ` Xueyuan Chen
2026-10-29 1:43 ` Sergey Senozhatsky
@ 2026-10-29 2:26 ` Sergey Senozhatsky
2026-11-01 23:47 ` Sergey Senozhatsky
2 siblings, 1 reply; 22+ messages in thread
From: Sergey Senozhatsky @ 2026-10-29 2:26 UTC (permalink / raw)
To: Nhat Pham
Cc: Sergey Senozhatsky, Xueyuan Chen, Barry Song, Yosry Ahmed,
Johannes Weiner, Brian Geffon, Minchan Kim, Andrew Morton,
linux-mm, linux-kernel, xueyuan.chen21
On (26/08/07 09:25), Nhat Pham wrote:
> Hmm we'd need to collect more data in our workloads to determine, but
> if we can compute compactable ratio (freeable_pages / total_pages) on
> a per size class basis, can we just skip the size class whose ratio is
> too bad? Would that at least cut down on the vast majority of
> fruitless memcpys and lock acquisitions etc?
To calculate those we need to tool pool/class locks. But technically
possible. Not sure, how would be determine the threshold tho.
On the other alternative is quite simple. We can make it
"default ZSWAP", for example.
---
diff --git a/mm/Kconfig b/mm/Kconfig
index afff1b25b543..72542946bc53 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -157,6 +157,17 @@ config ZSMALLOC_CHAIN_SIZE
For more information, see zsmalloc documentation.
+config ZSMALLOC_SHRINKER
+ bool "Enable zsmalloc pool shrinker"
+ default y
+ help
+ This option enables the zsmalloc pool shrinker, which allows
+ the zsmalloc pool to be shrunk when the system is under memory
+ pressure. The shrinker will attempt to free up memory by
+ compacting zspages and releasing empty zspages back to the system.
+
+ If unsure, say N.
+
endmenu
menu "Slab allocator options"
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 7ef80e0da626..e0d7ab9142bb 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -276,8 +276,10 @@ struct zs_pool {
struct zs_pool_stats stats;
+#ifdef CONFIG_ZSMALLOC_SHRINKER
/* Compact classes */
struct shrinker *shrinker;
+#endif
#ifdef CONFIG_ZSMALLOC_STAT
struct dentry *stat_dentry;
@@ -2050,8 +2052,9 @@ void zs_pool_stats(struct zs_pool *pool, struct zs_pool_stats *stats)
}
EXPORT_SYMBOL_GPL(zs_pool_stats);
+#ifdef CONFIG_ZSMALLOC_SHRINKER
static unsigned long zs_shrinker_scan(struct shrinker *shrinker,
- struct shrink_control *sc)
+ struct shrink_control *sc)
{
unsigned long pages_freed;
struct zs_pool *pool = shrinker->private_data;
@@ -2067,7 +2070,7 @@ static unsigned long zs_shrinker_scan(struct shrinker *shrinker,
}
static unsigned long zs_shrinker_count(struct shrinker *shrinker,
- struct shrink_control *sc)
+ struct shrink_control *sc)
{
int i;
struct size_class *class;
@@ -2105,6 +2108,10 @@ static int zs_register_shrinker(struct zs_pool *pool)
return 0;
}
+#else
+static void zs_unregister_shrinker(struct zs_pool *pool) { }
+static int zs_register_shrinker(struct zs_pool *pool) { return 0; }
+#endif
static int calculate_zspage_chain_size(int class_size)
{
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-10-29 1:43 ` Sergey Senozhatsky
2026-10-29 1:48 ` Sergey Senozhatsky
@ 2026-10-30 2:05 ` Xueyuan Chen
1 sibling, 0 replies; 22+ messages in thread
From: Xueyuan Chen @ 2026-10-30 2:05 UTC (permalink / raw)
To: Sergey Senozhatsky
Cc: Nhat Pham, Xueyuan Chen, Barry Song, Yosry Ahmed,
Johannes Weiner, Brian Geffon, Minchan Kim, Andrew Morton,
linux-mm, linux-kernel, xueyuan.chen21
On 2026-10-29 10:43 +0900, Sergey Senozhatsky wrote:
> On (26/08/07 09:25), Nhat Pham wrote:
> > > On (26/08/07 18:57), Xueyuan Chen wrote:
> > > > Hi Sergey,
> > > >
> > > > Here is some additional data:
> > > >
> > > > I used the following definitions:
> > > > compactable ratio = freeable_pages / total_pages
> > > > memory reclaimed = pages_freed * PAGE_SIZE
> > > >
> > > > freeable_pages is the estimate before compaction, based on the same
> > > > calculation as zs_shrinker_count(), while pages_freed is the actual
> > > > number of backing pages released.
> > > >
> > > > There were 264 callbacks in the trace:
> > > > callback elapsed time:
> > > > median: 5.77 ms
> > > > p95: 55.82 ms
> > > > maximum: 271.36 ms
> > > >
> > > > compactable ratio before compaction:
> > > > median: 0.32%
> > > > p95: 2.86%
> > > > maximum: 8.33%
> > > >
> > > > memory reclaimed per callback:
> > > > median: 3.80 MiB
> > > > p95: 30.45 MiB
> > > > maximum: 92.73 MiB
> > > >
> > > > The longest callback took 271.36 ms. Its compactable ratio was 3.25%,
> > > > and it released 7,650 pages, or about 29.88 MiB.
> > > >
> > > > There was also a 241.91 ms callback (with 30 schedule-outs) with a
> > > > compactable ratio of 0.44%. It released 1,019 pages, or about
> > > > 3.98 MiB.
> > > >
> > > > Based on this data, it seems better to remove the shrinker.
> > > >
> > > > Would you prefer that I change v2 to remove the zsmalloc shrinker
> > > > callbacks directly?
> > >
> > > Let's bring in heavy artillery to this discussion, in addition to Andrew
> > > and Minchan, adding Nhat, Yosry, Barry, Johannes, Brian (random order).
> > >
> > > Folks, I'm bullish on removal of zsmalloc shrinker callbacks.
> > > I don't think those buy us much apart from memcpy-s and lock
> > > contention. Systems that want to compact zsmalloc have a sysfs
> > > knob (and API) to do so (based on zram mm_stat numbers).
> >
> > Hmm we'd need to collect more data in our workloads to determine, but
> > if we can compute compactable ratio (freeable_pages / total_pages) on
> > a per size class basis, can we just skip the size class whose ratio is
> > too bad? Would that at least cut down on the vast majority of
> > fruitless memcpys and lock acquisitions etc?
> >
> > I'm always a bit hesitant to over-rely on userspace, especially when
> > kernel has information to do something smart about it. It might not
> > react in time, and many proactive reclaiming schemes back off under
> > heavy memory pressure.
>
> Apologies for the delay.
>
> The thing about shrinker compaction is that it's sort of on the
> wrong end. It doesn't trigger compaction when memory is plentiful,
> no matter the internal fragmentation rate, and start firing compaction
Makes sense to me. The fragmentation ratio alone doesn't determine the latency
impact, that also depends on how muchdata compaction needs to move and whether
it overlaps with foreground zram activity.
--
Thanks,
Xueyuan
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-10-29 2:26 ` Sergey Senozhatsky
@ 2026-11-01 23:47 ` Sergey Senozhatsky
2026-11-02 20:24 ` Chris Wiseman
0 siblings, 1 reply; 22+ messages in thread
From: Sergey Senozhatsky @ 2026-11-01 23:47 UTC (permalink / raw)
To: Sergey Senozhatsky
Cc: Nhat Pham, Xueyuan Chen, Barry Song, Yosry Ahmed, Chris Wiseman,
Johannes Weiner, Brian Geffon, Minchan Kim, Andrew Morton,
linux-mm, linux-kernel, xueyuan.chen21
Adding Chris for visibility
On (26/10/29 11:26), Sergey Senozhatsky wrote:
> On (26/08/07 09:25), Nhat Pham wrote:
> > Hmm we'd need to collect more data in our workloads to determine, but
> > if we can compute compactable ratio (freeable_pages / total_pages) on
> > a per size class basis, can we just skip the size class whose ratio is
> > too bad? Would that at least cut down on the vast majority of
> > fruitless memcpys and lock acquisitions etc?
[..]
> ---
>
> diff --git a/mm/Kconfig b/mm/Kconfig
> index afff1b25b543..72542946bc53 100644
> --- a/mm/Kconfig
> +++ b/mm/Kconfig
> @@ -157,6 +157,17 @@ config ZSMALLOC_CHAIN_SIZE
>
> For more information, see zsmalloc documentation.
>
> +config ZSMALLOC_SHRINKER
> + bool "Enable zsmalloc pool shrinker"
> + default y
> + help
> + This option enables the zsmalloc pool shrinker, which allows
> + the zsmalloc pool to be shrunk when the system is under memory
> + pressure. The shrinker will attempt to free up memory by
> + compacting zspages and releasing empty zspages back to the system.
> +
> + If unsure, say N.
> +
> endmenu
>
> menu "Slab allocator options"
> diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
> index 7ef80e0da626..e0d7ab9142bb 100644
> --- a/mm/zsmalloc.c
> +++ b/mm/zsmalloc.c
> @@ -276,8 +276,10 @@ struct zs_pool {
>
> struct zs_pool_stats stats;
>
> +#ifdef CONFIG_ZSMALLOC_SHRINKER
> /* Compact classes */
> struct shrinker *shrinker;
> +#endif
>
> #ifdef CONFIG_ZSMALLOC_STAT
> struct dentry *stat_dentry;
> @@ -2050,8 +2052,9 @@ void zs_pool_stats(struct zs_pool *pool, struct zs_pool_stats *stats)
> }
> EXPORT_SYMBOL_GPL(zs_pool_stats);
>
> +#ifdef CONFIG_ZSMALLOC_SHRINKER
> static unsigned long zs_shrinker_scan(struct shrinker *shrinker,
> - struct shrink_control *sc)
> + struct shrink_control *sc)
> {
> unsigned long pages_freed;
> struct zs_pool *pool = shrinker->private_data;
> @@ -2067,7 +2070,7 @@ static unsigned long zs_shrinker_scan(struct shrinker *shrinker,
> }
>
> static unsigned long zs_shrinker_count(struct shrinker *shrinker,
> - struct shrink_control *sc)
> + struct shrink_control *sc)
> {
> int i;
> struct size_class *class;
> @@ -2105,6 +2108,10 @@ static int zs_register_shrinker(struct zs_pool *pool)
>
> return 0;
> }
> +#else
> +static void zs_unregister_shrinker(struct zs_pool *pool) { }
> +static int zs_register_shrinker(struct zs_pool *pool) { return 0; }
> +#endif
>
> static int calculate_zspage_chain_size(int class_size)
> {
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-10-29 1:48 ` Sergey Senozhatsky
@ 2026-11-02 2:58 ` Xueyuan Chen
2026-11-04 18:06 ` Nhat Pham
1 sibling, 0 replies; 22+ messages in thread
From: Xueyuan Chen @ 2026-11-02 2:58 UTC (permalink / raw)
To: Sergey Senozhatsky
Cc: Nhat Pham, Xueyuan Chen, Barry Song, Yosry Ahmed,
Johannes Weiner, Brian Geffon, Minchan Kim, Andrew Morton,
linux-mm, linux-kernel, xueyuan.chen21
On 2026-10-29 10:48 +0900, Sergey Senozhatsky wrote:
> On (26/10/29 10:43), Sergey Senozhatsky wrote:
> [..]
> > > Hmm we'd need to collect more data in our workloads to determine, but
> > > if we can compute compactable ratio (freeable_pages / total_pages) on
> > > a per size class basis, can we just skip the size class whose ratio is
> > > too bad? Would that at least cut down on the vast majority of
> > > fruitless memcpys and lock acquisitions etc?
> > >
> > > I'm always a bit hesitant to over-rely on userspace, especially when
> > > kernel has information to do something smart about it. It might not
> > > react in time, and many proactive reclaiming schemes back off under
> > > heavy memory pressure.
> >
> > Apologies for the delay.
> >
> > The thing about shrinker compaction is that it's sort of on the
> > wrong end. It doesn't trigger compaction when memory is plentiful,
> > no matter the internal fragmentation rate, and start firing compaction
> > scans when memory pressure hits. The problem with this is that, now
> > compaction moves objects (if can compact zspages) and releases empty
> > zspages, in parallel with potentially heavy swapping out activities,
> > which can simply allocate those released pages back. Which seems like
> > a useless exercise and needless memcpy-s. So I was thinking about
> > either putting it under config or just removing it (this might be a
> > harder decision).
>
> In embedded (android/bookOS/etc.) there is a daemon, that triggers
> various zram activities. We can wire in pool-compaction (once under
> memory pressure), which is a zram sysfs device attribute, instead
> of pondering zsmalloc with scan callbacks.
>
What triggering policy do you have in mind for the daemon?
If compaction is still triggered when the system is under memory
pressure, wouldn't it still overlap with heavy swap-out? The shrinker
can already run from kswapd, so moving it to a daemon alone would not
necessarily change that timing.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-11-01 23:47 ` Sergey Senozhatsky
@ 2026-11-02 20:24 ` Chris Wiseman
2026-11-04 17:57 ` Nhat Pham
0 siblings, 1 reply; 22+ messages in thread
From: Chris Wiseman @ 2026-11-02 20:24 UTC (permalink / raw)
To: Sergey Senozhatsky
Cc: Nhat Pham, Xueyuan Chen, Barry Song, Yosry Ahmed,
Johannes Weiner, Brian Geffon, Minchan Kim, Andrew Morton,
linux-mm, linux-kernel, xueyuan.chen21, Chris Wiseman
On (26/11/02 08:47), Sergey Senozhatsky wrote:
> Adding Chris for visibility
Thanks for looping me in, Sergey.
I tested your CONFIG_ZSMALLOC_SHRINKER=n patch in ARM64 QEMU (7.3.0+, 16
boots per arm) by fragmenting zram0, triggering a manual compaction pass
at pressure onset via /sys/block/zram0/compact, driving ~240 MB of
swap-outs under memory pressure, and running a post-swap manual
compaction pass.
Your theory holds up: with the shrinker enabled, the kernel compacted
2,218 pages (~9 MB) in the middle of the swap-out, only for incoming
swap-outs to immediately reuse those pages. With
CONFIG_ZSMALLOC_SHRINKER=n, mid-swap compaction dropped to 0 and zram
pool memory was identical both during the swap-out (120.9 MB vs
121.0 MB) and after manual compaction (110.9 MB vs 111.2 MB).
I also tested adding the unlocked zs_can_compact() pre-check in
__zs_compact() on top of CONFIG_ZSMALLOC_SHRINKER=n, which cuts each
userspace /sys/block/zram0/compact scan from 97 us to 27 us:
Shrinker ON Shrinker OFF Shrinker OFF + pre-check
-------------------------------------------------------------------------------------
Pages compacted mid-swap 2,218 0 0
zram mem_used_total (mid-swap) 121.0 MB 120.9 MB 121.1 MB
zram mem_used_total (post-compact) 111.2 MB 110.9 MB 111.1 MB
/sys/block/zram0/compact scan time 96 us 97 us 27 us
Representative /sys/block/zram0/mm_stat snapshots:
BASE (CONFIG_ZSMALLOC_SHRINKER=y)
pre_onset: 184553472 58747279 82350080 0 82374656 0 0 0 0
onset_compact: 184553472 58747279 60456960 0 82374656 0 5345 0 0
after_swap_out: 334196736 107289761 120946688 0 120946688 0 7570 29 29
post_compact: 334749696 107472834 110907392 0 120946688 0 10016 29 29
PATCHED (CONFIG_ZSMALLOC_SHRINKER=n)
pre_onset: 184553472 58747279 82350080 0 82374656 0 0 0 0
onset_compact: 184553472 58747279 60456960 0 82374656 0 5345 0 0
after_swap_out: 334372864 107347183 120922112 0 120922112 0 5345 29 29
post_compact: 334995456 107550158 111009792 0 120922112 0 7767 29 29
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-11-02 20:24 ` Chris Wiseman
@ 2026-11-04 17:57 ` Nhat Pham
2026-11-04 18:46 ` Chris Wiseman
0 siblings, 1 reply; 22+ messages in thread
From: Nhat Pham @ 2026-11-04 17:57 UTC (permalink / raw)
To: Chris Wiseman
Cc: Sergey Senozhatsky, Xueyuan Chen, Barry Song, Yosry Ahmed,
Johannes Weiner, Brian Geffon, Minchan Kim, Andrew Morton,
linux-mm, linux-kernel, xueyuan.chen21
On Mon, Nov 2, 2026 at 1:24 PM Chris Wiseman <chriswiseman@google.com> wrote:
>
> On (26/11/02 08:47), Sergey Senozhatsky wrote:
> > Adding Chris for visibility
>
> Thanks for looping me in, Sergey.
>
> I tested your CONFIG_ZSMALLOC_SHRINKER=n patch in ARM64 QEMU (7.3.0+, 16
> boots per arm) by fragmenting zram0, triggering a manual compaction pass
> at pressure onset via /sys/block/zram0/compact, driving ~240 MB of
> swap-outs under memory pressure, and running a post-swap manual
> compaction pass.
>
> Your theory holds up: with the shrinker enabled, the kernel compacted
> 2,218 pages (~9 MB) in the middle of the swap-out, only for incoming
> swap-outs to immediately reuse those pages. With
> CONFIG_ZSMALLOC_SHRINKER=n, mid-swap compaction dropped to 0 and zram
> pool memory was identical both during the swap-out (120.9 MB vs
> 121.0 MB) and after manual compaction (110.9 MB vs 111.2 MB).
>
> I also tested adding the unlocked zs_can_compact() pre-check in
> __zs_compact() on top of CONFIG_ZSMALLOC_SHRINKER=n, which cuts each
> userspace /sys/block/zram0/compact scan from 97 us to 27 us:
Is this precheck basically checking if we can free at least one zspage
of the size class before proceeding? Yeah the number looks good -
let's add that, in parallel!
>
> Shrinker ON Shrinker OFF Shrinker OFF + pre-check
> -------------------------------------------------------------------------------------
> Pages compacted mid-swap 2,218 0 0
> zram mem_used_total (mid-swap) 121.0 MB 120.9 MB 121.1 MB
> zram mem_used_total (post-compact) 111.2 MB 110.9 MB 111.1 MB
> /sys/block/zram0/compact scan time 96 us 97 us 27 us
>
> Representative /sys/block/zram0/mm_stat snapshots:
>
> BASE (CONFIG_ZSMALLOC_SHRINKER=y)
> pre_onset: 184553472 58747279 82350080 0 82374656 0 0 0 0
> onset_compact: 184553472 58747279 60456960 0 82374656 0 5345 0 0
> after_swap_out: 334196736 107289761 120946688 0 120946688 0 7570 29 29
> post_compact: 334749696 107472834 110907392 0 120946688 0 10016 29 29
>
> PATCHED (CONFIG_ZSMALLOC_SHRINKER=n)
> pre_onset: 184553472 58747279 82350080 0 82374656 0 0 0 0
> onset_compact: 184553472 58747279 60456960 0 82374656 0 5345 0 0
> after_swap_out: 334372864 107347183 120922112 0 120922112 0 5345 29 29
> post_compact: 334995456 107550158 111009792 0 120922112 0 7767 29 29
Ah ok hmm. Sounds like internal compaction isn't that helpful, i.e
zsmalloc already does a pretty decent job at packing objects that
there aren't a terrible amount of internal fragmentation in the first
place...?
Should we do CONFIG_ZSMALLOC_SHRINKER (default to N or to
CONFIG_ZSWAP) for now, and remove it in a couple of releases if users
in the wild do not complain?
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-10-29 1:48 ` Sergey Senozhatsky
2026-11-02 2:58 ` Xueyuan Chen
@ 2026-11-04 18:06 ` Nhat Pham
1 sibling, 0 replies; 22+ messages in thread
From: Nhat Pham @ 2026-11-04 18:06 UTC (permalink / raw)
To: Sergey Senozhatsky
Cc: Xueyuan Chen, Barry Song, Yosry Ahmed, Johannes Weiner,
Brian Geffon, Minchan Kim, Andrew Morton, linux-mm, linux-kernel,
xueyuan.chen21
On Wed, Oct 28, 2026 at 6:48 PM Sergey Senozhatsky
<senozhatsky@chromium.org> wrote:
>
> On (26/10/29 10:43), Sergey Senozhatsky wrote:
> [..]
> > > Hmm we'd need to collect more data in our workloads to determine, but
> > > if we can compute compactable ratio (freeable_pages / total_pages) on
> > > a per size class basis, can we just skip the size class whose ratio is
> > > too bad? Would that at least cut down on the vast majority of
> > > fruitless memcpys and lock acquisitions etc?
> > >
> > > I'm always a bit hesitant to over-rely on userspace, especially when
> > > kernel has information to do something smart about it. It might not
> > > react in time, and many proactive reclaiming schemes back off under
> > > heavy memory pressure.
> >
> > Apologies for the delay.
> >
> > The thing about shrinker compaction is that it's sort of on the
> > wrong end. It doesn't trigger compaction when memory is plentiful,
> > no matter the internal fragmentation rate, and start firing compaction
> > scans when memory pressure hits. The problem with this is that, now
> > compaction moves objects (if can compact zspages) and releases empty
> > zspages, in parallel with potentially heavy swapping out activities,
> > which can simply allocate those released pages back. Which seems like
> > a useless exercise and needless memcpy-s. So I was thinking about
> > either putting it under config or just removing it (this might be a
> > harder decision).
Hmmm I suppose if the new objects belong to the fragmented size class,
then there is no point in doing defragmentation, because the new
objects will fill the holes.
If they are of different size classes though it's a win to free these
fragmented zspages and reallocate them to the size classes of the
incoming objects right?
I can't really say which is more likely without data... And it might
be workload/reclaim-behavior dependent...
(The size class check for fragmentation level to skip internal
compaction is nice here because is agnostic to distribution and
trigger points. We should land that regardless).
>
> In embedded (android/bookOS/etc.) there is a daemon, that triggers
> various zram activities. We can wire in pool-compaction (once under
> memory pressure), which is a zram sysfs device attribute, instead
> of pondering zsmalloc with scan callbacks.
Internally we use senpai, which trigger memory reclaim when there is
no memory pressure, to reclaim cold data (which in turns trigger
zsmalloc compaction).
It still does both zswapping and zsmalloc compaction in the same
round-ish though.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-11-04 17:57 ` Nhat Pham
@ 2026-11-04 18:46 ` Chris Wiseman
2026-11-04 21:54 ` Nhat Pham
0 siblings, 1 reply; 22+ messages in thread
From: Chris Wiseman @ 2026-11-04 18:46 UTC (permalink / raw)
To: Nhat Pham
Cc: Sergey Senozhatsky, Xueyuan Chen, Barry Song, Yosry Ahmed,
Johannes Weiner, Brian Geffon, Minchan Kim, Andrew Morton,
linux-mm, linux-kernel, xueyuan.chen21, Chris Wiseman
On Wed, Nov 4, 2026 at 9:57 AM Nhat Pham <nphamcs@gmail.com> wrote:
>
> Is this precheck basically checking if we can free at least one zspage
> of the size class before proceeding? Yeah the number looks good -
> let's add that, in parallel!
Yeah, it just checks if a bucket has enough wasted slots to free at
least one full page before taking the locks. Sergey pointed out those
two counters aren't atomic together so an unlocked check is just a
best-effort hint - if you and Sergey are good with that, happy to send a
patch.
> Ah ok hmm. Sounds like internal compaction isn't that helpful, i.e
> zsmalloc already does a pretty decent job at packing objects that
> there aren't a terrible amount of internal fragmentation in the first
> place...?
> Should we do CONFIG_ZSMALLOC_SHRINKER (default to N or to
> CONFIG_ZSWAP) for now, and remove it in a couple of releases if users
> in the wild do not complain?
Compaction still helps when we trigger it between bursts (freed ~21 MB
before the swap storm and ~10 MB after). It just wastes time running
mid-swap when new writes are filling those open slots right back up.
Defaulting CONFIG_ZSMALLOC_SHRINKER to N (or CONFIG_ZSWAP) for a couple
releases makes sense to me.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-11-04 18:46 ` Chris Wiseman
@ 2026-11-04 21:54 ` Nhat Pham
2026-11-05 1:10 ` Xueyuan Chen
2026-11-05 5:01 ` Sergey Senozhatsky
0 siblings, 2 replies; 22+ messages in thread
From: Nhat Pham @ 2026-11-04 21:54 UTC (permalink / raw)
To: Chris Wiseman
Cc: Sergey Senozhatsky, Xueyuan Chen, Barry Song, Yosry Ahmed,
Johannes Weiner, Brian Geffon, Minchan Kim, Andrew Morton,
linux-mm, linux-kernel, xueyuan.chen21
On Wed, Nov 4, 2026 at 11:46 AM Chris Wiseman <chriswiseman@google.com> wrote:
>
> On Wed, Nov 4, 2026 at 9:57 AM Nhat Pham <nphamcs@gmail.com> wrote:
> >
> > Is this precheck basically checking if we can free at least one zspage
> > of the size class before proceeding? Yeah the number looks good -
> > let's add that, in parallel!
>
> Yeah, it just checks if a bucket has enough wasted slots to free at
> least one full page before taking the locks. Sergey pointed out those
You meant full zspage here right? IIUC we keep the entire chain of
zpages around until the entire zspage is gone?
> two counters aren't atomic together so an unlocked check is just a
> best-effort hint - if you and Sergey are good with that, happy to send a
> patch.
Personally I'm happy with it being a best-effort hint!
We can also recheck after we acquire the lock (but I suspect it's
unlikely we'll get radically different decision?)
Sergey, how do you feel about this?
>
> > Ah ok hmm. Sounds like internal compaction isn't that helpful, i.e
> > zsmalloc already does a pretty decent job at packing objects that
> > there aren't a terrible amount of internal fragmentation in the first
> > place...?
> > Should we do CONFIG_ZSMALLOC_SHRINKER (default to N or to
> > CONFIG_ZSWAP) for now, and remove it in a couple of releases if users
> > in the wild do not complain?
>
> Compaction still helps when we trigger it between bursts (freed ~21 MB
> before the swap storm and ~10 MB after). It just wastes time running
> mid-swap when new writes are filling those open slots right back up.
> Defaulting CONFIG_ZSMALLOC_SHRINKER to N (or CONFIG_ZSWAP) for a couple
> releases makes sense to me.
SGTM, but I'll let Sergey chime in!
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-11-04 21:54 ` Nhat Pham
@ 2026-11-05 1:10 ` Xueyuan Chen
2026-11-05 5:05 ` Sergey Senozhatsky
2026-11-05 5:01 ` Sergey Senozhatsky
1 sibling, 1 reply; 22+ messages in thread
From: Xueyuan Chen @ 2026-11-05 1:10 UTC (permalink / raw)
To: Nhat Pham
Cc: Chris Wiseman, Sergey Senozhatsky, Xueyuan Chen, Barry Song,
Yosry Ahmed, Johannes Weiner, Brian Geffon, Minchan Kim,
Andrew Morton, linux-mm, linux-kernel, xueyuan.chen21
On 2026-11-04 14:54 -0700, Nhat Pham wrote:
> On Wed, Nov 4, 2026 at 11:46 AM Chris Wiseman <chriswiseman@google.com> wrote:
> >
> > On Wed, Nov 4, 2026 at 9:57 AM Nhat Pham <nphamcs@gmail.com> wrote:
> > >
> > > Is this precheck basically checking if we can free at least one zspage
> > > of the size class before proceeding? Yeah the number looks good -
> > > let's add that, in parallel!
> >
> > Yeah, it just checks if a bucket has enough wasted slots to free at
> > least one full page before taking the locks. Sergey pointed out those
>
> You meant full zspage here right? IIUC we keep the entire chain of
> zpages around until the entire zspage is gone?
>
> > two counters aren't atomic together so an unlocked check is just a
> > best-effort hint - if you and Sergey are good with that, happy to send a
> > patch.
>
> Personally I'm happy with it being a best-effort hint!
>
> We can also recheck after we acquire the lock (but I suspect it's
> unlikely we'll get radically different decision?)
>
> Sergey, how do you feel about this?
>
> >
> > > Ah ok hmm. Sounds like internal compaction isn't that helpful, i.e
> > > zsmalloc already does a pretty decent job at packing objects that
> > > there aren't a terrible amount of internal fragmentation in the first
> > > place...?
> > > Should we do CONFIG_ZSMALLOC_SHRINKER (default to N or to
> > > CONFIG_ZSWAP) for now, and remove it in a couple of releases if users
> > > in the wild do not complain?
> >
> > Compaction still helps when we trigger it between bursts (freed ~21 MB
> > before the swap storm and ~10 MB after). It just wastes time running
> > mid-swap when new writes are filling those open slots right back up.
> > Defaulting CONFIG_ZSMALLOC_SHRINKER to N (or CONFIG_ZSWAP) for a couple
> > releases makes sense to me.
>
Hi Nhat, Chris,
> SGTM, but I'll let Sergey chime in!
Thanks, Nhat and Chris, for the discussion.
If Sergey has no objections, I'd be happy to send a follow-up series
to make the shrinker configurable and add the unlocked pre-check as
Nhat suggested.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-11-04 21:54 ` Nhat Pham
2026-11-05 1:10 ` Xueyuan Chen
@ 2026-11-05 5:01 ` Sergey Senozhatsky
1 sibling, 0 replies; 22+ messages in thread
From: Sergey Senozhatsky @ 2026-11-05 5:01 UTC (permalink / raw)
To: Nhat Pham
Cc: Chris Wiseman, Sergey Senozhatsky, Xueyuan Chen, Barry Song,
Yosry Ahmed, Johannes Weiner, Brian Geffon, Minchan Kim,
Andrew Morton, linux-mm, linux-kernel, xueyuan.chen21
On (26/11/04 14:54), Nhat Pham wrote:
> On Wed, Nov 4, 2026 at 11:46 AM Chris Wiseman <chriswiseman@google.com> wrote:
> >
> > On Wed, Nov 4, 2026 at 9:57 AM Nhat Pham <nphamcs@gmail.com> wrote:
> > >
> > > Is this precheck basically checking if we can free at least one zspage
> > > of the size class before proceeding? Yeah the number looks good -
> > > let's add that, in parallel!
> >
> > Yeah, it just checks if a bucket has enough wasted slots to free at
> > least one full page before taking the locks. Sergey pointed out those
>
> You meant full zspage here right? IIUC we keep the entire chain of
> zpages around until the entire zspage is gone?
Full zspage page, right.
> > two counters aren't atomic together so an unlocked check is just a
> > best-effort hint - if you and Sergey are good with that, happy to send a
> > patch.
>
> Personally I'm happy with it being a best-effort hint!
>
> We can also recheck after we acquire the lock (but I suspect it's
> unlikely we'll get radically different decision?)
>
> Sergey, how do you feel about this?
Well, I guess... I don't mind the lockless best effort hint.
I suppose another way could be an introduction of ->can_compact bool flag,
which we can set under the lock in zs_free() (that's where fragmentation is
created). zs_can_compact() doesn't seem too expensive, but calling it on
every zs_free() looks a bit bad, we sort of want to do less work in zs_free().
> >
> > > Ah ok hmm. Sounds like internal compaction isn't that helpful, i.e
> > > zsmalloc already does a pretty decent job at packing objects that
> > > there aren't a terrible amount of internal fragmentation in the first
> > > place...?
> > > Should we do CONFIG_ZSMALLOC_SHRINKER (default to N or to
> > > CONFIG_ZSWAP) for now, and remove it in a couple of releases if users
> > > in the wild do not complain?
> >
> > Compaction still helps when we trigger it between bursts (freed ~21 MB
> > before the swap storm and ~10 MB after). It just wastes time running
> > mid-swap when new writes are filling those open slots right back up.
> > Defaulting CONFIG_ZSMALLOC_SHRINKER to N (or CONFIG_ZSWAP) for a couple
> > releases makes sense to me.
>
> SGTM, but I'll let Sergey chime in!
So "depends on ZSWAP" looks a bit problematic, because zswap has both
ZSWAP_SHRINKER_DEFAULT_ON (which can select CONFIG_ZSMALLOC_SHRINKER),
but then zswap also has module_param_named(shrinker_enabled). So if
want to tie zsmalloc to zswap shrinker then we probably need to wire
in that run-time knob as well. If shrinker_enabled should imply zsmalloc
shrinker (which I think it didn't so far). zswap folks, do you have any
preferences?
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware
2026-11-05 1:10 ` Xueyuan Chen
@ 2026-11-05 5:05 ` Sergey Senozhatsky
0 siblings, 0 replies; 22+ messages in thread
From: Sergey Senozhatsky @ 2026-11-05 5:05 UTC (permalink / raw)
To: Xueyuan Chen
Cc: Nhat Pham, Chris Wiseman, Sergey Senozhatsky, Xueyuan Chen,
Barry Song, Yosry Ahmed, Johannes Weiner, Brian Geffon,
Minchan Kim, Andrew Morton, linux-mm, linux-kernel
On (26/11/05 09:10), Xueyuan Chen wrote:
[..]
> > SGTM, but I'll let Sergey chime in!
>
> Thanks, Nhat and Chris, for the discussion.
>
> If Sergey has no objections, I'd be happy to send a follow-up series
> to make the shrinker configurable and add the unlocked pre-check as
> Nhat suggested.
Thanks. Sounds like you and Chris will to have "Rock-Paper-Scissors"
to determine who sends a oatch ;) Just joking, let's first figure
out how exactly we want that zsmalloc-shrinker thing to behave wrt
zswap expectations.
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2026-11-05 5:05 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <cover.1786003779.git.xueyuan.chen@vivo.com>
2026-08-07 3:56 ` [RFC PATCH 0/2] mm: zsmalloc: make shrinker compaction budget-aware Sergey Senozhatsky
2026-08-07 10:57 ` Xueyuan Chen
2026-08-07 12:12 ` Sergey Senozhatsky
2026-08-07 16:25 ` Nhat Pham
2026-08-11 9:03 ` Xueyuan Chen
2026-08-11 16:25 ` Nhat Pham
2026-08-14 16:50 ` Xueyuan Chen
2026-08-18 12:11 ` Xueyuan Chen
2026-10-29 1:43 ` Sergey Senozhatsky
2026-10-29 1:48 ` Sergey Senozhatsky
2026-11-02 2:58 ` Xueyuan Chen
2026-11-04 18:06 ` Nhat Pham
2026-10-30 2:05 ` Xueyuan Chen
2026-10-29 2:26 ` Sergey Senozhatsky
2026-11-01 23:47 ` Sergey Senozhatsky
2026-11-02 20:24 ` Chris Wiseman
2026-11-04 17:57 ` Nhat Pham
2026-11-04 18:46 ` Chris Wiseman
2026-11-04 21:54 ` Nhat Pham
2026-11-05 1:10 ` Xueyuan Chen
2026-11-05 5:05 ` Sergey Senozhatsky
2026-11-05 5:01 ` Sergey Senozhatsky
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®