perf/amd/uncore: Allow F19h user coreid, threadmask, and sliceid specification
authorKim Phillips <kim.phillips@amd.com>
Mon, 21 Sep 2020 14:43:29 +0000 (09:43 -0500)
committerPeter Zijlstra <peterz@infradead.org>
Thu, 24 Sep 2020 13:55:50 +0000 (15:55 +0200)
On Family 19h, the driver checks for a populated 2-bit threadmask in
order to establish that the user wants to measure individual slices,
individual cores (only one can be measured at a time), and lets
the user also directly specify enallcores and/or enallslices if
desired.

Example F19h invocation to measure L3 accesses (event 4, umask 0xff)
by the first thread (id 0 -> mask 0x1) of the first core (id 0) on the
first slice (id 0):

perf stat -a -e instructions,amd_l3/umask=0xff,event=0x4,coreid=0,threadmask=1,sliceid=0,enallcores=0,enallslices=0/ <workload>

Signed-off-by: Kim Phillips <kim.phillips@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20200921144330.6331-4-kim.phillips@amd.com
arch/x86/events/amd/uncore.c

index 1e35c93..f026715 100644 (file)
@@ -190,8 +190,19 @@ static u64 l3_thread_slice_mask(u64 config)
                return ((config & AMD64_L3_SLICE_MASK) ? : AMD64_L3_SLICE_MASK) |
                       ((config & AMD64_L3_THREAD_MASK) ? : AMD64_L3_THREAD_MASK);
 
-       return AMD64_L3_EN_ALL_SLICES | AMD64_L3_EN_ALL_CORES |
-              AMD64_L3_F19H_THREAD_MASK;
+       /*
+        * If the user doesn't specify a threadmask, they're not trying to
+        * count core 0, so we enable all cores & threads.
+        * We'll also assume that they want to count slice 0 if they specify
+        * a threadmask and leave sliceid and enallslices unpopulated.
+        */
+       if (!(config & AMD64_L3_F19H_THREAD_MASK))
+               return AMD64_L3_F19H_THREAD_MASK | AMD64_L3_EN_ALL_SLICES |
+                      AMD64_L3_EN_ALL_CORES;
+
+       return config & (AMD64_L3_F19H_THREAD_MASK | AMD64_L3_SLICEID_MASK |
+                        AMD64_L3_EN_ALL_CORES | AMD64_L3_EN_ALL_SLICES |
+                        AMD64_L3_COREID_MASK);
 }
 
 static int amd_uncore_event_init(struct perf_event *event)
@@ -278,8 +289,13 @@ DEFINE_UNCORE_FORMAT_ATTR(event12, event,          "config:0-7,32-35");
 DEFINE_UNCORE_FORMAT_ATTR(event14,     event,          "config:0-7,32-35,59-60"); /* F17h+ DF */
 DEFINE_UNCORE_FORMAT_ATTR(event8,      event,          "config:0-7");             /* F17h+ L3 */
 DEFINE_UNCORE_FORMAT_ATTR(umask,       umask,          "config:8-15");
+DEFINE_UNCORE_FORMAT_ATTR(coreid,      coreid,         "config:42-44");           /* F19h L3 */
 DEFINE_UNCORE_FORMAT_ATTR(slicemask,   slicemask,      "config:48-51");           /* F17h L3 */
 DEFINE_UNCORE_FORMAT_ATTR(threadmask8, threadmask,     "config:56-63");           /* F17h L3 */
+DEFINE_UNCORE_FORMAT_ATTR(threadmask2, threadmask,     "config:56-57");           /* F19h L3 */
+DEFINE_UNCORE_FORMAT_ATTR(enallslices, enallslices,    "config:46");              /* F19h L3 */
+DEFINE_UNCORE_FORMAT_ATTR(enallcores,  enallcores,     "config:47");              /* F19h L3 */
+DEFINE_UNCORE_FORMAT_ATTR(sliceid,     sliceid,        "config:48-50");           /* F19h L3 */
 
 static struct attribute *amd_uncore_df_format_attr[] = {
        &format_attr_event12.attr, /* event14 if F17h+ */
@@ -290,8 +306,11 @@ static struct attribute *amd_uncore_df_format_attr[] = {
 static struct attribute *amd_uncore_l3_format_attr[] = {
        &format_attr_event12.attr, /* event8 if F17h+ */
        &format_attr_umask.attr,
-       NULL, /* slicemask if F17h */
-       NULL, /* threadmask8 if F17h */
+       NULL, /* slicemask if F17h,     coreid if F19h */
+       NULL, /* threadmask8 if F17h,   enallslices if F19h */
+       NULL, /*                        enallcores if F19h */
+       NULL, /*                        sliceid if F19h */
+       NULL, /*                        threadmask2 if F19h */
        NULL,
 };
 
@@ -583,7 +602,15 @@ static int __init amd_uncore_init(void)
        }
 
        if (boot_cpu_has(X86_FEATURE_PERFCTR_LLC)) {
-               if (boot_cpu_data.x86 >= 0x17) {
+               if (boot_cpu_data.x86 >= 0x19) {
+                       *l3_attr++ = &format_attr_event8.attr;
+                       *l3_attr++ = &format_attr_umask.attr;
+                       *l3_attr++ = &format_attr_coreid.attr;
+                       *l3_attr++ = &format_attr_enallslices.attr;
+                       *l3_attr++ = &format_attr_enallcores.attr;
+                       *l3_attr++ = &format_attr_sliceid.attr;
+                       *l3_attr++ = &format_attr_threadmask2.attr;
+               } else if (boot_cpu_data.x86 >= 0x17) {
                        *l3_attr++ = &format_attr_event8.attr;
                        *l3_attr++ = &format_attr_umask.attr;
                        *l3_attr++ = &format_attr_slicemask.attr;