<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux.git/kernel/sched/fair.c, branch v7.2-rc2</title>
<subtitle>Linux kernel source tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/'/>
<entry>
<title>sched/fair: Fix newidle vs core-sched</title>
<updated>2026-06-11T11:41:23+00:00</updated>
<author>
<name>Aaron Lu</name>
<email>ziqianlu@bytedance.com</email>
</author>
<published>2026-06-03T09:51:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=c095741713d1bc317b53e2da2b222e7448b6021f'/>
<id>c095741713d1bc317b53e2da2b222e7448b6021f</id>
<content type='text'>
While testing Prateek's throttle series, I noticed a panic issue when
coresched is enabled and bisected to this patch.

I fed the panic log and this patch to an agent and its analysis looks
correct to me(cpu56 and cpu57 are siblings in a VM):

       cpu57 (holds core-wide lock)

     pick_next_task() [core scheduling]
     for_each_cpu_wrap(i, smt_mask, 57):
       i=57: pick_task(rq_57)
             pick_task_fair(rq_57)
             -&gt; picks task A
       rq_57-&gt;core_pick = task A
       // task_rq(A) == rq_57

       i=56: pick_task(rq_56)
             pick_task_fair(rq_56)
             cfs_rq-&gt;nr_queued == 0
             goto idle
             sched_balance_newidle(rq_56)
             raw_spin_rq_unlock(rq_56)
             // core-wide lock released
             newidle_balance() pulls
               task A: rq_57 -&gt; rq_56
             // task_rq(A) == rq_56 now
             raw_spin_rq_lock(rq_56)
             // core-wide lock re-acquired
             return &gt; 0
             goto again
             pick_task_fair(rq_56)
             -&gt; picks task A
       rq_56-&gt;core_pick = task A

     // first loop done
     // rq_57-&gt;core_pick is still task A (set before lock release)
     // but task_rq(A) == rq_56 now
     next = rq_57-&gt;core_pick  // = task A

     put_prev_set_next_task(rq_57, prev, task A)
     __set_next_task_fair(rq_57, task A)
     hrtick_start_fair(rq_57, task A)
     WARN_ON_ONCE(task_rq(task A) != rq_57)
     // task_rq(A) == rq_56

IOW: by allowing pick_task_fair() to do newidle_balance and not returning
RETRY_TASK, it can end up selecting the same task on two CPUs. Restore the
previous state by never doing newidle when core scheduling is enabled.

Tested-by: Sven Schnelle &lt;svens@linux.ibm.com&gt;
Signed-off-by: "Aaron Lu" &lt;ziqianlu@bytedance.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Link: https://patch.msgid.link/20260603095108.GA1684319@bytedance.com
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
While testing Prateek's throttle series, I noticed a panic issue when
coresched is enabled and bisected to this patch.

I fed the panic log and this patch to an agent and its analysis looks
correct to me(cpu56 and cpu57 are siblings in a VM):

       cpu57 (holds core-wide lock)

     pick_next_task() [core scheduling]
     for_each_cpu_wrap(i, smt_mask, 57):
       i=57: pick_task(rq_57)
             pick_task_fair(rq_57)
             -&gt; picks task A
       rq_57-&gt;core_pick = task A
       // task_rq(A) == rq_57

       i=56: pick_task(rq_56)
             pick_task_fair(rq_56)
             cfs_rq-&gt;nr_queued == 0
             goto idle
             sched_balance_newidle(rq_56)
             raw_spin_rq_unlock(rq_56)
             // core-wide lock released
             newidle_balance() pulls
               task A: rq_57 -&gt; rq_56
             // task_rq(A) == rq_56 now
             raw_spin_rq_lock(rq_56)
             // core-wide lock re-acquired
             return &gt; 0
             goto again
             pick_task_fair(rq_56)
             -&gt; picks task A
       rq_56-&gt;core_pick = task A

     // first loop done
     // rq_57-&gt;core_pick is still task A (set before lock release)
     // but task_rq(A) == rq_56 now
     next = rq_57-&gt;core_pick  // = task A

     put_prev_set_next_task(rq_57, prev, task A)
     __set_next_task_fair(rq_57, task A)
     hrtick_start_fair(rq_57, task A)
     WARN_ON_ONCE(task_rq(task A) != rq_57)
     // task_rq(A) == rq_56

