#ifdef CONFIG_CONTEXT_SWITCH_TRACER
extern void
-ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next);
+ftrace_ctx_switch(void *rq, struct task_struct *prev, struct task_struct *next);
+extern void
+ftrace_wake_up_task(void *rq, struct task_struct *wakee,
+ struct task_struct *curr);
+extern void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data);
+extern void
+__trace_special(void *__tr, void *__data,
+ unsigned long arg1, unsigned long arg2, unsigned long arg3);
#else
static inline void
-ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next)
+ftrace_ctx_switch(void *rq, struct task_struct *prev, struct task_struct *next)
+{
+}
+static inline void
+sched_trace_special(unsigned long p1, unsigned long p2, unsigned long p3)
+{
+}
+static inline void
+ftrace_wake_up_task(void *rq, struct task_struct *wakee,
+ struct task_struct *curr)
+{
+}
+static inline void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data)
{
}
-#endif
-
-#ifdef CONFIG_SCHED_TRACER
-extern void
-ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr);
-#else
static inline void
-ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr)
+__trace_special(void *__tr, void *__data,
+ unsigned long arg1, unsigned long arg2, unsigned long arg3)
{
}
#endif
#endif /* CONFIG_SMP */
+#ifdef CONFIG_CONTEXT_SWITCH_TRACER
+
+void ftrace_all_fair_tasks(void *__rq, void *__tr, void *__data)
+{
+ struct sched_entity *se;
+ struct task_struct *p;
+ struct rb_node *curr;
+ struct rq *rq = __rq;
+
+ curr = first_fair(&rq->cfs);
+ if (!curr)
+ return;
+
+ while (curr) {
+ se = rb_entry(curr, struct sched_entity, run_node);
+ if (!entity_is_task(se))
+ continue;
+
+ p = task_of(se);
+
+ __trace_special(__tr, __data,
+ p->pid, p->se.vruntime, p->se.sum_exec_runtime);
+
+ curr = rb_next(curr);
+ }
+}
+
+#endif
+
/***
* try_to_wake_up - wake up a thread
* @p: the to-be-woken-up thread
out_activate:
#endif /* CONFIG_SMP */
- ftrace_wake_up_task(p, rq->curr);
+ ftrace_wake_up_task(rq, p, rq->curr);
schedstat_inc(p, se.nr_wakeups);
if (sync)
schedstat_inc(p, se.nr_wakeups_sync);
p->sched_class->task_new(rq, p);
inc_nr_running(rq);
}
- ftrace_wake_up_task(p, rq->curr);
+ ftrace_wake_up_task(rq, p, rq->curr);
check_preempt_curr(rq, p);
#ifdef CONFIG_SMP
if (p->sched_class->task_wake_up)
struct mm_struct *mm, *oldmm;
prepare_task_switch(rq, prev, next);
- ftrace_ctx_switch(prev, next);
+ ftrace_ctx_switch(rq, prev, next);
mm = next->mm;
oldmm = prev->active_mm;
/*
static int max_tracer_type_len;
static DEFINE_MUTEX(trace_types_lock);
-static DECLARE_WAIT_QUEUE_HEAD (trace_wait);
+static DECLARE_WAIT_QUEUE_HEAD(trace_wait);
+
+unsigned long trace_flags = TRACE_ITER_PRINT_PARENT;
+
+/*
+ * FIXME: where should this be called?
+ */
+void trace_wake_up(void)
+{
+ if (!(trace_flags & TRACE_ITER_BLOCK))
+ wake_up(&trace_wait);
+}
#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct trace_entry))
TRACE_FLAG_SOFTIRQ = 0x08,
};
-enum trace_iterator_flags {
- TRACE_ITER_PRINT_PARENT = 0x01,
- TRACE_ITER_SYM_OFFSET = 0x02,
- TRACE_ITER_SYM_ADDR = 0x04,
- TRACE_ITER_VERBOSE = 0x08,
- TRACE_ITER_RAW = 0x10,
- TRACE_ITER_HEX = 0x20,
- TRACE_ITER_BIN = 0x40,
- TRACE_ITER_BLOCK = 0x80,
- TRACE_ITER_STACKTRACE = 0x100,
-};
-
#define TRACE_ITER_SYM_MASK \
(TRACE_ITER_PRINT_PARENT|TRACE_ITER_SYM_OFFSET|TRACE_ITER_SYM_ADDR)
NULL
};
-static unsigned trace_flags = TRACE_ITER_PRINT_PARENT;
-
static DEFINE_SPINLOCK(ftrace_max_lock);
/*
entry->fn.ip = ip;
entry->fn.parent_ip = parent_ip;
spin_unlock_irqrestore(&data->lock, irq_flags);
-
- if (!(trace_flags & TRACE_ITER_BLOCK))
- wake_up(&trace_wait);
}
void
trace_function(tr, data, ip, parent_ip, flags);
}
+#ifdef CONFIG_CONTEXT_SWITCH_TRACER
+
void
-trace_special(struct trace_array *tr, struct trace_array_cpu *data,
- unsigned long arg1, unsigned long arg2, unsigned long arg3)
+__trace_special(void *__tr, void *__data,
+ unsigned long arg1, unsigned long arg2, unsigned long arg3)
{
+ struct trace_array_cpu *data = __data;
+ struct trace_array *tr = __tr;
struct trace_entry *entry;
unsigned long irq_flags;
entry->special.arg2 = arg2;
entry->special.arg3 = arg3;
spin_unlock_irqrestore(&data->lock, irq_flags);
-
- if (!(trace_flags & TRACE_ITER_BLOCK))
- wake_up(&trace_wait);
}
+#endif
+
void __trace_stack(struct trace_array *tr,
struct trace_array_cpu *data,
unsigned long flags,
entry->ctx.next_prio = next->prio;
__trace_stack(tr, data, flags, 4);
spin_unlock_irqrestore(&data->lock, irq_flags);
-
- if (!(trace_flags & TRACE_ITER_BLOCK))
- wake_up(&trace_wait);
}
void
entry->ctx.next_prio = wakee->prio;
__trace_stack(tr, data, flags, 5);
spin_unlock_irqrestore(&data->lock, irq_flags);
-
- if (!(trace_flags & TRACE_ITER_BLOCK))
- wake_up(&trace_wait);
}
#ifdef CONFIG_FTRACE
comm);
break;
case TRACE_SPECIAL:
- trace_seq_printf(s, " %lx %lx %lx\n",
+ trace_seq_printf(s, " %ld %ld %ld\n",
entry->special.arg1,
entry->special.arg2,
entry->special.arg3);
return 0;
break;
case TRACE_SPECIAL:
- ret = trace_seq_printf(s, " %lx %lx %lx\n",
+ ret = trace_seq_printf(s, " %ld %ld %ld\n",
entry->special.arg1,
entry->special.arg2,
entry->special.arg3);
break;
case TRACE_SPECIAL:
case TRACE_STACK:
- ret = trace_seq_printf(s, " %lx %lx %lx\n",
+ ret = trace_seq_printf(s, " %ld %ld %ld\n",
entry->special.arg1,
entry->special.arg2,
entry->special.arg3);
extern void *head_page(struct trace_array_cpu *data);
+extern unsigned long trace_flags;
+
+enum trace_iterator_flags {
+ TRACE_ITER_PRINT_PARENT = 0x01,
+ TRACE_ITER_SYM_OFFSET = 0x02,
+ TRACE_ITER_SYM_ADDR = 0x04,
+ TRACE_ITER_VERBOSE = 0x08,
+ TRACE_ITER_RAW = 0x10,
+ TRACE_ITER_HEX = 0x20,
+ TRACE_ITER_BIN = 0x40,
+ TRACE_ITER_BLOCK = 0x80,
+ TRACE_ITER_STACKTRACE = 0x100,
+};
+
#endif /* _LINUX_KERNEL_TRACE_H */
static int __read_mostly tracer_enabled;
static void
-ctx_switch_func(struct task_struct *prev, struct task_struct *next)
+ctx_switch_func(void *__rq, struct task_struct *prev, struct task_struct *next)
{
struct trace_array *tr = ctx_trace;
struct trace_array_cpu *data;
data = tr->data[cpu];
disabled = atomic_inc_return(&data->disabled);
- if (likely(disabled == 1))
+ if (likely(disabled == 1)) {
tracing_sched_switch_trace(tr, data, prev, next, flags);
+ ftrace_all_fair_tasks(__rq, tr, data);
+ }
atomic_dec(&data->disabled);
local_irq_restore(flags);
}
-static void wakeup_func(struct task_struct *wakee, struct task_struct *curr)
+static void
+wakeup_func(void *__rq, struct task_struct *wakee, struct task_struct *curr)
{
struct trace_array *tr = ctx_trace;
struct trace_array_cpu *data;
data = tr->data[cpu];
disabled = atomic_inc_return(&data->disabled);
- if (likely(disabled == 1))
+ if (likely(disabled == 1)) {
tracing_sched_wakeup_trace(tr, data, wakee, curr, flags);
+ ftrace_all_fair_tasks(__rq, tr, data);
+ }
atomic_dec(&data->disabled);
local_irq_restore(flags);
}
-void ftrace_ctx_switch(struct task_struct *prev, struct task_struct *next)
+void
+ftrace_ctx_switch(void *__rq, struct task_struct *prev,
+ struct task_struct *next)
{
tracing_record_cmdline(prev);
* If tracer_switch_func only points to the local
* switch func, it still needs the ptr passed to it.
*/
- ctx_switch_func(prev, next);
+ ctx_switch_func(__rq, prev, next);
/*
* Chain to the wakeup tracer (this is a NOP if disabled):
}
void
-ftrace_wake_up_task(struct task_struct *wakee, struct task_struct *curr)
+ftrace_wake_up_task(void *__rq, struct task_struct *wakee,
+ struct task_struct *curr)
{
tracing_record_cmdline(curr);
- wakeup_func(wakee, curr);
+ wakeup_func(__rq, wakee, curr);
/*
* Chain to the wakeup tracer (this is a NOP if disabled):