Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 140956
b: refs/heads/master
c: f58ba10
h: refs/heads/master
v: v3
  • Loading branch information
Frederic Weisbecker authored and Ingo Molnar committed Mar 13, 2009
1 parent d67117f commit e46bb6f
Show file tree
Hide file tree
Showing 24 changed files with 268 additions and 841 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b478b782e110fdb4135caa3062b6d687e989d994
refs/heads/master: f58ba100678f421bdcb000a3c71793f432dfab93
2 changes: 1 addition & 1 deletion trunk/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 29
EXTRAVERSION = -rc8
EXTRAVERSION = -rc7
NAME = Erotic Pickled Herring

# *DOCUMENTATION*
Expand Down
7 changes: 7 additions & 0 deletions trunk/arch/x86/include/asm/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@

#endif

/* FIXME: I don't want to stay hardcoded */
#ifdef CONFIG_X86_64
# define FTRACE_SYSCALL_MAX 296
#else
# define FTRACE_SYSCALL_MAX 333
#endif

#ifdef CONFIG_FUNCTION_TRACER
#define MCOUNT_ADDR ((long)(mcount))
#define MCOUNT_INSN_SIZE 5 /* sizeof mcount call */
Expand Down
63 changes: 63 additions & 0 deletions trunk/arch/x86/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,3 +453,66 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
}
}
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */

#ifdef CONFIG_FTRACE_SYSCALLS

extern unsigned long __start_syscalls_metadata[];
extern unsigned long __stop_syscalls_metadata[];
extern unsigned long *sys_call_table;

static struct syscall_metadata **syscalls_metadata;

static struct syscall_metadata *find_syscall_meta(unsigned long *syscall)
{
struct syscall_metadata *start;
struct syscall_metadata *stop;
char str[KSYM_SYMBOL_LEN];


start = (struct syscall_metadata *)__start_syscalls_metadata;
stop = (struct syscall_metadata *)__stop_syscalls_metadata;
kallsyms_lookup((unsigned long) syscall, NULL, NULL, NULL, str);

for ( ; start < stop; start++) {
if (start->name && !strcmp(start->name, str))
return start;
}
return NULL;
}

struct syscall_metadata *syscall_nr_to_meta(int nr)
{
if (!syscalls_metadata || nr >= FTRACE_SYSCALL_MAX || nr < 0)
return NULL;

return syscalls_metadata[nr];
}

void arch_init_ftrace_syscalls(void)
{
int i;
struct syscall_metadata *meta;
unsigned long **psys_syscall_table = &sys_call_table;
static atomic_t refs;

if (atomic_inc_return(&refs) != 1)
goto end;

syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
FTRACE_SYSCALL_MAX, GFP_KERNEL);
if (!syscalls_metadata) {
WARN_ON(1);
return;
}

for (i = 0; i < FTRACE_SYSCALL_MAX; i++) {
meta = find_syscall_meta(psys_syscall_table[i]);
syscalls_metadata[i] = meta;
}
return;

/* Paranoid: avoid overflow */
end:
atomic_dec(&refs);
}
#endif
1 change: 1 addition & 0 deletions trunk/include/linux/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ enum {
};