IOW: by allowing pick_task_fair() to do newidle_balance and not returning
RETRY_TASK, it can end up selecting the same task on two CPUs. Restore the
previous state by never doing newidle when core scheduling is enabled.

Tested-by: Sven Schnelle &lt;svens@linux.ibm.com&gt;
Signed-off-by: "Aaron Lu" &lt;ziqianlu@bytedance.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Link: https://patch.msgid.link/20260603095108.GA1684319@bytedance.com
</pre>
</div>
</content>
</entry>
<entry>
<title>sched/fair: Fix cpu_util runnable_avg arithmetic</title>
<updated>2026-06-09T08:28:08+00:00</updated>
<author>
<name>Hongyan Xia</name>
<email>hongyan.xia@transsion.com</email>
</author>
<published>2026-06-05T09:43:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=29922fdfc2a4008d66418bedd0ebf5038fc54efa'/>
<id>29922fdfc2a4008d66418bedd0ebf5038fc54efa</id>
<content type='text'>
If we take runnable_avg in max(runnable_avg, util_avg) in cpu_util(), we
should then add or subtract task runnable_avg, but the arithmetic below
is still with task util_avg. This mixes runnable_avg with util_avg which
is incorrect.

Fix by always doing arithmetic with runnable_avg and only take
max(runnable_avg, util_avg) at the last step.

Fixes: 7d0583cf9ec7 ("sched/fair, cpufreq: Introduce 'runnable boosting'")
Signed-off-by: Hongyan Xia &lt;hongyan.xia@transsion.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: Vincent Guittot &lt;vincent.guittot@linaro.org&gt;
Link: https://patch.msgid.link/20260605094318.37931-1-hongyan.xia@transsion.com
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
If we take runnable_avg in max(runnable_avg, util_avg) in cpu_util(), we
should then add or subtract task runnable_avg, but the arithmetic below
is still with task util_avg. This mixes runnable_avg with util_avg which
is incorrect.

Fix by always doing arithmetic with runnable_avg and only take
max(runnable_avg, util_avg) at the last step.

Fixes: 7d0583cf9ec7 ("sched/fair, cpufreq: Introduce 'runnable boosting'")
Signed-off-by: Hongyan Xia &lt;hongyan.xia@transsion.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: Vincent Guittot &lt;vincent.guittot@linaro.org&gt;
Link: https://patch.msgid.link/20260605094318.37931-1-hongyan.xia@transsion.com
</pre>
</div>
</content>
</entry>
<entry>
<title>sched/fair: Unify cfs_rq throttling via account_cfs_rq_runtime()</title>
<updated>2026-06-02T10:26:13+00:00</updated>
<author>
<name>Peter Zijlstra</name>
<email>peterz@infradead.org</email>
</author>
<published>2026-06-02T07:10:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=f666241e6bd5d9a494beca982e1953208dce531c'/>
<id>f666241e6bd5d9a494beca982e1953208dce531c</id>
<content type='text'>
assign_cfs_rq_runtime() during update_curr() sets the resched indicator
and relies on check_cfs_rq_runtime() during pick_next_task() /
put_prev_entity() to throttle the hierarchy once current task is
preempted / blocks.

Per-task throttle, on the other hand, uses throttle_cfs_rq() to simply
propagate the throttle signals, and then relies on task work to
individually throttle the runnable tasks on their way out to the
userspace.

Remove check_cfs_rq_runtime() and unify throttling into
account_cfs_rq_runtime() which only sets the cfs_rq-&gt;throttled,
cfs_rq-&gt;throttle_count indicators via throttle_cfs_rq() and optionally
adds the task work to the current task (donor) it is on the throttled
hierarchy.

throttle_cfs_rq() requests for sched_cfs_bandwidth_slice() worth of
bandwidth for the current hierarchy that enable it to continue running
uninterrupted when selected. For the rest, it requests a bare minimum of
"1" to ensure some bandwidth is available and pass the
"runtime_remaining &gt; 0" checks once selected.

