diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/perf_counter.c | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index fbed4d28ad7d..caa012cfe49a 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c | |||
@@ -1432,6 +1432,8 @@ static void free_counter_rcu(struct rcu_head *head) | |||
1432 | struct perf_counter *counter; | 1432 | struct perf_counter *counter; |
1433 | 1433 | ||
1434 | counter = container_of(head, struct perf_counter, rcu_head); | 1434 | counter = container_of(head, struct perf_counter, rcu_head); |
1435 | if (counter->ns) | ||
1436 | put_pid_ns(counter->ns); | ||
1435 | kfree(counter); | 1437 | kfree(counter); |
1436 | } | 1438 | } |
1437 | 1439 | ||
@@ -2267,6 +2269,28 @@ static void perf_output_end(struct perf_output_handle *handle) | |||
2267 | rcu_read_unlock(); | 2269 | rcu_read_unlock(); |
2268 | } | 2270 | } |
2269 | 2271 | ||
2272 | static u32 perf_counter_pid(struct perf_counter *counter, struct task_struct *p) | ||
2273 | { | ||
2274 | /* | ||
2275 | * only top level counters have the pid namespace they were created in | ||
2276 | */ | ||
2277 | if (counter->parent) | ||
2278 | counter = counter->parent; | ||
2279 | |||
2280 | return task_tgid_nr_ns(p, counter->ns); | ||
2281 | } | ||
2282 | |||
2283 | static u32 perf_counter_tid(struct perf_counter *counter, struct task_struct *p) | ||
2284 | { | ||
2285 | /* | ||
2286 | * only top level counters have the pid namespace they were created in | ||
2287 | */ | ||
2288 | if (counter->parent) | ||
2289 | counter = counter->parent; | ||
2290 | |||
2291 | return task_pid_nr_ns(p, counter->ns); | ||
2292 | } | ||
2293 | |||
2270 | static void perf_counter_output(struct perf_counter *counter, | 2294 | static void perf_counter_output(struct perf_counter *counter, |
2271 | int nmi, struct pt_regs *regs, u64 addr) | 2295 | int nmi, struct pt_regs *regs, u64 addr) |
2272 | { | 2296 | { |
@@ -2303,8 +2327,8 @@ static void perf_counter_output(struct perf_counter *counter, | |||
2303 | 2327 | ||
2304 | if (record_type & PERF_RECORD_TID) { | 2328 | if (record_type & PERF_RECORD_TID) { |
2305 | /* namespace issues */ | 2329 | /* namespace issues */ |
2306 | tid_entry.pid = current->group_leader->pid; | 2330 | tid_entry.pid = perf_counter_pid(counter, current); |
2307 | tid_entry.tid = current->pid; | 2331 | tid_entry.tid = perf_counter_tid(counter, current); |
2308 | 2332 | ||
2309 | header.type |= PERF_RECORD_TID; | 2333 | header.type |= PERF_RECORD_TID; |
2310 | header.size += sizeof(tid_entry); | 2334 | header.size += sizeof(tid_entry); |
@@ -2432,6 +2456,9 @@ static void perf_counter_comm_output(struct perf_counter *counter, | |||
2432 | if (ret) | 2456 | if (ret) |
2433 | return; | 2457 | return; |
2434 | 2458 | ||
2459 | comm_event->event.pid = perf_counter_pid(counter, comm_event->task); | ||
2460 | comm_event->event.tid = perf_counter_tid(counter, comm_event->task); | ||
2461 | |||
2435 | perf_output_put(&handle, comm_event->event); | 2462 | perf_output_put(&handle, comm_event->event); |
2436 | perf_output_copy(&handle, comm_event->comm, | 2463 | perf_output_copy(&handle, comm_event->comm, |
2437 | comm_event->comm_size); | 2464 | comm_event->comm_size); |
@@ -2504,8 +2531,6 @@ void perf_counter_comm(struct task_struct *task) | |||
2504 | .task = task, | 2531 | .task = task, |
2505 | .event = { | 2532 | .event = { |
2506 | .header = { .type = PERF_EVENT_COMM, }, | 2533 | .header = { .type = PERF_EVENT_COMM, }, |
2507 | .pid = task->group_leader->pid, | ||
2508 | .tid = task->pid, | ||
2509 | }, | 2534 | }, |
2510 | }; | 2535 | }; |
2511 | 2536 | ||
@@ -2542,6 +2567,9 @@ static void perf_counter_mmap_output(struct perf_counter *counter, | |||
2542 | if (ret) | 2567 | if (ret) |
2543 | return; | 2568 | return; |
2544 | 2569 | ||
2570 | mmap_event->event.pid = perf_counter_pid(counter, current); | ||
2571 | mmap_event->event.tid = perf_counter_tid(counter, current); | ||
2572 | |||
2545 | perf_output_put(&handle, mmap_event->event); | 2573 | perf_output_put(&handle, mmap_event->event); |
2546 | perf_output_copy(&handle, mmap_event->file_name, | 2574 | perf_output_copy(&handle, mmap_event->file_name, |
2547 | mmap_event->file_size); | 2575 | mmap_event->file_size); |
@@ -2641,8 +2669,6 @@ void perf_counter_mmap(unsigned long addr, unsigned long len, | |||
2641 | .file = file, | 2669 | .file = file, |
2642 | .event = { | 2670 | .event = { |
2643 | .header = { .type = PERF_EVENT_MMAP, }, | 2671 | .header = { .type = PERF_EVENT_MMAP, }, |
2644 | .pid = current->group_leader->pid, | ||
2645 | .tid = current->pid, | ||
2646 | .start = addr, | 2672 | .start = addr, |
2647 | .len = len, | 2673 | .len = len, |
2648 | .pgoff = pgoff, | 2674 | .pgoff = pgoff, |
@@ -2664,8 +2690,6 @@ void perf_counter_munmap(unsigned long addr, unsigned long len, | |||
2664 | .file = file, | 2690 | .file = file, |
2665 | .event = { | 2691 | .event = { |
2666 | .header = { .type = PERF_EVENT_MUNMAP, }, | 2692 | .header = { .type = PERF_EVENT_MUNMAP, }, |
2667 | .pid = current->group_leader->pid, | ||
2668 | .tid = current->pid, | ||
2669 | .start = addr, | 2693 | .start = addr, |
2670 | .len = len, | 2694 | .len = len, |
2671 | .pgoff = pgoff, | 2695 | .pgoff = pgoff, |
@@ -3445,6 +3469,8 @@ SYSCALL_DEFINE5(perf_counter_open, | |||
3445 | list_add_tail(&counter->owner_entry, ¤t->perf_counter_list); | 3469 | list_add_tail(&counter->owner_entry, ¤t->perf_counter_list); |
3446 | mutex_unlock(¤t->perf_counter_mutex); | 3470 | mutex_unlock(¤t->perf_counter_mutex); |
3447 | 3471 | ||
3472 | counter->ns = get_pid_ns(current->nsproxy->pid_ns); | ||
3473 | |||
3448 | fput_light(counter_file, fput_needed2); | 3474 | fput_light(counter_file, fput_needed2); |
3449 | 3475 | ||
3450 | out_fput: | 3476 | out_fput: |