FILE
sts.c
File preview with syntax highlighting.
linux-6.19.14/kernel/trace/rv/monitors/sts/sts.c
1// SPDX-License-Identifier: GPL-2.0 2#include <linux/ftrace.h> 3#include <linux/tracepoint.h> 4#include <linux/kernel.h> 5#include <linux/module.h> 6#include <linux/init.h> 7#include <linux/rv.h> 8#include <rv/instrumentation.h> 9#include <rv/da_monitor.h> 10 11#define MODULE_NAME "sts" 12 13#include <trace/events/sched.h> 14#include <trace/events/irq.h> 15#include <trace/events/preemptirq.h> 16#include <rv_trace.h> 17#include <monitors/sched/sched.h> 18 19#include "sts.h" 20 21static struct rv_monitor rv_sts; 22DECLARE_DA_MON_PER_CPU(sts, unsigned char); 23 24#ifdef CONFIG_X86_LOCAL_APIC 25#include <asm/trace/irq_vectors.h> 26 27static void handle_vector_irq_entry(void *data, int vector) 28{ 29 da_handle_event_sts(irq_entry_sts); 30} 31 32static void attach_vector_irq(void) 33{ 34 rv_attach_trace_probe("sts", local_timer_entry, handle_vector_irq_entry); 35 if (IS_ENABLED(CONFIG_IRQ_WORK)) 36 rv_attach_trace_probe("sts", irq_work_entry, handle_vector_irq_entry); 37 if (IS_ENABLED(CONFIG_SMP)) { 38 rv_attach_trace_probe("sts", reschedule_entry, handle_vector_irq_entry); 39 rv_attach_trace_probe("sts", call_function_entry, handle_vector_irq_entry); 40 rv_attach_trace_probe("sts", call_function_single_entry, handle_vector_irq_entry); 41 } 42} 43 44static void detach_vector_irq(void) 45{ 46 rv_detach_trace_probe("sts", local_timer_entry, handle_vector_irq_entry); 47 if (IS_ENABLED(CONFIG_IRQ_WORK)) 48 rv_detach_trace_probe("sts", irq_work_entry, handle_vector_irq_entry); 49 if (IS_ENABLED(CONFIG_SMP)) { 50 rv_detach_trace_probe("sts", reschedule_entry, handle_vector_irq_entry); 51 rv_detach_trace_probe("sts", call_function_entry, handle_vector_irq_entry); 52 rv_detach_trace_probe("sts", call_function_single_entry, handle_vector_irq_entry); 53 } 54} 55 56#else 57/* We assume irq_entry tracepoints are sufficient on other architectures */ 58static void attach_vector_irq(void) { } 59static void detach_vector_irq(void) { } 60#endif 61 62static void handle_irq_disable(void *data, unsigned long ip, unsigned long parent_ip) 63{ 64 da_handle_event_sts(irq_disable_sts); 65} 66 67static void handle_irq_enable(void *data, unsigned long ip, unsigned long parent_ip) 68{ 69 da_handle_event_sts(irq_enable_sts); 70} 71 72static void handle_irq_entry(void *data, int irq, struct irqaction *action) 73{ 74 da_handle_event_sts(irq_entry_sts); 75} 76 77static void handle_sched_switch(void *data, bool preempt, 78 struct task_struct *prev, 79 struct task_struct *next, 80 unsigned int prev_state) 81{ 82 da_handle_event_sts(sched_switch_sts); 83} 84 85static void handle_schedule_entry(void *data, bool preempt) 86{ 87 da_handle_event_sts(schedule_entry_sts); 88} 89 90static void handle_schedule_exit(void *data, bool is_switch) 91{ 92 da_handle_start_event_sts(schedule_exit_sts); 93} 94 95static int enable_sts(void) 96{ 97 int retval; 98 99 retval = da_monitor_init_sts(); 100 if (retval) 101 return retval; 102 103 rv_attach_trace_probe("sts", irq_disable, handle_irq_disable); 104 rv_attach_trace_probe("sts", irq_enable, handle_irq_enable); 105 rv_attach_trace_probe("sts", irq_handler_entry, handle_irq_entry); 106 rv_attach_trace_probe("sts", sched_switch, handle_sched_switch); 107 rv_attach_trace_probe("sts", sched_entry_tp, handle_schedule_entry); 108 rv_attach_trace_probe("sts", sched_exit_tp, handle_schedule_exit); 109 attach_vector_irq(); 110 111 return 0; 112} 113 114static void disable_sts(void) 115{ 116 rv_sts.enabled = 0; 117 118 rv_detach_trace_probe("sts", irq_disable, handle_irq_disable); 119 rv_detach_trace_probe("sts", irq_enable, handle_irq_enable); 120 rv_detach_trace_probe("sts", irq_handler_entry, handle_irq_entry); 121 rv_detach_trace_probe("sts", sched_switch, handle_sched_switch); 122 rv_detach_trace_probe("sts", sched_entry_tp, handle_schedule_entry); 123 rv_detach_trace_probe("sts", sched_exit_tp, handle_schedule_exit); 124 detach_vector_irq(); 125 126 da_monitor_destroy_sts(); 127} 128 129/* 130 * This is the monitor register section. 131 */ 132static struct rv_monitor rv_sts = { 133 .name = "sts", 134 .description = "schedule implies task switch.", 135 .enable = enable_sts, 136 .disable = disable_sts, 137 .reset = da_monitor_reset_all_sts, 138 .enabled = 0, 139}; 140 141static int __init register_sts(void) 142{ 143 return rv_register_monitor(&rv_sts, &rv_sched); 144} 145 146static void __exit unregister_sts(void) 147{ 148 rv_unregister_monitor(&rv_sts); 149} 150 151module_init(register_sts); 152module_exit(unregister_sts); 153 154MODULE_LICENSE("GPL"); 155MODULE_AUTHOR("Gabriele Monaco <gmonaco@redhat.com>"); 156MODULE_DESCRIPTION("sts: schedule implies task switch.");
~/
Read-only file preview.