For SCHED_PROXY_EXEC, a mutex holder cannot exit to userspace without
dropping it first and the mutex_unlock() ensures proxy is stopped before
the mutex handoff which preserves the current semantics for running a
throttled task until it exits to the userspace even if it acts as a
donor.

  [ prateek: rebased on tip, comments, commit message. ]

Reviewed-By: Benjamin Segall &lt;bsegall@google.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Signed-off-by: K Prateek Nayak &lt;kprateek.nayak@amd.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Tested-by: Aaron Lu &lt;ziqianlu@bytedance.com&gt;
Link: https://patch.msgid.link/20260602071005.11942-1-kprateek.nayak@amd.com
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
assign_cfs_rq_runtime() during update_curr() sets the resched indicator
and relies on check_cfs_rq_runtime() during pick_next_task() /
put_prev_entity() to throttle the hierarchy once current task is
preempted / blocks.

Per-task throttle, on the other hand, uses throttle_cfs_rq() to simply
propagate the throttle signals, and then relies on task work to
individually throttle the runnable tasks on their way out to the
userspace.

Remove check_cfs_rq_runtime() and unify throttling into
account_cfs_rq_runtime() which only sets the cfs_rq-&gt;throttled,
cfs_rq-&gt;throttle_count indicators via throttle_cfs_rq() and optionally
adds the task work to the current task (donor) it is on the throttled
hierarchy.

throttle_cfs_rq() requests for sched_cfs_bandwidth_slice() worth of
bandwidth for the current hierarchy that enable it to continue running
uninterrupted when selected. For the rest, it requests a bare minimum of
"1" to ensure some bandwidth is available and pass the
"runtime_remaining &gt; 0" checks once selected.

For SCHED_PROXY_EXEC, a mutex holder cannot exit to userspace without
dropping it first and the mutex_unlock() ensures proxy is stopped before
the mutex handoff which preserves the current semantics for running a
throttled task until it exits to the userspace even if it acts as a
donor.

  [ prateek: rebased on tip, comments, commit message. ]

Reviewed-By: Benjamin Segall &lt;bsegall@google.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Signed-off-by: K Prateek Nayak &lt;kprateek.nayak@amd.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Tested-by: Aaron Lu &lt;ziqianlu@bytedance.com&gt;
Link: https://patch.msgid.link/20260602071005.11942-1-kprateek.nayak@amd.com
</pre>
</div>
</content>
</entry>
<entry>
<title>sched/fair: Move the throttled tasks to a local list in tg_unthrottle_up()</title>
<updated>2026-06-02T10:26:12+00:00</updated>
<author>
<name>K Prateek Nayak</name>
<email>kprateek.nayak@amd.com</email>
</author>
<published>2026-06-02T05:25:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=102a28344a60e637934ffca62d50ff8319b11165'/>
<id>102a28344a60e637934ffca62d50ff8319b11165</id>
<content type='text'>
An update_curr() during the enqueue of throttled task will start
throttling the hierarchy from subsequent commit. This can lead to
tg_throttle_down() seeing non-empty throttled_limbo_list for the cfs_rq
attaching the task from throttled_limbo_list one by one. For example:

     R
     |
     A
    / \
  *B   C
       |
       rq-&gt;curr

*B is throttled with tasks on hte limbo list. When the tasks are
unthrottled via tg_unthrottle_up() and entity of group B is placed onto
A, update_curr() is called to catch up the vruntime and it may throttle
group A causing the subsequent tg_throttle_down() to see the pending
task's on B's limbo list.

  tg_unthrottle_up()
    /* --cfs_rq-&gt;throttle_count == 0 */
    list_for_each_entry_safe(p, cfs_rq-&gt;throttled_limbo_list)
      enqueue_task_fair()
        enqueue_entity(se /* B-&gt;se */)
          update_curr(cfs_rq /* A-&gt;gcfs_rq */)
            account_cfs_rq_runtime(cfs_rq)
              throttle_cfs_rq(cfs_rq /* A-&gt;gcfs_rq */ )
                tg_throttle_down()
                  /* Reaches B-&gt;cfs_rq with throttle_count == 0 */

                  !!! !list_empty(&amp;cfs_rq-&gt;throttled_limbo_list)) !!!

