aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/perf_counter.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-09-03 12:03:00 -0400
committerIngo Molnar <mingo@elte.hu>2009-09-03 12:46:23 -0400
commitdc86cabe4b242446ea9aa8492c727e1220817898 (patch)
treeeace3c21e20231d6f6359a223941efa419a82ea4 /kernel/perf_counter.c
parent6f4596d9312ba5fbf5f3231ef484823c4e684d2e (diff)
perf_counter: Fix output-sharing error path
We forget to release the fd in the PERF_FLAG_FD_OUTPUT error path. Reorganize the error flow here to be a clean fall-through logic. Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/perf_counter.c')
-rw-r--r--kernel/perf_counter.c40
1 files changed, 20 insertions, 20 deletions
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index 0aa609f69103..e0d91fdf0c3c 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -4316,15 +4316,15 @@ SYSCALL_DEFINE5(perf_counter_open,
4316 struct file *group_file = NULL; 4316 struct file *group_file = NULL;
4317 int fput_needed = 0; 4317 int fput_needed = 0;
4318 int fput_needed2 = 0; 4318 int fput_needed2 = 0;
4319 int ret; 4319 int err;
4320 4320
4321 /* for future expandability... */ 4321 /* for future expandability... */
4322 if (flags & ~(PERF_FLAG_FD_NO_GROUP | PERF_FLAG_FD_OUTPUT)) 4322 if (flags & ~(PERF_FLAG_FD_NO_GROUP | PERF_FLAG_FD_OUTPUT))
4323 return -EINVAL; 4323 return -EINVAL;
4324 4324
4325 ret = perf_copy_attr(attr_uptr, &attr); 4325 err = perf_copy_attr(attr_uptr, &attr);
4326 if (ret) 4326 if (err)
4327 return ret; 4327 return err;
4328 4328
4329 if (!attr.exclude_kernel) { 4329 if (!attr.exclude_kernel) {
4330 if (perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN)) 4330 if (perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN))
@@ -4348,7 +4348,7 @@ SYSCALL_DEFINE5(perf_counter_open,
4348 */ 4348 */
4349 group_leader = NULL; 4349 group_leader = NULL;
4350 if (group_fd != -1 && !(flags & PERF_FLAG_FD_NO_GROUP)) { 4350 if (group_fd != -1 && !(flags & PERF_FLAG_FD_NO_GROUP)) {
4351 ret = -EINVAL; 4351 err = -EINVAL;
4352 group_file = fget_light(group_fd, &fput_needed); 4352 group_file = fget_light(group_fd, &fput_needed);
4353 if (!group_file) 4353 if (!group_file)
4354 goto err_put_context; 4354 goto err_put_context;
@@ -4377,22 +4377,22 @@ SYSCALL_DEFINE5(perf_counter_open,
4377 4377
4378 counter = perf_counter_alloc(&attr, cpu, ctx, group_leader, 4378 counter = perf_counter_alloc(&attr, cpu, ctx, group_leader,
4379 NULL, GFP_KERNEL); 4379 NULL, GFP_KERNEL);
4380 ret = PTR_ERR(counter); 4380 err = PTR_ERR(counter);
4381 if (IS_ERR(counter)) 4381 if (IS_ERR(counter))
4382 goto err_put_context; 4382 goto err_put_context;
4383 4383
4384 ret = anon_inode_getfd("[perf_counter]", &perf_fops, counter, 0); 4384 err = anon_inode_getfd("[perf_counter]", &perf_fops, counter, 0);
4385 if (ret < 0) 4385 if (err < 0)
4386 goto err_free_put_context; 4386 goto err_free_put_context;
4387 4387
4388 counter_file = fget_light(ret, &fput_needed2); 4388 counter_file = fget_light(err, &fput_needed2);
4389 if (!counter_file) 4389 if (!counter_file)
4390 goto err_free_put_context; 4390 goto err_free_put_context;
4391 4391
4392 if (flags & PERF_FLAG_FD_OUTPUT) { 4392 if (flags & PERF_FLAG_FD_OUTPUT) {
4393 ret = perf_counter_set_output(counter, group_fd); 4393 err = perf_counter_set_output(counter, group_fd);
4394 if (ret) 4394 if (err)
4395 goto err_free_put_context; 4395 goto err_fput_free_put_context;
4396 } 4396 }
4397 4397
4398 counter->filp = counter_file; 4398 counter->filp = counter_file;
@@ -4408,20 +4408,20 @@ SYSCALL_DEFINE5(perf_counter_open,
4408 list_add_tail(&counter->owner_entry, &current->perf_counter_list); 4408 list_add_tail(&counter->owner_entry, &current->perf_counter_list);
4409 mutex_unlock(&current->perf_counter_mutex); 4409 mutex_unlock(&current->perf_counter_mutex);
4410 4410
4411err_fput_free_put_context:
4411 fput_light(counter_file, fput_needed2); 4412 fput_light(counter_file, fput_needed2);
4412 4413
4413out_fput:
4414 fput_light(group_file, fput_needed);
4415
4416 return ret;
4417
4418err_free_put_context: 4414err_free_put_context:
4419 kfree(counter); 4415 if (err < 0)
4416 kfree(counter);
4420 4417
4421err_put_context: 4418err_put_context:
4422 put_ctx(ctx); 4419 if (err < 0)
4420 put_ctx(ctx);
4421
4422 fput_light(group_file, fput_needed);
4423 4423
4424 goto out_fput; 4424 return err;
4425} 4425}
4426 4426
4427/* 4427/*