mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC PATCH] sched/fair: Address avruntime drift caused by entity_lag()
@ 2026-07-03  9:26 Chen Jinghuang
  2026-07-06 16:03 ` Vincent Guittot
  0 siblings, 1 reply; 5+ messages in thread
From: Chen Jinghuang @ 2026-07-03  9:26 UTC (permalink / raw)
  To: mingo, peterz, juri.lelli, vincent.guittot
  Cc: dietmar.eggemann, rostedt, bsegall, mgorman, vschneid,
	kprateek.nayak, linux-kernel

While running EEVDF-related test cases, we observed an anomalous
phenomenon where the vruntime of a continuously running scheduling
entity (se) exhibits an overall downward trend.

The test topology and observed behavior are as follows:

CPU 0                              CPU 1 / Other CPUs
+----------------------------+     +----------------------------+
| cgroup A        cgroup B   |     | cgroup A        cgroup B   |
|  |- A1 (Run)     |- B1     |     |  |- A2, A3...     |- B2, B3...|
|                    (50us S)|     |    (Frequent sleep/wake)   |
|                    (10us W)|     |                            |
+----------------------------+     +----------------------------+
       |
       v
A2/A3 frequent sleep/wake -> Frequent reweight of gse(A) on CPU 0
  -> Triggers vlag clamping -> Unidirectional avruntime drift
  -> gse->vruntime drops abnormally (while gse weight remains stable)

According to function_graph traces, frequent sleep/wake cycles of 
sibling tasks within the same cgroup cause the running task to repeatedly 
trigger update_cfs_cgroup() -> reweight_entity().

The root cause appears to point to the entity_lag() boundary limit
introduced in `reweight_entity()` to prevent overflows. During repeated
weight scaling, this limit introduces an asymmetric cumulative error.
Connsider an example here where se->vruntime > avruntime:

1. Downscale:
   se->vlag = entity_lag(cfs_rq, se, avruntime);
   se->vlag = div64_long(se->vlag * old_weight, weight);
   se->vruntime = avruntime - se->vlag;

   If the calculated vlag exceeds the limit boundary, it is clamped. 
   This causes the scaled vlag to be bigger than its theoretical value, 
   making the resulting se->vruntime smaller than it should be (forced 
   closer to avruntime).

2. Upscale:
   Because se->vruntime already carries the clamping error from the
   previous step, it implicitly shifts the subsequent global avruntime
   computation trajectory. When the weight is restored, se->vruntime
   deviates from its original true value, preventing the true vlag from
   being reconstructed and leading to a unidirectional avruntime drift.

Under frequent cgroup reweighting, this asymmetric truncation error 
accumulates, causing a unidirectional downward drift of vruntime.

Regarding this vlag limit mechanism in reweight_entity(), we would like
to raise a few questions for discussion:

Question 1: Is this deviation of se->vruntime expected?
For a currently running entity (curr se), due to RUN_TO_PARITY, it
typically operates in a state where se->vruntime > avruntime. During
reweighting, the limit forces its vruntime downward (closer to avruntime),
while attributes like deadline remain unaffected by the limit.

Question 2: Is the unidirectional drift of avruntime reasonable?
Since avruntime = avg_vruntime(), the deviation of se->vruntime
before and after reweighting (while its weight remains unchanged) shifts
the global avruntime downward. According to EEVDF core principles,
avruntime should remain invariant across weight changes.
(https://lore.kernel.org/lkml/20260415211149.2658910-1-jstultz@google.com/),

Question 3: Is the reduction of avruntime fair to other entities?
A non-functional reduction in global avruntime passively decreases the 
se->vlag of other queued entities on the runqueue, which practically 
worsens the starvation of those tasks.

Question 4: Does this lead to complete preemption suppression?
In entity_tick -> update_deadline, because curr->vruntime is abnormally
pulled down by the clamping error while its deadline is unchanged, the
condition vruntime < deadline can be continuously satisfied at every
tick. This skips resched_curr(), suppressing preemption until the
frequent reweighting stops or curr's vlag falls back within the limit.

While entity_lag() was originally introduced to prevent overflow-induced
NULL pointer dereferences, given its significant impact on EEVDF fairness,
should the necessity and implementation of this limit be reconsidered?

Analyzed-by: Hui Tang <tanghui20@huawei.com>
Analyzed-by: Zhang Qiao <zhangqiao22@huawei.com>
Analyzed-by: Zicheng Qu <quzicheng@huawei.com>
Analyzed-by: Chen Jinghuang <chenjinghuang2@huawei.com>

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-07-07 16:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-03  9:26 [RFC PATCH] sched/fair: Address avruntime drift caused by entity_lag() Chen Jinghuang
2026-07-06 16:03 ` Vincent Guittot
2026-07-07 12:51   ` chenjinghuang
2026-07-07 14:52     ` Vincent Guittot
2026-07-07 16:35       ` Vincent Guittot

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®