Skip to content

Commit 73a9a07

Browse files
authored
Merge pull request #5 from sched-ext/htejun
scx_central: Implement fallback for missing BPF_F_TIMER_CPU_PIN support
2 parents 9eb1f36 + 8ee1bc7 commit 73a9a07

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

scheds/kernel-examples/scx_central.bpf.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ const volatile s32 central_cpu;
6060
const volatile u32 nr_cpu_ids = 1; /* !0 for veristat, set during init */
6161
const volatile u64 slice_ns = SCX_SLICE_DFL;
6262

63+
bool timer_pinned = true;
6364
u64 nr_total, nr_locals, nr_queued, nr_lost_pids;
6465
u64 nr_timers, nr_dispatches, nr_mismatches, nr_retries;
6566
u64 nr_overflows;
@@ -255,7 +256,7 @@ static int central_timerfn(void *map, int *key, struct bpf_timer *timer)
255256
s32 i, curr_cpu;
256257

257258
curr_cpu = bpf_get_smp_processor_id();
258-
if (curr_cpu != central_cpu) {
259+
if (timer_pinned && (curr_cpu != central_cpu)) {
259260
scx_bpf_error("Central timer ran on CPU %d, not central CPU %d",
260261
curr_cpu, central_cpu);
261262
return 0;
@@ -308,12 +309,28 @@ int BPF_STRUCT_OPS_SLEEPABLE(central_init)
308309
if (!timer)
309310
return -ESRCH;
310311

311-
if (bpf_get_smp_processor_id() != central_cpu)
312+
if (bpf_get_smp_processor_id() != central_cpu) {
313+
scx_bpf_error("init from non-central CPU");
312314
return -EINVAL;
315+
}
313316

314317
bpf_timer_init(timer, &central_timer, CLOCK_MONOTONIC);
315318
bpf_timer_set_callback(timer, central_timerfn);
319+
316320
ret = bpf_timer_start(timer, TIMER_INTERVAL_NS, BPF_F_TIMER_CPU_PIN);
321+
/*
322+
* BPF_F_TIMER_CPU_PIN is pretty new (>=6.7). If we're running in a
323+
* kernel which doesn't have it, bpf_timer_start() will return -EINVAL.
324+
* Retry without the PIN. This would be the perfect use case for
325+
* bpf_core_enum_value_exists() but the enum type doesn't have a name
326+
* and can't be used with bpf_core_enum_value_exists(). Oh well...
327+
*/
328+
if (ret == -EINVAL) {
329+
timer_pinned = false;
330+
ret = bpf_timer_start(timer, TIMER_INTERVAL_NS, 0);
331+
}
332+
if (ret)
333+
scx_bpf_error("bpf_timer_start failed (%d)", ret);
317334
return ret;
318335
}
319336

scheds/kernel-examples/scx_central.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ int main(int argc, char **argv)
9898
link = bpf_map__attach_struct_ops(skel->maps.central_ops);
9999
SCX_BUG_ON(!link, "Failed to attach struct_ops");
100100

101+
if (!skel->data->timer_pinned)
102+
printf("WARNING : BPF_F_TIMER_CPU_PIN not available, timer not pinned to central\n");
103+
101104
while (!exit_req && !uei_exited(&skel->bss->uei)) {
102105
printf("[SEQ %llu]\n", seq++);
103106
printf("total :%10lu local:%10lu queued:%10lu lost:%10lu\n",

0 commit comments

Comments
 (0)