Index: linux-2.6.18/kernel/sched.c =================================================================== --- linux-2.6.18.orig/kernel/sched.c 2006-10-10 09:59:05.000000000 -0400 +++ linux-2.6.18/kernel/sched.c 2006-10-10 11:25:14.000000000 -0400 @@ -53,7 +53,7 @@ #include #include #include - +#include #include /* @@ -1804,6 +1804,8 @@ context_switch(struct rq *rq, struct tas struct mm_struct *mm = next->mm; struct mm_struct *oldmm = prev->active_mm; + LD_MARK2(context_switch, prev, next); + if (unlikely(!mm)) { next->active_mm = oldmm; atomic_inc(&oldmm->mm_count); Index: linux-2.6.18/mm/memory.c =================================================================== --- linux-2.6.18.orig/mm/memory.c 2006-09-20 21:37:42.000000000 -0400 +++ linux-2.6.18/mm/memory.c 2006-10-10 11:24:48.000000000 -0400 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -2326,6 +2327,8 @@ int __handle_mm_fault(struct mm_struct * pmd_t *pmd; pte_t *pte; + LD_MARK4(mm_fault, mm, vma, address, write_access); + __set_current_state(TASK_RUNNING); count_vm_event(PGFAULT); Index: linux-2.6.18/include/linux/logdev_marker.h =================================================================== --- linux-2.6.18.orig/include/linux/logdev_marker.h 2006-10-10 10:01:27.000000000 -0400 +++ linux-2.6.18/include/linux/logdev_marker.h 2006-10-10 11:24:48.000000000 -0400 @@ -54,6 +54,10 @@ /* Place tracing prototypes here */ +void LDCALLER(context_switch) (struct task_struct *prev, + struct task_struct *next); +void LDCALLER(mm_fault) (struct mm_struct *mm, struct vm_area_struct *vma, + unsigned long address, int write_access); #endif /* CONFIG_LOGDEV_TRACING */ Index: linux-2.6.18/kernel/logdev/logdev_tracers.c =================================================================== --- linux-2.6.18.orig/kernel/logdev/logdev_tracers.c 2006-10-10 10:01:27.000000000 -0400 +++ linux-2.6.18/kernel/logdev/logdev_tracers.c 2006-10-10 11:24:48.000000000 -0400 @@ -38,6 +38,39 @@ struct logdev_mark_hdr { /* ---------------- start here for user custom headers -------------------- */ /* Add Tracing IDs and structures here */ +/* these are just examples! */ +#define LOGMARK_EXAMPLE_ID 0xffff +#define LOGMARK_E_ID(x) ((LOGMARK_EXAMPLE_ID << 16)|(x)) + +#define LOGMARK_CNTXTSW LOGMARK_E_ID(1) +#define LOGMARK_MM_FAULT LOGMARK_E_ID(2) + + +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_state; + int next_prio; + int next_static_prio; + int next_normal_prio; + char prev_comm[TASK_COMM_LEN]; + char next_comm[TASK_COMM_LEN]; +}; + +struct logdev_mark_mm_fault { + struct logdev_mark_hdr hdr; + short pid; + char comm[TASK_COMM_LEN]; + struct mm_struct *mm; + struct vm_area_struct *vma; + unsigned long address; + int write_access; +}; + /* ---------------- end of user space custom headers ---------------- */ /* TODO, put this in logdev.c so I don't keep copying it */ @@ -65,6 +98,40 @@ 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_mm_fault_print(int cpu, int size, + struct logdev_mark_mm_fault *lm) +{ + logdev_print_hdr(cpu, &lm->hdr); + + printk("%s:%d mm=%p vma=%p address=%lx write_access=%d\n", + lm->comm, + lm->pid, + lm->mm, + lm->vma, + lm->address, + lm->write_access); +} + static void logdev_mark_callback(struct logdev_header *hdr, struct logdev_custom *custom, int cpu, @@ -74,6 +141,12 @@ 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; + case LOGMARK_MM_FAULT: + logdev_mark_mm_fault_print(cpu, hdr->size, rec); + break; default: printk("Unknown marker callback id %x\n", lm->id); @@ -92,6 +165,48 @@ 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; + + 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_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; + 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); +} + +void __kprobes LDCALLER(mm_fault) (struct mm_struct *mm, + struct vm_area_struct *vma, + unsigned long address, int write_access) +{ + struct logdev_mark_mm_fault lm; + + logmark_hdr(&lm.hdr, LOGMARK_MM_FAULT); + + lm.pid = current->pid; + memcpy(lm.comm, current->comm, TASK_COMM_LEN); + + lm.mm = mm; + lm.vma = vma; + lm.address = address; + lm.write_access = write_access; + + logdev_record(LOGMARK_ID_MARK, sizeof(lm), + &lm, sizeof(lm), NULL); +} static int __init logdev_tracer_init(void) {