diff options
author | Steven Rostedt (Red Hat) <srostedt@redhat.com> | 2013-03-02 17:37:14 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2013-03-15 00:34:53 -0400 |
commit | 315326c16ad08771fe0f075a08a18c99976f29f5 (patch) | |
tree | 6ba1483c9f6bbbba061c5de87ddab2263d0b06a4 | |
parent | 34ef61b1fa6172e994e441f1f0241dc53a75bd5f (diff) |
tracing: Fix trace events build without modules
The new multi-buffers added a descriptor that kept track of module
events, and the directories they use, with struct ftace_module_file_ops.
This is used to add a ref count to keep modules from unloading while
their files are being accessed.
As the descriptor is only needed when CONFIG_MODULES is enabled, it
is only declared when the config is enabled. But that struct is
dereferenced in a few areas outside the #ifdef CONFIG_MODULES.
By adding some helper routines and moving code around a little,
events can be compiled again without modules.
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r-- | kernel/trace/trace_events.c | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 63b4bdf84593..0f1307a29fcf 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -1546,9 +1546,18 @@ struct ftrace_module_file_ops { | |||
1546 | struct file_operations filter; | 1546 | struct file_operations filter; |
1547 | }; | 1547 | }; |
1548 | 1548 | ||
1549 | static struct ftrace_module_file_ops *find_ftrace_file_ops(struct module *mod) | 1549 | static struct ftrace_module_file_ops * |
1550 | find_ftrace_file_ops(struct ftrace_module_file_ops *file_ops, struct module *mod) | ||
1550 | { | 1551 | { |
1551 | struct ftrace_module_file_ops *file_ops; | 1552 | /* |
1553 | * As event_calls are added in groups by module, | ||
1554 | * when we find one file_ops, we don't need to search for | ||
1555 | * each call in that module, as the rest should be the | ||
1556 | * same. Only search for a new one if the last one did | ||
1557 | * not match. | ||
1558 | */ | ||
1559 | if (file_ops && mod == file_ops->mod) | ||
1560 | return file_ops; | ||
1552 | 1561 | ||
1553 | list_for_each_entry(file_ops, &ftrace_module_file_list, list) { | 1562 | list_for_each_entry(file_ops, &ftrace_module_file_list, list) { |
1554 | if (file_ops->mod == mod) | 1563 | if (file_ops->mod == mod) |
@@ -1664,16 +1673,35 @@ static int trace_module_notify(struct notifier_block *self, | |||
1664 | 1673 | ||
1665 | return 0; | 1674 | return 0; |
1666 | } | 1675 | } |
1676 | |||
1677 | static int | ||
1678 | __trace_add_new_mod_event(struct ftrace_event_call *call, | ||
1679 | struct trace_array *tr, | ||
1680 | struct ftrace_module_file_ops *file_ops) | ||
1681 | { | ||
1682 | return __trace_add_new_event(call, tr, | ||
1683 | &file_ops->id, &file_ops->enable, | ||
1684 | &file_ops->filter, &file_ops->format); | ||
1685 | } | ||
1686 | |||
1667 | #else | 1687 | #else |
1668 | static struct ftrace_module_file_ops *find_ftrace_file_ops(struct module *mod) | 1688 | static inline struct ftrace_module_file_ops * |
1689 | find_ftrace_file_ops(struct ftrace_module_file_ops *file_ops, struct module *mod) | ||
1669 | { | 1690 | { |
1670 | return NULL; | 1691 | return NULL; |
1671 | } | 1692 | } |
1672 | static int trace_module_notify(struct notifier_block *self, | 1693 | static inline int trace_module_notify(struct notifier_block *self, |
1673 | unsigned long val, void *data) | 1694 | unsigned long val, void *data) |
1674 | { | 1695 | { |
1675 | return 0; | 1696 | return 0; |
1676 | } | 1697 | } |
1698 | static inline int | ||
1699 | __trace_add_new_mod_event(struct ftrace_event_call *call, | ||
1700 | struct trace_array *tr, | ||
1701 | struct ftrace_module_file_ops *file_ops) | ||
1702 | { | ||
1703 | return -ENODEV; | ||
1704 | } | ||
1677 | #endif /* CONFIG_MODULES */ | 1705 | #endif /* CONFIG_MODULES */ |
1678 | 1706 | ||
1679 | /* Create a new event directory structure for a trace directory. */ | 1707 | /* Create a new event directory structure for a trace directory. */ |
@@ -1692,20 +1720,11 @@ __trace_add_event_dirs(struct trace_array *tr) | |||
1692 | * want the module to disappear when reading one | 1720 | * want the module to disappear when reading one |
1693 | * of these files). The file_ops keep account of | 1721 | * of these files). The file_ops keep account of |
1694 | * the module ref count. | 1722 | * the module ref count. |
1695 | * | ||
1696 | * As event_calls are added in groups by module, | ||
1697 | * when we find one file_ops, we don't need to search for | ||
1698 | * each call in that module, as the rest should be the | ||
1699 | * same. Only search for a new one if the last one did | ||
1700 | * not match. | ||
1701 | */ | 1723 | */ |
1702 | if (!file_ops || call->mod != file_ops->mod) | 1724 | file_ops = find_ftrace_file_ops(file_ops, call->mod); |
1703 | file_ops = find_ftrace_file_ops(call->mod); | ||
1704 | if (!file_ops) | 1725 | if (!file_ops) |
1705 | continue; /* Warn? */ | 1726 | continue; /* Warn? */ |
1706 | ret = __trace_add_new_event(call, tr, | 1727 | ret = __trace_add_new_mod_event(call, tr, file_ops); |
1707 | &file_ops->id, &file_ops->enable, | ||
1708 | &file_ops->filter, &file_ops->format); | ||
1709 | if (ret < 0) | 1728 | if (ret < 0) |
1710 | pr_warning("Could not create directory for event %s\n", | 1729 | pr_warning("Could not create directory for event %s\n", |
1711 | call->name); | 1730 | call->name); |
@@ -1794,9 +1813,7 @@ __add_event_to_tracers(struct ftrace_event_call *call, | |||
1794 | 1813 | ||
1795 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { | 1814 | list_for_each_entry(tr, &ftrace_trace_arrays, list) { |
1796 | if (file_ops) | 1815 | if (file_ops) |
1797 | __trace_add_new_event(call, tr, | 1816 | __trace_add_new_mod_event(call, tr, file_ops); |
1798 | &file_ops->id, &file_ops->enable, | ||
1799 | &file_ops->filter, &file_ops->format); | ||
1800 | else | 1817 | else |
1801 | __trace_add_new_event(call, tr, | 1818 | __trace_add_new_event(call, tr, |
1802 | &ftrace_event_id_fops, | 1819 | &ftrace_event_id_fops, |