0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/kallsyms.h>
0009 #include <linux/uaccess.h>
0010 #include <linux/module.h>
0011 #include <linux/ftrace.h>
0012 #include <linux/kprobes.h>
0013 #include "trace.h"
0014
0015 #define CREATE_TRACE_POINTS
0016 #include <trace/events/preemptirq.h>
0017
0018 #ifdef CONFIG_TRACE_IRQFLAGS
0019
0020 static DEFINE_PER_CPU(int, tracing_irq_cpu);
0021
0022
0023
0024
0025
0026
0027
0028 void trace_hardirqs_on_prepare(void)
0029 {
0030 if (this_cpu_read(tracing_irq_cpu)) {
0031 if (!in_nmi())
0032 trace_irq_enable(CALLER_ADDR0, CALLER_ADDR1);
0033 tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1);
0034 this_cpu_write(tracing_irq_cpu, 0);
0035 }
0036 }
0037 EXPORT_SYMBOL(trace_hardirqs_on_prepare);
0038 NOKPROBE_SYMBOL(trace_hardirqs_on_prepare);
0039
0040 void trace_hardirqs_on(void)
0041 {
0042 if (this_cpu_read(tracing_irq_cpu)) {
0043 if (!in_nmi())
0044 trace_irq_enable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
0045 tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1);
0046 this_cpu_write(tracing_irq_cpu, 0);
0047 }
0048
0049 lockdep_hardirqs_on_prepare();
0050 lockdep_hardirqs_on(CALLER_ADDR0);
0051 }
0052 EXPORT_SYMBOL(trace_hardirqs_on);
0053 NOKPROBE_SYMBOL(trace_hardirqs_on);
0054
0055
0056
0057
0058
0059
0060
0061 void trace_hardirqs_off_finish(void)
0062 {
0063 if (!this_cpu_read(tracing_irq_cpu)) {
0064 this_cpu_write(tracing_irq_cpu, 1);
0065 tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1);
0066 if (!in_nmi())
0067 trace_irq_disable(CALLER_ADDR0, CALLER_ADDR1);
0068 }
0069
0070 }
0071 EXPORT_SYMBOL(trace_hardirqs_off_finish);
0072 NOKPROBE_SYMBOL(trace_hardirqs_off_finish);
0073
0074 void trace_hardirqs_off(void)
0075 {
0076 lockdep_hardirqs_off(CALLER_ADDR0);
0077
0078 if (!this_cpu_read(tracing_irq_cpu)) {
0079 this_cpu_write(tracing_irq_cpu, 1);
0080 tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1);
0081 if (!in_nmi())
0082 trace_irq_disable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
0083 }
0084 }
0085 EXPORT_SYMBOL(trace_hardirqs_off);
0086 NOKPROBE_SYMBOL(trace_hardirqs_off);
0087
0088 __visible void trace_hardirqs_on_caller(unsigned long caller_addr)
0089 {
0090 if (this_cpu_read(tracing_irq_cpu)) {
0091 if (!in_nmi())
0092 trace_irq_enable_rcuidle(CALLER_ADDR0, caller_addr);
0093 tracer_hardirqs_on(CALLER_ADDR0, caller_addr);
0094 this_cpu_write(tracing_irq_cpu, 0);
0095 }
0096
0097 lockdep_hardirqs_on_prepare();
0098 lockdep_hardirqs_on(caller_addr);
0099 }
0100 EXPORT_SYMBOL(trace_hardirqs_on_caller);
0101 NOKPROBE_SYMBOL(trace_hardirqs_on_caller);
0102
0103 __visible void trace_hardirqs_off_caller(unsigned long caller_addr)
0104 {
0105 lockdep_hardirqs_off(caller_addr);
0106
0107 if (!this_cpu_read(tracing_irq_cpu)) {
0108 this_cpu_write(tracing_irq_cpu, 1);
0109 tracer_hardirqs_off(CALLER_ADDR0, caller_addr);
0110 if (!in_nmi())
0111 trace_irq_disable_rcuidle(CALLER_ADDR0, caller_addr);
0112 }
0113 }
0114 EXPORT_SYMBOL(trace_hardirqs_off_caller);
0115 NOKPROBE_SYMBOL(trace_hardirqs_off_caller);
0116 #endif
0117
0118 #ifdef CONFIG_TRACE_PREEMPT_TOGGLE
0119
0120 void trace_preempt_on(unsigned long a0, unsigned long a1)
0121 {
0122 if (!in_nmi())
0123 trace_preempt_enable_rcuidle(a0, a1);
0124 tracer_preempt_on(a0, a1);
0125 }
0126
0127 void trace_preempt_off(unsigned long a0, unsigned long a1)
0128 {
0129 if (!in_nmi())
0130 trace_preempt_disable_rcuidle(a0, a1);
0131 tracer_preempt_off(a0, a1);
0132 }
0133 #endif