diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/sched_ext/include/scx/common.bpf.h | 1 | ||||
| -rw-r--r-- | tools/sched_ext/scx_qmap.bpf.c | 37 | ||||
| -rw-r--r-- | tools/sched_ext/scx_qmap.c | 4 | 
3 files changed, 39 insertions, 3 deletions
| diff --git a/tools/sched_ext/include/scx/common.bpf.h b/tools/sched_ext/include/scx/common.bpf.h index 421118bc56ff..8686f84497db 100644 --- a/tools/sched_ext/include/scx/common.bpf.h +++ b/tools/sched_ext/include/scx/common.bpf.h @@ -34,6 +34,7 @@ void scx_bpf_dispatch(struct task_struct *p, u64 dsq_id, u64 slice, u64 enq_flag  u32 scx_bpf_dispatch_nr_slots(void) __ksym;  void scx_bpf_dispatch_cancel(void) __ksym;  bool scx_bpf_consume(u64 dsq_id) __ksym; +u32 scx_bpf_reenqueue_local(void) __ksym;  void scx_bpf_kick_cpu(s32 cpu, u64 flags) __ksym;  s32 scx_bpf_dsq_nr_queued(u64 dsq_id) __ksym;  void scx_bpf_destroy_dsq(u64 dsq_id) __ksym; diff --git a/tools/sched_ext/scx_qmap.bpf.c b/tools/sched_ext/scx_qmap.bpf.c index 879fc9c788e5..4a87377558c8 100644 --- a/tools/sched_ext/scx_qmap.bpf.c +++ b/tools/sched_ext/scx_qmap.bpf.c @@ -11,6 +11,8 @@   *   * - BPF-side queueing using PIDs.   * - Sleepable per-task storage allocation using ops.prep_enable(). + * - Using ops.cpu_release() to handle a higher priority scheduling class taking + *   the CPU away.   *   * This scheduler is primarily for demonstration and testing of sched_ext   * features and unlikely to be useful for actual workloads. @@ -90,7 +92,7 @@ struct {  } cpu_ctx_stor SEC(".maps");  /* Statistics */ -u64 nr_enqueued, nr_dispatched, nr_dequeued; +u64 nr_enqueued, nr_dispatched, nr_reenqueued, nr_dequeued;  s32 BPF_STRUCT_OPS(qmap_select_cpu, struct task_struct *p,  		   s32 prev_cpu, u64 wake_flags) @@ -164,6 +166,22 @@ void BPF_STRUCT_OPS(qmap_enqueue, struct task_struct *p, u64 enq_flags)  		return;  	} +	/* +	 * If the task was re-enqueued due to the CPU being preempted by a +	 * higher priority scheduling class, just re-enqueue the task directly +	 * on the global DSQ. As we want another CPU to pick it up, find and +	 * kick an idle CPU. +	 */ +	if (enq_flags & SCX_ENQ_REENQ) { +		s32 cpu; + +		scx_bpf_dispatch(p, SHARED_DSQ, 0, enq_flags); +		cpu = scx_bpf_pick_idle_cpu(p->cpus_ptr, 0); +		if (cpu >= 0) +			scx_bpf_kick_cpu(cpu, SCX_KICK_IDLE); +		return; +	} +  	ring = bpf_map_lookup_elem(&queue_arr, &idx);  	if (!ring) {  		scx_bpf_error("failed to find ring %d", idx); @@ -257,6 +275,22 @@ void BPF_STRUCT_OPS(qmap_dispatch, s32 cpu, struct task_struct *prev)  	}  } +void BPF_STRUCT_OPS(qmap_cpu_release, s32 cpu, struct scx_cpu_release_args *args) +{ +	u32 cnt; + +	/* +	 * Called when @cpu is taken by a higher priority scheduling class. This +	 * makes @cpu no longer available for executing sched_ext tasks. As we +	 * don't want the tasks in @cpu's local dsq to sit there until @cpu +	 * becomes available again, re-enqueue them into the global dsq. See +	 * %SCX_ENQ_REENQ handling in qmap_enqueue(). +	 */ +	cnt = scx_bpf_reenqueue_local(); +	if (cnt) +		__sync_fetch_and_add(&nr_reenqueued, cnt); +} +  s32 BPF_STRUCT_OPS(qmap_init_task, struct task_struct *p,  		   struct scx_init_task_args *args)  { @@ -339,6 +373,7 @@ SCX_OPS_DEFINE(qmap_ops,  	       .enqueue			= (void *)qmap_enqueue,  	       .dequeue			= (void *)qmap_dequeue,  	       .dispatch		= (void *)qmap_dispatch, +	       .cpu_release		= (void *)qmap_cpu_release,  	       .init_task		= (void *)qmap_init_task,  	       .dump			= (void *)qmap_dump,  	       .dump_cpu		= (void *)qmap_dump_cpu, diff --git a/tools/sched_ext/scx_qmap.c b/tools/sched_ext/scx_qmap.c index 594147a710a8..2a97421afe9a 100644 --- a/tools/sched_ext/scx_qmap.c +++ b/tools/sched_ext/scx_qmap.c @@ -112,9 +112,9 @@ int main(int argc, char **argv)  		long nr_enqueued = skel->bss->nr_enqueued;  		long nr_dispatched = skel->bss->nr_dispatched; -		printf("stats  : enq=%lu dsp=%lu delta=%ld deq=%"PRIu64"\n", +		printf("stats  : enq=%lu dsp=%lu delta=%ld reenq=%"PRIu64" deq=%"PRIu64"\n",  		       nr_enqueued, nr_dispatched, nr_enqueued - nr_dispatched, -		       skel->bss->nr_dequeued); +		       skel->bss->nr_reenqueued, skel->bss->nr_dequeued);  		fflush(stdout);  		sleep(1);  	} | 
