Skip to content

Commit

Permalink
Merge branch 'tip/tracing/ftrace' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/kernel/git/rostedt/linux-2.6-trace into tracing/ftrace
  • Loading branch information
Ingo Molnar committed Mar 13, 2009
2 parents 4c6ed8f + 5cc9854 commit 2084e02
Show file tree
Hide file tree
Showing 16 changed files with 747 additions and 132 deletions.
5 changes: 5 additions & 0 deletions include/linux/interrupt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
40 changes: 27 additions & 13 deletions include/linux/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -452,31 +452,45 @@ 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);

Expand Down
12 changes: 12 additions & 0 deletions include/trace/irq_event_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
16 changes: 14 additions & 2 deletions kernel/softirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <linux/ftrace.h>
#include <linux/smp.h>
#include <linux/tick.h>
#include <trace/irq.h>

#include <asm/irq.h>
/*
Expand Down Expand Up @@ -53,6 +54,12 @@ static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp

static DEFINE_PER_CPU(struct task_struct *, ksoftirqd);

char *softirq_to_name[NR_SOFTIRQS] = {
"HI_SOFTIRQ", "TIMER_SOFTIRQ", "NET_TX_SOFTIRQ", "NET_RX_SOFTIRQ",
"BLOCK_SOFTIRQ", "TASKLET_SOFTIRQ", "SCHED_SOFTIRQ", "HRTIMER_SOFTIRQ",
"RCU_SOFTIRQ"
};

/*
* we cannot loop indefinitely here to avoid userspace starvation,
* but we also don't want to introduce a worst case 1/HZ latency
Expand Down Expand Up @@ -180,6 +187,9 @@ EXPORT_SYMBOL(local_bh_enable_ip);
*/
#define MAX_SOFTIRQ_RESTART 10

DEFINE_TRACE(softirq_entry);
DEFINE_TRACE(softirq_exit);

asmlinkage void __do_softirq(void)
{
struct softirq_action *h;
Expand All @@ -206,12 +216,14 @@ asmlinkage void __do_softirq(void)
if (pending & 1) {
int prev_count = preempt_count();

trace_softirq_entry(h, softirq_vec);
h->action(h);

trace_softirq_exit(h, softirq_vec);
if (unlikely(prev_count != preempt_count())) {
printk(KERN_ERR "huh, entered softirq %td %p"
printk(KERN_ERR "huh, entered softirq %td %s %p"
"with preempt_count %08x,"
" exited with %08x?\n", h - softirq_vec,
softirq_to_name[h - softirq_vec],
h->action, prev_count, preempt_count());
preempt_count() = prev_count;
}
Expand Down
Loading

0 comments on commit 2084e02

Please sign in to comment.