aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/perf_counter.h3
-rw-r--r--kernel/perf_counter.c42
2 files changed, 37 insertions, 8 deletions
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h
index d970fbc16af..9ec20fc6bd3 100644
--- a/include/linux/perf_counter.h
+++ b/include/linux/perf_counter.h
@@ -317,6 +317,7 @@ enum perf_event_type {
317#include <linux/spinlock.h> 317#include <linux/spinlock.h>
318#include <linux/hrtimer.h> 318#include <linux/hrtimer.h>
319#include <linux/fs.h> 319#include <linux/fs.h>
320#include <linux/pid_namespace.h>
320#include <asm/atomic.h> 321#include <asm/atomic.h>
321 322
322struct task_struct; 323struct task_struct;
@@ -500,6 +501,8 @@ struct perf_counter {
500 501
501 void (*destroy)(struct perf_counter *); 502 void (*destroy)(struct perf_counter *);
502 struct rcu_head rcu_head; 503 struct rcu_head rcu_head;
504
505 struct pid_namespace *ns;
503#endif 506#endif
504}; 507};
505 508
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index fbed4d28ad7..caa012cfe49 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
2272static 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
2283static 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
2270static void perf_counter_output(struct perf_counter *counter, 2294static 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, &current->perf_counter_list); 3469 list_add_tail(&counter->owner_entry, &current->perf_counter_list);
3446 mutex_unlock(&current->perf_counter_mutex); 3470 mutex_unlock(&current->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
3450out_fput: 3476out_fput: