-#include <trace/events/sched.h>
-
-#define THIS_SYSTEM "custom_sched"
-
-#define SCHED_PRINT_FMT \
- C("prev_prio=%d next_pid=%d next_prio=%d", REC->prev_prio, REC->next_pid, \
- REC->next_prio)
-
-#define SCHED_WAKING_FMT \
- C("pid=%d prio=%d", REC->pid, REC->prio)
-
-#undef C
-#define C(a, b...) a, b
-
-static struct trace_event_fields sched_switch_fields[] = {
- {
- .type = "unsigned short",
- .name = "prev_prio",
- .size = sizeof(short),
- .align = __alignof__(short),
- .is_signed = 0,
- .filter_type = FILTER_OTHER,
- },
- {
- .type = "unsigned short",
- .name = "next_prio",
- .size = sizeof(short),
- .align = __alignof__(short),
- .is_signed = 0,
- .filter_type = FILTER_OTHER,
- },
- {
- .type = "unsigned int",
- .name = "next_prio",
- .size = sizeof(int),
- .align = __alignof__(int),
- .is_signed = 0,
- .filter_type = FILTER_OTHER,
- },
- {}
-};
-
-struct sched_event {
- struct trace_entry ent;
- unsigned short prev_prio;
- unsigned short next_prio;
- unsigned int next_pid;
-};
-
-static struct trace_event_fields sched_waking_fields[] = {
- {
- .type = "unsigned int",
- .name = "pid",
- .size = sizeof(int),
- .align = __alignof__(int),
- .is_signed = 0,
- .filter_type = FILTER_OTHER,
- },
- {
- .type = "unsigned short",
- .name = "prio",
- .size = sizeof(short),
- .align = __alignof__(short),
- .is_signed = 0,
- .filter_type = FILTER_OTHER,
- },
- {}
-};
-
-struct wake_event {
- struct trace_entry ent;
- unsigned int pid;
- unsigned short prio;
-};
-
-static void sched_switch_probe(void *data, bool preempt, struct task_struct *prev,
- struct task_struct *next)
-{
- struct trace_event_file *trace_file = data;
- struct trace_event_buffer fbuffer;
- struct sched_event *entry;
-
- if (trace_trigger_soft_disabled(trace_file))
- return;
-
- entry = trace_event_buffer_reserve(&fbuffer, trace_file,
- sizeof(*entry));
-
- if (!entry)
- return;
-
- entry->prev_prio = prev->prio;
- entry->next_prio = next->prio;
- entry->next_pid = next->pid;
-
- trace_event_buffer_commit(&fbuffer);
-}
-
-static struct trace_event_class sched_switch_class = {
- .system = THIS_SYSTEM,
- .reg = trace_event_reg,
- .fields_array = sched_switch_fields,
- .fields = LIST_HEAD_INIT(sched_switch_class.fields),
- .probe = sched_switch_probe,
-};
-
-static void sched_waking_probe(void *data, struct task_struct *t)
-{
- struct trace_event_file *trace_file = data;
- struct trace_event_buffer fbuffer;
- struct wake_event *entry;
-
- if (trace_trigger_soft_disabled(trace_file))
- return;
-
- entry = trace_event_buffer_reserve(&fbuffer, trace_file,
- sizeof(*entry));
-
- if (!entry)
- return;
-
- entry->prio = t->prio;
- entry->pid = t->pid;
-
- trace_event_buffer_commit(&fbuffer);
-}
-
-static struct trace_event_class sched_waking_class = {
- .system = THIS_SYSTEM,
- .reg = trace_event_reg,
- .fields_array = sched_waking_fields,
- .fields = LIST_HEAD_INIT(sched_waking_class.fields),
- .probe = sched_waking_probe,
-};
-
-static enum print_line_t sched_switch_output(struct trace_iterator *iter, int flags,
- struct trace_event *trace_event)
-{
- struct trace_seq *s = &iter->seq;
- struct sched_event *REC = (struct sched_event *)iter->ent;
- int ret;
-
- ret = trace_raw_output_prep(iter, trace_event);
- if (ret != TRACE_TYPE_HANDLED)
- return ret;
-
- trace_seq_printf(s, SCHED_PRINT_FMT);
- trace_seq_putc(s, '\n');