Re: [PATCH 2/6] sched/numa: fix scan-period ratio denominator checks

From: Li Zhe

Date: Wed Oct 14 2026 - 23:51:01 EST


On 10/14/26 8:56 PM, Gregory Price wrote:
> On Wed, Oct 14, 2026 at 05:43:43PM +0800, Li Zhe wrote:
>> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
>> index 1053437933ee..76532b8202dc 100644
>> --- a/kernel/sched/fair.c
>> +++ b/kernel/sched/fair.c
>> @@ -3698,6 +3698,8 @@ static void update_task_scan_period(struct task_struct *p,
>>
>> unsigned long remote = p->numa_faults_locality[0];
>> unsigned long local = p->numa_faults_locality[1];
>> + unsigned long locality_faults = local + remote;
>> + unsigned long type_faults = private + shared;
>>
>> /*
>> * If there were no record hinting faults then either the task is
>> @@ -3706,7 +3708,7 @@ static void update_task_scan_period(struct task_struct *p,
>> * migration then it implies we are migrating too quickly or the local
>> * node is overloaded. In either case, scan slower
>> */
>> - if (local + shared == 0 || p->numa_faults_locality[2]) {
>> + if (!locality_faults || !type_faults || p->numa_faults_locality[2]) {
>> p->numa_scan_period = min(p->numa_scan_period_max,
>> p->numa_scan_period << 1);
>>
> This does more than just change the div/o below, it changes the behavior
> of the function overall. It's not clear to me this change is correct.

Yes, this intentionally changes the fallback condition.

The old local + shared check mixes two independent dimensions. The
ratios below are computed from local + remote and private + shared, so
those are the denominators that decide whether the sample is usable.

The old check can also classify a pure remote-private window as an
unusable sample: local == 0 and shared == 0, while remote and private
are non-zero. That is exactly the kind of signal that should go through
the normal scan-period decision, since commit 37ec97deb3a8 wanted to
speed scanning up only when many private faults are on remote memory.

So the fallback is meant to be used when one of the actual ratios cannot
be computed, i.e. when local + remote == 0 or private + shared == 0.
Otherwise the sample should not be discarded before the ratio logic.

Thanks,
Zhe

>
>> @@ -3723,8 +3725,8 @@ static void update_task_scan_period(struct task_struct *p,
>> * >= NUMA_PERIOD_THRESHOLD scan period increases (scan slower)
>> */
>> period_slot = DIV_ROUND_UP(p->numa_scan_period, NUMA_PERIOD_SLOTS);
>> - lr_ratio = (local * NUMA_PERIOD_SLOTS) / (local + remote);
>> - ps_ratio = (private * NUMA_PERIOD_SLOTS) / (private + shared);
>> + lr_ratio = (local * NUMA_PERIOD_SLOTS) / locality_faults;
>> + ps_ratio = (private * NUMA_PERIOD_SLOTS) / type_faults;
>>
> This otherwise looks fine.
>
> ~Gregory