File Index
Files and directories
Sign in
FILE

nrp.c

File preview with syntax highlighting.

linux-6.19.14/kernel/trace/rv/monitors/nrp/nrp.c 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 "nrp"
 12
 13#include <trace/events/irq.h>
 14#include <trace/events/sched.h>
 15#include <rv_trace.h>
 16#include <monitors/sched/sched.h>
 17
 18#include "nrp.h"
 19
 20static struct rv_monitor rv_nrp;
 21DECLARE_DA_MON_PER_TASK(nrp, unsigned char);
 22
 23#ifdef CONFIG_X86_LOCAL_APIC
 24#include <asm/trace/irq_vectors.h>
 25
 26static void handle_vector_irq_entry(void *data, int vector)
 27{
 28	da_handle_event_nrp(current, irq_entry_nrp);
 29}
 30
 31static void attach_vector_irq(void)
 32{
 33	rv_attach_trace_probe("nrp", local_timer_entry, handle_vector_irq_entry);
 34	if (IS_ENABLED(CONFIG_IRQ_WORK))
 35		rv_attach_trace_probe("nrp", irq_work_entry, handle_vector_irq_entry);
 36	if (IS_ENABLED(CONFIG_SMP)) {
 37		rv_attach_trace_probe("nrp", reschedule_entry, handle_vector_irq_entry);
 38		rv_attach_trace_probe("nrp", call_function_entry, handle_vector_irq_entry);
 39		rv_attach_trace_probe("nrp", call_function_single_entry, handle_vector_irq_entry);
 40	}
 41}
 42
 43static void detach_vector_irq(void)
 44{
 45	rv_detach_trace_probe("nrp", local_timer_entry, handle_vector_irq_entry);
 46	if (IS_ENABLED(CONFIG_IRQ_WORK))
 47		rv_detach_trace_probe("nrp", irq_work_entry, handle_vector_irq_entry);
 48	if (IS_ENABLED(CONFIG_SMP)) {
 49		rv_detach_trace_probe("nrp", reschedule_entry, handle_vector_irq_entry);
 50		rv_detach_trace_probe("nrp", call_function_entry, handle_vector_irq_entry);
 51		rv_detach_trace_probe("nrp", call_function_single_entry, handle_vector_irq_entry);
 52	}
 53}
 54
 55#else
 56/* We assume irq_entry tracepoints are sufficient on other architectures */
 57static void attach_vector_irq(void) { }
 58static void detach_vector_irq(void) { }
 59#endif
 60
 61static void handle_irq_entry(void *data, int irq, struct irqaction *action)
 62{
 63	da_handle_event_nrp(current, irq_entry_nrp);
 64}
 65
 66static void handle_sched_need_resched(void *data, struct task_struct *tsk,
 67				      int cpu, int tif)
 68{
 69	/*
 70	 * Although need_resched leads to both the rescheduling and preempt_irq
 71	 * states, it is safer to start the monitor always in preempt_irq,
 72	 * which may not mirror the system state but makes the monitor simpler,
 73	 */
 74	if (tif == TIF_NEED_RESCHED)
 75		da_handle_start_event_nrp(tsk, sched_need_resched_nrp);
 76}
 77
 78static void handle_schedule_entry(void *data, bool preempt)
 79{
 80	if (preempt)
 81		da_handle_event_nrp(current, schedule_entry_preempt_nrp);
 82	else
 83		da_handle_event_nrp(current, schedule_entry_nrp);
 84}
 85
 86static int enable_nrp(void)
 87{
 88	int retval;
 89
 90	retval = da_monitor_init_nrp();
 91	if (retval)
 92		return retval;
 93
 94	rv_attach_trace_probe("nrp", irq_handler_entry, handle_irq_entry);
 95	rv_attach_trace_probe("nrp", sched_set_need_resched_tp, handle_sched_need_resched);
 96	rv_attach_trace_probe("nrp", sched_entry_tp, handle_schedule_entry);
 97	attach_vector_irq();
 98
 99	return 0;
100}
101
102static void disable_nrp(void)
103{
104	rv_nrp.enabled = 0;
105
106	rv_detach_trace_probe("nrp", irq_handler_entry, handle_irq_entry);
107	rv_detach_trace_probe("nrp", sched_set_need_resched_tp, handle_sched_need_resched);
108	rv_detach_trace_probe("nrp", sched_entry_tp, handle_schedule_entry);
109	detach_vector_irq();
110
111	da_monitor_destroy_nrp();
112}
113
114static struct rv_monitor rv_nrp = {
115	.name = "nrp",
116	.description = "need resched preempts.",
117	.enable = enable_nrp,
118	.disable = disable_nrp,
119	.reset = da_monitor_reset_all_nrp,
120	.enabled = 0,
121};
122
123static int __init register_nrp(void)
124{
125	return rv_register_monitor(&rv_nrp, &rv_sched);
126}
127
128static void __exit unregister_nrp(void)
129{
130	rv_unregister_monitor(&rv_nrp);
131}
132
133module_init(register_nrp);
134module_exit(unregister_nrp);
135
136MODULE_LICENSE("GPL");
137MODULE_AUTHOR("Gabriele Monaco <gmonaco@redhat.com>");
138MODULE_DESCRIPTION("nrp: need resched preempts.");
~/ Read-only file preview.