mirror of
https://github.com/sched-ext/scx.git
synced 2024-11-28 05:30:24 +00:00
scx_layered: Add timer helpers
Add registry of timers and a helper for running timers. Signed-off-by: Daniel Hodges <hodges.daniel.scott@gmail.com>
This commit is contained in:
parent
d5b8aafa1a
commit
4898f5082a
@ -47,7 +47,7 @@ enum consts {
|
||||
LO_FALLBACK_DSQ = (MAX_LAYERS * MAX_LLCS) + MAX_LLCS + 1,
|
||||
|
||||
/* XXX remove */
|
||||
MAX_CGRP_PREFIXES = 32
|
||||
MAX_CGRP_PREFIXES = 32
|
||||
};
|
||||
|
||||
enum layer_kind {
|
||||
|
@ -10,6 +10,7 @@
|
||||
#endif
|
||||
|
||||
#include "intf.h"
|
||||
#include "timer.bpf.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
@ -49,6 +50,23 @@ static u32 preempt_cursor;
|
||||
|
||||
#include "util.bpf.c"
|
||||
|
||||
|
||||
static __always_inline bool run_timer_cb(int key)
|
||||
{
|
||||
switch (key) {
|
||||
case NOOP_TIMER:
|
||||
case MAX_TIMERS:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
struct layered_timer layered_timers[MAX_TIMERS] = {
|
||||
{0, CLOCK_BOOTTIME, 0},
|
||||
};
|
||||
|
||||
#include "timer.bpf.c"
|
||||
|
||||
UEI_DEFINE(uei);
|
||||
|
||||
static inline bool vtime_before(u64 a, u64 b)
|
||||
@ -2245,6 +2263,7 @@ s32 BPF_STRUCT_OPS_SLEEPABLE(layered_init)
|
||||
}
|
||||
}
|
||||
}
|
||||
start_layered_timers();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
74
scheds/rust/scx_layered/src/bpf/timer.bpf.c
Normal file
74
scheds/rust/scx_layered/src/bpf/timer.bpf.c
Normal file
@ -0,0 +1,74 @@
|
||||
/* Copyright (c) Meta Platforms, Inc. and affiliates. */
|
||||
#include <bpf/bpf_core_read.h>
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include <bpf/bpf_tracing.h>
|
||||
|
||||
|
||||
struct timer_wrapper {
|
||||
struct bpf_timer timer;
|
||||
};
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_ARRAY);
|
||||
__uint(max_entries, MAX_TIMERS);
|
||||
__type(key, int);
|
||||
__type(value, struct timer_wrapper);
|
||||
} layered_timer_data SEC(".maps");
|
||||
|
||||
|
||||
static int layered_timer_cb(void *map, int key, struct timer_wrapper *timerw)
|
||||
{
|
||||
struct layered_timer *cb_timer = MEMBER_VPTR(layered_timers, [key]);
|
||||
bool resched = run_timer_cb(key);
|
||||
|
||||
if (!resched || cb_timer->interval_ns == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return bpf_timer_start(&timerw->timer,
|
||||
cb_timer->interval_ns,
|
||||
cb_timer->start_flags);
|
||||
}
|
||||
|
||||
static int start_layered_timers(void)
|
||||
{
|
||||
struct timer_wrapper *timerw;
|
||||
int timer_id, err;
|
||||
|
||||
bpf_for(timer_id, 0, MAX_TIMERS) {
|
||||
timerw = bpf_map_lookup_elem(&layered_timer_data, &timer_id);
|
||||
if (!timerw) {
|
||||
scx_bpf_error("Failed to lookup layered timer");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
struct layered_timer *new_timer = MEMBER_VPTR(layered_timers, [timer_id]);
|
||||
if (!new_timer) {
|
||||
scx_bpf_error("can't happen");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
err = bpf_timer_init(&timerw->timer,
|
||||
&layered_timer_data, new_timer->init_flags);
|
||||
if (err) {
|
||||
scx_bpf_error("can't happen");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
err = bpf_timer_set_callback(&timerw->timer, &layered_timer_cb);
|
||||
if (err) {
|
||||
scx_bpf_error("can't happen");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
err = bpf_timer_start(&timerw->timer,
|
||||
new_timer->interval_ns,
|
||||
new_timer->start_flags);
|
||||
if (err) {
|
||||
scx_bpf_error("can't happen");
|
||||
return -ENOENT;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
24
scheds/rust/scx_layered/src/bpf/timer.bpf.h
Normal file
24
scheds/rust/scx_layered/src/bpf/timer.bpf.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* Copyright (c) Meta Platforms, Inc. and affiliates. */
|
||||
#ifndef __LAYERED_TIMER_H
|
||||
#define __LAYERED_TIMER_H
|
||||
#include <bpf/bpf_core_read.h>
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include <bpf/bpf_tracing.h>
|
||||
|
||||
enum timer_consts {
|
||||
// kernel definitions
|
||||
CLOCK_BOOTTIME = 7,
|
||||
};
|
||||
|
||||
struct layered_timer {
|
||||
// if set to 0 the timer will only be scheduled once
|
||||
int interval_ns;
|
||||
u64 init_flags;
|
||||
u64 start_flags;
|
||||
};
|
||||
|
||||
enum layer_timer_callbacks {
|
||||
NOOP_TIMER,
|
||||
MAX_TIMERS,
|
||||
};
|
||||
#endif /* __LAYERED_TIMER_H */
|
Loading…
Reference in New Issue
Block a user