diff options
| author | Oleg Nesterov <oleg@redhat.com> | 2013-07-26 13:25:32 -0400 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2013-07-29 22:04:30 -0400 |
| commit | 1a11126bcb7c93c289bf3218fa546fd3b0c0df8b (patch) | |
| tree | ffbfb4e73894c00bf674ece92c2531505a877a1b /kernel/trace | |
| parent | 5ae90d8e467e625e447000cb4335c4db973b1095 (diff) | |
tracing: Turn event/id->i_private into call->event.type
event_id_read() is racy, ftrace_event_call can be already freed
by trace_remove_event_call() callers.
Change event_create_dir() to pass "data = call->event.type", this
is all event_id_read() needs. ftrace_event_id_fops no longer needs
tracing_open_generic().
We add the new helper, event_file_data(), to read ->i_private, it
will have more users.
Note: currently ACCESS_ONCE() and "id != 0" check are not needed,
but we are going to change event_remove/rmdir to clear ->i_private.
Link: http://lkml.kernel.org/r/20130726172532.GA3605@redhat.com
Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace')
| -rw-r--r-- | kernel/trace/trace_events.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 898f868833f2..c2d13c528c3c 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
| @@ -409,6 +409,11 @@ static void put_system(struct ftrace_subsystem_dir *dir) | |||
| 409 | mutex_unlock(&event_mutex); | 409 | mutex_unlock(&event_mutex); |
| 410 | } | 410 | } |
| 411 | 411 | ||
| 412 | static void *event_file_data(struct file *filp) | ||
| 413 | { | ||
| 414 | return ACCESS_ONCE(file_inode(filp)->i_private); | ||
| 415 | } | ||
| 416 | |||
| 412 | /* | 417 | /* |
| 413 | * Open and update trace_array ref count. | 418 | * Open and update trace_array ref count. |
| 414 | * Must have the current trace_array passed to it. | 419 | * Must have the current trace_array passed to it. |
| @@ -946,14 +951,18 @@ static int trace_format_open(struct inode *inode, struct file *file) | |||
| 946 | static ssize_t | 951 | static ssize_t |
| 947 | event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) | 952 | event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) |
| 948 | { | 953 | { |
| 949 | struct ftrace_event_call *call = filp->private_data; | 954 | int id = (long)event_file_data(filp); |
| 950 | char buf[32]; | 955 | char buf[32]; |
| 951 | int len; | 956 | int len; |
| 952 | 957 | ||
| 953 | if (*ppos) | 958 | if (*ppos) |
| 954 | return 0; | 959 | return 0; |
| 955 | 960 | ||
| 956 | len = sprintf(buf, "%d\n", call->event.type); | 961 | if (unlikely(!id)) |
| 962 | return -ENODEV; | ||
| 963 | |||
| 964 | len = sprintf(buf, "%d\n", id); | ||
| 965 | |||
| 957 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); | 966 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); |
| 958 | } | 967 | } |
| 959 | 968 | ||
| @@ -1240,7 +1249,6 @@ static const struct file_operations ftrace_event_format_fops = { | |||
| 1240 | }; | 1249 | }; |
| 1241 | 1250 | ||
| 1242 | static const struct file_operations ftrace_event_id_fops = { | 1251 | static const struct file_operations ftrace_event_id_fops = { |
| 1243 | .open = tracing_open_generic, | ||
| 1244 | .read = event_id_read, | 1252 | .read = event_id_read, |
| 1245 | .llseek = default_llseek, | 1253 | .llseek = default_llseek, |
| 1246 | }; | 1254 | }; |
| @@ -1488,8 +1496,8 @@ event_create_dir(struct dentry *parent, | |||
| 1488 | 1496 | ||
| 1489 | #ifdef CONFIG_PERF_EVENTS | 1497 | #ifdef CONFIG_PERF_EVENTS |
| 1490 | if (call->event.type && call->class->reg) | 1498 | if (call->event.type && call->class->reg) |
| 1491 | trace_create_file("id", 0444, file->dir, call, | 1499 | trace_create_file("id", 0444, file->dir, |
| 1492 | id); | 1500 | (void *)(long)call->event.type, id); |
| 1493 | #endif | 1501 | #endif |
| 1494 | 1502 | ||
| 1495 | /* | 1503 | /* |
