1/*
2 * trace context switch
3 *
4 * Copyright (C) 2007 Steven Rostedt <srostedt@redhat.com>
5 *
6 */
7#include <linux/module.h>
8#include <linux/kallsyms.h>
9#include <linux/uaccess.h>
10#include <linux/ftrace.h>
11#include <trace/events/sched.h>
12
13#include "trace.h"
14
15static int			sched_ref;
16static DEFINE_MUTEX(sched_register_mutex);
17
18static void
19probe_sched_switch(void *ignore, struct task_struct *prev, struct task_struct *next)
20{
21	if (unlikely(!sched_ref))
22		return;
23
24	tracing_record_cmdline(prev);
25	tracing_record_cmdline(next);
26}
27
28static void
29probe_sched_wakeup(void *ignore, struct task_struct *wakee, int success)
30{
31	if (unlikely(!sched_ref))
32		return;
33
34	tracing_record_cmdline(current);
35}
36
37static int tracing_sched_register(void)
38{
39	int ret;
40
41	ret = register_trace_sched_wakeup(probe_sched_wakeup, NULL);
42	if (ret) {
43		pr_info("wakeup trace: Couldn't activate tracepoint"
44			" probe to kernel_sched_wakeup\n");
45		return ret;
46	}
47
48	ret = register_trace_sched_wakeup_new(probe_sched_wakeup, NULL);
49	if (ret) {
50		pr_info("wakeup trace: Couldn't activate tracepoint"
51			" probe to kernel_sched_wakeup_new\n");
52		goto fail_deprobe;
53	}
54
55	ret = register_trace_sched_switch(probe_sched_switch, NULL);
56	if (ret) {
57		pr_info("sched trace: Couldn't activate tracepoint"
58			" probe to kernel_sched_switch\n");
59		goto fail_deprobe_wake_new;
60	}
61
62	return ret;
63fail_deprobe_wake_new:
64	unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL);
65fail_deprobe:
66	unregister_trace_sched_wakeup(probe_sched_wakeup, NULL);
67	return ret;
68}
69
70static void tracing_sched_unregister(void)
71{
72	unregister_trace_sched_switch(probe_sched_switch, NULL);
73	unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL);
74	unregister_trace_sched_wakeup(probe_sched_wakeup, NULL);
75}
76
77static void tracing_start_sched_switch(void)
78{
79	mutex_lock(&sched_register_mutex);
80	if (!(sched_ref++))
81		tracing_sched_register();
82	mutex_unlock(&sched_register_mutex);
83}
84
85static void tracing_stop_sched_switch(void)
86{
87	mutex_lock(&sched_register_mutex);
88	if (!(--sched_ref))
89		tracing_sched_unregister();
90	mutex_unlock(&sched_register_mutex);
91}
92
93void tracing_start_cmdline_record(void)
94{
95	tracing_start_sched_switch();
96}
97
98void tracing_stop_cmdline_record(void)
99{
100	tracing_stop_sched_switch();
101}
102