1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 235e8e302SSteven Rostedt /* 335e8e302SSteven Rostedt * trace context switch 435e8e302SSteven Rostedt * 535e8e302SSteven Rostedt * Copyright (C) 2007 Steven Rostedt <srostedt@redhat.com> 635e8e302SSteven Rostedt * 735e8e302SSteven Rostedt */ 835e8e302SSteven Rostedt #include <linux/module.h> 935e8e302SSteven Rostedt #include <linux/kallsyms.h> 1035e8e302SSteven Rostedt #include <linux/uaccess.h> 1135e8e302SSteven Rostedt #include <linux/ftrace.h> 12ad8d75ffSSteven Rostedt #include <trace/events/sched.h> 1335e8e302SSteven Rostedt 1435e8e302SSteven Rostedt #include "trace.h" 1535e8e302SSteven Rostedt 16d914ba37SJoel Fernandes #define RECORD_CMDLINE 1 17d914ba37SJoel Fernandes #define RECORD_TGID 2 18d914ba37SJoel Fernandes 19d914ba37SJoel Fernandes static int sched_cmdline_ref; 20d914ba37SJoel Fernandes static int sched_tgid_ref; 21efade6e7SFrederic Weisbecker static DEFINE_MUTEX(sched_register_mutex); 2282e04af4SFrederic Weisbecker 23e309b41dSIngo Molnar static void 24c73464b1SPeter Zijlstra probe_sched_switch(void *ignore, bool preempt, 25c73464b1SPeter Zijlstra struct task_struct *prev, struct task_struct *next) 2635e8e302SSteven Rostedt { 27d914ba37SJoel Fernandes int flags; 28b07c3f19SMathieu Desnoyers 29d914ba37SJoel Fernandes flags = (RECORD_TGID * !!sched_tgid_ref) + 30d914ba37SJoel Fernandes (RECORD_CMDLINE * !!sched_cmdline_ref); 31d914ba37SJoel Fernandes 32d914ba37SJoel Fernandes if (!flags) 33d914ba37SJoel Fernandes return; 34d914ba37SJoel Fernandes tracing_record_taskinfo_sched_switch(prev, next, flags); 3535e8e302SSteven Rostedt } 3635e8e302SSteven Rostedt 375b82a1b0SMathieu Desnoyers static void 38fbd705a0SPeter Zijlstra probe_sched_wakeup(void *ignore, struct task_struct *wakee) 395b82a1b0SMathieu Desnoyers { 40d914ba37SJoel Fernandes int flags; 41dcef788eSZhaolei 42d914ba37SJoel Fernandes flags = (RECORD_TGID * !!sched_tgid_ref) + 43d914ba37SJoel Fernandes (RECORD_CMDLINE * !!sched_cmdline_ref); 44d914ba37SJoel Fernandes 45d914ba37SJoel Fernandes if (!flags) 46d914ba37SJoel Fernandes return; 47d914ba37SJoel Fernandes tracing_record_taskinfo(current, flags); 4857422797SIngo Molnar } 4957422797SIngo Molnar 505b82a1b0SMathieu Desnoyers static int tracing_sched_register(void) 515b82a1b0SMathieu Desnoyers { 525b82a1b0SMathieu Desnoyers int ret; 535b82a1b0SMathieu Desnoyers 5438516ab5SSteven Rostedt ret = register_trace_sched_wakeup(probe_sched_wakeup, NULL); 555b82a1b0SMathieu Desnoyers if (ret) { 56b07c3f19SMathieu Desnoyers pr_info("wakeup trace: Couldn't activate tracepoint" 575b82a1b0SMathieu Desnoyers " probe to kernel_sched_wakeup\n"); 585b82a1b0SMathieu Desnoyers return ret; 595b82a1b0SMathieu Desnoyers } 605b82a1b0SMathieu Desnoyers 6138516ab5SSteven Rostedt ret = register_trace_sched_wakeup_new(probe_sched_wakeup, NULL); 625b82a1b0SMathieu Desnoyers if (ret) { 63b07c3f19SMathieu Desnoyers pr_info("wakeup trace: Couldn't activate tracepoint" 645b82a1b0SMathieu Desnoyers " probe to kernel_sched_wakeup_new\n"); 655b82a1b0SMathieu Desnoyers goto fail_deprobe; 665b82a1b0SMathieu Desnoyers } 675b82a1b0SMathieu Desnoyers 6838516ab5SSteven Rostedt ret = register_trace_sched_switch(probe_sched_switch, NULL); 695b82a1b0SMathieu Desnoyers if (ret) { 70b07c3f19SMathieu Desnoyers pr_info("sched trace: Couldn't activate tracepoint" 7173d8b8bcSWenji Huang " probe to kernel_sched_switch\n"); 725b82a1b0SMathieu Desnoyers goto fail_deprobe_wake_new; 735b82a1b0SMathieu Desnoyers } 745b82a1b0SMathieu Desnoyers 755b82a1b0SMathieu Desnoyers return ret; 765b82a1b0SMathieu Desnoyers fail_deprobe_wake_new: 7738516ab5SSteven Rostedt unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL); 785b82a1b0SMathieu Desnoyers fail_deprobe: 7938516ab5SSteven Rostedt unregister_trace_sched_wakeup(probe_sched_wakeup, NULL); 805b82a1b0SMathieu Desnoyers return ret; 815b82a1b0SMathieu Desnoyers } 825b82a1b0SMathieu Desnoyers 835b82a1b0SMathieu Desnoyers static void tracing_sched_unregister(void) 845b82a1b0SMathieu Desnoyers { 8538516ab5SSteven Rostedt unregister_trace_sched_switch(probe_sched_switch, NULL); 8638516ab5SSteven Rostedt unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL); 8738516ab5SSteven Rostedt unregister_trace_sched_wakeup(probe_sched_wakeup, NULL); 885b82a1b0SMathieu Desnoyers } 895b82a1b0SMathieu Desnoyers 90d914ba37SJoel Fernandes static void tracing_start_sched_switch(int ops) 915b82a1b0SMathieu Desnoyers { 9264ae572bSMathieu Desnoyers bool sched_register; 9364ae572bSMathieu Desnoyers 94efade6e7SFrederic Weisbecker mutex_lock(&sched_register_mutex); 9564ae572bSMathieu Desnoyers sched_register = (!sched_cmdline_ref && !sched_tgid_ref); 96d914ba37SJoel Fernandes 97d914ba37SJoel Fernandes switch (ops) { 98d914ba37SJoel Fernandes case RECORD_CMDLINE: 99d914ba37SJoel Fernandes sched_cmdline_ref++; 100d914ba37SJoel Fernandes break; 101d914ba37SJoel Fernandes 102d914ba37SJoel Fernandes case RECORD_TGID: 103d914ba37SJoel Fernandes sched_tgid_ref++; 104d914ba37SJoel Fernandes break; 105d914ba37SJoel Fernandes } 106d914ba37SJoel Fernandes 107d914ba37SJoel Fernandes if (sched_register && (sched_cmdline_ref || sched_tgid_ref)) 1085b82a1b0SMathieu Desnoyers tracing_sched_register(); 109efade6e7SFrederic Weisbecker mutex_unlock(&sched_register_mutex); 1105b82a1b0SMathieu Desnoyers } 1115b82a1b0SMathieu Desnoyers 112d914ba37SJoel Fernandes static void tracing_stop_sched_switch(int ops) 1135b82a1b0SMathieu Desnoyers { 114efade6e7SFrederic Weisbecker mutex_lock(&sched_register_mutex); 115d914ba37SJoel Fernandes 116d914ba37SJoel Fernandes switch (ops) { 117d914ba37SJoel Fernandes case RECORD_CMDLINE: 118d914ba37SJoel Fernandes sched_cmdline_ref--; 119d914ba37SJoel Fernandes break; 120d914ba37SJoel Fernandes 121d914ba37SJoel Fernandes case RECORD_TGID: 122d914ba37SJoel Fernandes sched_tgid_ref--; 123d914ba37SJoel Fernandes break; 124d914ba37SJoel Fernandes } 125d914ba37SJoel Fernandes 126d914ba37SJoel Fernandes if (!sched_cmdline_ref && !sched_tgid_ref) 1275b82a1b0SMathieu Desnoyers tracing_sched_unregister(); 128efade6e7SFrederic Weisbecker mutex_unlock(&sched_register_mutex); 1295b82a1b0SMathieu Desnoyers } 1305b82a1b0SMathieu Desnoyers 13141bc8144SSteven Rostedt void tracing_start_cmdline_record(void) 13241bc8144SSteven Rostedt { 133d914ba37SJoel Fernandes tracing_start_sched_switch(RECORD_CMDLINE); 13441bc8144SSteven Rostedt } 13541bc8144SSteven Rostedt 13641bc8144SSteven Rostedt void tracing_stop_cmdline_record(void) 13741bc8144SSteven Rostedt { 138d914ba37SJoel Fernandes tracing_stop_sched_switch(RECORD_CMDLINE); 139d914ba37SJoel Fernandes } 140d914ba37SJoel Fernandes 141d914ba37SJoel Fernandes void tracing_start_tgid_record(void) 142d914ba37SJoel Fernandes { 143d914ba37SJoel Fernandes tracing_start_sched_switch(RECORD_TGID); 144d914ba37SJoel Fernandes } 145d914ba37SJoel Fernandes 146d914ba37SJoel Fernandes void tracing_stop_tgid_record(void) 147d914ba37SJoel Fernandes { 148d914ba37SJoel Fernandes tracing_stop_sched_switch(RECORD_TGID); 14941bc8144SSteven Rostedt } 150