Move the tasks from throttled_limbo_list onto a local list before
starting the unthrottle to prevent the splat described above. If the
hierarchy is throttled again in middle of an unthrottle, put the pending
tasks back onto the limbo list to prevent running them unnecessarily.

Signed-off-by: K Prateek Nayak &lt;kprateek.nayak@amd.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: Benjamin Segall &lt;bsegall@google.com&gt;
Tested-by: Aaron Lu &lt;ziqianlu@bytedance.com&gt;
Link: https://patch.msgid.link/20260602052531.11450-2-kprateek.nayak@amd.com
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
An update_curr() during the enqueue of throttled task will start
throttling the hierarchy from subsequent commit. This can lead to
tg_throttle_down() seeing non-empty throttled_limbo_list for the cfs_rq
attaching the task from throttled_limbo_list one by one. For example:

     R
     |
     A
    / \
  *B   C
       |
       rq-&gt;curr

*B is throttled with tasks on hte limbo list. When the tasks are
unthrottled via tg_unthrottle_up() and entity of group B is placed onto
A, update_curr() is called to catch up the vruntime and it may throttle
group A causing the subsequent tg_throttle_down() to see the pending
task's on B's limbo list.

  tg_unthrottle_up()
    /* --cfs_rq-&gt;throttle_count == 0 */
    list_for_each_entry_safe(p, cfs_rq-&gt;throttled_limbo_list)
      enqueue_task_fair()
        enqueue_entity(se /* B-&gt;se */)
          update_curr(cfs_rq /* A-&gt;gcfs_rq */)
            account_cfs_rq_runtime(cfs_rq)
              throttle_cfs_rq(cfs_rq /* A-&gt;gcfs_rq */ )
                tg_throttle_down()
                  /* Reaches B-&gt;cfs_rq with throttle_count == 0 */

                  !!! !list_empty(&amp;cfs_rq-&gt;throttled_limbo_list)) !!!

Move the tasks from throttled_limbo_list onto a local list before
starting the unthrottle to prevent the splat described above. If the
hierarchy is throttled again in middle of an unthrottle, put the pending
tasks back onto the limbo list to prevent running them unnecessarily.

Signed-off-by: K Prateek Nayak &lt;kprateek.nayak@amd.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: Benjamin Segall &lt;bsegall@google.com&gt;
Tested-by: Aaron Lu &lt;ziqianlu@bytedance.com&gt;
Link: https://patch.msgid.link/20260602052531.11450-2-kprateek.nayak@amd.com
</pre>
</div>
</content>
</entry>
<entry>
<title>sched/fair: Call update_curr() before unthrottling the hierarchy</title>
<updated>2026-06-02T10:26:12+00:00</updated>
<author>
<name>K Prateek Nayak</name>
<email>kprateek.nayak@amd.com</email>
</author>
<published>2026-06-02T05:25:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=28ad5427682bccf06074366f347a6083d6730c1e'/>
<id>28ad5427682bccf06074366f347a6083d6730c1e</id>
<content type='text'>
Subsequent commits will allow update_curr() to throttle the hierarchy
when the runtime accounting exceeds allocated quota. Call update_curr()
before the unthrottle event, and in tg_unthrottle_up() to catch up on
any remaining runtime and stabilize the "runtime_remaining" and
"throttle_count" for that cfs_rq.

Doing an update_curr() early ensures the cfs_rq is not throttled right
back up again when the unthrottle is in progress.

Since all callers of unthrottle_cfs_rq(), except two, already update the
rq_clock and call rq_clock_start_loop_update(), move the
update_rq_clock() from unthrottle_cfs_rq() to the callers that don't
update the rq_clock.

