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