FILE
opid.c
File preview with syntax highlighting.
linux-6.19.14/kernel/trace/rv/monitors/opid/opid.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 "opid" 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 "opid.h" 20 21static struct rv_monitor rv_opid; 22DECLARE_DA_MON_PER_CPU(opid, 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_opid(irq_entry_opid); 30} 31 32static void attach_vector_irq(void) 33{ 34 rv_attach_trace_probe("opid", local_timer_entry, handle_vector_irq_entry); 35 if (IS_ENABLED(CONFIG_IRQ_WORK)) 36 rv_attach_trace_probe("opid", irq_work_entry, handle_vector_irq_entry); 37 if (IS_ENABLED(CONFIG_SMP)) { 38 rv_attach_trace_probe("opid", reschedule_entry, handle_vector_irq_entry); 39 rv_attach_trace_probe("opid", call_function_entry, handle_vector_irq_entry); 40 rv_attach_trace_probe("opid", call_function_single_entry, handle_vector_irq_entry); 41 } 42} 43 44static void detach_vector_irq(void) 45{ 46 rv_detach_trace_probe("opid", local_timer_entry, handle_vector_irq_entry); 47 if (IS_ENABLED(CONFIG_IRQ_WORK)) 48 rv_detach_trace_probe("opid", irq_work_entry, handle_vector_irq_entry); 49 if (IS_ENABLED(CONFIG_SMP)) { 50 rv_detach_trace_probe("opid", reschedule_entry, handle_vector_irq_entry); 51 rv_detach_trace_probe("opid", call_function_entry, handle_vector_irq_entry); 52 rv_detach_trace_probe("opid", 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_opid(irq_disable_opid); 65} 66 67static void handle_irq_enable(void *data, unsigned long ip, unsigned long parent_ip) 68{ 69 da_handle_event_opid(irq_enable_opid); 70} 71 72static void handle_irq_entry(void *data, int irq, struct irqaction *action) 73{ 74 da_handle_event_opid(irq_entry_opid); 75} 76 77static void handle_preempt_disable(void *data, unsigned long ip, unsigned long parent_ip) 78{ 79 da_handle_event_opid(preempt_disable_opid); 80} 81 82static void handle_preempt_enable(void *data, unsigned long ip, unsigned long parent_ip) 83{ 84 da_handle_event_opid(preempt_enable_opid); 85} 86 87static void handle_sched_need_resched(void *data, struct task_struct *tsk, int cpu, int tif) 88{ 89 /* The monitor's intitial state is not in_irq */ 90 if (this_cpu_read(hardirq_context)) 91 da_handle_event_opid(sched_need_resched_opid); 92 else 93 da_handle_start_event_opid(sched_need_resched_opid); 94} 95 96static void handle_sched_waking(void *data, struct task_struct *p) 97{ 98 /* The monitor's intitial state is not in_irq */ 99 if (this_cpu_read(hardirq_context)) 100 da_handle_event_opid(sched_waking_opid); 101 else 102 da_handle_start_event_opid(sched_waking_opid); 103} 104 105static int enable_opid(void) 106{ 107 int retval; 108 109 retval = da_monitor_init_opid(); 110 if (retval) 111 return retval; 112 113 rv_attach_trace_probe("opid", irq_disable, handle_irq_disable); 114 rv_attach_trace_probe("opid", irq_enable, handle_irq_enable); 115 rv_attach_trace_probe("opid", irq_handler_entry, handle_irq_entry); 116 rv_attach_trace_probe("opid", preempt_disable, handle_preempt_disable); 117 rv_attach_trace_probe("opid", preempt_enable, handle_preempt_enable); 118 rv_attach_trace_probe("opid", sched_set_need_resched_tp, handle_sched_need_resched); 119 rv_attach_trace_probe("opid", sched_waking, handle_sched_waking); 120 attach_vector_irq(); 121 122 return 0; 123} 124 125static void disable_opid(void) 126{ 127 rv_opid.enabled = 0; 128 129 rv_detach_trace_probe("opid", irq_disable, handle_irq_disable); 130 rv_detach_trace_probe("opid", irq_enable, handle_irq_enable); 131 rv_detach_trace_probe("opid", irq_handler_entry, handle_irq_entry); 132 rv_detach_trace_probe("opid", preempt_disable, handle_preempt_disable); 133 rv_detach_trace_probe("opid", preempt_enable, handle_preempt_enable); 134 rv_detach_trace_probe("opid", sched_set_need_resched_tp, handle_sched_need_resched); 135 rv_detach_trace_probe("opid", sched_waking, handle_sched_waking); 136 detach_vector_irq(); 137 138 da_monitor_destroy_opid(); 139} 140 141/* 142 * This is the monitor register section. 143 */ 144static struct rv_monitor rv_opid = { 145 .name = "opid", 146 .description = "operations with preemption and irq disabled.", 147 .enable = enable_opid, 148 .disable = disable_opid, 149 .reset = da_monitor_reset_all_opid, 150 .enabled = 0, 151}; 152 153static int __init register_opid(void) 154{ 155 return rv_register_monitor(&rv_opid, &rv_sched); 156} 157 158static void __exit unregister_opid(void) 159{ 160 rv_unregister_monitor(&rv_opid); 161} 162 163module_init(register_opid); 164module_exit(unregister_opid); 165 166MODULE_LICENSE("GPL"); 167MODULE_AUTHOR("Gabriele Monaco <gmonaco@redhat.com>"); 168MODULE_DESCRIPTION("opid: operations with preemption and irq disabled.");
~/
Read-only file preview.