Signed-off-by: K Prateek Nayak &lt;kprateek.nayak@amd.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: Benjamin Segall &lt;bsegall@google.com&gt;
Tested-by: Aaron Lu &lt;ziqianlu@bytedance.com&gt;
Link: https://patch.msgid.link/20260602052531.11450-1-kprateek.nayak@amd.com
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Subsequent commits will allow update_curr() to throttle the hierarchy
when the runtime accounting exceeds allocated quota. Call update_curr()
before the unthrottle event, and in tg_unthrottle_up() to catch up on
any remaining runtime and stabilize the "runtime_remaining" and
"throttle_count" for that cfs_rq.

Doing an update_curr() early ensures the cfs_rq is not throttled right
back up again when the unthrottle is in progress.

Since all callers of unthrottle_cfs_rq(), except two, already update the
rq_clock and call rq_clock_start_loop_update(), move the
update_rq_clock() from unthrottle_cfs_rq() to the callers that don't
update the rq_clock.

Signed-off-by: K Prateek Nayak &lt;kprateek.nayak@amd.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: Benjamin Segall &lt;bsegall@google.com&gt;
Tested-by: Aaron Lu &lt;ziqianlu@bytedance.com&gt;
Link: https://patch.msgid.link/20260602052531.11450-1-kprateek.nayak@amd.com
</pre>
</div>
</content>
</entry>
<entry>
<title>sched/fair: Use throttled_csd_list for local unthrottle</title>
<updated>2026-06-02T10:26:12+00:00</updated>
<author>
<name>K Prateek Nayak</name>
<email>kprateek.nayak@amd.com</email>
</author>
<published>2026-06-02T05:00:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=253edcf5436c916f2fbf7b880443c7f1ed76101d'/>
<id>253edcf5436c916f2fbf7b880443c7f1ed76101d</id>
<content type='text'>
When distribute_cfs_runtime() encounters a local cfs_rq, it adds it to a
local list and unthrottles it at the end, when it is done unthrottling
other cfs_rq(s) on cfs_b-&gt;throttled_cfs_rq until the bandwidth runs out.

Instead of using a local list, reuse the local CPU's
rq-&gt;throttled_csd_list and the __cfsb_csd_unthrottle() path for
unthrottle.

If this is the first cfs_rq to be queued on the "throttled_csd_list", it
prevents the need for a remote CPUs to interrupt this local CPU if they
themselves are performing async unthrottle.

If this is not the first cfs_rq on the list, there is an async unthrottle
operation pending on this local CPU and the unthrottle can be batched
together.

No functional changes intended.

Signed-off-by: K Prateek Nayak &lt;kprateek.nayak@amd.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: Benjamin Segall &lt;bsegall@google.com&gt;
Tested-by: Aaron Lu &lt;ziqianlu@bytedance.com&gt;
Link: https://patch.msgid.link/20260602050005.11160-3-kprateek.nayak@amd.com
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When distribute_cfs_runtime() encounters a local cfs_rq, it adds it to a
local list and unthrottles it at the end, when it is done unthrottling
other cfs_rq(s) on cfs_b-&gt;throttled_cfs_rq until the bandwidth runs out.

Instead of using a local list, reuse the local CPU's
rq-&gt;throttled_csd_list and the __cfsb_csd_unthrottle() path for
unthrottle.

If this is the first cfs_rq to be queued on the "throttled_csd_list", it
prevents the need for a remote CPUs to interrupt this local CPU if they
themselves are performing async unthrottle.

If this is not the first cfs_rq on the list, there is an async unthrottle
operation pending on this local CPU and the unthrottle can be batched
together.

No functional changes intended.

Signed-off-by: K Prateek Nayak &lt;kprateek.nayak@amd.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: Benjamin Segall &lt;bsegall@google.com&gt;
Tested-by: Aaron Lu &lt;ziqianlu@bytedance.com&gt;
Link: https://patch.msgid.link/20260602050005.11160-3-kprateek.nayak@amd.com
</pre>
</div>
</content>
</entry>
<entry>
<title>sched/fair: Convert cfs bandwidth throttling to use guards</title>
<updated>2026-06-02T10:26:11+00:00</updated>
<author>
<name>K Prateek Nayak</name>
<email>kprateek.nayak@amd.com</email>
</author>
<published>2026-06-02T05:00:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=1abbecd1d2d2fdd96e52f541f07ee2b163631bee'/>
<id>1abbecd1d2d2fdd96e52f541f07ee2b163631bee</id>
<content type='text'>
Routine conversion of rcu_read_lock(), spin_lock*, and rq_lock usage
within the cfs bandwidth controller to use class guards.