struct dyn_ftrace {
struct list_head list;
unsigned long ip; /* address of mcount call-site */
unsigned long flags;
struct dyn_arch_ftrace arch;
Expand Down
5 changes: 0 additions & 5 deletions trunk/include/linux/interrupt.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,11 +258,6 @@ 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: 13 additions & 27 deletions trunk/include/linux/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -452,45 +452,31 @@ do { \

#define trace_printk(fmt, args...) \
do { \
__trace_printk_check_format(fmt, ##args); \
if (__builtin_constant_p(fmt)) { \
static const char *trace_printk_fmt \
__attribute__((section("__trace_printk_fmt"))) = \
__builtin_constant_p(fmt) ? fmt : NULL; \
static const char *trace_printk_fmt \
__attribute__((section("__trace_printk_fmt"))); \
\
if (!trace_printk_fmt) \
trace_printk_fmt = fmt; \
\
__trace_bprintk(_THIS_IP_, trace_printk_fmt, ##args); \
} else \
__trace_printk(_THIS_IP_, fmt, ##args); \
__trace_printk_check_format(fmt, ##args); \
__trace_printk(_THIS_IP_, trace_printk_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 { \
if (__builtin_constant_p(fmt)) { \
static const char *trace_printk_fmt \
__attribute__((section("__trace_printk_fmt"))) = \
__builtin_constant_p(fmt) ? fmt : NULL; \
static const char *trace_printk_fmt \
__attribute__((section("__trace_printk_fmt"))); \
\
if (!trace_printk_fmt) \
trace_printk_fmt = fmt; \
\
__ftrace_vbprintk(_THIS_IP_, trace_printk_fmt, vargs); \
} else \
__ftrace_vprintk(_THIS_IP_, fmt, vargs); \
__ftrace_vprintk(_THIS_IP_, trace_printk_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: 0 additions & 12 deletions trunk/include/trace/irq_event_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,4 @@ 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
15 changes: 2 additions & 13 deletions trunk/kernel/softirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include <linux/ftrace.h>
#include <linux/smp.h>
#include <linux/tick.h>
#include <trace/irq.h>

#include <asm/irq.h>
/*
Expand Down Expand Up @@ -54,11 +53,6 @@ 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", "TIMER", "NET_TX", "NET_RX", "BLOCK",
"TASKLET", "SCHED", "HRTIMER", "RCU"
};

/*
* 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 @@ -186,9 +180,6 @@ 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 @@ -215,14 +206,12 @@ 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 %s %p"
printk(KERN_ERR "huh, entered softirq %td %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
52 changes: 34 additions & 18 deletions trunk/kernel/trace/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ enum {

static int ftrace_filtered;

static struct dyn_ftrace *ftrace_new_addrs;
static LIST_HEAD(ftrace_new_addrs);

static DEFINE_MUTEX(ftrace_regex_lock);

Expand Down Expand Up @@ -356,8 +356,7 @@ void ftrace_release(void *start, unsigned long size)

mutex_lock(&ftrace_lock);
do_for_each_ftrace_rec(pg, rec) {
if ((rec->ip >= s) && (rec->ip < e) &&
!(rec->flags & FTRACE_FL_FREE))
if ((rec->ip >= s) && (rec->ip < e))
ftrace_free_rec(rec);
} while_for_each_ftrace_rec();
mutex_unlock(&ftrace_lock);
Expand Down Expand Up @@ -409,8 +408,8 @@ ftrace_record_ip(unsigned long ip)
return NULL;

rec->ip = ip;
rec->flags = (unsigned long)ftrace_new_addrs;
ftrace_new_addrs = rec;

list_add(&rec->list, &ftrace_new_addrs);

return rec;
}
Expand Down Expand Up @@ -532,12 +531,11 @@ static void ftrace_replace_code(int enable)

do_for_each_ftrace_rec(pg, rec) {
/*
* Skip over free records, records that have
* failed and not converted.
* Skip over free records and records that have
* failed.
*/
if (rec->flags & FTRACE_FL_FREE ||
rec->flags & FTRACE_FL_FAILED ||
rec->flags & FTRACE_FL_CONVERTED)
rec->flags & FTRACE_FL_FAILED)
continue;

/* ignore updates to this record's mcount site */
Expand All @@ -549,7 +547,7 @@ static void ftrace_replace_code(int enable)
}

failed = __ftrace_replace_code(rec, enable);
if (failed) {
if (failed && (rec->flags & FTRACE_FL_CONVERTED)) {
rec->flags |= FTRACE_FL_FAILED;
if ((system_state == SYSTEM_BOOTING) ||
!core_kernel_text(rec->ip)) {
Expand Down Expand Up @@ -716,21 +714,19 @@ unsigned long ftrace_update_tot_cnt;

static int ftrace_update_code(struct module *mod)
{
struct dyn_ftrace *p;
struct dyn_ftrace *p, *t;
cycle_t start, stop;

start = ftrace_now(raw_smp_processor_id());
ftrace_update_cnt = 0;

while (ftrace_new_addrs) {
list_for_each_entry_safe(p, t, &ftrace_new_addrs, list) {

/* If something went wrong, bail without enabling anything */
if (unlikely(ftrace_disabled))
return -1;

p = ftrace_new_addrs;
ftrace_new_addrs = (struct dyn_ftrace *)p->flags;
p->flags = 0L;
list_del_init(&p->list);

/* convert record (i.e, patch mcount-call with NOP) */
if (ftrace_code_disable(mod, p)) {
Expand Down Expand Up @@ -1122,6 +1118,16 @@ ftrace_notrace_open(struct inode *inode, struct file *file)
return ftrace_regex_open(inode, file, 0);
}

static ssize_t
ftrace_regex_read(struct file *file, char __user *ubuf,
size_t cnt, loff_t *ppos)
{
if (file->f_mode & FMODE_READ)
return seq_read(file, ubuf, cnt, ppos);
else
return -EPERM;
}

static loff_t
ftrace_regex_lseek(struct file *file, loff_t offset, int origin)
{
Expand Down Expand Up @@ -1874,15 +1880,15 @@ static const struct file_operations ftrace_failures_fops = {

static const struct file_operations ftrace_filter_fops = {
.open = ftrace_filter_open,
.read = seq_read,
.read = ftrace_regex_read,
.write = ftrace_filter_write,
.llseek = ftrace_regex_lseek,
.release = ftrace_filter_release,
};

static const struct file_operations ftrace_notrace_fops = {
.open = ftrace_notrace_open,
.read = seq_read,
.read = ftrace_regex_read,
.write = ftrace_notrace_write,
.llseek = ftrace_regex_lseek,
.release = ftrace_notrace_release,
Expand Down Expand Up @@ -1984,6 +1990,16 @@ ftrace_graph_open(struct inode *inode, struct file *file)
return ret;
}

static ssize_t
ftrace_graph_read(struct file *file, char __user *ubuf,
size_t cnt, loff_t *ppos)
{
if (file->f_mode & FMODE_READ)
return seq_read(file, ubuf, cnt, ppos);
else
return -EPERM;
}

static int
ftrace_set_func(unsigned long *array, int *idx, char *buffer)
{
Expand Down Expand Up @@ -2114,7 +2130,7 @@ ftrace_graph_write(struct file *file, const char __user *ubuf,

static const struct file_operations ftrace_graph_fops = {
.open = ftrace_graph_open,
.read = seq_read,
.read = ftrace_graph_read,
.write = ftrace_graph_write,
};
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
Expand Down
Loading

0 comments on commit e46bb6f

Please sign in to comment.