Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'sched_ext-for-6.19-rc3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext

Pull sched_ext fixes from Tejun Heo:

- Fix uninitialized @ret on alloc_percpu() failure leading to
ERR_PTR(0)

- Fix PREEMPT_RT warning when bypass load balancer sends IPI to offline
CPU by using resched_cpu() instead of resched_curr()

- Fix comment referring to renamed function

- Update scx_show_state.py for scx_root and scx_aborting changes

* tag 'sched_ext-for-6.19-rc3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext:
tools/sched_ext: update scx_show_state.py for scx_aborting change
tools/sched_ext: fix scx_show_state.py for scx_root change
sched_ext: Use the resched_cpu() to replace resched_curr() in the bypass_lb_node()
sched_ext: Fix some comments in ext.c
sched_ext: fix uninitialized ret on alloc_percpu() failure

+16 -17
+10 -13
kernel/sched/ext.c
··· 1577 1577 * 1578 1578 * @p may go through multiple stopping <-> running transitions between 1579 1579 * here and put_prev_task_scx() if task attribute changes occur while 1580 - * balance_scx() leaves @rq unlocked. However, they don't contain any 1580 + * balance_one() leaves @rq unlocked. However, they don't contain any 1581 1581 * information meaningful to the BPF scheduler and can be suppressed by 1582 1582 * skipping the callbacks if the task is !QUEUED. 1583 1583 */ ··· 2372 2372 * preempted, and it regaining control of the CPU. 2373 2373 * 2374 2374 * ->cpu_release() complements ->cpu_acquire(), which is emitted the 2375 - * next time that balance_scx() is invoked. 2375 + * next time that balance_one() is invoked. 2376 2376 */ 2377 2377 if (!rq->scx.cpu_released) { 2378 2378 if (SCX_HAS_OP(sch, cpu_release)) { ··· 2478 2478 } 2479 2479 2480 2480 /* 2481 - * If balance_scx() is telling us to keep running @prev, replenish slice 2481 + * If balance_one() is telling us to keep running @prev, replenish slice 2482 2482 * if necessary and keep running @prev. Otherwise, pop the first one 2483 2483 * from the local DSQ. 2484 2484 */ ··· 3956 3956 nr_donor_target, nr_target); 3957 3957 } 3958 3958 3959 - for_each_cpu(cpu, resched_mask) { 3960 - struct rq *rq = cpu_rq(cpu); 3961 - 3962 - raw_spin_rq_lock_irq(rq); 3963 - resched_curr(rq); 3964 - raw_spin_rq_unlock_irq(rq); 3965 - } 3959 + for_each_cpu(cpu, resched_mask) 3960 + resched_cpu(cpu); 3966 3961 3967 3962 for_each_cpu_and(cpu, cpu_online_mask, node_mask) { 3968 3963 u32 nr = READ_ONCE(cpu_rq(cpu)->scx.bypass_dsq.nr); ··· 4020 4025 * 4021 4026 * - ops.dispatch() is ignored. 4022 4027 * 4023 - * - balance_scx() does not set %SCX_RQ_BAL_KEEP on non-zero slice as slice 4028 + * - balance_one() does not set %SCX_RQ_BAL_KEEP on non-zero slice as slice 4024 4029 * can't be trusted. Whenever a tick triggers, the running task is rotated to 4025 4030 * the tail of the queue with core_sched_at touched. 4026 4031 * ··· 4778 4783 } 4779 4784 4780 4785 sch->pcpu = alloc_percpu(struct scx_sched_pcpu); 4781 - if (!sch->pcpu) 4786 + if (!sch->pcpu) { 4787 + ret = -ENOMEM; 4782 4788 goto err_free_gdsqs; 4789 + } 4783 4790 4784 4791 sch->helper = kthread_run_worker(0, "sched_ext_helper"); 4785 4792 if (IS_ERR(sch->helper)) { ··· 6064 6067 /* 6065 6068 * A successfully consumed task can be dequeued before it starts 6066 6069 * running while the CPU is trying to migrate other dispatched 6067 - * tasks. Bump nr_tasks to tell balance_scx() to retry on empty 6070 + * tasks. Bump nr_tasks to tell balance_one() to retry on empty 6068 6071 * local DSQ. 6069 6072 */ 6070 6073 dspc->nr_tasks++;
+6 -4
tools/sched_ext/scx_show_state.py
··· 27 27 def state_str(state): 28 28 return prog['scx_enable_state_str'][state].string_().decode() 29 29 30 - ops = prog['scx_ops'] 30 + root = prog['scx_root'] 31 31 enable_state = read_atomic("scx_enable_state_var") 32 32 33 - print(f'ops : {ops.name.string_().decode()}') 33 + if root: 34 + print(f'ops : {root.ops.name.string_().decode()}') 35 + else: 36 + print('ops : ') 34 37 print(f'enabled : {read_static_key("__scx_enabled")}') 35 38 print(f'switching_all : {read_int("scx_switching_all")}') 36 39 print(f'switched_all : {read_static_key("__scx_switched_all")}') 37 40 print(f'enable_state : {state_str(enable_state)} ({enable_state})') 38 - print(f'in_softlockup : {prog["scx_in_softlockup"].value_()}') 39 - print(f'breather_depth: {read_atomic("scx_breather_depth")}') 41 + print(f'aborting : {prog["scx_aborting"].value_()}') 40 42 print(f'bypass_depth : {prog["scx_bypass_depth"].value_()}') 41 43 print(f'nr_rejected : {read_atomic("scx_nr_rejected")}') 42 44 print(f'enable_seq : {read_atomic("scx_enable_seq")}')