Only notable changes are:

 - Checking for "cfs_rq-&gt;runtime_remaining &lt;= 0" instead of the inverse
   to spot a throttle and break early. This also saves the need
   for extra indentation in the unthrottle case.

 - Reordering of list_del_rcu() against throttled_clock indicator update
   in unthrottle_cfs_rq(). Both are done with "cfs_b-&gt;lock" held after
   the "cfs_rq-&gt;throttled" is cleared which make the reordering safe
   against concurrent list modifications.

No functional changes intended.

Signed-off-by: K Prateek Nayak &lt;kprateek.nayak@amd.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: Ben Segall &lt;bsegall@google.com&gt;
Tested-by: Aaron Lu &lt;ziqianlu@bytedance.com&gt;
Link: https://patch.msgid.link/20260602050005.11160-2-kprateek.nayak@amd.com
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Routine conversion of rcu_read_lock(), spin_lock*, and rq_lock usage
within the cfs bandwidth controller to use class guards.

Only notable changes are:

 - Checking for "cfs_rq-&gt;runtime_remaining &lt;= 0" instead of the inverse
   to spot a throttle and break early. This also saves the need
   for extra indentation in the unthrottle case.

 - Reordering of list_del_rcu() against throttled_clock indicator update
   in unthrottle_cfs_rq(). Both are done with "cfs_b-&gt;lock" held after
   the "cfs_rq-&gt;throttled" is cleared which make the reordering safe
   against concurrent list modifications.

No functional changes intended.

Signed-off-by: K Prateek Nayak &lt;kprateek.nayak@amd.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: Ben Segall &lt;bsegall@google.com&gt;
Tested-by: Aaron Lu &lt;ziqianlu@bytedance.com&gt;
Link: https://patch.msgid.link/20260602050005.11160-2-kprateek.nayak@amd.com
</pre>
</div>
</content>
</entry>
<entry>
<title>sched/fair: Allocate cfs_tg_state with percpu allocator</title>
<updated>2026-06-02T10:26:11+00:00</updated>
<author>
<name>Zecheng Li</name>
<email>zecheng@google.com</email>
</author>
<published>2026-05-22T14:15:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=b8fea7af0e40feb6d9cbbd60b66ff0ec265e868f'/>
<id>b8fea7af0e40feb6d9cbbd60b66ff0ec265e868f</id>
<content type='text'>
To remove the cfs_rq pointer array in task_group, allocate the combined
cfs_rq and sched_entity using the per-cpu allocator.

This patch implements the following:

 - Changes task_group-&gt;cfs_rq from 'struct cfs_rq **' to
   'struct cfs_rq __percpu *'.

 - Updates memory allocation in alloc_fair_sched_group() and
   free_fair_sched_group() to use alloc_percpu() and free_percpu()
   respectively.

 - Uses the inline accessor tg_cfs_rq(tg, cpu) with per_cpu_ptr() to retrieve
   the pointer to cfs_rq for the given task group and CPU.

 - Replaces direct accesses tg-&gt;cfs_rq[cpu] with calls to the new tg_cfs_rq(tg,
   cpu) helper.

 - Handles the root_task_group: since struct rq is already a per-cpu variable
   (runqueues), its embedded cfs_rq (rq-&gt;cfs) is also per-cpu. Therefore, we
   assign root_task_group.cfs_rq = &amp;runqueues.cfs.

 - Cleanup the code in initializing the root task group.

This change places each CPU's cfs_rq and sched_entity in its local per-cpu
memory area to remove the per-task_group pointer arrays.

