mirror of
https://github.com/JakeHillion/scx.git
synced 2024-11-26 03:20:24 +00:00
scx_rustland: provide get/set_cpu_owner()
Provide the following primitives to get and set CPU ownership in the BPF part. This improves code readability and these primitives can be used by the BPF part as a baseline to implement a better CPU idle tracking in the future. Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
This commit is contained in:
parent
cd7e1c6248
commit
7d01be9568
@ -148,6 +148,40 @@ struct {
|
||||
__type(value, u32);
|
||||
} cpu_map SEC(".maps");
|
||||
|
||||
/*
|
||||
* Assign a task to a CPU (used in .running() and .stopping()).
|
||||
*
|
||||
* If pid == 0 the CPU will be considered idle.
|
||||
*/
|
||||
static void set_cpu_owner(u32 cpu, u32 pid)
|
||||
{
|
||||
u32 *owner;
|
||||
|
||||
owner = bpf_map_lookup_elem(&cpu_map, &cpu);
|
||||
if (!owner) {
|
||||
scx_bpf_error("Failed to look up cpu_map for cpu %u", cpu);
|
||||
return;
|
||||
}
|
||||
*owner= pid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the pid of the task that is currently running on @cpu.
|
||||
*
|
||||
* Return 0 if the CPU is idle.
|
||||
*/
|
||||
static u32 get_cpu_owner(u32 cpu)
|
||||
{
|
||||
u32 *owner;
|
||||
|
||||
owner = bpf_map_lookup_elem(&cpu_map, &cpu);
|
||||
if (!owner) {
|
||||
scx_bpf_error("Failed to look up cpu_map for cpu %u", cpu);
|
||||
return 0;
|
||||
}
|
||||
return *owner;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if the target task @p is the user-space scheduler.
|
||||
*/
|
||||
@ -225,9 +259,6 @@ static void dispatch_global(struct task_struct *p, u64 enq_flags)
|
||||
* If the CPU where the task was running is still idle, then the task can be
|
||||
* dispatched immediately on the same CPU from .enqueue(), without having to
|
||||
* call the scheduler.
|
||||
*
|
||||
* In the future we may want to improve this part and figure out a way to move
|
||||
* this logic into the user-space scheduler as well.
|
||||
*/
|
||||
s32 BPF_STRUCT_OPS(rustland_select_cpu, struct task_struct *p, s32 prev_cpu,
|
||||
u64 wake_flags)
|
||||
@ -243,11 +274,11 @@ s32 BPF_STRUCT_OPS(rustland_select_cpu, struct task_struct *p, s32 prev_cpu,
|
||||
* Always try to keep the tasks on the same CPU (unless the user-space
|
||||
* scheduler decides otherwise).
|
||||
*
|
||||
* Then check if the previously used CPU is still idle, in this case we
|
||||
* can dispatch directly from .enqueue() bypassing the user-space
|
||||
* Check if the previously used CPU is idle, in this case we can
|
||||
* dispatch directly from .enqueue(), bypassing the user-space
|
||||
* scheduler.
|
||||
*/
|
||||
tctx->force_local = scx_bpf_test_and_clear_cpu_idle(prev_cpu);
|
||||
tctx->force_local = get_cpu_owner(prev_cpu) == 0;
|
||||
|
||||
return prev_cpu;
|
||||
}
|
||||
@ -412,25 +443,15 @@ void BPF_STRUCT_OPS(rustland_dispatch, s32 cpu, struct task_struct *prev)
|
||||
/* Task @p starts on a CPU */
|
||||
void BPF_STRUCT_OPS(rustland_running, struct task_struct *p)
|
||||
{
|
||||
u32 key = scx_bpf_task_cpu(p);
|
||||
u32 *value;
|
||||
|
||||
dbg_msg("start: pid=%d (%s)", p->pid, p->comm);
|
||||
value = bpf_map_lookup_elem(&cpu_map, &key);
|
||||
if (value)
|
||||
*value = p->pid;
|
||||
set_cpu_owner(scx_bpf_task_cpu(p), p->pid);
|
||||
}
|
||||
|
||||
/* Task @p releases a CPU */
|
||||
void BPF_STRUCT_OPS(rustland_stopping, struct task_struct *p, bool runnable)
|
||||
{
|
||||
u32 key = scx_bpf_task_cpu(p);
|
||||
u32 *value;
|
||||
|
||||
dbg_msg("stop: pid=%d (%s)", p->pid, p->comm);
|
||||
value = bpf_map_lookup_elem(&cpu_map, &key);
|
||||
if (value)
|
||||
*value = 0;
|
||||
set_cpu_owner(scx_bpf_task_cpu(p), 0);
|
||||
}
|
||||
|
||||
/* Task @p is created */
|
||||
|
Loading…
Reference in New Issue
Block a user