diff options
| author | Ingo Molnar <mingo@elte.hu> | 2008-05-12 15:20:52 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2008-05-23 15:04:44 -0400 |
| commit | 4e65551905fb0300ae7e667cbaa41ee2e3f29a13 (patch) | |
| tree | 0e642c311e31043eecf86c218128c40e1ddac782 | |
| parent | 4c1f4d4f0175129934d5dbc19a39296430937a05 (diff) | |
ftrace: sched tracer, trace full rbtree
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
| -rw-r--r-- | include/linux/sched.h | 32 | ||||
| -rw-r--r-- | kernel/sched.c | 35 | ||||
| -rw-r--r-- | kernel/trace/trace.c | 55 | ||||
| -rw-r--r-- | kernel/trace/trace.h | 14 | ||||
| -rw-r--r-- | kernel/trace/trace_sched_switch.c | 24 |
5 files changed, 108 insertions, 52 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index 05744f9cb096..652d380ae563 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
| @@ -2119,20 +2119,34 @@ static inline void arch_pick_mmap_layout(struct mm_struct *mm) | |||
| 2119 | 2119 | ||
| 2120 | #ifdef CONFIG_CONTEXT_SWITCH_TRACER | 2120 | #ifdef CONFIG_CONTEXT_SWITCH_TRACER |
| 2121 | extern void | 2121 | extern void |
| 2122 | ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next); | 2122 | ftrace_ctx_switch(void *rq, struct task_struct *prev, struct task_struct *next); |
| 2123 | extern void | ||
| 2124 | ftrace_wake_up_task(void *rq, struct task_struct *wakee, | ||
| 2125 | struct task_struct *curr); | ||
| 2126 | extern void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data); | ||
| 2127 | extern void | ||
| 2128 | __trace_special(void *__tr, void *__data, | ||
| 2129 | unsigned long arg1, unsigned long arg2, unsigned long arg3); | ||
| 2123 | #else | 2130 | #else |
| 2124 | static inline void | 2131 | static inline void |
| 2125 | ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next) | 2132 | ftrace_ctx_switch(void *rq, struct task_struct *prev, struct task_struct *next) |
| 2133 | { | ||
| 2134 | } | ||
| 2135 | static inline void | ||
| 2136 | sched_trace_special(unsigned long p1, unsigned long p2, unsigned long p3) | ||
| 2137 | { | ||
| 2138 | } | ||
| 2139 | static inline void | ||
| 2140 | ftrace_wake_up_task(void *rq, struct task_struct *wakee, | ||
| 2141 | struct task_struct *curr) | ||
| 2142 | { | ||
| 2143 | } | ||
| 2144 | static inline void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data) | ||
| 2126 | { | 2145 | { |
| 2127 | } | 2146 | } |
| 2128 | #endif | ||
| 2129 | |||
| 2130 | #ifdef CONFIG_SCHED_TRACER | ||
| 2131 | extern void | ||
| 2132 | ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr); | ||
| 2133 | #else | ||
| 2134 | static inline void | 2147 | static inline void |
| 2135 | ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr) | 2148 | __trace_special(void *__tr, void *__data, |
| 2149 | unsigned long arg1, unsigned long arg2, unsigned long arg3) | ||
| 2136 | { | 2150 | { |
| 2137 | } | 2151 | } |
| 2138 | #endif | 2152 | #endif |
diff --git a/kernel/sched.c b/kernel/sched.c index 53ab1174664f..b9208a0e33a0 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -2394,6 +2394,35 @@ static int sched_balance_self(int cpu, int flag) | |||
| 2394 | 2394 | ||
| 2395 | #endif /* CONFIG_SMP */ | 2395 | #endif /* CONFIG_SMP */ |
| 2396 | 2396 | ||
| 2397 | #ifdef CONFIG_CONTEXT_SWITCH_TRACER | ||
| 2398 | |||
| 2399 | void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data) | ||
| 2400 | { | ||
| 2401 | struct sched_entity *se; | ||
| 2402 | struct task_struct *p; | ||
| 2403 | struct rb_node *curr; | ||
| 2404 | struct rq *rq = __rq; | ||
| 2405 | |||
| 2406 | curr = first_fair(&rq->cfs); | ||
| 2407 | if (!curr) | ||
| 2408 | return; | ||
| 2409 | |||
| 2410 | while (curr) { | ||
| 2411 | se = rb_entry(curr, struct sched_entity, run_node); | ||
| 2412 | if (!entity_is_task(se)) | ||
| 2413 | continue; | ||
| 2414 | |||
| 2415 | p = task_of(se); | ||
| 2416 | |||
| 2417 | __trace_special(__tr, __data, | ||
| 2418 | p->pid, p->se.vruntime, p->se.sum_exec_runtime); | ||
| 2419 | |||
| 2420 | curr = rb_next(curr); | ||
| 2421 | } | ||
| 2422 | } | ||
| 2423 | |||
| 2424 | #endif | ||
| 2425 | |||
| 2397 | /*** | 2426 | /*** |
| 2398 | * try_to_wake_up - wake up a thread | 2427 | * try_to_wake_up - wake up a thread |
| 2399 | * @p: the to-be-woken-up thread | 2428 | * @p: the to-be-woken-up thread |
| @@ -2468,7 +2497,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync) | |||
| 2468 | 2497 | ||
| 2469 | out_activate: | 2498 | out_activate: |
| 2470 | #endif /* CONFIG_SMP */ | 2499 | #endif /* CONFIG_SMP */ |
| 2471 | ftrace_wake_up_task(p, rq->curr); | 2500 | ftrace_wake_up_task(rq, p, rq->curr); |
| 2472 | schedstat_inc(p, se.nr_wakeups); | 2501 | schedstat_inc(p, se.nr_wakeups); |
| 2473 | if (sync) | 2502 | if (sync) |
| 2474 | schedstat_inc(p, se.nr_wakeups_sync); | 2503 | schedstat_inc(p, se.nr_wakeups_sync); |
| @@ -2613,7 +2642,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) | |||
| 2613 | p->sched_class->task_new(rq, p); | 2642 | p->sched_class->task_new(rq, p); |
| 2614 | inc_nr_running(rq); | 2643 | inc_nr_running(rq); |
| 2615 | } | 2644 | } |
| 2616 | ftrace_wake_up_task(p, rq->curr); | 2645 | ftrace_wake_up_task(rq, p, rq->curr); |
| 2617 | check_preempt_curr(rq, p); | 2646 | check_preempt_curr(rq, p); |
| 2618 | #ifdef CONFIG_SMP | 2647 | #ifdef CONFIG_SMP |
| 2619 | if (p->sched_class->task_wake_up) | 2648 | if (p->sched_class->task_wake_up) |
| @@ -2786,7 +2815,7 @@ context_switch(struct rq *rq, struct task_struct *prev, | |||
| 2786 | struct mm_struct *mm, *oldmm; | 2815 | struct mm_struct *mm, *oldmm; |
| 2787 | 2816 | ||
| 2788 | prepare_task_switch(rq, prev, next); | 2817 | prepare_task_switch(rq, prev, next); |
| 2789 | ftrace_ctx_switch(prev, next); | 2818 | ftrace_ctx_switch(rq, prev, next); |
| 2790 | mm = next->mm; | 2819 | mm = next->mm; |
| 2791 | oldmm = prev->active_mm; | 2820 | oldmm = prev->active_mm; |
| 2792 | /* | 2821 | /* |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0e4b7119e263..65173b14b914 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -66,7 +66,18 @@ static struct tracer *current_trace __read_mostly; | |||
| 66 | static int max_tracer_type_len; | 66 | static int max_tracer_type_len; |
| 67 | 67 | ||
| 68 | static DEFINE_MUTEX(trace_types_lock); | 68 | static DEFINE_MUTEX(trace_types_lock); |
| 69 | static DECLARE_WAIT_QUEUE_HEAD (trace_wait); | 69 | static DECLARE_WAIT_QUEUE_HEAD(trace_wait); |
| 70 | |||
| 71 | unsigned long trace_flags = TRACE_ITER_PRINT_PARENT; | ||
| 72 | |||
| 73 | /* | ||
| 74 | * FIXME: where should this be called? | ||
| 75 | */ | ||
| 76 | void trace_wake_up(void) | ||
| 77 | { | ||
| 78 | if (!(trace_flags & TRACE_ITER_BLOCK)) | ||
| 79 | wake_up(&trace_wait); | ||
| 80 | } | ||
| 70 | 81 | ||
| 71 | #define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct trace_entry)) | 82 | #define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct trace_entry)) |
| 72 | 83 | ||
| @@ -103,18 +114,6 @@ enum trace_flag_type { | |||
| 103 | TRACE_FLAG_SOFTIRQ = 0x08, | 114 | TRACE_FLAG_SOFTIRQ = 0x08, |
| 104 | }; | 115 | }; |
| 105 | 116 | ||
| 106 | enum trace_iterator_flags { | ||
| 107 | TRACE_ITER_PRINT_PARENT = 0x01, | ||
| 108 | TRACE_ITER_SYM_OFFSET = 0x02, | ||
| 109 | TRACE_ITER_SYM_ADDR = 0x04, | ||
| 110 | TRACE_ITER_VERBOSE = 0x08, | ||
| 111 | TRACE_ITER_RAW = 0x10, | ||
| 112 | TRACE_ITER_HEX = 0x20, | ||
| 113 | TRACE_ITER_BIN = 0x40, | ||
| 114 | TRACE_ITER_BLOCK = 0x80, | ||
| 115 | TRACE_ITER_STACKTRACE = 0x100, | ||
| 116 | }; | ||
| 117 | |||
| 118 | #define TRACE_ITER_SYM_MASK \ | 117 | #define TRACE_ITER_SYM_MASK \ |
| 119 | (TRACE_ITER_PRINT_PARENT|TRACE_ITER_SYM_OFFSET|TRACE_ITER_SYM_ADDR) | 118 | (TRACE_ITER_PRINT_PARENT|TRACE_ITER_SYM_OFFSET|TRACE_ITER_SYM_ADDR) |
| 120 | 119 | ||
| @@ -132,8 +131,6 @@ static const char *trace_options[] = { | |||
| 132 | NULL | 131 | NULL |
| 133 | }; | 132 | }; |
| 134 | 133 | ||
| 135 | static unsigned trace_flags = TRACE_ITER_PRINT_PARENT; | ||
| 136 | |||
| 137 | static DEFINE_SPINLOCK(ftrace_max_lock); | 134 | static DEFINE_SPINLOCK(ftrace_max_lock); |
| 138 | 135 | ||
| 139 | /* | 136 | /* |
| @@ -660,9 +657,6 @@ trace_function(struct trace_array *tr, struct trace_array_cpu *data, | |||
| 660 | entry->fn.ip = ip; | 657 | entry->fn.ip = ip; |
| 661 | entry->fn.parent_ip = parent_ip; | 658 | entry->fn.parent_ip = parent_ip; |
| 662 | spin_unlock_irqrestore(&data->lock, irq_flags); | 659 | spin_unlock_irqrestore(&data->lock, irq_flags); |
| 663 | |||
| 664 | if (!(trace_flags & TRACE_ITER_BLOCK)) | ||
| 665 | wake_up(&trace_wait); | ||
| 666 | } | 660 | } |
| 667 | 661 | ||
| 668 | void | 662 | void |
| @@ -673,10 +667,14 @@ ftrace(struct trace_array *tr, struct trace_array_cpu *data, | |||
| 673 | trace_function(tr, data, ip, parent_ip, flags); | 667 | trace_function(tr, data, ip, parent_ip, flags); |
| 674 | } | 668 | } |
| 675 | 669 | ||
| 670 | #ifdef CONFIG_CONTEXT_SWITCH_TRACER | ||
| 671 | |||
