|
@@ -27,8 +27,8 @@ DEFINE_MUTEX(event_mutex);
|
|
|
|
|
|
LIST_HEAD(ftrace_events);
|
|
LIST_HEAD(ftrace_events);
|
|
|
|
|
|
-int trace_define_field(struct ftrace_event_call *call, const char *type,
|
|
|
|
- const char *name, int offset, int size, int is_signed,
|
|
|
|
|
|
+int trace_define_field(struct ftrace_event_call *call, char *type,
|
|
|
|
+ char *name, int offset, int size, int is_signed,
|
|
int filter_type)
|
|
int filter_type)
|
|
{
|
|
{
|
|
struct ftrace_event_field *field;
|
|
struct ftrace_event_field *field;
|
|
@@ -92,9 +92,7 @@ int trace_define_common_fields(struct ftrace_event_call *call)
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(trace_define_common_fields);
|
|
EXPORT_SYMBOL_GPL(trace_define_common_fields);
|
|
|
|
|
|
-#ifdef CONFIG_MODULES
|
|
|
|
-
|
|
|
|
-static void trace_destroy_fields(struct ftrace_event_call *call)
|
|
|
|
|
|
+void trace_destroy_fields(struct ftrace_event_call *call)
|
|
{
|
|
{
|
|
struct ftrace_event_field *field, *next;
|
|
struct ftrace_event_field *field, *next;
|
|
|
|
|
|
@@ -106,8 +104,6 @@ static void trace_destroy_fields(struct ftrace_event_call *call)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-#endif /* CONFIG_MODULES */
|
|
|
|
-
|
|
|
|
static void ftrace_event_enable_disable(struct ftrace_event_call *call,
|
|
static void ftrace_event_enable_disable(struct ftrace_event_call *call,
|
|
int enable)
|
|
int enable)
|
|
{
|
|
{
|
|
@@ -116,14 +112,14 @@ static void ftrace_event_enable_disable(struct ftrace_event_call *call,
|
|
if (call->enabled) {
|
|
if (call->enabled) {
|
|
call->enabled = 0;
|
|
call->enabled = 0;
|
|
tracing_stop_cmdline_record();
|
|
tracing_stop_cmdline_record();
|
|
- call->unregfunc(call->data);
|
|
|
|
|
|
+ call->unregfunc(call);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case 1:
|
|
case 1:
|
|
if (!call->enabled) {
|
|
if (!call->enabled) {
|
|
call->enabled = 1;
|
|
call->enabled = 1;
|
|
tracing_start_cmdline_record();
|
|
tracing_start_cmdline_record();
|
|
- call->regfunc(call->data);
|
|
|
|
|
|
+ call->regfunc(call);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -991,27 +987,43 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-#define for_each_event(event, start, end) \
|
|
|
|
- for (event = start; \
|
|
|
|
- (unsigned long)event < (unsigned long)end; \
|
|
|
|
- event++)
|
|
|
|
|
|
+static int __trace_add_event_call(struct ftrace_event_call *call)
|
|
|
|
+{
|
|
|
|
+ struct dentry *d_events;
|
|
|
|
+ int ret;
|
|
|
|
|
|
-#ifdef CONFIG_MODULES
|
|
|
|
|
|
+ if (!call->name)
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
-static LIST_HEAD(ftrace_module_file_list);
|
|
|
|
|
|
+ if (call->raw_init) {
|
|
|
|
+ ret = call->raw_init(call);
|
|
|
|
+ if (ret < 0) {
|
|
|
|
+ if (ret != -ENOSYS)
|
|
|
|
+ pr_warning("Could not initialize trace "
|
|
|
|
+ "events/%s\n", call->name);
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
-/*
|
|
|
|
- * 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;
|
|
|
|
-};
|
|
|
|
|
|
+ d_events = event_trace_events_dir();
|
|
|
|
+ if (!d_events)
|
|
|
|
+ return -ENOENT;
|
|
|
|
+
|
|
|
|
+ list_add(&call->list, &ftrace_events);
|
|
|
|
+ return event_create_dir(call, d_events, &ftrace_event_id_fops,
|
|
|
|
+ &ftrace_enable_fops, &ftrace_event_filter_fops,
|
|
|
|
+ &ftrace_event_format_fops);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* Add an additional event_call dynamically */
|
|
|
|
+int trace_add_event_call(struct ftrace_event_call *call)
|
|
|
|
+{
|
|
|
|
+ int ret;
|
|
|
|
+ mutex_lock(&event_mutex);
|
|
|
|
+ ret = __trace_add_event_call(call);
|
|
|
|
+ mutex_unlock(&event_mutex);
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
|
|
static void remove_subsystem_dir(const char *name)
|
|
static void remove_subsystem_dir(const char *name)
|
|
{
|
|
{
|
|
@@ -1039,6 +1051,48 @@ static void remove_subsystem_dir(const char *name)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void __trace_remove_event_call(struct ftrace_event_call *call)
|
|
|
|
+{
|
|
|
|
+ ftrace_event_enable_disable(call, 0);
|
|
|
|
+ if (call->event)
|
|
|
|
+ __unregister_ftrace_event(call->event);
|
|
|
|
+ debugfs_remove_recursive(call->dir);
|
|
|
|
+ list_del(&call->list);
|
|
|
|
+ trace_destroy_fields(call);
|
|
|
|
+ destroy_preds(call);
|
|
|
|
+ remove_subsystem_dir(call->system);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* Remove an event_call */
|
|
|
|
+void trace_remove_event_call(struct ftrace_event_call *call)
|
|
|
|
+{
|
|
|
|
+ mutex_lock(&event_mutex);
|
|
|
|
+ __trace_remove_event_call(call);
|
|
|
|
+ mutex_unlock(&event_mutex);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#define for_each_event(event, start, end) \
|
|
|
|
+ for (event = start; \
|
|
|
|
+ (unsigned long)event < (unsigned long)end; \
|
|
|
|
+ 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 *
|
|
static struct ftrace_module_file_ops *
|
|
trace_create_file_ops(struct module *mod)
|
|
trace_create_file_ops(struct module *mod)
|
|
{
|
|
{
|
|
@@ -1096,7 +1150,7 @@ static void trace_module_add_events(struct module *mod)
|
|
if (!call->name)
|
|
if (!call->name)
|
|
continue;
|
|
continue;
|
|
if (call->raw_init) {
|
|
if (call->raw_init) {
|
|
- ret = call->raw_init();
|
|
|
|
|
|
+ ret = call->raw_init(call);
|
|
if (ret < 0) {
|
|
if (ret < 0) {
|
|
if (ret != -ENOSYS)
|
|
if (ret != -ENOSYS)
|
|
pr_warning("Could not initialize trace "
|
|
pr_warning("Could not initialize trace "
|
|
@@ -1131,14 +1185,7 @@ static void trace_module_remove_events(struct module *mod)
|
|
list_for_each_entry_safe(call, p, &ftrace_events, list) {
|
|
list_for_each_entry_safe(call, p, &ftrace_events, list) {
|
|
if (call->mod == mod) {
|
|
if (call->mod == mod) {
|
|
found = true;
|
|
found = true;
|
|
- ftrace_event_enable_disable(call, 0);
|
|
|
|
- if (call->event)
|
|
|
|
- __unregister_ftrace_event(call->event);
|
|
|
|
- debugfs_remove_recursive(call->dir);
|
|
|
|
- list_del(&call->list);
|
|
|
|
- trace_destroy_fields(call);
|
|
|
|
- destroy_preds(call);
|
|
|
|
- remove_subsystem_dir(call->system);
|
|
|
|
|
|
+ __trace_remove_event_call(call);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1256,7 +1303,7 @@ static __init int event_trace_init(void)
|
|
if (!call->name)
|
|
if (!call->name)
|
|
continue;
|
|
continue;
|
|
if (call->raw_init) {
|
|
if (call->raw_init) {
|
|
- ret = call->raw_init();
|
|
|
|
|
|
+ ret = call->raw_init(call);
|
|
if (ret < 0) {
|
|
if (ret < 0) {
|
|
if (ret != -ENOSYS)
|
|
if (ret != -ENOSYS)
|
|
pr_warning("Could not initialize trace "
|
|
pr_warning("Could not initialize trace "
|