From 432b4bc02ee9fb58d00c25d6af47167187327280 Mon Sep 17 00:00:00 2001 From: Dmitri Vorobiev Date: Sun, 22 Mar 2009 19:11:11 +0200 Subject: [PATCH] --- yaml --- r: 141026 b: refs/heads/master c: b8b94265337f83b7db9c5f429b1769d463d7da8c h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/include/linux/ring_buffer.h | 11 +- trunk/kernel/extable.c | 14 +- trunk/kernel/trace/Makefile | 1 - trunk/kernel/trace/ring_buffer.c | 125 ++----- trunk/kernel/trace/trace.c | 44 +-- trunk/kernel/trace/trace.h | 76 +--- trunk/kernel/trace/trace_clock.c | 1 + trunk/kernel/trace/trace_events.c | 203 +--------- trunk/kernel/trace/trace_events_filter.c | 427 ---------------------- trunk/kernel/trace/trace_events_stage_2.h | 45 --- trunk/kernel/trace/trace_events_stage_3.h | 9 +- trunk/kernel/trace/trace_nop.c | 1 - trunk/mm/memory.c | 8 - 14 files changed, 69 insertions(+), 898 deletions(-) delete mode 100644 trunk/kernel/trace/trace_events_filter.c diff --git a/[refs] b/[refs] index 05f9778483a3..423a259d3d90 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 9a8118baaeb0eaa148913bed77bf9c6335f6ca63 +refs/heads/master: b8b94265337f83b7db9c5f429b1769d463d7da8c diff --git a/trunk/include/linux/ring_buffer.h b/trunk/include/linux/ring_buffer.h index e1b7b2173885..9e6052bd1a1c 100644 --- a/trunk/include/linux/ring_buffer.h +++ b/trunk/include/linux/ring_buffer.h @@ -18,13 +18,10 @@ struct ring_buffer_event { /** * enum ring_buffer_type - internal ring buffer types * - * @RINGBUF_TYPE_PADDING: Left over page padding or discarded event - * If time_delta is 0: - * array is ignored - * size is variable depending on how much + * @RINGBUF_TYPE_PADDING: Left over page padding + * array is ignored + * size is variable depending on how much * padding is needed - * If time_delta is non zero: - * everything else same as RINGBUF_TYPE_DATA * * @RINGBUF_TYPE_TIME_EXTEND: Extend the time delta * array[0] = time delta (28 .. 59) @@ -68,8 +65,6 @@ ring_buffer_event_time_delta(struct ring_buffer_event *event) return event->time_delta; } -void ring_buffer_event_discard(struct ring_buffer_event *event); - /* * size is in bytes for each per CPU buffer. */ diff --git a/trunk/kernel/extable.c b/trunk/kernel/extable.c index 0df6253730be..25d39b0c3a1b 100644 --- a/trunk/kernel/extable.c +++ b/trunk/kernel/extable.c @@ -15,11 +15,21 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include +#include #include -#include -#include + #include +#include + +/* + * mutex protecting text section modification (dynamic code patching). + * some users need to sleep (allocating memory...) while they hold this lock. + * + * NOT exported to modules - patching kernel text is a really delicate matter. + */ +DEFINE_MUTEX(text_mutex); extern struct exception_table_entry __start___ex_table[]; extern struct exception_table_entry __stop___ex_table[]; diff --git a/trunk/kernel/trace/Makefile b/trunk/kernel/trace/Makefile index 2630f5121ec1..0e45c206c2f9 100644 --- a/trunk/kernel/trace/Makefile +++ b/trunk/kernel/trace/Makefile @@ -45,6 +45,5 @@ obj-$(CONFIG_EVENT_TRACER) += events.o obj-$(CONFIG_EVENT_TRACER) += trace_export.o obj-$(CONFIG_FTRACE_SYSCALLS) += trace_syscalls.o obj-$(CONFIG_EVENT_PROFILE) += trace_event_profile.o -obj-$(CONFIG_EVENT_TRACER) += trace_events_filter.o libftrace-y := ftrace.o diff --git a/trunk/kernel/trace/ring_buffer.c b/trunk/kernel/trace/ring_buffer.c index a09027ec1714..808b14bbf076 100644 --- a/trunk/kernel/trace/ring_buffer.c +++ b/trunk/kernel/trace/ring_buffer.c @@ -189,65 +189,16 @@ enum { RB_LEN_TIME_STAMP = 16, }; -static inline int rb_null_event(struct ring_buffer_event *event) -{ - return event->type == RINGBUF_TYPE_PADDING && event->time_delta == 0; -} - -static inline int rb_discarded_event(struct ring_buffer_event *event) -{ - return event->type == RINGBUF_TYPE_PADDING && event->time_delta; -} - -static void rb_event_set_padding(struct ring_buffer_event *event) -{ - event->type = RINGBUF_TYPE_PADDING; - event->time_delta = 0; -} - -/** - * ring_buffer_event_discard - discard an event in the ring buffer - * @buffer: the ring buffer - * @event: the event to discard - * - * Sometimes a event that is in the ring buffer needs to be ignored. - * This function lets the user discard an event in the ring buffer - * and then that event will not be read later. - * - * Note, it is up to the user to be careful with this, and protect - * against races. If the user discards an event that has been consumed - * it is possible that it could corrupt the ring buffer. - */ -void ring_buffer_event_discard(struct ring_buffer_event *event) -{ - event->type = RINGBUF_TYPE_PADDING; - /* time delta must be non zero */ - if (!event->time_delta) - event->time_delta = 1; -} - -static unsigned -rb_event_data_length(struct ring_buffer_event *event) -{ - unsigned length; - - if (event->len) - length = event->len * RB_ALIGNMENT; - else - length = event->array[0]; - return length + RB_EVNT_HDR_SIZE; -} - /* inline for ring buffer fast paths */ static unsigned rb_event_length(struct ring_buffer_event *event) { + unsigned length; + switch (event->type) { case RINGBUF_TYPE_PADDING: - if (rb_null_event(event)) - /* undefined */ - return -1; - return rb_event_data_length(event); + /* undefined */ + return -1; case RINGBUF_TYPE_TIME_EXTEND: return RB_LEN_TIME_EXTEND; @@ -256,7 +207,11 @@ rb_event_length(struct ring_buffer_event *event) return RB_LEN_TIME_STAMP; case RINGBUF_TYPE_DATA: - return rb_event_data_length(event); + if (event->len) + length = event->len * RB_ALIGNMENT; + else + length = event->array[0]; + return length + RB_EVNT_HDR_SIZE; default: BUG(); } @@ -580,8 +535,8 @@ static void rb_free_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer) extern int ring_buffer_page_too_big(void); #ifdef CONFIG_HOTPLUG_CPU -static int __cpuinit rb_cpu_notify(struct notifier_block *self, - unsigned long action, void *hcpu); +static int rb_cpu_notify(struct notifier_block *self, + unsigned long action, void *hcpu); #endif /** @@ -890,6 +845,11 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) } EXPORT_SYMBOL_GPL(ring_buffer_resize); +static inline int rb_null_event(struct ring_buffer_event *event) +{ + return event->type == RINGBUF_TYPE_PADDING; +} + static inline void * __rb_data_page_index(struct buffer_data_page *bpage, unsigned index) { @@ -1259,7 +1219,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, if (tail < BUF_PAGE_SIZE) { /* Mark the rest of the page with padding */ event = __rb_page_index(tail_page, tail); - rb_event_set_padding(event); + event->type = RINGBUF_TYPE_PADDING; } if (tail <= BUF_PAGE_SIZE) @@ -2009,7 +1969,7 @@ static void rb_advance_reader(struct ring_buffer_per_cpu *cpu_buffer) event = rb_reader_event(cpu_buffer); - if (event->type == RINGBUF_TYPE_DATA || rb_discarded_event(event)) + if (event->type == RINGBUF_TYPE_DATA) cpu_buffer->entries--; rb_update_read_stamp(cpu_buffer, event); @@ -2092,18 +2052,9 @@ rb_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts) switch (event->type) { case RINGBUF_TYPE_PADDING: - if (rb_null_event(event)) - RB_WARN_ON(cpu_buffer, 1); - /* - * Because the writer could be discarding every - * event it creates (which would probably be bad) - * if we were to go back to "again" then we may never - * catch up, and will trigger the warn on, or lock - * the box. Return the padding, and we will release - * the current locks, and try again. - */ + RB_WARN_ON(cpu_buffer, 1); rb_advance_reader(cpu_buffer); - return event; + return NULL; case RINGBUF_TYPE_TIME_EXTEND: /* Internal data, OK to advance */ @@ -2164,12 +2115,8 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) switch (event->type) { case RINGBUF_TYPE_PADDING: - if (rb_null_event(event)) { - rb_inc_iter(iter); - goto again; - } - rb_advance_iter(iter); - return event; + rb_inc_iter(iter); + goto again; case RINGBUF_TYPE_TIME_EXTEND: /* Internal data, OK to advance */ @@ -2216,16 +2163,10 @@ ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts) if (!cpumask_test_cpu(cpu, buffer->cpumask)) return NULL; - again: spin_lock_irqsave(&cpu_buffer->reader_lock, flags); event = rb_buffer_peek(buffer, cpu, ts); spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); - if (event && event->type == RINGBUF_TYPE_PADDING) { - cpu_relax(); - goto again; - } - return event; } @@ -2244,16 +2185,10 @@ ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts) struct ring_buffer_event *event; unsigned long flags; - again: spin_lock_irqsave(&cpu_buffer->reader_lock, flags); event = rb_iter_peek(iter, ts); spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); - if (event && event->type == RINGBUF_TYPE_PADDING) { - cpu_relax(); - goto again; - } - return event; } @@ -2272,7 +2207,6 @@ ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts) struct ring_buffer_event *event = NULL; unsigned long flags; - again: /* might be called in atomic */ preempt_disable(); @@ -2294,11 +2228,6 @@ ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts) out: preempt_enable(); - if (event && event->type == RINGBUF_TYPE_PADDING) { - cpu_relax(); - goto again; - } - return event; } EXPORT_SYMBOL_GPL(ring_buffer_consume); @@ -2377,7 +2306,6 @@ ring_buffer_read(struct ring_buffer_iter *iter, u64 *ts) struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer; unsigned long flags; - again: spin_lock_irqsave(&cpu_buffer->reader_lock, flags); event = rb_iter_peek(iter, ts); if (!event) @@ -2387,11 +2315,6 @@ ring_buffer_read(struct ring_buffer_iter *iter, u64 *ts) out: spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); - if (event && event->type == RINGBUF_TYPE_PADDING) { - cpu_relax(); - goto again; - } - return event; } EXPORT_SYMBOL_GPL(ring_buffer_read); @@ -2861,8 +2784,8 @@ static __init int rb_init_debugfs(void) fs_initcall(rb_init_debugfs); #ifdef CONFIG_HOTPLUG_CPU -static int __cpuinit rb_cpu_notify(struct notifier_block *self, - unsigned long action, void *hcpu) +static int rb_cpu_notify(struct notifier_block *self, + unsigned long action, void *hcpu) { struct ring_buffer *buffer = container_of(self, struct ring_buffer, cpu_notify); diff --git a/trunk/kernel/trace/trace.c b/trunk/kernel/trace/trace.c index 89f0c2544ad0..ace685c70186 100644 --- a/trunk/kernel/trace/trace.c +++ b/trunk/kernel/trace/trace.c @@ -382,7 +382,7 @@ ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt) return cnt; } -ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt) +static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt) { int len; void *ret; @@ -860,25 +860,15 @@ static void ftrace_trace_stack(struct trace_array *tr, static void ftrace_trace_userstack(struct trace_array *tr, unsigned long flags, int pc); -static inline void __trace_buffer_unlock_commit(struct trace_array *tr, - struct ring_buffer_event *event, - unsigned long flags, int pc, - int wake) +void trace_buffer_unlock_commit(struct trace_array *tr, + struct ring_buffer_event *event, + unsigned long flags, int pc) { ring_buffer_unlock_commit(tr->buffer, event); ftrace_trace_stack(tr, flags, 6, pc); ftrace_trace_userstack(tr, flags, pc); - - if (wake) - trace_wake_up(); -} - -void trace_buffer_unlock_commit(struct trace_array *tr, - struct ring_buffer_event *event, - unsigned long flags, int pc) -{ - __trace_buffer_unlock_commit(tr, event, flags, pc, 1); + trace_wake_up(); } struct ring_buffer_event * @@ -892,13 +882,7 @@ trace_current_buffer_lock_reserve(unsigned char type, unsigned long len, void trace_current_buffer_unlock_commit(struct ring_buffer_event *event, unsigned long flags, int pc) { - return __trace_buffer_unlock_commit(&global_trace, event, flags, pc, 1); -} - -void trace_nowake_buffer_unlock_commit(struct ring_buffer_event *event, - unsigned long flags, int pc) -{ - return __trace_buffer_unlock_commit(&global_trace, event, flags, pc, 0); + return trace_buffer_unlock_commit(&global_trace, event, flags, pc); } void @@ -924,7 +908,7 @@ trace_function(struct trace_array *tr, } #ifdef CONFIG_FUNCTION_GRAPH_TRACER -static int __trace_graph_entry(struct trace_array *tr, +static void __trace_graph_entry(struct trace_array *tr, struct ftrace_graph_ent *trace, unsigned long flags, int pc) @@ -933,17 +917,15 @@ static int __trace_graph_entry(struct trace_array *tr, struct ftrace_graph_ent_entry *entry; if (unlikely(local_read(&__get_cpu_var(ftrace_cpu_disabled)))) - return 0; + return; event = trace_buffer_lock_reserve(&global_trace, TRACE_GRAPH_ENT, sizeof(*entry), flags, pc); if (!event) - return 0; + return; entry = ring_buffer_event_data(event); entry->graph_ent = *trace; ring_buffer_unlock_commit(global_trace.buffer, event); - - return 1; } static void __trace_graph_return(struct trace_array *tr, @@ -1164,7 +1146,6 @@ int trace_graph_entry(struct ftrace_graph_ent *trace) struct trace_array_cpu *data; unsigned long flags; long disabled; - int ret; int cpu; int pc; @@ -1180,18 +1161,15 @@ int trace_graph_entry(struct ftrace_graph_ent *trace) disabled = atomic_inc_return(&data->disabled); if (likely(disabled == 1)) { pc = preempt_count(); - ret = __trace_graph_entry(tr, trace, flags, pc); - } else { - ret = 0; + __trace_graph_entry(tr, trace, flags, pc); } /* Only do the atomic if it is not already set */ if (!test_tsk_trace_graph(current)) set_tsk_trace_graph(current); - atomic_dec(&data->disabled); local_irq_restore(flags); - return ret; + return 1; } void trace_graph_return(struct ftrace_graph_ret *trace) diff --git a/trunk/kernel/trace/trace.h b/trunk/kernel/trace/trace.h index 90a848debcba..7cfb741be200 100644 --- a/trunk/kernel/trace/trace.h +++ b/trunk/kernel/trace/trace.h @@ -483,8 +483,6 @@ trace_current_buffer_lock_reserve(unsigned char type, unsigned long len, unsigned long flags, int pc); void trace_current_buffer_unlock_commit(struct ring_buffer_event *event, unsigned long flags, int pc); -void trace_nowake_buffer_unlock_commit(struct ring_buffer_event *event, - unsigned long flags, int pc); struct trace_entry *tracing_get_trace_entry(struct trace_array *tr, struct trace_array_cpu *data); @@ -777,27 +775,16 @@ enum { TRACE_EVENT_TYPE_RAW = 2, }; -struct ftrace_event_field { - struct list_head link; - char *name; - char *type; - int offset; - int size; -}; - struct ftrace_event_call { - char *name; - char *system; - struct dentry *dir; - int enabled; - int (*regfunc)(void); - void (*unregfunc)(void); - int id; - int (*raw_init)(void); - int (*show_format)(struct trace_seq *s); - int (*define_fields)(void); - struct list_head fields; - struct filter_pred **preds; + char *name; + char *system; + struct dentry *dir; + int enabled; + int (*regfunc)(void); + void (*unregfunc)(void); + int id; + int (*raw_init)(void); + int (*show_format)(struct trace_seq *s); #ifdef CONFIG_EVENT_PROFILE atomic_t profile_count; @@ -806,51 +793,6 @@ struct ftrace_event_call { #endif }; -struct event_subsystem { - struct list_head list; - const char *name; - struct dentry *entry; - struct filter_pred **preds; -}; - -#define events_for_each(event) \ - for (event = __start_ftrace_events; \ - (unsigned long)event < (unsigned long)__stop_ftrace_events; \ - event++) - -#define MAX_FILTER_PRED 8 - -struct filter_pred; - -typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event); - -struct filter_pred { - filter_pred_fn_t fn; - u64 val; - char *str_val; - int str_len; - char *field_name; - int offset; - int not; - int or; - int compound; - int clear; -}; - -int trace_define_field(struct ftrace_event_call *call, char *type, - char *name, int offset, int size); -extern void filter_free_pred(struct filter_pred *pred); -extern void filter_print_preds(struct filter_pred **preds, - struct trace_seq *s); -extern int filter_parse(char **pbuf, struct filter_pred *pred); -extern int filter_add_pred(struct ftrace_event_call *call, - struct filter_pred *pred); -extern void filter_free_preds(struct ftrace_event_call *call); -extern int filter_match_preds(struct ftrace_event_call *call, void *rec); -extern void filter_free_subsystem_preds(struct event_subsystem *system); -extern int filter_add_subsystem_pred(struct event_subsystem *system, - struct filter_pred *pred); - void event_trace_printk(unsigned long ip, const char *fmt, ...); extern struct ftrace_event_call __start_ftrace_events[]; extern struct ftrace_event_call __stop_ftrace_events[]; diff --git a/trunk/kernel/trace/trace_clock.c b/trunk/kernel/trace/trace_clock.c index 05b176abfd30..b588fd81f7f9 100644 --- a/trunk/kernel/trace/trace_clock.c +++ b/trunk/kernel/trace/trace_clock.c @@ -18,6 +18,7 @@ #include #include #include +#include /* * trace_clock_local(): the simplest and least coherent tracing clock. diff --git a/trunk/kernel/trace/trace_events.c b/trunk/kernel/trace/trace_events.c index 64ec4d278ffb..3047b56f6637 100644 --- a/trunk/kernel/trace/trace_events.c +++ b/trunk/kernel/trace/trace_events.c @@ -19,39 +19,6 @@ static DEFINE_MUTEX(event_mutex); -int trace_define_field(struct ftrace_event_call *call, char *type, - char *name, int offset, int size) -{ - struct ftrace_event_field *field; - - field = kzalloc(sizeof(*field), GFP_KERNEL); - if (!field) - goto err; - - field->name = kstrdup(name, GFP_KERNEL); - if (!field->name) - goto err; - - field->type = kstrdup(type, GFP_KERNEL); - if (!field->type) - goto err; - - field->offset = offset; - field->size = size; - list_add(&field->link, &call->fields); - - return 0; - -err: - if (field) { - kfree(field->name); - kfree(field->type); - } - kfree(field); - - return -ENOMEM; -} - static void ftrace_clear_events(void) { struct ftrace_event_call *call = (void *)__start_ftrace_events; @@ -376,8 +343,7 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, #undef FIELD #define FIELD(type, name) \ - #type, "common_" #name, offsetof(typeof(field), name), \ - sizeof(field.name) + #type, #name, offsetof(typeof(field), name), sizeof(field.name) static int trace_write_header(struct trace_seq *s) { @@ -464,139 +430,6 @@ event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) return r; } -static ssize_t -event_filter_read(struct file *filp, char __user *ubuf, size_t cnt, - loff_t *ppos) -{ - struct ftrace_event_call *call = filp->private_data; - struct trace_seq *s; - int r; - - if (*ppos) - return 0; - - s = kmalloc(sizeof(*s), GFP_KERNEL); - if (!s) - return -ENOMEM; - - trace_seq_init(s); - - filter_print_preds(call->preds, s); - r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len); - - kfree(s); - - return r; -} - -static ssize_t -event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt, - loff_t *ppos) -{ - struct ftrace_event_call *call = filp->private_data; - char buf[64], *pbuf = buf; - struct filter_pred *pred; - int err; - - if (cnt >= sizeof(buf)) - return -EINVAL; - - if (copy_from_user(&buf, ubuf, cnt)) - return -EFAULT; - - pred = kzalloc(sizeof(*pred), GFP_KERNEL); - if (!pred) - return -ENOMEM; - - err = filter_parse(&pbuf, pred); - if (err < 0) { - filter_free_pred(pred); - return err; - } - - if (pred->clear) { - filter_free_preds(call); - filter_free_pred(pred); - return cnt; - } - - if (filter_add_pred(call, pred)) { - filter_free_pred(pred); - return -EINVAL; - } - - *ppos += cnt; - - return cnt; -} - -static ssize_t -subsystem_filter_read(struct file *filp, char __user *ubuf, size_t cnt, - loff_t *ppos) -{ - struct event_subsystem *system = filp->private_data; - struct trace_seq *s; - int r; - - if (*ppos) - return 0; - - s = kmalloc(sizeof(*s), GFP_KERNEL); - if (!s) - return -ENOMEM; - - trace_seq_init(s); - - filter_print_preds(system->preds, s); - r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len); - - kfree(s); - - return r; -} - -static ssize_t -subsystem_filter_write(struct file *filp, const char __user *ubuf, size_t cnt, - loff_t *ppos) -{ - struct event_subsystem *system = filp->private_data; - char buf[64], *pbuf = buf; - struct filter_pred *pred; - int err; - - if (cnt >= sizeof(buf)) - return -EINVAL; - - if (copy_from_user(&buf, ubuf, cnt)) - return -EFAULT; - - pred = kzalloc(sizeof(*pred), GFP_KERNEL); - if (!pred) - return -ENOMEM; - - err = filter_parse(&pbuf, pred); - if (err < 0) { - filter_free_pred(pred); - return err; - } - - if (pred->clear) { - filter_free_subsystem_preds(system); - filter_free_pred(pred); - return cnt; - } - - if (filter_add_subsystem_pred(system, pred)) { - filter_free_subsystem_preds(system); - filter_free_pred(pred); - return -EINVAL; - } - - *ppos += cnt; - - return cnt; -} - static const struct seq_operations show_event_seq_ops = { .start = t_start, .next = t_next, @@ -642,18 +475,6 @@ static const struct file_operations ftrace_event_id_fops = { .read = event_id_read, }; -static const struct file_operations ftrace_event_filter_fops = { - .open = tracing_open_generic, - .read = event_filter_read, - .write = event_filter_write, -}; - -static const struct file_operations ftrace_subsystem_filter_fops = { - .open = tracing_open_generic, - .read = subsystem_filter_read, - .write = subsystem_filter_write, -}; - static struct dentry *event_trace_events_dir(void) { static struct dentry *d_tracer; @@ -674,6 +495,12 @@ static struct dentry *event_trace_events_dir(void) return d_events; } +struct event_subsystem { + struct list_head list; + const char *name; + struct dentry *entry; +}; + static LIST_HEAD(event_subsystems); static struct dentry * @@ -706,8 +533,6 @@ event_subsystem_dir(const char *name, struct dentry *d_events) system->name = name; list_add(&system->list, &event_subsystems); - system->preds = NULL; - return system->entry; } @@ -756,20 +581,6 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events) call->name); } - if (call->define_fields) { - ret = call->define_fields(); - if (ret < 0) { - pr_warning("Could not initialize trace point" - " events/%s\n", call->name); - return ret; - } - entry = debugfs_create_file("filter", 0644, call->dir, call, - &ftrace_event_filter_fops); - if (!entry) - pr_warning("Could not create debugfs " - "'%s/filter' entry\n", call->name); - } - /* A trace may not want to export its format */ if (!call->show_format) return 0; diff --git a/trunk/kernel/trace/trace_events_filter.c b/trunk/kernel/trace/trace_events_filter.c deleted file mode 100644 index 026be412f356..000000000000 --- a/trunk/kernel/trace/trace_events_filter.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - * trace_events_filter - generic event filtering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright (C) 2009 Tom Zanussi - */ - -#include -#include -#include -#include - -#include "trace.h" -#include "trace_output.h" - -static int filter_pred_64(struct filter_pred *pred, void *event) -{ - u64 *addr = (u64 *)(event + pred->offset); - u64 val = (u64)pred->val; - int match; - - match = (val == *addr) ^ pred->not; - - return match; -} - -static int filter_pred_32(struct filter_pred *pred, void *event) -{ - u32 *addr = (u32 *)(event + pred->offset); - u32 val = (u32)pred->val; - int match; - - match = (val == *addr) ^ pred->not; - - return match; -} - -static int filter_pred_16(struct filter_pred *pred, void *event) -{ - u16 *addr = (u16 *)(event + pred->offset); - u16 val = (u16)pred->val; - int match; - - match = (val == *addr) ^ pred->not; - - return match; -} - -static int filter_pred_8(struct filter_pred *pred, void *event) -{ - u8 *addr = (u8 *)(event + pred->offset); - u8 val = (u8)pred->val; - int match; - - match = (val == *addr) ^ pred->not; - - return match; -} - -static int filter_pred_string(struct filter_pred *pred, void *event) -{ - char *addr = (char *)(event + pred->offset); - int cmp, match; - - cmp = strncmp(addr, pred->str_val, pred->str_len); - - match = (!cmp) ^ pred->not; - - return match; -} - -/* return 1 if event matches, 0 otherwise (discard) */ -int filter_match_preds(struct ftrace_event_call *call, void *rec) -{ - int i, matched, and_failed = 0; - struct filter_pred *pred; - - for (i = 0; i < MAX_FILTER_PRED; i++) { - if (call->preds[i]) { - pred = call->preds[i]; - if (and_failed && !pred->or) - continue; - matched = pred->fn(pred, rec); - if (!matched && !pred->or) { - and_failed = 1; - continue; - } else if (matched && pred->or) - return 1; - } else - break; - } - - if (and_failed) - return 0; - - return 1; -} - -void filter_print_preds(struct filter_pred **preds, struct trace_seq *s) -{ - char *field_name; - struct filter_pred *pred; - int i; - - if (!preds) { - trace_seq_printf(s, "none\n"); - return; - } - - for (i = 0; i < MAX_FILTER_PRED; i++) { - if (preds[i]) { - pred = preds[i]; - field_name = pred->field_name; - if (i) - trace_seq_printf(s, pred->or ? "|| " : "&& "); - trace_seq_printf(s, "%s ", field_name); - trace_seq_printf(s, pred->not ? "!= " : "== "); - if (pred->str_val) - trace_seq_printf(s, "%s\n", pred->str_val); - else - trace_seq_printf(s, "%llu\n", pred->val); - } else - break; - } -} - -static struct ftrace_event_field * -find_event_field(struct ftrace_event_call *call, char *name) -{ - struct ftrace_event_field *field; - - list_for_each_entry(field, &call->fields, link) { - if (!strcmp(field->name, name)) - return field; - } - - return NULL; -} - -void filter_free_pred(struct filter_pred *pred) -{ - if (!pred) - return; - - kfree(pred->field_name); - kfree(pred->str_val); - kfree(pred); -} - -void filter_free_preds(struct ftrace_event_call *call) -{ - int i; - - if (call->preds) { - for (i = 0; i < MAX_FILTER_PRED; i++) - filter_free_pred(call->preds[i]); - kfree(call->preds); - call->preds = NULL; - } -} - -void filter_free_subsystem_preds(struct event_subsystem *system) -{ - struct ftrace_event_call *call = __start_ftrace_events; - int i; - - if (system->preds) { - for (i = 0; i < MAX_FILTER_PRED; i++) - filter_free_pred(system->preds[i]); - kfree(system->preds); - system->preds = NULL; - } - - events_for_each(call) { - if (!call->name || !call->regfunc) - continue; - - if (!strcmp(call->system, system->name)) - filter_free_preds(call); - } -} - -static int __filter_add_pred(struct ftrace_event_call *call, - struct filter_pred *pred) -{ - int i; - - if (call->preds && !pred->compound) - filter_free_preds(call); - - if (!call->preds) { - call->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred), - GFP_KERNEL); - if (!call->preds) - return -ENOMEM; - } - - for (i = 0; i < MAX_FILTER_PRED; i++) { - if (!call->preds[i]) { - call->preds[i] = pred; - return 0; - } - } - - return -ENOMEM; -} - -static int is_string_field(const char *type) -{ - if (strchr(type, '[') && strstr(type, "char")) - return 1; - - return 0; -} - -int filter_add_pred(struct ftrace_event_call *call, struct filter_pred *pred) -{ - struct ftrace_event_field *field; - - field = find_event_field(call, pred->field_name); - if (!field) - return -EINVAL; - - pred->offset = field->offset; - - if (is_string_field(field->type)) { - if (!pred->str_val) - return -EINVAL; - pred->fn = filter_pred_string; - pred->str_len = field->size; - return __filter_add_pred(call, pred); - } else { - if (pred->str_val) - return -EINVAL; - } - - switch (field->size) { - case 8: - pred->fn = filter_pred_64; - break; - case 4: - pred->fn = filter_pred_32; - break; - case 2: - pred->fn = filter_pred_16; - break; - case 1: - pred->fn = filter_pred_8; - break; - default: - return -EINVAL; - } - - return __filter_add_pred(call, pred); -} - -static struct filter_pred *copy_pred(struct filter_pred *pred) -{ - struct filter_pred *new_pred = kmalloc(sizeof(*pred), GFP_KERNEL); - if (!new_pred) - return NULL; - - memcpy(new_pred, pred, sizeof(*pred)); - - if (pred->field_name) { - new_pred->field_name = kstrdup(pred->field_name, GFP_KERNEL); - if (!new_pred->field_name) { - kfree(new_pred); - return NULL; - } - } - - if (pred->str_val) { - new_pred->str_val = kstrdup(pred->str_val, GFP_KERNEL); - if (!new_pred->str_val) { - filter_free_pred(new_pred); - return NULL; - } - } - - return new_pred; -} - -int filter_add_subsystem_pred(struct event_subsystem *system, - struct filter_pred *pred) -{ - struct ftrace_event_call *call = __start_ftrace_events; - struct filter_pred *event_pred; - int i; - - if (system->preds && !pred->compound) - filter_free_subsystem_preds(system); - - if (!system->preds) { - system->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred), - GFP_KERNEL); - if (!system->preds) - return -ENOMEM; - } - - for (i = 0; i < MAX_FILTER_PRED; i++) { - if (!system->preds[i]) { - system->preds[i] = pred; - break; - } - } - - if (i == MAX_FILTER_PRED) - return -EINVAL; - - events_for_each(call) { - int err; - - if (!call->name || !call->regfunc) - continue; - - if (strcmp(call->system, system->name)) - continue; - - if (!find_event_field(call, pred->field_name)) - continue; - - event_pred = copy_pred(pred); - if (!event_pred) - goto oom; - - err = filter_add_pred(call, event_pred); - if (err) - filter_free_pred(event_pred); - if (err == -ENOMEM) - goto oom; - } - - return 0; - -oom: - system->preds[i] = NULL; - return -ENOMEM; -} - -int filter_parse(char **pbuf, struct filter_pred *pred) -{ - char *tmp, *tok, *val_str = NULL; - int tok_n = 0; - - /* field ==/!= number, or/and field ==/!= number, number */ - while ((tok = strsep(pbuf, " \n"))) { - if (tok_n == 0) { - if (!strcmp(tok, "0")) { - pred->clear = 1; - return 0; - } else if (!strcmp(tok, "&&")) { - pred->or = 0; - pred->compound = 1; - } else if (!strcmp(tok, "||")) { - pred->or = 1; - pred->compound = 1; - } else - pred->field_name = tok; - tok_n = 1; - continue; - } - if (tok_n == 1) { - if (!pred->field_name) - pred->field_name = tok; - else if (!strcmp(tok, "!=")) - pred->not = 1; - else if (!strcmp(tok, "==")) - pred->not = 0; - else { - pred->field_name = NULL; - return -EINVAL; - } - tok_n = 2; - continue; - } - if (tok_n == 2) { - if (pred->compound) { - if (!strcmp(tok, "!=")) - pred->not = 1; - else if (!strcmp(tok, "==")) - pred->not = 0; - else { - pred->field_name = NULL; - return -EINVAL; - } - } else { - val_str = tok; - break; /* done */ - } - tok_n = 3; - continue; - } - if (tok_n == 3) { - val_str = tok; - break; /* done */ - } - } - - pred->field_name = kstrdup(pred->field_name, GFP_KERNEL); - if (!pred->field_name) - return -ENOMEM; - - pred->val = simple_strtoull(val_str, &tmp, 10); - if (tmp == val_str) { - pred->str_val = kstrdup(val_str, GFP_KERNEL); - if (!pred->str_val) - return -ENOMEM; - } - - return 0; -} - - diff --git a/trunk/kernel/trace/trace_events_stage_2.h b/trunk/kernel/trace/trace_events_stage_2.h index 30743f7d4110..5117c43f5c67 100644 --- a/trunk/kernel/trace/trace_events_stage_2.h +++ b/trunk/kernel/trace/trace_events_stage_2.h @@ -129,48 +129,3 @@ ftrace_format_##call(struct trace_seq *s) \ } #include - -#undef __field -#define __field(type, item) \ - ret = trace_define_field(event_call, #type, #item, \ - offsetof(typeof(field), item), \ - sizeof(field.item)); \ - if (ret) \ - return ret; - -#undef __array -#define __array(type, item, len) \ - ret = trace_define_field(event_call, #type "[" #len "]", #item, \ - offsetof(typeof(field), item), \ - sizeof(field.item)); \ - if (ret) \ - return ret; - -#define __common_field(type, item) \ - ret = trace_define_field(event_call, #type, "common_" #item, \ - offsetof(typeof(field.ent), item), \ - sizeof(field.ent.item)); \ - if (ret) \ - return ret; - -#undef TRACE_EVENT -#define TRACE_EVENT(call, proto, args, tstruct, func, print) \ -int \ -ftrace_define_fields_##call(void) \ -{ \ - struct ftrace_raw_##call field; \ - struct ftrace_event_call *event_call = &event_##call; \ - int ret; \ - \ - __common_field(unsigned char, type); \ - __common_field(unsigned char, flags); \ - __common_field(unsigned char, preempt_count); \ - __common_field(int, pid); \ - __common_field(int, tgid); \ - \ - tstruct; \ - \ - return ret; \ -} - -#include diff --git a/trunk/kernel/trace/trace_events_stage_3.h b/trunk/kernel/trace/trace_events_stage_3.h index 9d2fa78cecca..6b3261ca988c 100644 --- a/trunk/kernel/trace/trace_events_stage_3.h +++ b/trunk/kernel/trace/trace_events_stage_3.h @@ -204,7 +204,6 @@ static struct ftrace_event_call event_##call; \ \ static void ftrace_raw_event_##call(proto) \ { \ - struct ftrace_event_call *call = &event_##call; \ struct ring_buffer_event *event; \ struct ftrace_raw_##call *entry; \ unsigned long irq_flags; \ @@ -222,11 +221,7 @@ static void ftrace_raw_event_##call(proto) \ \ assign; \ \ - if (call->preds && !filter_match_preds(call, entry)) \ - ring_buffer_event_discard(event); \ - \ - trace_nowake_buffer_unlock_commit(event, irq_flags, pc); \ - \ + trace_current_buffer_unlock_commit(event, irq_flags, pc); \ } \ \ static int ftrace_raw_reg_event_##call(void) \ @@ -257,7 +252,6 @@ static int ftrace_raw_init_event_##call(void) \ if (!id) \ return -ENODEV; \ event_##call.id = id; \ - INIT_LIST_HEAD(&event_##call.fields); \ return 0; \ } \ \ @@ -270,7 +264,6 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ .regfunc = ftrace_raw_reg_event_##call, \ .unregfunc = ftrace_raw_unreg_event_##call, \ .show_format = ftrace_format_##call, \ - .define_fields = ftrace_define_fields_##call, \ _TRACE_PROFILE_INIT(call) \ } diff --git a/trunk/kernel/trace/trace_nop.c b/trunk/kernel/trace/trace_nop.c index 394f94417e2f..9aa84bde23cd 100644 --- a/trunk/kernel/trace/trace_nop.c +++ b/trunk/kernel/trace/trace_nop.c @@ -91,7 +91,6 @@ struct tracer nop_trace __read_mostly = .name = "nop", .init = nop_trace_init, .reset = nop_trace_reset, - .wait_pipe = poll_wait_pipe, #ifdef CONFIG_FTRACE_SELFTEST .selftest = trace_selftest_startup_nop, #endif diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index 05fab3bc5b4b..dfc9e4ea4e8b 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -101,14 +101,6 @@ int randomize_va_space __read_mostly = 2; #endif -/* - * mutex protecting text section modification (dynamic code patching). - * some users need to sleep (allocating memory...) while they hold this lock. - * - * NOT exported to modules - patching kernel text is a really delicate matter. - */ -DEFINE_MUTEX(text_mutex); - static int __init disable_randmaps(char *s) { randomize_va_space = 0;