summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/linux/perf_counter.h5
-rw-r--r--kernel/perf_counter.c18
2 files changed, 20 insertions, 3 deletions
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h
index c256635377d4..7fdbdf8be775 100644
--- a/include/linux/perf_counter.h
+++ b/include/linux/perf_counter.h
@@ -127,8 +127,9 @@ struct perf_counter_hw_event {
exclude_kernel : 1, /* ditto kernel */
exclude_hv : 1, /* ditto hypervisor */
exclude_idle : 1, /* don't count when idle */
+ include_tid : 1, /* include the tid */
- __reserved_1 : 55;
+ __reserved_1 : 54;
__u32 extra_config_len;
__u32 __reserved_4;
@@ -164,6 +165,8 @@ struct perf_event_header {
enum perf_event_type {
PERF_EVENT_IP = 0,
PERF_EVENT_GROUP = 1,
+
+ __PERF_EVENT_TID = 0x100,
};
#ifdef __KERNEL__
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index 7669afe82cc7..f3e1b27bc1b8 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -1528,16 +1528,30 @@ out:
static void perf_output_simple(struct perf_counter *counter,
int nmi, struct pt_regs *regs)
{
+ unsigned int size;
struct {
struct perf_event_header header;
u64 ip;
+ u32 pid, tid;
} event;
event.header.type = PERF_EVENT_IP;
- event.header.size = sizeof(event);
event.ip = instruction_pointer(regs);
- perf_output_write(counter, nmi, &event, sizeof(event));
+ size = sizeof(event);
+
+ if (counter->hw_event.include_tid) {
+ /* namespace issues */
+ event.pid = current->group_leader->pid;
+ event.tid = current->pid;
+
+ event.header.type |= __PERF_EVENT_TID;
+ } else
+ size -= sizeof(u64);
+
+ event.header.size = size;
+
+ perf_output_write(counter, nmi, &event, size);
}
static void perf_output_group(struct perf_counter *counter, int nmi)