Re: [PATCH RFC] mm/memory: drop PROCESS_PAGES_NON_PREEMPT_BATCH

From: Salunke, Hrushikesh

Date: Thu Oct 22 2026 - 06:54:52 EST


On 22-10-2026 15:28, Pedro Falcato wrote:

> On Thu, Oct 22, 2026 at 08:14:30AM +0000, Shivank Garg wrote:
>> clear_contig_highpages() clears the whole range at once under
>> preemptible models. Otherwise it clears PROCESS_PAGES_NON_PREEMPT_BATCH
>> pages at a time, with a cond_resched() in between. The batch is 32MB if
>> the architecture defines clear_pages(), and one page otherwise.
>>
>> Since commit 7dadeaa6e851 ("sched: Further restrict the preemption
>> modes"), architectures that support lazy preemption only offer the
>> full, lazy and RT preemption models, also with PREEMPT_DYNAMIC. x86 is
>> one of them, and it is the only architecture that defines
>> clear_pages(). So the 32MB batch is never used: whenever
>> clear_contig_highpages() runs under a cooperative model, the batch is
>> one page.
>>
>> Make that explicit. Clear the whole range when CONFIG_PREEMPTION is
>> set, and one page at a time with cond_resched() in between otherwise.
>> Drop PROCESS_PAGES_NON_PREEMPT_BATCH, which has no other users.
>>
>> PREEMPT_DYNAMIC kernels also have CONFIG_PREEMPTION set, and
>> cond_resched() does nothing on any of these kernels. So a build-time
>> CONFIG_PREEMPTION check is enough, and preempt_model_preemptible() is
>> not needed.
>>
>> No functional change intended.
>>
>> Suggested-by: David Hildenbrand <david@xxxxxxxxxx>
>> Signed-off-by: Shivank Garg <shivankg@xxxxxxx>
>> ---
>> This came up in review of the copy_mc_highpages() series [1]. Pedro
>> pointed out that most architecture are full or lazy preempt, so mm does
>> not need to check the preemption model at runtime or batch the copy for
>> cond_resched(), and simple per-page fallback is enough for non-preemptible
>> models. David suggested doing the same for the zeroing path, and
>> this patch does that.
>>
>> [1] https://lore.kernel.org/all/20261019-batpagecopy-v2-1-d75e7d0dfaae@xxxxxxx
>> ---
>> include/linux/mm.h | 28 +---------------------------
>> mm/memory.c | 29 ++++++++++++++++-------------
>> 2 files changed, 17 insertions(+), 40 deletions(-)
> Awesome!
>
>> diff --git a/include/linux/mm.h b/include/linux/mm.h
>> index 35f5fc43861a..1083d0645d63 100644
>> --- a/include/linux/mm.h
>> +++ b/include/linux/mm.h
>> @@ -5269,7 +5269,7 @@ static inline void clear_page_guard(struct zone *zone, struct page *page,
>> *
>> * When running under preemptible models this is not a problem. Under
>> * cooperatively scheduled models, however, the caller is expected to
>> - * limit @npages to no more than PROCESS_PAGES_NON_PREEMPT_BATCH.
>> + * clear one page at a time and call cond_resched() in between.
> Why can't clear_pages() itself do cond_resched()?

clear_pages() is also used from contexts that cannot sleep. The page
allocator zeroes via clear_highpages_kasan_tagged(), which uses
clear_pages() for __GFP_ZERO/init_on_alloc in post_alloc_hook() and
for init_on_free in __free_pages_prepare(). Those run in whatever
context the allocation or free happens in, so clear_pages() can't call
cond_resched().

Regards,
Hrushikesh