Skip to content

Commit

Permalink
lcore_monitor: add hook for irq entry/exit (#717)
Browse files Browse the repository at this point in the history
output like below:
lm_event_handler: sched out 5.315us as comm: migration/30
lm_event_handler: sched out 4.640us as comm: migration/30
lm_event_handler: sched out 5.304us as comm: migration/30
lm_event_handler: sched out 0.787us as irq: 348
lm_event_handler: sched out 1.248us as irq: 348

Signed-off-by: Frank Du <[email protected]>
  • Loading branch information
frankdjx authored Jan 23, 2024
1 parent bc3f494 commit b2c1cb2
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 18 deletions.
52 changes: 44 additions & 8 deletions tools/ebpf/lcore_monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
struct lcore_monitor_ctx {
char bpf_prog[64];
struct lcore_tid_cfg cfg;
struct lcore_tid_event out;
struct lcore_tid_event sched_out;
struct lcore_tid_event irq_entry;
};

enum lm_args_cmd {
Expand Down Expand Up @@ -132,19 +133,30 @@ static int lm_event_handler(void* pri, void* data, size_t data_sz) {

dbg("%s: type %d, ns %" PRIu64 "\n", __func__, e->type, e->ns);
if (e->type == LCORE_SCHED_OUT) {
memcpy(&ctx->out, e, sizeof(ctx->out));
dbg("%s: out ns %" PRIu64 "\n", __func__, ctx->out.ns);
memcpy(&ctx->sched_out, e, sizeof(ctx->sched_out));
dbg("%s: out ns %" PRIu64 "\n", __func__, ctx->sched_out.ns);
return 0;
}

if (e->type == LCORE_SCHED_IN) {
float ns = e->ns - ctx->out.ns;
int next_pid = ctx->out.next_pid;
float ns = e->ns - ctx->sched_out.ns;
int next_pid = ctx->sched_out.next_pid;
char process_name[64];
get_process_name_by_pid(next_pid, process_name, sizeof(process_name));
info("%s: sched out %.3fus as comm: %s\n", __func__, ns / 1000, process_name);
}

if (e->type == LCORE_IRQ_ENTRY) {
memcpy(&ctx->irq_entry, e, sizeof(ctx->irq_entry));
dbg("%s: irq_entry ns %" PRIu64 "\n", __func__, ctx->irq_entry.ns);
return 0;
}

if (e->type == LCORE_IRQ_EXIT) {
float ns = e->ns - ctx->irq_entry.ns;
info("%s: sched out %.3fus as irq: %d\n", __func__, ns / 1000, ctx->irq_entry.irq);
}

return 0;
}

Expand Down Expand Up @@ -194,15 +206,39 @@ int main(int argc, char** argv) {
return -1;
}

/* attach bpf_prog_sched_switch */
prog = bpf_object__find_program_by_name(obj, "bpf_prog_sched_switch");
if (!prog) {
err("%s, finding BPF program failed\n", __func__);
err("%s, finding bpf_prog_sched_switch failed\n", __func__);
return -1;
}

link = bpf_program__attach_tracepoint(prog, "sched", "sched_switch");
if (libbpf_get_error(link)) {
err("%s, attaching BPF program to tracepoint failed\n", __func__);
err("%s, attaching bpf_prog_sched_switch to tracepoint failed\n", __func__);
return -1;
}

/* attach bpf_prog_irq_handler_entry */
prog = bpf_object__find_program_by_name(obj, "bpf_prog_irq_handler_entry");
if (!prog) {
err("%s, finding bpf_prog_irq_handler_entry failed\n", __func__);
return -1;
}
link = bpf_program__attach_tracepoint(prog, "irq", "irq_handler_entry");
if (libbpf_get_error(link)) {
err("%s, attaching bpf_prog_irq_handler_entry to tracepoint failed\n", __func__);
return -1;
}

/* attach bpf_prog_irq_handler_exit */
prog = bpf_object__find_program_by_name(obj, "bpf_prog_irq_handler_exit");
if (!prog) {
err("%s, finding bpf_prog_irq_handler_exit failed\n", __func__);
return -1;
}
link = bpf_program__attach_tracepoint(prog, "irq", "irq_handler_exit");
if (libbpf_get_error(link)) {
err("%s, attaching bpf_prog_irq_handler_exit to tracepoint failed\n", __func__);
return -1;
}

Expand Down
15 changes: 12 additions & 3 deletions tools/ebpf/lcore_monitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,23 @@ struct lcore_tid_cfg {
};

enum lcore_tid_event_type {
LCORE_SCHED_IN,
LCORE_SCHED_OUT,
/* hook on tracepoint/sched/sched_switch */
LCORE_SCHED_IN, /* the t_pid was scheduled in */
LCORE_SCHED_OUT, /* the t_pid was scheduled out */
/* note: irq hook is only for io interrupt, not for system irq like timer */
/* hook on tracepoint/irq/irq_handler_entry */
LCORE_IRQ_ENTRY,
/* hook on tracepoint/irq/irq_handler_exit */
LCORE_IRQ_EXIT,
};

struct lcore_tid_event {
enum lcore_tid_event_type type;
uint64_t ns;
int next_pid;
union {
int next_pid; /* for LCORE_SCHED_IN/LCORE_SCHED_OUT */
int irq; /* for LCORE_IRQ_ENTRY/LCORE_IRQ_EXIT */
};
};

#endif
75 changes: 68 additions & 7 deletions tools/ebpf/lcore_monitor_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,15 @@ struct {
__uint(max_entries, 512 * 1024);
} lm_events_map SEC(".maps");

static int lm_event_submit(enum lcore_tid_event_type type,
struct trace_event_raw_sched_switch* args) {
static struct lcore_tid_cfg* lm_get_cfg(void) {
struct lcore_tid_cfg* cfg;
uint32_t key = 0;
cfg = bpf_map_lookup_elem(&lm_cfg_map, &key);
return cfg;
}

static int lm_switch_event_submit(enum lcore_tid_event_type type,
struct trace_event_raw_sched_switch* args) {
struct lcore_tid_event* e;

e = bpf_ringbuf_reserve(&lm_events_map, sizeof(*e), 0);
Expand All @@ -44,26 +51,80 @@ static int lm_event_submit(enum lcore_tid_event_type type,

SEC("tracepoint/sched/sched_switch")
int bpf_prog_sched_switch(struct trace_event_raw_sched_switch* args) {
uint32_t key = 0;
struct lcore_tid_cfg* cfg = bpf_map_lookup_elem(&lm_cfg_map, &key);
struct lcore_tid_cfg* cfg = lm_get_cfg();
if (!cfg) return 0;

/* core id check */
if (bpf_get_smp_processor_id() != cfg->core_id) return 0;

if (cfg->bpf_trace) {
char fmt[] = "prev_pid %d next_pid in\n";
char fmt[] = "sched_switch: prev_pid %d next_pid in\n";
bpf_trace_printk(fmt, sizeof(fmt), args->prev_pid, args->next_pid);
}

if (args->prev_pid == cfg->t_pid) {
lm_event_submit(LCORE_SCHED_OUT, args);
lm_switch_event_submit(LCORE_SCHED_OUT, args);
}

if (args->next_pid == cfg->t_pid) {
lm_event_submit(LCORE_SCHED_IN, args);
lm_switch_event_submit(LCORE_SCHED_IN, args);
}

return 0;
}

static int lm_irq_event_submit(enum lcore_tid_event_type type,
struct trace_event_raw_irq_handler_entry* args) {
struct lcore_tid_event* e;

e = bpf_ringbuf_reserve(&lm_events_map, sizeof(*e), 0);
if (!e) {
char fmt[] = "lm event ringbuf reserve fail\n";
bpf_trace_printk(fmt, sizeof(fmt));
return 0;
}

e->type = type;
e->ns = bpf_ktime_get_ns();
e->irq = args->irq;

bpf_ringbuf_submit(e, 0);
return 0;
}

SEC("tracepoint/irq/irq_handler_entry")
int bpf_prog_irq_handler_entry(struct trace_event_raw_irq_handler_entry* args) {
struct lcore_tid_cfg* cfg = lm_get_cfg();
if (!cfg) return 0;

/* core id check */
if (bpf_get_smp_processor_id() != cfg->core_id) return 0;

if (cfg->bpf_trace) {
char fmt[] = "irq_handler_entry, irq %d\n";
bpf_trace_printk(fmt, sizeof(fmt), args->irq);
}

lm_irq_event_submit(LCORE_IRQ_ENTRY, args);

return 0;
}

SEC("tracepoint/irq/irq_handler_exit")
int bpf_prog_irq_handler_exit(struct trace_event_raw_irq_handler_entry* args) {
struct lcore_tid_cfg* cfg = lm_get_cfg();
if (!cfg) return 0;

/* core id check */
if (bpf_get_smp_processor_id() != cfg->core_id) return 0;

if (cfg->bpf_trace) {
char fmt[] = "irq_handler_exit, irq %d\n";
bpf_trace_printk(fmt, sizeof(fmt), args->irq);
}

lm_irq_event_submit(LCORE_IRQ_EXIT, args);

return 0;
}

Expand Down

0 comments on commit b2c1cb2

Please sign in to comment.