The PERF_SAMPLE_CGROUP bit is to save (perf_event) cgroup information
in the sample.  It will add a 64-bit integer to identify current
cgroup and it's the inode number in the cgroup file system.  Userspace
should use this information with PERF_RECORD_CGROUP event to match
which cgroup it belongs.

Cc: Tejun Heo <t...@kernel.org>
Cc: Li Zefan <lize...@huawei.com>
Cc: Johannes Weiner <han...@cmpxchg.org>
Signed-off-by: Namhyung Kim <namhy...@kernel.org>
---
 include/linux/perf_event.h      |  1 +
 include/uapi/linux/perf_event.h |  3 ++-
 kernel/events/core.c            | 16 ++++++++++++++++
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index e8ad3c590a23..2b9661aa4240 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -958,6 +958,7 @@ struct perf_sample_data {
        u64                             stack_user_size;
 
        u64                             phys_addr;
+       u64                             cgroup;
 } ____cacheline_aligned;
 
 /* default value for data source */
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index cb07c24b715f..91a552bf9611 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -141,8 +141,9 @@ enum perf_event_sample_format {
        PERF_SAMPLE_TRANSACTION                 = 1U << 17,
        PERF_SAMPLE_REGS_INTR                   = 1U << 18,
        PERF_SAMPLE_PHYS_ADDR                   = 1U << 19,
+       PERF_SAMPLE_CGROUP                      = 1U << 20,
 
-       PERF_SAMPLE_MAX = 1U << 20,             /* non-ABI */
+       PERF_SAMPLE_MAX = 1U << 21,             /* non-ABI */
 
        __PERF_SAMPLE_CALLCHAIN_EARLY           = 1ULL << 63, /* non-ABI; 
internal use */
 };
diff --git a/kernel/events/core.c b/kernel/events/core.c
index d898263db4fc..04ae6a42a98b 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -1754,6 +1754,9 @@ static void __perf_event_header_size(struct perf_event 
*event, u64 sample_type)
        if (sample_type & PERF_SAMPLE_PHYS_ADDR)
                size += sizeof(data->phys_addr);
 
+       if (sample_type & PERF_SAMPLE_CGROUP)
+               size += sizeof(data->cgroup);
+
        event->header_size = size;
 }
 
@@ -6388,6 +6391,19 @@ void perf_output_sample(struct perf_output_handle 
*handle,
        if (sample_type & PERF_SAMPLE_PHYS_ADDR)
                perf_output_put(handle, data->phys_addr);
 
+       if (sample_type & PERF_SAMPLE_CGROUP) {
+               u64 ino = 0;
+
+#ifdef CONFIG_CGROUP_PERF
+               struct cgroup *cgrp;
+
+               /* protected by RCU */
+               cgrp = task_css_check(current, perf_event_cgrp_id, 1)->cgroup;
+               ino = cgroup_ino(cgrp);
+#endif
+               perf_output_put(handle, ino);
+       }
+
        if (!event->attr.watermark) {
                int wakeup_events = event->attr.wakeup_events;
 
-- 
2.23.0.187.g17f5b7556c-goog

Reply via email to