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 /kernel | |
| 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>
Diffstat (limited to 'kernel')
| -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 |
4 files changed, 85 insertions, 43 deletions
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 | |||
| 676 | void | 672 | void |
| 677 | trace_special(struct trace_array *tr, struct trace_array_cpu *data, | 673 | __trace_special(void *__tr, void *__data, |
| 678 | unsigned long arg1, unsigned long arg2, unsigned long arg3) | 674 | unsigned long arg1, unsigned long arg2, unsigned long arg3) |
| 679 | { | 675 | { |
| 676 | struct trace_array_cpu *data = __data; | ||
| 677 | struct trace_array *tr = __tr; | ||
| 680 | struct trace_entry *entry; | 678 | struct trace_entry *entry; |
| 681 | unsigned long irq_flags; | 679 | unsigned long irq_flags; |
| 682 | 680 | ||
| @@ -688,11 +686,10 @@ trace_special(struct trace_array *tr, struct trace_array_cpu *data, | |||
| 688 | entry->special.arg2 = arg2; | 686 | entry->special.arg2 = arg2; |
| 689 | entry->special.arg3 = arg3; | 687 | entry->special.arg3 = arg3; |
| 690 | spin_unlock_irqrestore(&data->lock, irq_flags); | 688 | spin_unlock_irqrestore(&data->lock, irq_flags); |
| 691 | |||
| 692 | if (!(trace_flags & TRACE_ITER_BLOCK)) | ||
| 693 | wake_up(&trace_wait); | ||
| 694 | } | 689 | } |
| 695 | 690 | ||
| 691 | #endif | ||
| 692 | |||
| 696 | void __trace_stack(struct trace_array *tr, | 693 | void __trace_stack(struct trace_array *tr, |
| 697 | struct trace_array_cpu *data, | 694 | struct trace_array_cpu *data, |
| 698 | unsigned long flags, | 695 | unsigned long flags, |
| @@ -739,9 +736,6 @@ tracing_sched_switch_trace(struct trace_array *tr, | |||
| 739 | entry->ctx.next_prio = next->prio; | 736 | entry->ctx.next_prio = next->prio; |
| 740 | __trace_stack(tr, data, flags, 4); | 737 | __trace_stack(tr, data, flags, 4); |
| 741 | spin_unlock_irqrestore(&data->lock, irq_flags); | 738 | spin_unlock_irqrestore(&data->lock, irq_flags); |
| 742 | |||
| 743 | if (!(trace_flags & TRACE_ITER_BLOCK)) | ||
| 744 | wake_up(&trace_wait); | ||
| 745 | } | 739 | } |
| 746 | 740 | ||
| 747 | void | 741 | void |
| @@ -765,9 +759,6 @@ tracing_sched_wakeup_trace(struct trace_array *tr, | |||
| 765 | entry->ctx.next_prio = wakee->prio; | 759 | entry->ctx.next_prio = wakee->prio; |
| 766 | __trace_stack(tr, data, flags, 5); | 760 | __trace_stack(tr, data, flags, 5); |
| 767 | spin_unlock_irqrestore(&data->lock, irq_flags); | 761 | spin_unlock_irqrestore(&data->lock, irq_flags); |
| 768 | |||
