--- include/linux/logdev_marker.h | 2 + kernel/logdev/logdev_tracers.c | 76 +++++++++++++++++++++++++++++++++++++++++ kernel/sched.c | 3 + 3 files changed, 81 insertions(+) Index: linux-2.6.21.5-rt20/include/linux/logdev_marker.h =================================================================== --- linux-2.6.21.5-rt20.orig/include/linux/logdev_marker.h 2007-07-11 14:28:53.000000000 +0200 +++ linux-2.6.21.5-rt20/include/linux/logdev_marker.h 2007-07-11 14:28:56.000000000 +0200 @@ -53,6 +53,8 @@ #ifdef CONFIG_LOGDEV_TRACING /* Place tracing prototypes here */ +void LDCALLER(context_switch) (struct task_struct *prev, + struct task_struct *next); #endif /* CONFIG_LOGDEV_TRACING */ Index: linux-2.6.21.5-rt20/kernel/logdev/logdev_tracers.c =================================================================== --- linux-2.6.21.5-rt20.orig/kernel/logdev/logdev_tracers.c 2007-07-11 14:28:53.000000000 +0200 +++ linux-2.6.21.5-rt20/kernel/logdev/logdev_tracers.c 2007-07-11 14:28:56.000000000 +0200 @@ -37,6 +37,28 @@ struct logdev_mark_hdr { /* ---------------- start here for user custom headers -------------------- */ /* Add Tracing IDs and structures here */ +#define LOGMARK_EXAMPLE_ID 0xffff +#define LOGMARK_E_ID(x) ((LOGMARK_EXAMPLE_ID << 16)|(x)) + +#define LOGMARK_CNTXTSW LOGMARK_E_ID(1) + +struct logdev_mark_switch { + struct logdev_mark_hdr hdr; + short pid_prev; + short pid_next; + int prev_prio; + int prev_static_prio; + int prev_normal_prio; + int prev_rt_prio; + int prev_state; + int next_prio; + int next_static_prio; + int next_normal_prio; + int next_rt_prio; + char prev_comm[TASK_COMM_LEN]; + char next_comm[TASK_COMM_LEN]; +}; + /* ---------------- end of user space custom headers ---------------- */ @@ -65,6 +87,26 @@ static void logdev_print_hdr(int cpu, /* Place printing of traces here */ +static void logdev_mark_switch_print(int cpu, int size, + struct logdev_mark_switch *lm) +{ + logdev_print_hdr(cpu, &lm->hdr); + + printk("%s:%d(%d:%d:%d) -->> ", + lm->prev_comm, + lm->pid_prev, + lm->prev_prio, + lm->prev_static_prio, + lm->prev_normal_prio); + + printk("%s:%d(%d:%d:%d)\n", + lm->next_comm, + lm->pid_next, + lm->next_prio, + lm->next_static_prio, + lm->next_normal_prio); +} + static void logdev_mark_callback(struct logdev_header *hdr, struct logdev_custom *custom, int cpu, @@ -74,6 +116,9 @@ static void logdev_mark_callback(struct switch (lm->id) { /* Add callbacks for traces here */ + case LOGMARK_CNTXTSW: + logdev_mark_switch_print(cpu, hdr->size, rec); + break; default: printk("Unknown marker callback id %x\n", lm->id); @@ -92,6 +137,37 @@ static void __kprobes logmark_hdr(struct /* Add tracing callback functions here */ +void __kprobes LDCALLER(context_switch) (struct task_struct *prev, + struct task_struct *next) +{ + struct logdev_mark_switch lm; + + /* Filter on test task */ + /* + if ((strncmp(prev->comm, "sched_football", 14) != 0) && + (strncmp(next->comm, "sched_football", 14) != 0)) + return; + */ + + logmark_hdr(&lm.hdr, LOGMARK_CNTXTSW); + + lm.pid_prev = prev->pid; + lm.prev_prio = prev->prio; + lm.prev_static_prio = prev->static_prio; + lm.prev_normal_prio = prev->normal_prio; + lm.prev_rt_prio = prev->rt_priority; + lm.prev_state = prev->state; + lm.pid_next = next->pid; + lm.next_prio = next->prio; + lm.next_static_prio = next->static_prio; + lm.next_normal_prio = next->normal_prio; + lm.next_rt_prio = next->rt_priority; + memcpy(lm.prev_comm, prev->comm, TASK_COMM_LEN); + memcpy(lm.next_comm, next->comm, TASK_COMM_LEN); + + logdev_record(LOGMARK_ID_MARK, sizeof(lm), + &lm, sizeof(lm), NULL); +} static int __init logdev_tracer_init(void) { Index: linux-2.6.21.5-rt20/kernel/sched.c =================================================================== --- linux-2.6.21.5-rt20.orig/kernel/sched.c 2007-07-11 10:09:48.000000000 +0200 +++ linux-2.6.21.5-rt20/kernel/sched.c 2007-07-11 14:28:56.000000000 +0200 @@ -61,6 +61,7 @@ #include #include #include +#include #include #include @@ -2143,6 +2144,8 @@ context_switch(struct rq *rq, struct tas { struct mm_struct *mm, *oldmm; + LD_MARK2(context_switch, prev, next); + prepare_task_switch(rq, next); mm = next->mm; oldmm = prev->active_mm;