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

Configure Feed

Select the types of activity you want to include in your feed.

sched_ext: Add reenq_flags plumbing to scx_bpf_dsq_reenq()

Add infrastructure to pass flags through the deferred reenqueue path.
reenq_local() now takes a reenq_flags parameter, and scx_sched_pcpu gains a
deferred_reenq_local_flags field to accumulate flags from multiple
scx_bpf_dsq_reenq() calls before processing. No flags are defined yet.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Andrea Righi <arighi@nvidia.com>

Tejun Heo ffa7ae07 9c34c507

+38 -5
+28 -5
kernel/sched/ext.c
··· 1080 1080 schedule_deferred(rq); 1081 1081 } 1082 1082 1083 - static void schedule_dsq_reenq(struct scx_sched *sch, struct scx_dispatch_q *dsq) 1083 + static void schedule_dsq_reenq(struct scx_sched *sch, struct scx_dispatch_q *dsq, 1084 + u64 reenq_flags) 1084 1085 { 1085 1086 /* 1086 1087 * Allowing reenqueues doesn't make sense while bypassing. This also ··· 1098 1097 scoped_guard (raw_spinlock_irqsave, &rq->scx.deferred_reenq_lock) { 1099 1098 if (list_empty(&drl->node)) 1100 1099 list_move_tail(&drl->node, &rq->scx.deferred_reenq_locals); 1100 + drl->flags |= reenq_flags; 1101 1101 } 1102 1102 1103 1103 schedule_deferred(rq); ··· 3619 3617 } 3620 3618 } 3621 3619 3622 - static u32 reenq_local(struct scx_sched *sch, struct rq *rq) 3620 + static bool task_should_reenq(struct task_struct *p, u64 reenq_flags) 3621 + { 3622 + if (reenq_flags & SCX_REENQ_ANY) 3623 + return true; 3624 + return false; 3625 + } 3626 + 3627 + static u32 reenq_local(struct scx_sched *sch, struct rq *rq, u64 reenq_flags) 3623 3628 { 3624 3629 LIST_HEAD(tasks); 3625 3630 u32 nr_enqueued = 0; ··· 3660 3651 if (!scx_is_descendant(task_sch, sch)) 3661 3652 continue; 3662 3653 3654 + if (!task_should_reenq(p, reenq_flags)) 3655 + continue; 3656 + 3663 3657 dispatch_dequeue(rq, p); 3664 3658 list_add_tail(&p->scx.dsq_list.node, &tasks); 3665 3659 } ··· 3682 3670 3683 3671 while (true) { 3684 3672 struct scx_sched *sch; 3673 + u64 reenq_flags = 0; 3685 3674 3686 3675 scoped_guard (raw_spinlock, &rq->scx.deferred_reenq_lock) { 3687 3676 struct scx_deferred_reenq_local *drl = ··· 3697 3684 sch_pcpu = container_of(drl, struct scx_sched_pcpu, 3698 3685 deferred_reenq_local); 3699 3686 sch = sch_pcpu->sch; 3687 + swap(drl->flags, reenq_flags); 3700 3688 list_del_init(&drl->node); 3701 3689 } 3702 3690 3703 - reenq_local(sch, rq); 3691 + reenq_local(sch, rq, reenq_flags); 3704 3692 } 3705 3693 } 3706 3694 ··· 7830 7816 rq = cpu_rq(smp_processor_id()); 7831 7817 lockdep_assert_rq_held(rq); 7832 7818 7833 - return reenq_local(sch, rq); 7819 + return reenq_local(sch, rq, 0); 7834 7820 } 7835 7821 7836 7822 __bpf_kfunc_end_defs(); ··· 8268 8254 if (unlikely(!sch)) 8269 8255 return; 8270 8256 8257 + if (unlikely(reenq_flags & ~__SCX_REENQ_USER_MASK)) { 8258 + scx_error(sch, "invalid SCX_REENQ flags 0x%llx", reenq_flags); 8259 + return; 8260 + } 8261 + 8262 + /* not specifying any filter bits is the same as %SCX_REENQ_ANY */ 8263 + if (!(reenq_flags & __SCX_REENQ_FILTER_MASK)) 8264 + reenq_flags |= SCX_REENQ_ANY; 8265 + 8271 8266 dsq = find_dsq_for_dispatch(sch, this_rq(), dsq_id, smp_processor_id()); 8272 - schedule_dsq_reenq(sch, dsq); 8267 + schedule_dsq_reenq(sch, dsq, reenq_flags); 8273 8268 } 8274 8269 8275 8270 /**
+10
kernel/sched/ext_internal.h
··· 956 956 957 957 struct scx_deferred_reenq_local { 958 958 struct list_head node; 959 + u64 flags; 959 960 }; 960 961 961 962 struct scx_sched_pcpu { ··· 1127 1126 * etc.). 1128 1127 */ 1129 1128 SCX_DEQ_SCHED_CHANGE = 1LLU << 33, 1129 + }; 1130 + 1131 + enum scx_reenq_flags { 1132 + /* low 16bits determine which tasks should be reenqueued */ 1133 + SCX_REENQ_ANY = 1LLU << 0, /* all tasks */ 1134 + 1135 + __SCX_REENQ_FILTER_MASK = 0xffffLLU, 1136 + 1137 + __SCX_REENQ_USER_MASK = SCX_REENQ_ANY, 1130 1138 }; 1131 1139 1132 1140 enum scx_pick_idle_cpu_flags {