summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/interrupt.h5
-rw-r--r--include/linux/kernel.h40
-rw-r--r--include/trace/irq_event_types.h12
3 files changed, 44 insertions, 13 deletions
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 472f11765f60..9b7e9d743476 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -258,6 +258,11 @@ enum
NR_SOFTIRQS
};
+/* map softirq index to softirq name. update 'softirq_to_name' in
+ * kernel/softirq.c when adding a new softirq.
+ */
+extern char *softirq_to_name[NR_SOFTIRQS];
+
/* softirq mask and active fields moved to irq_cpustat_t in
* asm/hardirq.h to get better cache usage. KAO
*/
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 7742798c9208..1daca3b062bb 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -452,32 +452,46 @@ do { \
#define trace_printk(fmt, args...) \
do { \
- static const char *trace_printk_fmt \
- __attribute__((section("__trace_printk_fmt"))); \
- \
- if (!trace_printk_fmt) \
- trace_printk_fmt = fmt; \
- \
__trace_printk_check_format(fmt, ##args); \
- __trace_printk(_THIS_IP_, trace_printk_fmt, ##args); \
+ if (__builtin_constant_p(fmt)) { \
+ static const char *trace_printk_fmt \
+ __attribute__((section("__trace_printk_fmt"))) = \
+ __builtin_constant_p(fmt) ? fmt : NULL; \
+ \
+ __trace_bprintk(_THIS_IP_, trace_printk_fmt, ##args); \
+ } else \
+ __trace_printk(_THIS_IP_, fmt, ##args); \
} while (0)
extern int
+__trace_bprintk(unsigned long ip, const char *fmt, ...)
+ __attribute__ ((format (printf, 2, 3)));
+
+extern int
__trace_printk(unsigned long ip, const char *fmt, ...)
__attribute__ ((format (printf, 2, 3)));
+/*
+ * The double __builtin_constant_p is because gcc will give us an error
+ * if we try to allocate the static variable to fmt if it is not a
+ * constant. Even with the outer if statement.
+ */
#define ftrace_vprintk(fmt, vargs) \
do { \
- static const char *trace_printk_fmt \
- __attribute__((section("__trace_printk_fmt"))); \
- \
- if (!trace_printk_fmt) \
- trace_printk_fmt = fmt; \
+ if (__builtin_constant_p(fmt)) { \
+ static const char *trace_printk_fmt \
+ __attribute__((section("__trace_printk_fmt"))) = \
+ __builtin_constant_p(fmt) ? fmt : NULL; \
\
- __ftrace_vprintk(_THIS_IP_, trace_printk_fmt, vargs); \
+ __ftrace_vbprintk(_THIS_IP_, trace_printk_fmt, vargs); \
+ } else \
+ __ftrace_vprintk(_THIS_IP_, fmt, vargs); \
} while (0)
extern int
+__ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap);
+
+extern int
__ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap);
extern void ftrace_dump(void);
diff --git a/include/trace/irq_event_types.h b/include/trace/irq_event_types.h
index 214bb928fe9e..85964ebd47ec 100644
--- a/include/trace/irq_event_types.h
+++ b/include/trace/irq_event_types.h
@@ -40,4 +40,16 @@ TRACE_EVENT(irq_handler_exit,
__entry->irq, __entry->ret ? "handled" : "unhandled")
);
+TRACE_FORMAT(softirq_entry,
+ TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
+ TP_ARGS(h, vec),
+ TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec])
+ );
+
+TRACE_FORMAT(softirq_exit,
+ TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
+ TP_ARGS(h, vec),
+ TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec])
+ );
+
#undef TRACE_SYSTEM