|
@@ -4999,8 +4999,8 @@ SYSCALL_DEFINE5(perf_event_open,
|
|
struct perf_event_context *ctx;
|
|
struct perf_event_context *ctx;
|
|
struct file *event_file = NULL;
|
|
struct file *event_file = NULL;
|
|
struct file *group_file = NULL;
|
|
struct file *group_file = NULL;
|
|
|
|
+ int event_fd;
|
|
int fput_needed = 0;
|
|
int fput_needed = 0;
|
|
- int fput_needed2 = 0;
|
|
|
|
int err;
|
|
int err;
|
|
|
|
|
|
/* for future expandability... */
|
|
/* for future expandability... */
|
|
@@ -5021,12 +5021,18 @@ SYSCALL_DEFINE5(perf_event_open,
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ event_fd = get_unused_fd_flags(O_RDWR);
|
|
|
|
+ if (event_fd < 0)
|
|
|
|
+ return event_fd;
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Get the target context (task or percpu):
|
|
* Get the target context (task or percpu):
|
|
*/
|
|
*/
|
|
ctx = find_get_context(pid, cpu);
|
|
ctx = find_get_context(pid, cpu);
|
|
- if (IS_ERR(ctx))
|
|
|
|
- return PTR_ERR(ctx);
|
|
|
|
|
|
+ if (IS_ERR(ctx)) {
|
|
|
|
+ err = PTR_ERR(ctx);
|
|
|
|
+ goto err_fd;
|
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
/*
|
|
* Look up the group leader (we will attach this event to it):
|
|
* Look up the group leader (we will attach this event to it):
|
|
@@ -5066,13 +5072,11 @@ SYSCALL_DEFINE5(perf_event_open,
|
|
if (IS_ERR(event))
|
|
if (IS_ERR(event))
|
|
goto err_put_context;
|
|
goto err_put_context;
|
|
|
|
|
|
- err = anon_inode_getfd("[perf_event]", &perf_fops, event, O_RDWR);
|
|
|
|
- if (err < 0)
|
|
|
|
- goto err_free_put_context;
|
|
|
|
-
|
|
|
|
- event_file = fget_light(err, &fput_needed2);
|
|
|
|
- if (!event_file)
|
|
|
|
|
|
+ event_file = anon_inode_getfile("[perf_event]", &perf_fops, event, O_RDWR);
|
|
|
|
+ if (IS_ERR(event_file)) {
|
|
|
|
+ err = PTR_ERR(event_file);
|
|
goto err_free_put_context;
|
|
goto err_free_put_context;
|
|
|
|
+ }
|
|
|
|
|
|
if (flags & PERF_FLAG_FD_OUTPUT) {
|
|
if (flags & PERF_FLAG_FD_OUTPUT) {
|
|
err = perf_event_set_output(event, group_fd);
|
|
err = perf_event_set_output(event, group_fd);
|
|
@@ -5093,19 +5097,19 @@ SYSCALL_DEFINE5(perf_event_open,
|
|
list_add_tail(&event->owner_entry, ¤t->perf_event_list);
|
|
list_add_tail(&event->owner_entry, ¤t->perf_event_list);
|
|
mutex_unlock(¤t->perf_event_mutex);
|
|
mutex_unlock(¤t->perf_event_mutex);
|
|
|
|
|
|
-err_fput_free_put_context:
|
|
|
|
- fput_light(event_file, fput_needed2);
|
|
|
|
|
|
+ fput_light(group_file, fput_needed);
|
|
|
|
+ fd_install(event_fd, event_file);
|
|
|
|
+ return event_fd;
|
|
|
|
|
|
|
|
+err_fput_free_put_context:
|
|
|
|
+ fput(event_file);
|
|
err_free_put_context:
|
|
err_free_put_context:
|
|
- if (err < 0)
|
|
|
|
- free_event(event);
|
|
|
|
-
|
|
|
|
|
|
+ free_event(event);
|
|
err_put_context:
|
|
err_put_context:
|
|
- if (err < 0)
|
|
|
|
- put_ctx(ctx);
|
|
|
|
-
|
|
|
|
fput_light(group_file, fput_needed);
|
|
fput_light(group_file, fput_needed);
|
|
-
|
|
|
|
|
|
+ put_ctx(ctx);
|
|
|
|
+err_fd:
|
|
|
|
+ put_unused_fd(event_fd);
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|