Signed-off-by: Zecheng Li &lt;zecheng@google.com&gt;
Signed-off-by: Zecheng Li &lt;zli94@ncsu.edu&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: K Prateek Nayak &lt;kprateek.nayak@amd.com&gt;
Reviewed-by: Josh Don &lt;joshdon@google.com&gt;
Link: https://patch.msgid.link/20260522141623.600235-4-zli94@ncsu.edu
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
To remove the cfs_rq pointer array in task_group, allocate the combined
cfs_rq and sched_entity using the per-cpu allocator.

This patch implements the following:

 - Changes task_group-&gt;cfs_rq from 'struct cfs_rq **' to
   'struct cfs_rq __percpu *'.

 - Updates memory allocation in alloc_fair_sched_group() and
   free_fair_sched_group() to use alloc_percpu() and free_percpu()
   respectively.

 - Uses the inline accessor tg_cfs_rq(tg, cpu) with per_cpu_ptr() to retrieve
   the pointer to cfs_rq for the given task group and CPU.

 - Replaces direct accesses tg-&gt;cfs_rq[cpu] with calls to the new tg_cfs_rq(tg,
   cpu) helper.

 - Handles the root_task_group: since struct rq is already a per-cpu variable
   (runqueues), its embedded cfs_rq (rq-&gt;cfs) is also per-cpu. Therefore, we
   assign root_task_group.cfs_rq = &amp;runqueues.cfs.

 - Cleanup the code in initializing the root task group.

This change places each CPU's cfs_rq and sched_entity in its local per-cpu
memory area to remove the per-task_group pointer arrays.

Signed-off-by: Zecheng Li &lt;zecheng@google.com&gt;
Signed-off-by: Zecheng Li &lt;zli94@ncsu.edu&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: K Prateek Nayak &lt;kprateek.nayak@amd.com&gt;
Reviewed-by: Josh Don &lt;joshdon@google.com&gt;
Link: https://patch.msgid.link/20260522141623.600235-4-zli94@ncsu.edu
</pre>
</div>
</content>
</entry>
<entry>
<title>sched/fair: Remove task_group-&gt;se pointer array</title>
<updated>2026-06-02T10:26:11+00:00</updated>
<author>
<name>Zecheng Li</name>
<email>zecheng@google.com</email>
</author>
<published>2026-05-22T14:15:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=89e1f67186baca353b68115bb98bd0bfed9f80c8'/>
<id>89e1f67186baca353b68115bb98bd0bfed9f80c8</id>
<content type='text'>
Now that struct sched_entity is co-located with struct cfs_rq for non-root task
groups, the task_group-&gt;se pointer array is redundant. The associated
sched_entity can be loaded directly from the cfs_rq.

This patch performs the access conversion with the helpers:

 - is_root_task_group(tg): checks if a task group is the root task group. It
   compares the task group's address with the global root_task_group variable.

 - tg_se(tg, cpu): retrieves the cfs_rq and returns the address of the
   co-located se. This function checks if tg is the root task group to ensure
   behaving the same of previous tg-&gt;se[cpu]. Replaces all accesses that use
   the tg-&gt;se[cpu] pointer array with calls to the new tg_se(tg, cpu) accessor.

 - cfs_rq_se(cfs_rq): simplifies access paths like cfs_rq-&gt;tg-&gt;se[...] to use
   the co-located sched_entity. This function also checks if tg is the root
   task group to ensure same behavior.

Since tg_se is not in very hot code paths, and the branch is a register
comparison with an immediate value (`&amp;root_task_group`), the performance impact
is expected to be negligible.

Signed-off-by: Zecheng Li &lt;zecheng@google.com&gt;
Signed-off-by: Zecheng Li &lt;zli94@ncsu.edu&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: K Prateek Nayak &lt;kprateek.nayak@amd.com&gt;
Reviewed-by: Josh Don &lt;joshdon@google.com&gt;
Link: https://patch.msgid.link/20260522141623.600235-3-zli94@ncsu.edu
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Now that struct sched_entity is co-located with struct cfs_rq for non-root task
groups, the task_group-&gt;se pointer array is redundant. The associated
sched_entity can be loaded directly from the cfs_rq.

