* [PATCH 0/5] [GIT PULL] tracing/events: remove TRACE_FORMAT and handle overflow ids
@ 2009-04-25 4:20 Steven Rostedt
2009-04-25 4:20 ` [PATCH 1/5] tracing/lockdep: convert lockdep to use TRACE_EVENT macro Steven Rostedt
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: Steven Rostedt @ 2009-04-25 4:20 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Peter Zijlstra, Frederic Weisbecker,
Li Zefan
Ingo,
This patch series first removes TRACE_FORMAT. It is no longer needed,
and with the new __string feature of TRACE_EVENT (thanks Frederic!)
these formats can be easly converted.
The ending patch (and reason that the TRACE_FORMAT is removed)
is to make the trace event ids reusable. That is, if a module
with a trace point is added and removed more than the number
of events possible (event->type is only 16 bits), it will then
search the list for freed events.
It is very unlikely that a trace event id will exceed the max number,
and before that happens the operation is O(1). But once the max
is exceeded, it is O(n). But this only runs once on module load
so it should not be a cause for alarm.
The last patch is a fix for reference counting of event files used by
modules.
Please pull the latest tip/tracing/ftrace-2 tree, which can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace.git
tip/tracing/ftrace-2
Steven Rostedt (5):
tracing/lockdep: convert lockdep to use TRACE_EVENT macro
tracing/irq: convert irq traces to use TRACE_EVENT macro
tracing: remove deprecated TRACE_FORMAT
tracing/events: reuse trace event ids after overflow
tracing/events: make modules have their own file_operations structure
----
include/linux/ftrace_event.h | 1 +
include/linux/tracepoint.h | 5 --
include/trace/define_trace.h | 4 --
include/trace/events/irq.h | 57 ++++++++++++++++++++----
include/trace/events/lockdep.h | 56 +++++++++++++++++++----
include/trace/ftrace.h | 66 ---------------------------
kernel/trace/trace_events.c | 95 +++++++++++++++++++++++++++++++++++++---
kernel/trace/trace_output.c | 71 +++++++++++++++++++++++++-----
8 files changed, 243 insertions(+), 112 deletions(-)
--
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/5] tracing/lockdep: convert lockdep to use TRACE_EVENT macro
2009-04-25 4:20 [PATCH 0/5] [GIT PULL] tracing/events: remove TRACE_FORMAT and handle overflow ids Steven Rostedt
@ 2009-04-25 4:20 ` Steven Rostedt
2009-04-25 4:20 ` [PATCH 2/5] tracing/irq: convert irq traces " Steven Rostedt
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Steven Rostedt @ 2009-04-25 4:20 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Peter Zijlstra, Frederic Weisbecker,
Li Zefan
[-- Attachment #1: 0001-tracing-lockdep-convert-lockdep-to-use-TRACE_EVENT.patch --]
[-- Type: text/plain, Size: 2212 bytes --]
From: Steven Rostedt <srostedt@redhat.com>
The TRACE_FORMAT will soon be deprecated. This patch converts it to
the TRACE_EVENT macro.
Note, this change should also speed up the tracing.
[ Impact: remove a user of deprecated TRACE_FORMAT ]
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
include/trace/events/lockdep.h | 56 ++++++++++++++++++++++++++++++++-------
1 files changed, 46 insertions(+), 10 deletions(-)
diff --git a/include/trace/events/lockdep.h b/include/trace/events/lockdep.h
index 3ca315c..0e956c9 100644
--- a/include/trace/events/lockdep.h
+++ b/include/trace/events/lockdep.h
@@ -9,28 +9,64 @@
#ifdef CONFIG_LOCKDEP
-TRACE_FORMAT(lock_acquire,
+TRACE_EVENT(lock_acquire,
+
TP_PROTO(struct lockdep_map *lock, unsigned int subclass,
int trylock, int read, int check,
struct lockdep_map *next_lock, unsigned long ip),
+
TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip),
- TP_FMT("%s%s%s", trylock ? "try " : "",
- read ? "read " : "", lock->name)
- );
-TRACE_FORMAT(lock_release,
+ TP_STRUCT__entry(
+ __field(unsigned int, flags)
+ __string(name, lock->name)
+ ),
+
+ TP_fast_assign(
+ __entry->flags = (trylock ? 1 : 0) | (read ? 2 : 0);
+ __assign_str(name, lock->name);
+ ),
+
+ TP_printk("%s%s%s", (__entry->flags & 1) ? "try " : "",
+ (__entry->flags & 2) ? "read " : "",
+ __get_str(name))
+);
+
+TRACE_EVENT(lock_release,
+
TP_PROTO(struct lockdep_map *lock, int nested, unsigned long ip),
+
TP_ARGS(lock, nested, ip),
- TP_FMT("%s", lock->name)
- );
+
+ TP_STRUCT__entry(
+ __string(name, lock->name)
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, lock->name);
+ ),
+
+ TP_printk("%s", __get_str(name))
+);
#ifdef CONFIG_LOCK_STAT
-TRACE_FORMAT(lock_contended,
+TRACE_EVENT(lock_contended,
+
TP_PROTO(struct lockdep_map *lock, unsigned long ip),
+
TP_ARGS(lock, ip),
- TP_FMT("%s", lock->name)
- );
+
+ TP_STRUCT__entry(
+ __string(name, lock->name)
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, lock->name);
+ ),
+
+ TP_printk("%s", __get_str(name))
+);
TRACE_EVENT(lock_acquired,
TP_PROTO(struct lockdep_map *lock, unsigned long ip, s64 waittime),
--
1.6.2.1
--
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/5] tracing/irq: convert irq traces to use TRACE_EVENT macro
2009-04-25 4:20 [PATCH 0/5] [GIT PULL] tracing/events: remove TRACE_FORMAT and handle overflow ids Steven Rostedt
2009-04-25 4:20 ` [PATCH 1/5] tracing/lockdep: convert lockdep to use TRACE_EVENT macro Steven Rostedt
@ 2009-04-25 4:20 ` Steven Rostedt
2009-04-25 4:20 ` [PATCH 3/5] tracing: remove deprecated TRACE_FORMAT Steven Rostedt
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Steven Rostedt @ 2009-04-25 4:20 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Peter Zijlstra, Frederic Weisbecker,
Li Zefan, Jason Baron
[-- Attachment #1: 0002-tracing-irq-convert-irq-traces-to-use-TRACE_EVENT-m.patch --]
[-- Type: text/plain, Size: 2361 bytes --]
From: Steven Rostedt <srostedt@redhat.com>
The TRACE_FORMAT will soon be deprecated. This patch converts it to
the TRACE_EVENT macro.
Note, this change should also speed up the tracing.
[ Impact: remove a user of deprecated TRACE_FORMAT ]
Cc: Jason Baron <jbaron@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
include/trace/events/irq.h | 57 +++++++++++++++++++++++++++++++++++++-------
1 files changed, 48 insertions(+), 9 deletions(-)
diff --git a/include/trace/events/irq.h b/include/trace/events/irq.h
index 75e3468..7686864 100644
--- a/include/trace/events/irq.h
+++ b/include/trace/events/irq.h
@@ -10,11 +10,24 @@
/*
* Tracepoint for entry of interrupt handler:
*/
-TRACE_FORMAT(irq_handler_entry,
+TRACE_EVENT(irq_handler_entry,
+
TP_PROTO(int irq, struct irqaction *action),
+
TP_ARGS(irq, action),
- TP_FMT("irq=%d handler=%s", irq, action->name)
- );
+
+ TP_STRUCT__entry(
+ __field( int, irq )
+ __string( name, action->name )
+ ),
+
+ TP_fast_assign(
+ __entry->irq = irq;
+ __assign_str(name, action->name);
+ ),
+
+ TP_printk("irq=%d handler=%s", __entry->irq, __get_str(name))
+);
/*
* Tracepoint for return of an interrupt handler:
@@ -39,17 +52,43 @@ TRACE_EVENT(irq_handler_exit,
__entry->irq, __entry->ret ? "handled" : "unhandled")
);
-TRACE_FORMAT(softirq_entry,
+TRACE_EVENT(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_STRUCT__entry(
+ __field( int, vec )
+ __string( name, softirq_to_name[h-vec] )
+ ),
+
+ TP_fast_assign(
+ __entry->vec = (int)(h - vec);
+ __assign_str(name, softirq_to_name[h-vec]);
+ ),
+
+ TP_printk("softirq=%d action=%s", __entry->vec, __get_str(name))
+);
+
+TRACE_EVENT(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])
- );
+
+ TP_STRUCT__entry(
+ __field( int, vec )
+ __string( name, softirq_to_name[h-vec] )
+ ),
+
+ TP_fast_assign(
+ __entry->vec = (int)(h - vec);
+ __assign_str(name, softirq_to_name[h-vec]);
+ ),
+
+ TP_printk("softirq=%d action=%s", __entry->vec, __get_str(name))
+);
#endif /* _TRACE_IRQ_H */
--
1.6.2.1
--
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/5] tracing: remove deprecated TRACE_FORMAT
2009-04-25 4:20 [PATCH 0/5] [GIT PULL] tracing/events: remove TRACE_FORMAT and handle overflow ids Steven Rostedt
2009-04-25 4:20 ` [PATCH 1/5] tracing/lockdep: convert lockdep to use TRACE_EVENT macro Steven Rostedt
2009-04-25 4:20 ` [PATCH 2/5] tracing/irq: convert irq traces " Steven Rostedt
@ 2009-04-25 4:20 ` Steven Rostedt
2009-04-25 4:20 ` [PATCH 4/5] tracing/events: reuse trace event ids after overflow Steven Rostedt
2009-04-25 4:20 ` [PATCH 5/5] tracing/events: make modules have their own file_operations structure Steven Rostedt
4 siblings, 0 replies; 8+ messages in thread
From: Steven Rostedt @ 2009-04-25 4:20 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Peter Zijlstra, Frederic Weisbecker,
Li Zefan
[-- Attachment #1: 0003-tracing-remove-deprecated-TRACE_FORMAT.patch --]
[-- Type: text/plain, Size: 4167 bytes --]
From: Steven Rostedt <srostedt@redhat.com>
The TRACE_FORMAT macro has been deprecated by the TRACE_EVENT macro.
There are no more users. All new users must use the TRACE_EVENT macro.
[ Impact: remove old functionality ]
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
include/linux/tracepoint.h | 5 ---
include/trace/define_trace.h | 4 --
include/trace/ftrace.h | 66 ------------------------------------------
3 files changed, 0 insertions(+), 75 deletions(-)
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index 4353f3f..14df7e6 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -158,11 +158,6 @@ static inline void tracepoint_synchronize_unregister(void)
#define PARAMS(args...) args
-#ifndef TRACE_FORMAT
-#define TRACE_FORMAT(name, proto, args, fmt) \
- DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
-#endif
-
#ifndef TRACE_EVENT
/*
* For use with the TRACE_EVENT macro:
diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h
index abc611f..f7a7ae1 100644
--- a/include/trace/define_trace.h
+++ b/include/trace/define_trace.h
@@ -26,10 +26,6 @@
#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
DEFINE_TRACE(name)
-#undef TRACE_FORMAT
-#define TRACE_FORMAT(name, proto, args, print) \
- DEFINE_TRACE(name)
-
#undef DECLARE_TRACE
#define DECLARE_TRACE(name, proto, args) \
DEFINE_TRACE(name)
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index a77f71a..1e68114 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -18,9 +18,6 @@
#include <linux/ftrace_event.h>
-#undef TRACE_FORMAT
-#define TRACE_FORMAT(call, proto, args, fmt)
-
#undef __array
#define __array(type, item, len) type item[len];
@@ -62,9 +59,6 @@
*
*/
-#undef TRACE_FORMAT
-#define TRACE_FORMAT(call, proto, args, fmt)
-
#undef __array
#define __array(type, item, len)
@@ -298,16 +292,6 @@ ftrace_define_fields_##call(void) \
* unregister_trace_<call>(ftrace_event_<call>);
* }
*
- * For those macros defined with TRACE_FORMAT:
- *
- * static struct ftrace_event_call __used
- * __attribute__((__aligned__(4)))
- * __attribute__((section("_ftrace_events"))) event_<call> = {
- * .name = "<call>",
- * .regfunc = ftrace_reg_event_<call>,
- * .unregfunc = ftrace_unreg_event_<call>,
- * }
- *
*
* For those macros defined with TRACE_EVENT:
*
@@ -417,56 +401,6 @@ static void ftrace_profile_disable_##call(struct ftrace_event_call *call) \
#define _TRACE_PROFILE_INIT(call)
#endif
-#define _TRACE_FORMAT(call, proto, args, fmt) \
-static void ftrace_event_##call(proto) \
-{ \
- event_trace_printk(_RET_IP_, #call ": " fmt); \
-} \
- \
-static int ftrace_reg_event_##call(void) \
-{ \
- int ret; \
- \
- ret = register_trace_##call(ftrace_event_##call); \
- if (ret) \
- pr_info("event trace: Could not activate trace point " \
- "probe to " #call "\n"); \
- return ret; \
-} \
- \
-static void ftrace_unreg_event_##call(void) \
-{ \
- unregister_trace_##call(ftrace_event_##call); \
-} \
- \
-static struct ftrace_event_call event_##call; \
- \
-static int ftrace_init_event_##call(void) \
-{ \
- int id; \
- \
- id = register_ftrace_event(NULL); \
- if (!id) \
- return -ENODEV; \
- event_##call.id = id; \
- return 0; \
-}
-
-#undef TRACE_FORMAT
-#define TRACE_FORMAT(call, proto, args, fmt) \
-_TRACE_FORMAT(call, PARAMS(proto), PARAMS(args), PARAMS(fmt)) \
-_TRACE_PROFILE(call, PARAMS(proto), PARAMS(args)) \
-static struct ftrace_event_call __used \
-__attribute__((__aligned__(4))) \
-__attribute__((section("_ftrace_events"))) event_##call = { \
- .name = #call, \
- .system = __stringify(TRACE_SYSTEM), \
- .raw_init = ftrace_init_event_##call, \
- .regfunc = ftrace_reg_event_##call, \
- .unregfunc = ftrace_unreg_event_##call, \
- _TRACE_PROFILE_INIT(call) \
-}
-
#undef __entry
#define __entry entry
--
1.6.2.1
--
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/5] tracing/events: reuse trace event ids after overflow
2009-04-25 4:20 [PATCH 0/5] [GIT PULL] tracing/events: remove TRACE_FORMAT and handle overflow ids Steven Rostedt
` (2 preceding siblings ...)
2009-04-25 4:20 ` [PATCH 3/5] tracing: remove deprecated TRACE_FORMAT Steven Rostedt
@ 2009-04-25 4:20 ` Steven Rostedt
2009-04-25 4:20 ` [PATCH 5/5] tracing/events: make modules have their own file_operations structure Steven Rostedt
4 siblings, 0 replies; 8+ messages in thread
From: Steven Rostedt @ 2009-04-25 4:20 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Peter Zijlstra, Frederic Weisbecker,
Li Zefan
[-- Attachment #1: 0004-tracing-events-reuse-trace-event-ids-after-overflow.patch --]
[-- Type: text/plain, Size: 3703 bytes --]
From: Steven Rostedt <srostedt@redhat.com>
With modules being able to add trace events, and the max trace event
counter is 16 bits (65536) we can overflow the counter easily
with a simple while loop adding and removing modules that contain
trace events.
This patch links together the registered trace events and on overflow
searches for available trace event ids. It will still fail if
over 65536 events are registered, but considering that a typical
kernel only has 22000 functions, 65000 events should be sufficient.
Reported-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
include/linux/ftrace_event.h | 1 +
kernel/trace/trace_output.c | 71 +++++++++++++++++++++++++++++++++++------
2 files changed, 61 insertions(+), 11 deletions(-)
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index 07e0a6d..78a9ba2 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -56,6 +56,7 @@ typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter,
int flags);
struct trace_event {
struct hlist_node node;
+ struct list_head list;
int type;
trace_print_func trace;
trace_print_func raw;
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index 06997e7..5fc51f0 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -483,6 +483,36 @@ struct trace_event *ftrace_find_event(int type)
return NULL;
}
+static LIST_HEAD(ftrace_event_list);
+
+static int trace_search_list(struct list_head **list)
+{
+ struct trace_event *e;
+ int last = __TRACE_LAST_TYPE;
+
+ if (list_empty(&ftrace_event_list)) {
+ *list = &ftrace_event_list;
+ return last + 1;
+ }
+
+ /*
+ * We used up all possible max events,
+ * lets see if somebody freed one.
+ */
+ list_for_each_entry(e, &ftrace_event_list, list) {
+ if (e->type != last + 1)
+ break;
+ last++;
+ }
+
+ /* Did we used up all 65 thousand events??? */
+ if ((last + 1) > FTRACE_MAX_EVENT)
+ return 0;
+
+ *list = &e->list;
+ return last + 1;
+}
+
/**
* register_ftrace_event - register output for an event type
* @event: the event type to register
@@ -505,20 +535,40 @@ int register_ftrace_event(struct trace_event *event)
mutex_lock(&trace_event_mutex);
- if (!event) {
- ret = next_event_type++;
+ if (WARN_ON(!event))
goto out;
- }
- if (!event->type)
- event->type = next_event_type++;
- else if (event->type > __TRACE_LAST_TYPE) {
+ INIT_LIST_HEAD(&event->list);
+
+ if (!event->type) {
+ struct list_head *list;
+
+ if (next_event_type > FTRACE_MAX_EVENT) {
+
+ event->type = trace_search_list(&list);
+ if (!event->type)
+ goto out;
+
+ } else {
+
+ event->type = next_event_type++;
+ list = &ftrace_event_list;
+ }
+
+ if (WARN_ON(ftrace_find_event(event->type)))
+ goto out;
+
+ list_add_tail(&event->list, list);
+
+ } else if (event->type > __TRACE_LAST_TYPE) {
printk(KERN_WARNING "Need to add type to trace.h\n");
WARN_ON(1);
- }
-
- if (ftrace_find_event(event->type))
goto out;
+ } else {
+ /* Is this event already used */
+ if (ftrace_find_event(event->type))
+ goto out;
+ }
if (event->trace == NULL)
event->trace = trace_nop_print;
@@ -537,8 +587,6 @@ int register_ftrace_event(struct trace_event *event)
out:
mutex_unlock(&trace_event_mutex);
- WARN_ON_ONCE(next_event_type > FTRACE_MAX_EVENT);
-
return ret;
}
EXPORT_SYMBOL_GPL(register_ftrace_event);
@@ -551,6 +599,7 @@ int unregister_ftrace_event(struct trace_event *event)
{
mutex_lock(&trace_event_mutex);
hlist_del(&event->node);
+ list_del(&event->list);
mutex_unlock(&trace_event_mutex);
return 0;
--
1.6.2.1
--
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5/5] tracing/events: make modules have their own file_operations structure
2009-04-25 4:20 [PATCH 0/5] [GIT PULL] tracing/events: remove TRACE_FORMAT and handle overflow ids Steven Rostedt
` (3 preceding siblings ...)
2009-04-25 4:20 ` [PATCH 4/5] tracing/events: reuse trace event ids after overflow Steven Rostedt
@ 2009-04-25 4:20 ` Steven Rostedt
2009-04-25 17:26 ` Greg KH
4 siblings, 1 reply; 8+ messages in thread
From: Steven Rostedt @ 2009-04-25 4:20 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Peter Zijlstra, Frederic Weisbecker,
Li Zefan, Greg KH
[-- Attachment #1: 0005-tracing-events-make-modules-have-their-own-file_ope.patch --]
[-- Type: text/plain, Size: 5588 bytes --]
From: Steven Rostedt <srostedt@redhat.com>
For proper module reference counting, the file_operations that modules use
must have the "owner" field set to the module. Unfortunately, the trace events
use share file_operations. The same file_operations are used by all both
kernel core and all modules.
This patch makes the modules allocate their own file_operations and
copies the functions from the core kernel. This allows those file
operations to be owned by the module.
Care is taken to free this code on module unload.
Thanks to Greg KH for reminding me that file_operations must be owned
by the module to have reference counting take place.
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
kernel/trace/trace_events.c | 95 +++++++++++++++++++++++++++++++++++++++---
1 files changed, 88 insertions(+), 7 deletions(-)
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index b920815..be4d3a4 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -770,7 +770,11 @@ event_subsystem_dir(const char *name, struct dentry *d_events)
}
static int
-event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
+event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
+ const struct file_operations *id,
+ const struct file_operations *enable,
+ const struct file_operations *filter,
+ const struct file_operations *format)
{
struct dentry *entry;
int ret;
@@ -800,11 +804,11 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
if (call->regfunc)
entry = trace_create_file("enable", 0644, call->dir, call,
- &ftrace_enable_fops);
+ enable);
if (call->id)
entry = trace_create_file("id", 0444, call->dir, call,
- &ftrace_event_id_fops);
+ id);
if (call->define_fields) {
ret = call->define_fields();
@@ -814,7 +818,7 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
return ret;
}
entry = trace_create_file("filter", 0644, call->dir, call,
- &ftrace_event_filter_fops);
+ filter);
}
/* A trace may not want to export its format */
@@ -822,7 +826,7 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
return 0;
entry = trace_create_file("format", 0444, call->dir, call,
- &ftrace_event_format_fops);
+ format);
return 0;
}
@@ -833,8 +837,60 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
event++)
#ifdef CONFIG_MODULES
+
+static LIST_HEAD(ftrace_module_file_list);
+
+/*
+ * Modules must own their file_operations to keep up with
+ * reference counting.
+ */
+struct ftrace_module_file_ops {
+ struct list_head list;
+ struct module *mod;
+ struct file_operations id;
+ struct file_operations enable;
+ struct file_operations format;
+ struct file_operations filter;
+};
+
+static struct ftrace_module_file_ops *
+trace_create_file_ops(struct module *mod)
+{
+ struct ftrace_module_file_ops *file_ops;
+
+ /*
+ * This is a bit of a PITA. To allow for correct reference
+ * counting, modules must "own" their file_operations.
+ * To do this, we allocate the file operations that will be
+ * used in the event directory.
+ */
+
+ file_ops = kmalloc(sizeof(*file_ops), GFP_KERNEL);
+ if (!file_ops)
+ return NULL;
+
+ file_ops->mod = mod;
+
+ file_ops->id = ftrace_event_id_fops;
+ file_ops->id.owner = mod;
+
+ file_ops->enable = ftrace_enable_fops;
+ file_ops->enable.owner = mod;
+
+ file_ops->filter = ftrace_event_filter_fops;
+ file_ops->filter.owner = mod;
+
+ file_ops->format = ftrace_event_format_fops;
+ file_ops->format.owner = mod;
+
+ list_add(&file_ops->list, &ftrace_module_file_list);
+
+ return file_ops;
+}
+
static void trace_module_add_events(struct module *mod)
{
+ struct ftrace_module_file_ops *file_ops = NULL;
struct ftrace_event_call *call, *start, *end;
struct dentry *d_events;
@@ -852,14 +908,27 @@ static void trace_module_add_events(struct module *mod)
/* The linker may leave blanks */
if (!call->name)
continue;
+
+ /*
+ * This module has events, create file ops for this module
+ * if not already done.
+ */
+ if (!file_ops) {
+ file_ops = trace_create_file_ops(mod);
+ if (!file_ops)
+ return;
+ }
call->mod = mod;
list_add(&call->list, &ftrace_events);
- event_create_dir(call, d_events);
+ event_create_dir(call, d_events,
+ &file_ops->id, &file_ops->enable,
+ &file_ops->filter, &file_ops->format);
}
}
static void trace_module_remove_events(struct module *mod)
{
+ struct ftrace_module_file_ops *file_ops;
struct ftrace_event_call *call, *p;
list_for_each_entry_safe(call, p, &ftrace_events, list) {
@@ -874,6 +943,16 @@ static void trace_module_remove_events(struct module *mod)
list_del(&call->list);
}
}
+
+ /* Now free the file_operations */
+ list_for_each_entry(file_ops, &ftrace_module_file_list, list) {
+ if (file_ops->mod == mod)
+ break;
+ }
+ if (&file_ops->list != &ftrace_module_file_list) {
+ list_del(&file_ops->list);
+ kfree(file_ops);
+ }
}
static int trace_module_notify(struct notifier_block *self,
@@ -954,7 +1033,9 @@ static __init int event_trace_init(void)
if (!call->name)
continue;
list_add(&call->list, &ftrace_events);
- event_create_dir(call, d_events);
+ event_create_dir(call, d_events, &ftrace_event_id_fops,
+ &ftrace_enable_fops, &ftrace_event_filter_fops,
+ &ftrace_event_format_fops);
}
ret = register_module_notifier(&trace_module_nb);
--
1.6.2.1
--
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 5/5] tracing/events: make modules have their own file_operations structure
2009-04-25 4:20 ` [PATCH 5/5] tracing/events: make modules have their own file_operations structure Steven Rostedt
@ 2009-04-25 17:26 ` Greg KH
2009-04-26 11:05 ` Ingo Molnar
0 siblings, 1 reply; 8+ messages in thread
From: Greg KH @ 2009-04-25 17:26 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-kernel, Ingo Molnar, Andrew Morton, Peter Zijlstra,
Frederic Weisbecker, Li Zefan
On Sat, Apr 25, 2009 at 12:20:35AM -0400, Steven Rostedt wrote:
> From: Steven Rostedt <srostedt@redhat.com>
>
> For proper module reference counting, the file_operations that modules use
> must have the "owner" field set to the module. Unfortunately, the trace events
> use share file_operations. The same file_operations are used by all both
> kernel core and all modules.
>
> This patch makes the modules allocate their own file_operations and
> copies the functions from the core kernel. This allows those file
> operations to be owned by the module.
>
> Care is taken to free this code on module unload.
>
> Thanks to Greg KH for reminding me that file_operations must be owned
> by the module to have reference counting take place.
>
> Cc: Greg KH <greg@kroah.com>
> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Looks good, feel free to add an:
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
to it.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 5/5] tracing/events: make modules have their own file_operations structure
2009-04-25 17:26 ` Greg KH
@ 2009-04-26 11:05 ` Ingo Molnar
0 siblings, 0 replies; 8+ messages in thread
From: Ingo Molnar @ 2009-04-26 11:05 UTC (permalink / raw)
To: Greg KH
Cc: Steven Rostedt, linux-kernel, Andrew Morton, Peter Zijlstra,
Frederic Weisbecker, Li Zefan
* Greg KH <greg@kroah.com> wrote:
> On Sat, Apr 25, 2009 at 12:20:35AM -0400, Steven Rostedt wrote:
> > From: Steven Rostedt <srostedt@redhat.com>
> >
> > For proper module reference counting, the file_operations that modules use
> > must have the "owner" field set to the module. Unfortunately, the trace events
> > use share file_operations. The same file_operations are used by all both
> > kernel core and all modules.
> >
> > This patch makes the modules allocate their own file_operations and
> > copies the functions from the core kernel. This allows those file
> > operations to be owned by the module.
> >
> > Care is taken to free this code on module unload.
> >
> > Thanks to Greg KH for reminding me that file_operations must be owned
> > by the module to have reference counting take place.
> >
> > Cc: Greg KH <greg@kroah.com>
> > Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
>
> Looks good, feel free to add an:
> Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
> to it.
I've amended the final commit with your ack - thanks guys!
Ingo
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-04-26 11:06 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-25 4:20 [PATCH 0/5] [GIT PULL] tracing/events: remove TRACE_FORMAT and handle overflow ids Steven Rostedt
2009-04-25 4:20 ` [PATCH 1/5] tracing/lockdep: convert lockdep to use TRACE_EVENT macro Steven Rostedt
2009-04-25 4:20 ` [PATCH 2/5] tracing/irq: convert irq traces " Steven Rostedt
2009-04-25 4:20 ` [PATCH 3/5] tracing: remove deprecated TRACE_FORMAT Steven Rostedt
2009-04-25 4:20 ` [PATCH 4/5] tracing/events: reuse trace event ids after overflow Steven Rostedt
2009-04-25 4:20 ` [PATCH 5/5] tracing/events: make modules have their own file_operations structure Steven Rostedt
2009-04-25 17:26 ` Greg KH
2009-04-26 11:05 ` Ingo Molnar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox