scx_bpfland: expose the amount of online CPUs

Periodically report the amount of online CPUs to stdout.

The online CPUs are initially evaluated looking at the online cpumask,
then the value is updated in the .cpu_offline() / .cpu_online()
callbacks.

Tested-by: Piotr Gorski <lucjan.lucjanov@gmail.com>
Signed-off-by: Andrea Righi <righi.andrea@gmail.com>
This commit is contained in:
Andrea Righi 2024-07-10 14:05:47 +02:00
parent 3a47b484af
commit f59aa52fe7
2 changed files with 32 additions and 2 deletions

View File

@ -84,7 +84,7 @@ volatile u64 nr_direct_dispatches, nr_kthread_dispatches,
/* /*
* Amount of currently running tasks. * Amount of currently running tasks.
*/ */
volatile u64 nr_running, nr_interactive; volatile u64 nr_running, nr_interactive, nr_online_cpus;
/* /*
* Exit information. * Exit information.
@ -682,12 +682,16 @@ void BPF_STRUCT_OPS(bpfland_cpu_online, s32 cpu)
{ {
/* Set the CPU state to offline */ /* Set the CPU state to offline */
set_cpu_state(offline_cpumask, cpu, false); set_cpu_state(offline_cpumask, cpu, false);
__sync_fetch_and_add(&nr_online_cpus, 1);
} }
void BPF_STRUCT_OPS(bpfland_cpu_offline, s32 cpu) void BPF_STRUCT_OPS(bpfland_cpu_offline, s32 cpu)
{ {
/* Set the CPU state to online */ /* Set the CPU state to online */
set_cpu_state(offline_cpumask, cpu, true); set_cpu_state(offline_cpumask, cpu, true);
__sync_fetch_and_sub(&nr_online_cpus, 1);
} }
s32 BPF_STRUCT_OPS(bpfland_init_task, struct task_struct *p, s32 BPF_STRUCT_OPS(bpfland_init_task, struct task_struct *p,
@ -700,12 +704,38 @@ s32 BPF_STRUCT_OPS(bpfland_init_task, struct task_struct *p,
return -ENOMEM; return -ENOMEM;
} }
/*
* Evaluate the amount of online CPUs.
*/
s32 get_nr_online_cpus(void)
{
const struct cpumask *online_cpumask;
u64 cpu_max = scx_bpf_nr_cpu_ids();
int i, cpus = 0;
cpu_max = scx_bpf_nr_cpu_ids();
online_cpumask = scx_bpf_get_online_cpumask();
bpf_for(i, 0, cpu_max) {
if (!bpf_cpumask_test_cpu(i, online_cpumask))
continue;
cpus++;
}
scx_bpf_put_cpumask(online_cpumask);
return cpus;
}
s32 BPF_STRUCT_OPS_SLEEPABLE(bpfland_init) s32 BPF_STRUCT_OPS_SLEEPABLE(bpfland_init)
{ {
struct bpf_cpumask *mask; struct bpf_cpumask *mask;
int err; int err;
s32 cpu; s32 cpu;
/* Initialize amount of online CPUs */
nr_online_cpus = get_nr_online_cpus();
/* Create per-CPU DSQs (used to dispatch tasks directly on a CPU) */ /* Create per-CPU DSQs (used to dispatch tasks directly on a CPU) */
bpf_for(cpu, 0, MAX_CPUS) { bpf_for(cpu, 0, MAX_CPUS) {
err = scx_bpf_create_dsq(cpu_to_dsq(cpu), -1); err = scx_bpf_create_dsq(cpu_to_dsq(cpu), -1);

View File

@ -205,7 +205,7 @@ impl<'a> Scheduler<'a> {
} }
fn update_stats(&mut self) { fn update_stats(&mut self) {
let nr_cpus = libbpf_rs::num_possible_cpus().unwrap(); let nr_cpus = self.skel.bss().nr_online_cpus;
let nr_running = self.skel.bss().nr_running; let nr_running = self.skel.bss().nr_running;
let nr_interactive = self.skel.bss().nr_interactive; let nr_interactive = self.skel.bss().nr_interactive;
let nr_kthread_dispatches = self.skel.bss().nr_kthread_dispatches; let nr_kthread_dispatches = self.skel.bss().nr_kthread_dispatches;