diff options
Diffstat (limited to 'kernel/trace/trace_sched_wakeup.c')
| -rw-r--r-- | kernel/trace/trace_sched_wakeup.c | 36 | 
1 files changed, 22 insertions, 14 deletions
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index ad69f105a7c..cf43bdb1763 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -24,6 +24,7 @@ static int __read_mostly	tracer_enabled;  static struct task_struct	*wakeup_task;  static int			wakeup_cpu; +static int			wakeup_current_cpu;  static unsigned			wakeup_prio = -1;  static int			wakeup_rt; @@ -56,33 +57,23 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip)  	resched = ftrace_preempt_disable();  	cpu = raw_smp_processor_id(); +	if (cpu != wakeup_current_cpu) +		goto out_enable; +  	data = tr->data[cpu];  	disabled = atomic_inc_return(&data->disabled);  	if (unlikely(disabled != 1))  		goto out;  	local_irq_save(flags); -	__raw_spin_lock(&wakeup_lock); - -	if (unlikely(!wakeup_task)) -		goto unlock; - -	/* -	 * The task can't disappear because it needs to -	 * wake up first, and we have the wakeup_lock. -	 */ -	if (task_cpu(wakeup_task) != cpu) -		goto unlock;  	trace_function(tr, ip, parent_ip, flags, pc); - unlock: -	__raw_spin_unlock(&wakeup_lock);  	local_irq_restore(flags);   out:  	atomic_dec(&data->disabled); - + out_enable:  	ftrace_preempt_enable(resched);  } @@ -107,6 +98,14 @@ static int report_latency(cycle_t delta)  	return 1;  } +static void probe_wakeup_migrate_task(struct task_struct *task, int cpu) +{ +	if (task != wakeup_task) +		return; + +	wakeup_current_cpu = cpu; +} +  static void notrace  probe_wakeup_sched_switch(struct rq *rq, struct task_struct *prev,  	struct task_struct *next) @@ -244,6 +243,7 @@ probe_wakeup(struct rq *rq, struct task_struct *p, int success)  	__wakeup_reset(wakeup_trace);  	wakeup_cpu = task_cpu(p); +	wakeup_current_cpu = wakeup_cpu;  	wakeup_prio = p->prio;  	wakeup_task = p; @@ -293,6 +293,13 @@ static void start_wakeup_tracer(struct trace_array *tr)  		goto fail_deprobe_wake_new;  	} +	ret = register_trace_sched_migrate_task(probe_wakeup_migrate_task); +	if (ret) { +		pr_info("wakeup trace: Couldn't activate tracepoint" +			" probe to kernel_sched_migrate_task\n"); +		return; +	} +  	wakeup_reset(tr);  	/* @@ -325,6 +332,7 @@ static void stop_wakeup_tracer(struct trace_array *tr)  	unregister_trace_sched_switch(probe_wakeup_sched_switch);  	unregister_trace_sched_wakeup_new(probe_wakeup);  	unregister_trace_sched_wakeup(probe_wakeup); +	unregister_trace_sched_migrate_task(probe_wakeup_migrate_task);  }  static int __wakeup_tracer_init(struct trace_array *tr)  |