This patch performs the access conversion with the helpers:

 - is_root_task_group(tg): checks if a task group is the root task group. It
   compares the task group's address with the global root_task_group variable.

 - tg_se(tg, cpu): retrieves the cfs_rq and returns the address of the
   co-located se. This function checks if tg is the root task group to ensure
   behaving the same of previous tg-&gt;se[cpu]. Replaces all accesses that use
   the tg-&gt;se[cpu] pointer array with calls to the new tg_se(tg, cpu) accessor.

 - cfs_rq_se(cfs_rq): simplifies access paths like cfs_rq-&gt;tg-&gt;se[...] to use
   the co-located sched_entity. This function also checks if tg is the root
   task group to ensure same behavior.

Since tg_se is not in very hot code paths, and the branch is a register
comparison with an immediate value (`&amp;root_task_group`), the performance impact
is expected to be negligible.

Signed-off-by: Zecheng Li &lt;zecheng@google.com&gt;
Signed-off-by: Zecheng Li &lt;zli94@ncsu.edu&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: K Prateek Nayak &lt;kprateek.nayak@amd.com&gt;
Reviewed-by: Josh Don &lt;joshdon@google.com&gt;
Link: https://patch.msgid.link/20260522141623.600235-3-zli94@ncsu.edu
</pre>
</div>
</content>
</entry>
<entry>
<title>sched/fair: Co-locate cfs_rq and sched_entity in cfs_tg_state</title>
<updated>2026-06-02T10:26:10+00:00</updated>
<author>
<name>Zecheng Li</name>
<email>zecheng@google.com</email>
</author>
<published>2026-05-22T14:15:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=dfcfc97b6df0ea8e1b7d3b590022782abbec3389'/>
<id>dfcfc97b6df0ea8e1b7d3b590022782abbec3389</id>
<content type='text'>
Improve data locality and reduce pointer chasing by allocating struct
cfs_rq and struct sched_entity together for non-root task groups. This
is achieved by introducing a new combined struct cfs_tg_state that
holds both objects in a single allocation.

This patch:

 - Introduces struct cfs_tg_state that embeds cfs_rq, sched_entity, and
   sched_statistics together in a single structure.

 - Updates __schedstats_from_se() in stats.h to use cfs_tg_state for accessing
   sched_statistics from a group sched_entity.

 - Modifies alloc_fair_sched_group() and free_fair_sched_group() to allocate
   and free the new struct as a single unit.

 - Modifies the per-CPU pointers in task_group-&gt;se and task_group-&gt;cfs_rq to
   point to the members in the new combined structure.

Signed-off-by: Zecheng Li &lt;zecheng@google.com&gt;
Signed-off-by: Zecheng Li &lt;zli94@ncsu.edu&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: K Prateek Nayak &lt;kprateek.nayak@amd.com&gt;
Reviewed-by: Josh Don &lt;joshdon@google.com&gt;
Link: https://patch.msgid.link/20260522141623.600235-2-zli94@ncsu.edu
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Improve data locality and reduce pointer chasing by allocating struct
cfs_rq and struct sched_entity together for non-root task groups. This
is achieved by introducing a new combined struct cfs_tg_state that
holds both objects in a single allocation.

This patch:

 - Introduces struct cfs_tg_state that embeds cfs_rq, sched_entity, and
   sched_statistics together in a single structure.

 - Updates __schedstats_from_se() in stats.h to use cfs_tg_state for accessing
   sched_statistics from a group sched_entity.

 - Modifies alloc_fair_sched_group() and free_fair_sched_group() to allocate
   and free the new struct as a single unit.

 - Modifies the per-CPU pointers in task_group-&gt;se and task_group-&gt;cfs_rq to
   point to the members in the new combined structure.

Signed-off-by: Zecheng Li &lt;zecheng@google.com&gt;
Signed-off-by: Zecheng Li &lt;zli94@ncsu.edu&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: K Prateek Nayak &lt;kprateek.nayak@amd.com&gt;
Reviewed-by: Josh Don &lt;joshdon@google.com&gt;
Link: https://patch.msgid.link/20260522141623.600235-2-zli94@ncsu.edu
</pre>
</div>
</content>
</entry>
</feed>
