linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC 0/8] perf/x86: Add msr probe interface
@ 2019-03-18 18:21 Jiri Olsa
  2019-03-18 18:21 ` [PATCH 1/8] " Jiri Olsa
                   ` (7 more replies)
  0 siblings, 8 replies; 12+ messages in thread
From: Jiri Olsa @ 2019-03-18 18:21 UTC (permalink / raw)
  To: Peter Zijlstra, Liang, Kan, Stephane Eranian, Andy Lutomirski
  Cc: lkml, Ingo Molnar, Namhyung Kim, Alexander Shishkin, Andi Kleen,
	Vince Weaver, Thomas Gleixner, Arnaldo Carvalho de Melo

hi,
following up on [1], this patchset factors out the MSR
probe code and use it in msr,cstate* and rapl PMUs.

The functionality stays the same with one exception:
the event is not exported if the rdmsr return zero
on event's msr.

I still need to run tests on other models and verify
rapl model table properly, but I'd like to ask it
something like this would be acceptable.

Also available in:
  git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
  perf/msr

thanks,
jirka


[1] https://lore.kernel.org/lkml/20190301114250.GA23459@krava/
---
Jiri Olsa (8):
      perf/x86: Add msr probe interface
      perf/x86/msr: Use new probe function
      perf/x86/cstate: Use new probe function
      perf/x86/rapl: Use new msr detection interface
      perf/x86/rapl: Get rapl_cntr_mask from new probe framework
      perf/x86/rapl: Get msr values from new probe framework
      perf/x86/rapl: Get attributes from new probe framework
      perf/x86/rapl: Get quirk state from new probe framework

 arch/x86/events/Makefile       |   2 +-
 arch/x86/events/intel/cstate.c |  92 +++++++++++++++++++++++------------------------
 arch/x86/events/intel/rapl.c   | 341 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------------------------------------------------------------
 arch/x86/events/msr.c          |  76 ++++++++++++++++++---------------------
 arch/x86/events/probe.c        |  36 +++++++++++++++++++
 arch/x86/events/probe.h        |  22 ++++++++++++
 6 files changed, 272 insertions(+), 297 deletions(-)
 create mode 100644 arch/x86/events/probe.c
 create mode 100644 arch/x86/events/probe.h

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/8] perf/x86: Add msr probe interface
  2019-03-18 18:21 [RFC 0/8] perf/x86: Add msr probe interface Jiri Olsa
@ 2019-03-18 18:21 ` Jiri Olsa
  2019-03-20 15:48   ` Peter Zijlstra
  2019-03-18 18:21 ` [PATCH 2/8] perf/x86/msr: Use new probe function Jiri Olsa
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 12+ messages in thread
From: Jiri Olsa @ 2019-03-18 18:21 UTC (permalink / raw)
  To: Peter Zijlstra, Liang, Kan, Stephane Eranian, Andy Lutomirski
  Cc: lkml, Ingo Molnar, Namhyung Kim, Alexander Shishkin, Andi Kleen,
	Vince Weaver, Thomas Gleixner, Arnaldo Carvalho de Melo

Adding perf_msr_probe function to provide interface for
checking up on MSR register and add its related event
attributes if it passes the check.

User defines following struct for each MSR register:

  struct perf_msr {
       u64                       msr;
       struct attribute        **attrs;
       bool                    (*test)(int idx, void *data);
       bool                      no_check;
  };

Where:
  msr      - is the MSR address
  attrs    - is attributes array to add if the check passed
  test     - is test function pointer
  no_check - is bool that bypass the check and adds the
              attribute without any test

The array of struct perf_msr is passed into:

  perf_msr_probe(struct perf_msr *msr, int cnt,
                struct attribute **attrs, void *data)

Together with:
  cnt   - which is the number of struct msr array elements
  attrs - which is an array placeholder for added attributes
          and needs to be big enough
  data  -which is user pointer passed to the test function

The perf_msr_probe will executed test code, read the MSR and
check the value is != 0. If all these tests pass, related
attributes are added into attrs array.

Also adding MSR_ATTR macro helper to define attribute array
from single attribute. It will be used in following patches.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 arch/x86/events/Makefile |  2 +-
 arch/x86/events/probe.c  | 36 ++++++++++++++++++++++++++++++++++++
 arch/x86/events/probe.h  | 22 ++++++++++++++++++++++
 3 files changed, 59 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/events/probe.c
 create mode 100644 arch/x86/events/probe.h

diff --git a/arch/x86/events/Makefile b/arch/x86/events/Makefile
index b8ccdb5c9244..ec29a466444a 100644
--- a/arch/x86/events/Makefile
+++ b/arch/x86/events/Makefile
@@ -1,4 +1,4 @@
-obj-y					+= core.o
+obj-y					+= core.o probe.o
 obj-y					+= amd/
 obj-$(CONFIG_X86_LOCAL_APIC)            += msr.o
 obj-$(CONFIG_CPU_SUP_INTEL)		+= intel/
diff --git a/arch/x86/events/probe.c b/arch/x86/events/probe.c
new file mode 100644
index 000000000000..0052b730c55e
--- /dev/null
+++ b/arch/x86/events/probe.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/export.h>
+#include <linux/bits.h>
+#include "probe.h"
+
+unsigned long
+perf_msr_probe(struct perf_msr *msr, int cnt,
+	       struct attribute **attrs, void *data)
+{
+	unsigned long avail = 0;
+	unsigned int bit;
+	u64 val;
+
+	if (cnt >= BITS_PER_LONG)
+		return 0;
+
+	for (bit = 0; bit < cnt; bit++) {
+		struct attribute **a = msr[bit].attrs;
+
+		if (!msr[bit].no_check) {
+			if (msr[bit].test && !msr[bit].test(bit, data))
+				continue;
+			if (rdmsrl_safe(msr[bit].msr, &val) || !val)
+				continue;
+		}
+
+		while (*a)
+			*attrs++ = *a++;
+
+		avail |= bit;
+	}
+
+	*attrs = NULL;
+	return avail;
+}
+EXPORT_SYMBOL_GPL(perf_msr_probe);
diff --git a/arch/x86/events/probe.h b/arch/x86/events/probe.h
new file mode 100644
index 000000000000..42dd666533c3
--- /dev/null
+++ b/arch/x86/events/probe.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ARCH_X86_EVENTS_PROBE_H__
+#define __ARCH_X86_EVENTS_PROBE_H__
+#include <linux/sysfs.h>
+
+#define MSR_ATTR(__n)				\
+static struct attribute *msr_##__n[] = {	\
+	&__n.attr.attr,				\
+	NULL,					\
+}
+
+struct perf_msr {
+	u64			  msr;
+	struct attribute	**attrs;
+	bool			(*test)(int idx, void *data);
+	bool			  no_check;
+};
+
+unsigned long
+perf_msr_probe(struct perf_msr *msr, int cnt,
+	       struct attribute **attrs, void *data);
+#endif /* __ARCH_X86_EVENTS_PROBE_H__ */
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/8] perf/x86/msr: Use new probe function
  2019-03-18 18:21 [RFC 0/8] perf/x86: Add msr probe interface Jiri Olsa
  2019-03-18 18:21 ` [PATCH 1/8] " Jiri Olsa
@ 2019-03-18 18:21 ` Jiri Olsa
  2019-03-18 18:21 ` [PATCH 3/8] perf/x86/cstate: " Jiri Olsa
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Jiri Olsa @ 2019-03-18 18:21 UTC (permalink / raw)
  To: Peter Zijlstra, Liang, Kan, Stephane Eranian, Andy Lutomirski
  Cc: lkml, Ingo Molnar, Namhyung Kim, Alexander Shishkin, Andi Kleen,
	Vince Weaver, Thomas Gleixner, Arnaldo Carvalho de Melo

Using perf_msr_probe function to add msr events.

The functionality is the same, with one exception,
that perf_msr_probe checks for rdmsr to return
value != 0 for given MSR register.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 arch/x86/events/msr.c | 76 ++++++++++++++++++++-----------------------
 1 file changed, 35 insertions(+), 41 deletions(-)

diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c
index a878e6286e4a..926d887aa606 100644
--- a/arch/x86/events/msr.c
+++ b/arch/x86/events/msr.c
@@ -2,6 +2,7 @@
 #include <linux/perf_event.h>
 #include <linux/nospec.h>
 #include <asm/intel-family.h>
+#include "probe.h"
 
 enum perf_msr_id {
 	PERF_MSR_TSC			= 0,
@@ -12,32 +13,30 @@ enum perf_msr_id {
 	PERF_MSR_PTSC			= 5,
 	PERF_MSR_IRPERF			= 6,
 	PERF_MSR_THERM			= 7,
-	PERF_MSR_THERM_SNAP		= 8,
-	PERF_MSR_THERM_UNIT		= 9,
 	PERF_MSR_EVENT_MAX,
 };
 
-static bool test_aperfmperf(int idx)
+static bool test_aperfmperf(int idx, void *data)
 {
 	return boot_cpu_has(X86_FEATURE_APERFMPERF);
 }
 
-static bool test_ptsc(int idx)
+static bool test_ptsc(int idx, void *data)
 {
 	return boot_cpu_has(X86_FEATURE_PTSC);
 }
 
-static bool test_irperf(int idx)
+static bool test_irperf(int idx, void *data)
 {
 	return boot_cpu_has(X86_FEATURE_IRPERF);
 }
 
-static bool test_therm_status(int idx)
+static bool test_therm_status(int idx, void *data)
 {
 	return boot_cpu_has(X86_FEATURE_DTHERM);
 }
 
-static bool test_intel(int idx)
+static bool test_intel(int idx, void *data)
 {
 	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
 	    boot_cpu_data.x86 != 6)
@@ -97,12 +96,6 @@ static bool test_intel(int idx)
 	return false;
 }
 
-struct perf_msr {
-	u64	msr;
-	struct	perf_pmu_events_attr *attr;
-	bool	(*test)(int idx);
-};
-
 PMU_EVENT_ATTR_STRING(tsc,				evattr_tsc,		"event=0x00"	);
 PMU_EVENT_ATTR_STRING(aperf,				evattr_aperf,		"event=0x01"	);
 PMU_EVENT_ATTR_STRING(mperf,				evattr_mperf,		"event=0x02"	);
@@ -114,17 +107,32 @@ PMU_EVENT_ATTR_STRING(cpu_thermal_margin,		evattr_therm,		"event=0x07"	);
 PMU_EVENT_ATTR_STRING(cpu_thermal_margin.snapshot,	evattr_therm_snap,	"1"		);
 PMU_EVENT_ATTR_STRING(cpu_thermal_margin.unit,		evattr_therm_unit,	"C"		);
 
+static unsigned long msr_mask;
+
+MSR_ATTR(evattr_tsc);
+MSR_ATTR(evattr_aperf);
+MSR_ATTR(evattr_mperf);
+MSR_ATTR(evattr_pperf);
+MSR_ATTR(evattr_smi);
+MSR_ATTR(evattr_ptsc);
+MSR_ATTR(evattr_irperf);
+
+static struct attribute *msr_evattr_therm[] = {
+	&evattr_therm.attr.attr,
+	&evattr_therm_snap.attr.attr,
+	&evattr_therm_unit.attr.attr,
+	NULL,
+};
+
 static struct perf_msr msr[] = {
-	[PERF_MSR_TSC]		= { 0,				&evattr_tsc,		NULL,			},
-	[PERF_MSR_APERF]	= { MSR_IA32_APERF,		&evattr_aperf,		test_aperfmperf,	},
-	[PERF_MSR_MPERF]	= { MSR_IA32_MPERF,		&evattr_mperf,		test_aperfmperf,	},
-	[PERF_MSR_PPERF]	= { MSR_PPERF,			&evattr_pperf,		test_intel,		},
-	[PERF_MSR_SMI]		= { MSR_SMI_COUNT,		&evattr_smi,		test_intel,		},
-	[PERF_MSR_PTSC]		= { MSR_F15H_PTSC,		&evattr_ptsc,		test_ptsc,		},
-	[PERF_MSR_IRPERF]	= { MSR_F17H_IRPERF,		&evattr_irperf,		test_irperf,		},
-	[PERF_MSR_THERM]	= { MSR_IA32_THERM_STATUS,	&evattr_therm,		test_therm_status,	},
-	[PERF_MSR_THERM_SNAP]	= { MSR_IA32_THERM_STATUS,	&evattr_therm_snap,	test_therm_status,	},
-	[PERF_MSR_THERM_UNIT]	= { MSR_IA32_THERM_STATUS,	&evattr_therm_unit,	test_therm_status,	},
+	[PERF_MSR_TSC]		= { 0,				msr_evattr_tsc,		NULL,			},
+	[PERF_MSR_APERF]	= { MSR_IA32_APERF,		msr_evattr_aperf,	test_aperfmperf,	},
+	[PERF_MSR_MPERF]	= { MSR_IA32_MPERF,		msr_evattr_mperf,	test_aperfmperf,	},
+	[PERF_MSR_PPERF]	= { MSR_PPERF,			msr_evattr_pperf,	test_intel,		},
+	[PERF_MSR_SMI]		= { MSR_SMI_COUNT,		msr_evattr_smi,		test_intel,		},
+	[PERF_MSR_PTSC]		= { MSR_F15H_PTSC,		msr_evattr_ptsc,	test_ptsc,		},
+	[PERF_MSR_IRPERF]	= { MSR_F17H_IRPERF,		msr_evattr_irperf,	test_irperf,		},
+	[PERF_MSR_THERM]	= { MSR_IA32_THERM_STATUS,	msr_evattr_therm,	test_therm_status,	},
 };
 
 static struct attribute *events_attrs[PERF_MSR_EVENT_MAX + 1] = {
@@ -168,7 +176,7 @@ static int msr_event_init(struct perf_event *event)
 
 	cfg = array_index_nospec((unsigned long)cfg, PERF_MSR_EVENT_MAX);
 
-	if (!msr[cfg].attr)
+	if (!(msr_mask & (1 << cfg)))
 		return -EINVAL;
 
 	event->hw.idx		= -1;
@@ -255,28 +263,14 @@ static struct pmu pmu_msr = {
 
 static int __init msr_init(void)
 {
-	int i, j = 0;
-
 	if (!boot_cpu_has(X86_FEATURE_TSC)) {
 		pr_cont("no MSR PMU driver.\n");
 		return 0;
 	}
 
-	/* Probe the MSRs. */
-	for (i = PERF_MSR_TSC + 1; i < PERF_MSR_EVENT_MAX; i++) {
-		u64 val;
-
-		/* Virt sucks; you cannot tell if a R/O MSR is present :/ */
-		if (!msr[i].test(i) || rdmsrl_safe(msr[i].msr, &val))
-			msr[i].attr = NULL;
-	}
-
-	/* List remaining MSRs in the sysfs attrs. */
-	for (i = 0; i < PERF_MSR_EVENT_MAX; i++) {
-		if (msr[i].attr)
-			events_attrs[j++] = &msr[i].attr->attr.attr;
-	}
-	events_attrs[j] = NULL;
+	msr[PERF_MSR_TSC].no_check = true;
+	msr_mask = perf_msr_probe(msr, PERF_MSR_EVENT_MAX,
+				  events_attrs, NULL);
 
 	perf_pmu_register(&pmu_msr, "msr", -1);
 
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/8] perf/x86/cstate: Use new probe function
  2019-03-18 18:21 [RFC 0/8] perf/x86: Add msr probe interface Jiri Olsa
  2019-03-18 18:21 ` [PATCH 1/8] " Jiri Olsa
  2019-03-18 18:21 ` [PATCH 2/8] perf/x86/msr: Use new probe function Jiri Olsa
@ 2019-03-18 18:21 ` Jiri Olsa
  2019-03-18 18:21 ` [PATCH 4/8] perf/x86/rapl: Use new msr detection interface Jiri Olsa
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Jiri Olsa @ 2019-03-18 18:21 UTC (permalink / raw)
  To: Peter Zijlstra, Liang, Kan, Stephane Eranian, Andy Lutomirski
  Cc: lkml, Ingo Molnar, Namhyung Kim, Alexander Shishkin, Andi Kleen,
	Vince Weaver, Thomas Gleixner, Arnaldo Carvalho de Melo

Using perf_msr_probe function to add msr events.

The functionality is the same, with one exception,
that perf_msr_probe checks for rdmsr to return
value != 0 for given MSR register.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 arch/x86/events/intel/cstate.c | 92 +++++++++++++++++-----------------
 1 file changed, 46 insertions(+), 46 deletions(-)

diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c
index 94a4b7fc75d0..af0b9236445a 100644
--- a/arch/x86/events/intel/cstate.c
+++ b/arch/x86/events/intel/cstate.c
@@ -96,6 +96,7 @@
 #include <asm/cpu_device_id.h>
 #include <asm/intel-family.h>
 #include "../perf_event.h"
+#include "../probe.h"
 
 MODULE_LICENSE("GPL");
 
@@ -149,11 +150,23 @@ PMU_EVENT_ATTR_STRING(c3-residency, evattr_cstate_core_c3, "event=0x01");
 PMU_EVENT_ATTR_STRING(c6-residency, evattr_cstate_core_c6, "event=0x02");
 PMU_EVENT_ATTR_STRING(c7-residency, evattr_cstate_core_c7, "event=0x03");
 
-static struct perf_cstate_msr core_msr[] = {
-	[PERF_CSTATE_CORE_C1_RES] = { MSR_CORE_C1_RES,		&evattr_cstate_core_c1 },
-	[PERF_CSTATE_CORE_C3_RES] = { MSR_CORE_C3_RESIDENCY,	&evattr_cstate_core_c3 },
-	[PERF_CSTATE_CORE_C6_RES] = { MSR_CORE_C6_RESIDENCY,	&evattr_cstate_core_c6 },
-	[PERF_CSTATE_CORE_C7_RES] = { MSR_CORE_C7_RESIDENCY,	&evattr_cstate_core_c7 },
+static unsigned long core_msr_mask;
+
+MSR_ATTR(evattr_cstate_core_c1);
+MSR_ATTR(evattr_cstate_core_c3);
+MSR_ATTR(evattr_cstate_core_c6);
+MSR_ATTR(evattr_cstate_core_c7);
+
+static bool test_msr(int idx, void *data)
+{
+	return test_bit(idx, (unsigned long *) data);
+}
+
+static struct perf_msr core_msr[] = {
+	[PERF_CSTATE_CORE_C1_RES] = { MSR_CORE_C1_RES,		msr_evattr_cstate_core_c1,	test_msr },
+	[PERF_CSTATE_CORE_C3_RES] = { MSR_CORE_C3_RESIDENCY,	msr_evattr_cstate_core_c3,	test_msr },
+	[PERF_CSTATE_CORE_C6_RES] = { MSR_CORE_C6_RESIDENCY,	msr_evattr_cstate_core_c6,	test_msr },
+	[PERF_CSTATE_CORE_C7_RES] = { MSR_CORE_C7_RESIDENCY,	msr_evattr_cstate_core_c7,	test_msr },
 };
 
 static struct attribute *core_events_attrs[PERF_CSTATE_CORE_EVENT_MAX + 1] = {
@@ -219,14 +232,24 @@ PMU_EVENT_ATTR_STRING(c8-residency, evattr_cstate_pkg_c8, "event=0x04");
 PMU_EVENT_ATTR_STRING(c9-residency, evattr_cstate_pkg_c9, "event=0x05");
 PMU_EVENT_ATTR_STRING(c10-residency, evattr_cstate_pkg_c10, "event=0x06");
 
-static struct perf_cstate_msr pkg_msr[] = {
-	[PERF_CSTATE_PKG_C2_RES] = { MSR_PKG_C2_RESIDENCY,	&evattr_cstate_pkg_c2 },
-	[PERF_CSTATE_PKG_C3_RES] = { MSR_PKG_C3_RESIDENCY,	&evattr_cstate_pkg_c3 },
-	[PERF_CSTATE_PKG_C6_RES] = { MSR_PKG_C6_RESIDENCY,	&evattr_cstate_pkg_c6 },
-	[PERF_CSTATE_PKG_C7_RES] = { MSR_PKG_C7_RESIDENCY,	&evattr_cstate_pkg_c7 },
-	[PERF_CSTATE_PKG_C8_RES] = { MSR_PKG_C8_RESIDENCY,	&evattr_cstate_pkg_c8 },
-	[PERF_CSTATE_PKG_C9_RES] = { MSR_PKG_C9_RESIDENCY,	&evattr_cstate_pkg_c9 },
-	[PERF_CSTATE_PKG_C10_RES] = { MSR_PKG_C10_RESIDENCY,	&evattr_cstate_pkg_c10 },
+static unsigned long pkg_msr_mask;
+
+MSR_ATTR(evattr_cstate_pkg_c2);
+MSR_ATTR(evattr_cstate_pkg_c3);
+MSR_ATTR(evattr_cstate_pkg_c6);
+MSR_ATTR(evattr_cstate_pkg_c7);
+MSR_ATTR(evattr_cstate_pkg_c8);
+MSR_ATTR(evattr_cstate_pkg_c9);
+MSR_ATTR(evattr_cstate_pkg_c10);
+
+static struct perf_msr pkg_msr[] = {
+	[PERF_CSTATE_PKG_C2_RES]  = { MSR_PKG_C2_RESIDENCY,	msr_evattr_cstate_pkg_c2,	test_msr },
+	[PERF_CSTATE_PKG_C3_RES]  = { MSR_PKG_C3_RESIDENCY,	msr_evattr_cstate_pkg_c3,	test_msr },
+	[PERF_CSTATE_PKG_C6_RES]  = { MSR_PKG_C6_RESIDENCY,	msr_evattr_cstate_pkg_c6,	test_msr },
+	[PERF_CSTATE_PKG_C7_RES]  = { MSR_PKG_C7_RESIDENCY,	msr_evattr_cstate_pkg_c7,	test_msr },
+	[PERF_CSTATE_PKG_C8_RES]  = { MSR_PKG_C8_RESIDENCY,	msr_evattr_cstate_pkg_c8,	test_msr },
+	[PERF_CSTATE_PKG_C9_RES]  = { MSR_PKG_C9_RESIDENCY,	msr_evattr_cstate_pkg_c9,	test_msr },
+	[PERF_CSTATE_PKG_C10_RES] = { MSR_PKG_C10_RESIDENCY,	msr_evattr_cstate_pkg_c10,	test_msr },
 };
 
 static struct attribute *pkg_events_attrs[PERF_CSTATE_PKG_EVENT_MAX + 1] = {
@@ -289,7 +312,8 @@ static int cstate_pmu_event_init(struct perf_event *event)
 	if (event->pmu == &cstate_core_pmu) {
 		if (cfg >= PERF_CSTATE_CORE_EVENT_MAX)
 			return -EINVAL;
-		if (!core_msr[cfg].attr)
+		cfg = array_index_nospec((unsigned long)cfg, PERF_CSTATE_CORE_EVENT_MAX);
+		if (!(core_msr_mask & (1 << cfg)))
 			return -EINVAL;
 		event->hw.event_base = core_msr[cfg].msr;
 		cpu = cpumask_any_and(&cstate_core_cpu_mask,
@@ -298,7 +322,7 @@ static int cstate_pmu_event_init(struct perf_event *event)
 		if (cfg >= PERF_CSTATE_PKG_EVENT_MAX)
 			return -EINVAL;
 		cfg = array_index_nospec((unsigned long)cfg, PERF_CSTATE_PKG_EVENT_MAX);
-		if (!pkg_msr[cfg].attr)
+		if (!(pkg_msr_mask & (1 << cfg)))
 			return -EINVAL;
 		event->hw.event_base = pkg_msr[cfg].msr;
 		cpu = cpumask_any_and(&cstate_pkg_cpu_mask,
@@ -582,31 +606,6 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = {
 };
 MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match);
 
-/*
- * Probe the cstate events and insert the available one into sysfs attrs
- * Return false if there are no available events.
- */
-static bool __init cstate_probe_msr(const unsigned long evmsk, int max,
-                                   struct perf_cstate_msr *msr,
-                                   struct attribute **attrs)
-{
-	bool found = false;
-	unsigned int bit;
-	u64 val;
-
-	for (bit = 0; bit < max; bit++) {
-		if (test_bit(bit, &evmsk) && !rdmsrl_safe(msr[bit].msr, &val)) {
-			*attrs++ = &msr[bit].attr->attr.attr;
-			found = true;
-		} else {
-			msr[bit].attr = NULL;
-		}
-	}
-	*attrs = NULL;
-
-	return found;
-}
-
 static int __init cstate_probe(const struct cstate_model *cm)
 {
 	/* SLM has different MSR for PKG C6 */
@@ -618,13 +617,14 @@ static int __init cstate_probe(const struct cstate_model *cm)
 		pkg_msr[PERF_CSTATE_CORE_C6_RES].msr = MSR_KNL_CORE_C6_RESIDENCY;
 
 
-	has_cstate_core = cstate_probe_msr(cm->core_events,
-					   PERF_CSTATE_CORE_EVENT_MAX,
-					   core_msr, core_events_attrs);
+	core_msr_mask = perf_msr_probe(core_msr, PERF_CSTATE_CORE_EVENT_MAX,
+				       core_events_attrs, (void *) &cm->core_events);
+
+	pkg_msr_mask = perf_msr_probe(pkg_msr, PERF_CSTATE_PKG_EVENT_MAX,
+				      pkg_events_attrs, (void *) &cm->pkg_events);
 
-	has_cstate_pkg = cstate_probe_msr(cm->pkg_events,
-					  PERF_CSTATE_PKG_EVENT_MAX,
-					  pkg_msr, pkg_events_attrs);
+	has_cstate_core = !!core_msr_mask;
+	has_cstate_pkg  = !!pkg_msr_mask;
 
 	return (has_cstate_core || has_cstate_pkg) ? 0 : -ENODEV;
 }
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/8] perf/x86/rapl: Use new msr detection interface
  2019-03-18 18:21 [RFC 0/8] perf/x86: Add msr probe interface Jiri Olsa
                   ` (2 preceding siblings ...)
  2019-03-18 18:21 ` [PATCH 3/8] perf/x86/cstate: " Jiri Olsa
@ 2019-03-18 18:21 ` Jiri Olsa
  2019-03-18 18:21 ` [PATCH 5/8] perf/x86/rapl: Get rapl_cntr_mask from new probe framework Jiri Olsa
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Jiri Olsa @ 2019-03-18 18:21 UTC (permalink / raw)
  To: Peter Zijlstra, Liang, Kan, Stephane Eranian, Andy Lutomirski
  Cc: lkml, Ingo Molnar, Namhyung Kim, Alexander Shishkin, Andi Kleen,
	Vince Weaver, Thomas Gleixner, Arnaldo Carvalho de Melo

Using perf_msr_probe function to add msr events.

Adding new rapl_model_match device table, that
gathers events info for given model, following
the msr and cstate module design.

It will replace the current rapl_cpu_match device
table and detection code in following patches.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 arch/x86/events/intel/rapl.c | 149 +++++++++++++++++++++++++++++++++++
 1 file changed, 149 insertions(+)

diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c
index 94dc564146ca..5bd6c3d963fb 100644
--- a/arch/x86/events/intel/rapl.c
+++ b/arch/x86/events/intel/rapl.c
@@ -57,6 +57,7 @@
 #include <asm/cpu_device_id.h>
 #include <asm/intel-family.h>
 #include "../perf_event.h"
+#include "../probe.h"
 
 MODULE_LICENSE("GPL");
 
@@ -75,6 +76,17 @@ MODULE_LICENSE("GPL");
 #define INTEL_RAPL_PSYS		0x5	/* pseudo-encoding */
 
 #define NR_RAPL_DOMAINS         0x5
+
+enum perf_rapl_events {
+	PERF_RAPL_PP0 = 0,		/* all cores */
+	PERF_RAPL_PKG,			/* entire package */
+	PERF_RAPL_RAM,			/* DRAM */
+	PERF_RAPL_PP1,			/* gpu */
+	PERF_RAPL_PSYS,			/* psys */
+
+	PERF_RAPL_MAX,
+};
+
 static const char *const rapl_domain_names[NR_RAPL_DOMAINS] __initconst = {
 	"pp0-core",
 	"package",
@@ -152,6 +164,11 @@ struct rapl_pmus {
 	struct rapl_pmu		*pmus[];
 };
 
+struct rapl_model {
+	unsigned long	events;
+	bool		apply_quirk;
+};
+
  /* 1/2^hw_unit Joule */
 static int rapl_hw_unit[NR_RAPL_DOMAINS] __read_mostly;
 static struct rapl_pmus *rapl_pmus;
@@ -560,6 +577,54 @@ static const struct attribute_group *rapl_attr_groups[] = {
 	NULL,
 };
 
+static struct attribute *rapl_events_cores[] = {
+	EVENT_PTR(rapl_cores),
+	EVENT_PTR(rapl_cores_unit),
+	EVENT_PTR(rapl_cores_scale),
+	NULL,
+};
+
+static struct attribute *rapl_events_pkg[] = {
+	EVENT_PTR(rapl_pkg),
+	EVENT_PTR(rapl_pkg_unit),
+	EVENT_PTR(rapl_pkg_scale),
+	NULL,
+};
+
+static struct attribute *rapl_events_ram[] = {
+	EVENT_PTR(rapl_ram),
+	EVENT_PTR(rapl_ram_unit),
+	EVENT_PTR(rapl_ram_scale),
+	NULL,
+};
+
+static struct attribute *rapl_events_gpu[] = {
+	EVENT_PTR(rapl_gpu),
+	EVENT_PTR(rapl_gpu_unit),
+	EVENT_PTR(rapl_gpu_scale),
+	NULL,
+};
+
+static struct attribute *rapl_events_psys[] = {
+	EVENT_PTR(rapl_psys),
+	EVENT_PTR(rapl_psys_unit),
+	EVENT_PTR(rapl_psys_scale),
+	NULL,
+};
+
+static bool test_msr(int idx, void *data)
+{
+	return test_bit(idx, (unsigned long *) data);
+}
+
+static struct perf_msr rapl_msrs[] = {
+	[PERF_RAPL_PP0]  = { MSR_PP0_ENERGY_STATUS,      rapl_events_cores,	test_msr },
+	[PERF_RAPL_PKG]  = { MSR_PKG_ENERGY_STATUS,      rapl_events_pkg,	test_msr },
+	[PERF_RAPL_RAM]  = { MSR_DRAM_ENERGY_STATUS,     rapl_events_ram,	test_msr },
+	[PERF_RAPL_PP1]  = { MSR_PP1_ENERGY_STATUS,      rapl_events_gpu,	test_msr },
+	[PERF_RAPL_PSYS] = { MSR_PLATFORM_ENERGY_STATUS, rapl_events_psys,	test_msr },
+};
+
 static int rapl_cpu_offline(unsigned int cpu)
 {
 	struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu);
@@ -780,13 +845,97 @@ static const struct x86_cpu_id rapl_cpu_match[] __initconst = {
 
 MODULE_DEVICE_TABLE(x86cpu, rapl_cpu_match);
 
+static struct rapl_model model_snb = {
+	.events		= BIT(PERF_RAPL_PP0) |
+			  BIT(PERF_RAPL_PKG) |
+			  BIT(PERF_RAPL_PP1),
+	.apply_quirk	= false,
+};
+
+static struct rapl_model model_snbep = {
+	.events		= BIT(PERF_RAPL_PP0) |
+			  BIT(PERF_RAPL_PKG) |
+			  BIT(PERF_RAPL_RAM),
+	.apply_quirk	= false,
+};
+
+static struct rapl_model model_hsw = {
+	.events		= BIT(PERF_RAPL_PP0) |
+			  BIT(PERF_RAPL_PKG) |
+			  BIT(PERF_RAPL_PP1) |
+			  BIT(PERF_RAPL_RAM),
+	.apply_quirk	= false,
+};
+
+static struct rapl_model model_hsx = {
+	.events		= BIT(PERF_RAPL_PP0) |
+			  BIT(PERF_RAPL_PKG) |
+			  BIT(PERF_RAPL_RAM),
+	.apply_quirk	= true,
+};
+
+static struct rapl_model model_knl = {
+	.events		= BIT(PERF_RAPL_PKG) |
+			  BIT(PERF_RAPL_RAM),
+	.apply_quirk	= true,
+};
+
+static struct rapl_model model_skl = {
+	.events		= BIT(PERF_RAPL_PP0) |
+			  BIT(PERF_RAPL_PKG) |
+			  BIT(PERF_RAPL_PP1) |
+			  BIT(PERF_RAPL_RAM) |
+			  BIT(PERF_RAPL_PSYS),
+	.apply_quirk	= false,
+};
+
+static const struct x86_cpu_id rapl_model_match[] __initconst = {
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_SANDYBRIDGE,		model_snb),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_SANDYBRIDGE_X,		model_snbep),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_IVYBRIDGE,		model_snb),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_IVYBRIDGE_X,		model_snbep),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_CORE,		model_hsw),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_X,		model_hsx),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_ULT,		model_hsw),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_GT3E,		model_hsw),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_CORE,		model_hsw),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_GT3E,		model_hsw),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_X,		model_hsx),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_XEON_D,	model_hsx),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNL,		model_knl),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNM,		model_knl),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_MOBILE,		model_skl),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_DESKTOP,	model_skl),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_X,		model_hsx),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_KABYLAKE_MOBILE,	model_skl),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_KABYLAKE_DESKTOP,	model_skl),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_CANNONLAKE_MOBILE,	model_skl),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT,		model_hsw),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT_X,	model_hsw),
+	X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT_PLUS,	model_hsw),
+	{},
+};
+
+static struct attribute *rapl_events_attrs[PERF_RAPL_MAX*3 + 1] = {
+	NULL,
+};
+
 static int __init rapl_pmu_init(void)
 {
 	const struct x86_cpu_id *id;
 	struct intel_rapl_init_fun *rapl_init;
+	struct rapl_model *rm;
 	bool apply_quirk;
 	int ret;
 
+	id = x86_match_cpu(rapl_model_match);
+	if (!id)
+		return -ENODEV;
+
+	rm = (struct rapl_model *)id->driver_data;
+	perf_msr_probe(rapl_msrs, PERF_RAPL_MAX,
+		       rapl_events_attrs, (void *) &rm->events);
+
 	id = x86_match_cpu(rapl_cpu_match);
 	if (!id)
 		return -ENODEV;
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 5/8] perf/x86/rapl: Get rapl_cntr_mask from new probe framework
  2019-03-18 18:21 [RFC 0/8] perf/x86: Add msr probe interface Jiri Olsa
                   ` (3 preceding siblings ...)
  2019-03-18 18:21 ` [PATCH 4/8] perf/x86/rapl: Use new msr detection interface Jiri Olsa
@ 2019-03-18 18:21 ` Jiri Olsa
  2019-03-18 18:21 ` [PATCH 6/8] perf/x86/rapl: Get msr values " Jiri Olsa
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Jiri Olsa @ 2019-03-18 18:21 UTC (permalink / raw)
  To: Peter Zijlstra, Liang, Kan, Stephane Eranian, Andy Lutomirski
  Cc: lkml, Ingo Molnar, Namhyung Kim, Alexander Shishkin, Andi Kleen,
	Vince Weaver, Thomas Gleixner, Arnaldo Carvalho de Melo

We get rapl_cntr_mask from perf_msr_probe call, as a replacement
for current intel_rapl_init_fun::cntr_mask value for each model.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 arch/x86/events/intel/rapl.c | 39 ++----------------------------------
 1 file changed, 2 insertions(+), 37 deletions(-)

diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c
index 5bd6c3d963fb..bef547583338 100644
--- a/arch/x86/events/intel/rapl.c
+++ b/arch/x86/events/intel/rapl.c
@@ -95,33 +95,6 @@ static const char *const rapl_domain_names[NR_RAPL_DOMAINS] __initconst = {
 	"psys",
 };
 
-/* Clients have PP0, PKG */
-#define RAPL_IDX_CLN	(1<<RAPL_IDX_PP0_NRG_STAT|\
-			 1<<RAPL_IDX_PKG_NRG_STAT|\
-			 1<<RAPL_IDX_PP1_NRG_STAT)
-
-/* Servers have PP0, PKG, RAM */
-#define RAPL_IDX_SRV	(1<<RAPL_IDX_PP0_NRG_STAT|\
-			 1<<RAPL_IDX_PKG_NRG_STAT|\
-			 1<<RAPL_IDX_RAM_NRG_STAT)
-
-/* Servers have PP0, PKG, RAM, PP1 */
-#define RAPL_IDX_HSW	(1<<RAPL_IDX_PP0_NRG_STAT|\
-			 1<<RAPL_IDX_PKG_NRG_STAT|\
-			 1<<RAPL_IDX_RAM_NRG_STAT|\
-			 1<<RAPL_IDX_PP1_NRG_STAT)
-
-/* SKL clients have PP0, PKG, RAM, PP1, PSYS */
-#define RAPL_IDX_SKL_CLN (1<<RAPL_IDX_PP0_NRG_STAT|\
-			  1<<RAPL_IDX_PKG_NRG_STAT|\
-			  1<<RAPL_IDX_RAM_NRG_STAT|\
-			  1<<RAPL_IDX_PP1_NRG_STAT|\
-			  1<<RAPL_IDX_PSYS_NRG_STAT)
-
-/* Knights Landing has PKG, RAM */
-#define RAPL_IDX_KNL	(1<<RAPL_IDX_PKG_NRG_STAT|\
-			 1<<RAPL_IDX_RAM_NRG_STAT)
-
 /*
  * event code: LSB 8 bits, passed in attr->config
  * any other bit is reserved
@@ -767,43 +740,36 @@ static int __init init_rapl_pmus(void)
 
 struct intel_rapl_init_fun {
 	bool apply_quirk;
-	int cntr_mask;
 	struct attribute **attrs;
 };
 
 static const struct intel_rapl_init_fun snb_rapl_init __initconst = {
 	.apply_quirk = false,
-	.cntr_mask = RAPL_IDX_CLN,
 	.attrs = rapl_events_cln_attr,
 };
 
 static const struct intel_rapl_init_fun hsx_rapl_init __initconst = {
 	.apply_quirk = true,
-	.cntr_mask = RAPL_IDX_SRV,
 	.attrs = rapl_events_srv_attr,
 };
 
 static const struct intel_rapl_init_fun hsw_rapl_init __initconst = {
 	.apply_quirk = false,
-	.cntr_mask = RAPL_IDX_HSW,
 	.attrs = rapl_events_hsw_attr,
 };
 
 static const struct intel_rapl_init_fun snbep_rapl_init __initconst = {
 	.apply_quirk = false,
-	.cntr_mask = RAPL_IDX_SRV,
 	.attrs = rapl_events_srv_attr,
 };
 
 static const struct intel_rapl_init_fun knl_rapl_init __initconst = {
 	.apply_quirk = true,
-	.cntr_mask = RAPL_IDX_KNL,
 	.attrs = rapl_events_knl_attr,
 };
 
 static const struct intel_rapl_init_fun skl_rapl_init __initconst = {
 	.apply_quirk = false,
-	.cntr_mask = RAPL_IDX_SKL_CLN,
 	.attrs = rapl_events_skl_attr,
 };
 
@@ -933,8 +899,8 @@ static int __init rapl_pmu_init(void)
 		return -ENODEV;
 
 	rm = (struct rapl_model *)id->driver_data;
-	perf_msr_probe(rapl_msrs, PERF_RAPL_MAX,
-		       rapl_events_attrs, (void *) &rm->events);
+	rapl_cntr_mask = perf_msr_probe(rapl_msrs, PERF_RAPL_MAX,
+					rapl_events_attrs, (void *) &rm->events);
 
 	id = x86_match_cpu(rapl_cpu_match);
 	if (!id)
@@ -942,7 +908,6 @@ static int __init rapl_pmu_init(void)
 
 	rapl_init = (struct intel_rapl_init_fun *)id->driver_data;
 	apply_quirk = rapl_init->apply_quirk;
-	rapl_cntr_mask = rapl_init->cntr_mask;
 	rapl_pmu_events_group.attrs = rapl_init->attrs;
 
 	ret = rapl_check_hw_unit(apply_quirk);
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 6/8] perf/x86/rapl: Get msr values from new probe framework
  2019-03-18 18:21 [RFC 0/8] perf/x86: Add msr probe interface Jiri Olsa
                   ` (4 preceding siblings ...)
  2019-03-18 18:21 ` [PATCH 5/8] perf/x86/rapl: Get rapl_cntr_mask from new probe framework Jiri Olsa
@ 2019-03-18 18:21 ` Jiri Olsa
  2019-03-18 18:21 ` [PATCH 7/8] perf/x86/rapl: Get attributes " Jiri Olsa
  2019-03-18 18:21 ` [PATCH 8/8] perf/x86/rapl: Get quirk state " Jiri Olsa
  7 siblings, 0 replies; 12+ messages in thread
From: Jiri Olsa @ 2019-03-18 18:21 UTC (permalink / raw)
  To: Peter Zijlstra, Liang, Kan, Stephane Eranian, Andy Lutomirski
  Cc: lkml, Ingo Molnar, Namhyung Kim, Alexander Shishkin, Andi Kleen,
	Vince Weaver, Thomas Gleixner, Arnaldo Carvalho de Melo

There's no need to have special code for getting
the bit and msr value for given event. We can
now easily get it from rapl_msrs array.

Also getting rid of RAPL_IDX_*, which is no longer
needed and replacing INTEL_RAPL* with PERF_RAPL*
enums.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 arch/x86/events/intel/rapl.c | 53 ++++++++----------------------------
 1 file changed, 11 insertions(+), 42 deletions(-)

diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c
index bef547583338..870a676641c0 100644
--- a/arch/x86/events/intel/rapl.c
+++ b/arch/x86/events/intel/rapl.c
@@ -54,6 +54,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/perf_event.h>
+#include <linux/nospec.h>
 #include <asm/cpu_device_id.h>
 #include <asm/intel-family.h>
 #include "../perf_event.h"
@@ -64,19 +65,6 @@ MODULE_LICENSE("GPL");
 /*
  * RAPL energy status counters
  */
-#define RAPL_IDX_PP0_NRG_STAT	0	/* all cores */
-#define INTEL_RAPL_PP0		0x1	/* pseudo-encoding */
-#define RAPL_IDX_PKG_NRG_STAT	1	/* entire package */
-#define INTEL_RAPL_PKG		0x2	/* pseudo-encoding */
-#define RAPL_IDX_RAM_NRG_STAT	2	/* DRAM */
-#define INTEL_RAPL_RAM		0x3	/* pseudo-encoding */
-#define RAPL_IDX_PP1_NRG_STAT	3	/* gpu */
-#define INTEL_RAPL_PP1		0x4	/* pseudo-encoding */
-#define RAPL_IDX_PSYS_NRG_STAT	4	/* psys */
-#define INTEL_RAPL_PSYS		0x5	/* pseudo-encoding */
-
-#define NR_RAPL_DOMAINS         0x5
-
 enum perf_rapl_events {
 	PERF_RAPL_PP0 = 0,		/* all cores */
 	PERF_RAPL_PKG,			/* entire package */
@@ -85,6 +73,7 @@ enum perf_rapl_events {
 	PERF_RAPL_PSYS,			/* psys */
 
 	PERF_RAPL_MAX,
+	NR_RAPL_DOMAINS = PERF_RAPL_MAX,
 };
 
 static const char *const rapl_domain_names[NR_RAPL_DOMAINS] __initconst = {
@@ -148,6 +137,7 @@ static struct rapl_pmus *rapl_pmus;
 static cpumask_t rapl_cpu_mask;
 static unsigned int rapl_cntr_mask;
 static u64 rapl_timer_ms;
+static struct perf_msr rapl_msrs[];
 
 static inline struct rapl_pmu *cpu_to_rapl_pmu(unsigned int cpu)
 {
@@ -339,7 +329,7 @@ static void rapl_pmu_event_del(struct perf_event *event, int flags)
 static int rapl_pmu_event_init(struct perf_event *event)
 {
 	u64 cfg = event->attr.config & RAPL_EVENT_MASK;
-	int bit, msr, ret = 0;
+	int bit, ret = 0;
 	struct rapl_pmu *pmu;
 
 	/* only look at RAPL events */
@@ -355,33 +345,12 @@ static int rapl_pmu_event_init(struct perf_event *event)
 
 	event->event_caps |= PERF_EV_CAP_READ_ACTIVE_PKG;
 
-	/*
-	 * check event is known (determines counter)
-	 */
-	switch (cfg) {
-	case INTEL_RAPL_PP0:
-		bit = RAPL_IDX_PP0_NRG_STAT;
-		msr = MSR_PP0_ENERGY_STATUS;
-		break;
-	case INTEL_RAPL_PKG:
-		bit = RAPL_IDX_PKG_NRG_STAT;
-		msr = MSR_PKG_ENERGY_STATUS;
-		break;
-	case INTEL_RAPL_RAM:
-		bit = RAPL_IDX_RAM_NRG_STAT;
-		msr = MSR_DRAM_ENERGY_STATUS;
-		break;
-	case INTEL_RAPL_PP1:
-		bit = RAPL_IDX_PP1_NRG_STAT;
-		msr = MSR_PP1_ENERGY_STATUS;
-		break;
-	case INTEL_RAPL_PSYS:
-		bit = RAPL_IDX_PSYS_NRG_STAT;
-		msr = MSR_PLATFORM_ENERGY_STATUS;
-		break;
-	default:
+	if (!cfg || cfg >= NR_RAPL_DOMAINS + 1)
 		return -EINVAL;
-	}
+
+	cfg = array_index_nospec(cfg, NR_RAPL_DOMAINS + 1);
+	bit = cfg - 1;
+
 	/* check event supported */
 	if (!(rapl_cntr_mask & (1 << bit)))
 		return -EINVAL;
@@ -396,7 +365,7 @@ static int rapl_pmu_event_init(struct perf_event *event)
 		return -EINVAL;
 	event->cpu = pmu->cpu;
 	event->pmu_private = pmu;
-	event->hw.event_base = msr;
+	event->hw.event_base = rapl_msrs[bit].msr;
 	event->hw.config = cfg;
 	event->hw.idx = bit;
 
@@ -670,7 +639,7 @@ static int rapl_check_hw_unit(bool apply_quirk)
 	 * of 2. Datasheet, September 2014, Reference Number: 330784-001 "
 	 */
 	if (apply_quirk)
-		rapl_hw_unit[RAPL_IDX_RAM_NRG_STAT] = 16;
+		rapl_hw_unit[PERF_RAPL_RAM] = 16;
 
 	/*
 	 * Calculate the timer rate:
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 7/8] perf/x86/rapl: Get attributes from new probe framework
  2019-03-18 18:21 [RFC 0/8] perf/x86: Add msr probe interface Jiri Olsa
                   ` (5 preceding siblings ...)
  2019-03-18 18:21 ` [PATCH 6/8] perf/x86/rapl: Get msr values " Jiri Olsa
@ 2019-03-18 18:21 ` Jiri Olsa
  2019-03-18 18:21 ` [PATCH 8/8] perf/x86/rapl: Get quirk state " Jiri Olsa
  7 siblings, 0 replies; 12+ messages in thread
From: Jiri Olsa @ 2019-03-18 18:21 UTC (permalink / raw)
  To: Peter Zijlstra, Liang, Kan, Stephane Eranian, Andy Lutomirski
  Cc: lkml, Ingo Molnar, Namhyung Kim, Alexander Shishkin, Andi Kleen,
	Vince Weaver, Thomas Gleixner, Arnaldo Carvalho de Melo

We no longer need model specific attribute arrays,
because we get all this detected in rapl_events_attrs.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 arch/x86/events/intel/rapl.c | 90 +-----------------------------------
 1 file changed, 1 insertion(+), 89 deletions(-)

diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c
index 870a676641c0..065c2a8f8f9c 100644
--- a/arch/x86/events/intel/rapl.c
+++ b/arch/x86/events/intel/rapl.c
@@ -415,87 +415,6 @@ RAPL_EVENT_ATTR_STR(energy-ram.scale,     rapl_ram_scale, "2.3283064365386962890
 RAPL_EVENT_ATTR_STR(energy-gpu.scale,     rapl_gpu_scale, "2.3283064365386962890625e-10");
 RAPL_EVENT_ATTR_STR(energy-psys.scale,   rapl_psys_scale, "2.3283064365386962890625e-10");
 
-static struct attribute *rapl_events_srv_attr[] = {
-	EVENT_PTR(rapl_cores),
-	EVENT_PTR(rapl_pkg),
-	EVENT_PTR(rapl_ram),
-
-	EVENT_PTR(rapl_cores_unit),
-	EVENT_PTR(rapl_pkg_unit),
-	EVENT_PTR(rapl_ram_unit),
-
-	EVENT_PTR(rapl_cores_scale),
-	EVENT_PTR(rapl_pkg_scale),
-	EVENT_PTR(rapl_ram_scale),
-	NULL,
-};
-
-static struct attribute *rapl_events_cln_attr[] = {
-	EVENT_PTR(rapl_cores),
-	EVENT_PTR(rapl_pkg),
-	EVENT_PTR(rapl_gpu),
-
-	EVENT_PTR(rapl_cores_unit),
-	EVENT_PTR(rapl_pkg_unit),
-	EVENT_PTR(rapl_gpu_unit),
-
-	EVENT_PTR(rapl_cores_scale),
-	EVENT_PTR(rapl_pkg_scale),
-	EVENT_PTR(rapl_gpu_scale),
-	NULL,
-};
-
-static struct attribute *rapl_events_hsw_attr[] = {
-	EVENT_PTR(rapl_cores),
-	EVENT_PTR(rapl_pkg),
-	EVENT_PTR(rapl_gpu),
-	EVENT_PTR(rapl_ram),
-
-	EVENT_PTR(rapl_cores_unit),
-	EVENT_PTR(rapl_pkg_unit),
-	EVENT_PTR(rapl_gpu_unit),
-	EVENT_PTR(rapl_ram_unit),
-
-	EVENT_PTR(rapl_cores_scale),
-	EVENT_PTR(rapl_pkg_scale),
-	EVENT_PTR(rapl_gpu_scale),
-	EVENT_PTR(rapl_ram_scale),
-	NULL,
-};
-
-static struct attribute *rapl_events_skl_attr[] = {
-	EVENT_PTR(rapl_cores),
-	EVENT_PTR(rapl_pkg),
-	EVENT_PTR(rapl_gpu),
-	EVENT_PTR(rapl_ram),
-	EVENT_PTR(rapl_psys),
-
-	EVENT_PTR(rapl_cores_unit),
-	EVENT_PTR(rapl_pkg_unit),
-	EVENT_PTR(rapl_gpu_unit),
-	EVENT_PTR(rapl_ram_unit),
-	EVENT_PTR(rapl_psys_unit),
-
-	EVENT_PTR(rapl_cores_scale),
-	EVENT_PTR(rapl_pkg_scale),
-	EVENT_PTR(rapl_gpu_scale),
-	EVENT_PTR(rapl_ram_scale),
-	EVENT_PTR(rapl_psys_scale),
-	NULL,
-};
-
-static struct attribute *rapl_events_knl_attr[] = {
-	EVENT_PTR(rapl_pkg),
-	EVENT_PTR(rapl_ram),
-
-	EVENT_PTR(rapl_pkg_unit),
-	EVENT_PTR(rapl_ram_unit),
-
-	EVENT_PTR(rapl_pkg_scale),
-	EVENT_PTR(rapl_ram_scale),
-	NULL,
-};
-
 static struct attribute_group rapl_pmu_events_group = {
 	.name = "events",
 	.attrs = NULL, /* patched at runtime */
@@ -709,37 +628,30 @@ static int __init init_rapl_pmus(void)
 
 struct intel_rapl_init_fun {
 	bool apply_quirk;
-	struct attribute **attrs;
 };
 
 static const struct intel_rapl_init_fun snb_rapl_init __initconst = {
 	.apply_quirk = false,
-	.attrs = rapl_events_cln_attr,
 };
 
 static const struct intel_rapl_init_fun hsx_rapl_init __initconst = {
 	.apply_quirk = true,
-	.attrs = rapl_events_srv_attr,
 };
 
 static const struct intel_rapl_init_fun hsw_rapl_init __initconst = {
 	.apply_quirk = false,
-	.attrs = rapl_events_hsw_attr,
 };
 
 static const struct intel_rapl_init_fun snbep_rapl_init __initconst = {
 	.apply_quirk = false,
-	.attrs = rapl_events_srv_attr,
 };
 
 static const struct intel_rapl_init_fun knl_rapl_init __initconst = {
 	.apply_quirk = true,
-	.attrs = rapl_events_knl_attr,
 };
 
 static const struct intel_rapl_init_fun skl_rapl_init __initconst = {
 	.apply_quirk = false,
-	.attrs = rapl_events_skl_attr,
 };
 
 static const struct x86_cpu_id rapl_cpu_match[] __initconst = {
@@ -877,7 +789,7 @@ static int __init rapl_pmu_init(void)
 
 	rapl_init = (struct intel_rapl_init_fun *)id->driver_data;
 	apply_quirk = rapl_init->apply_quirk;
-	rapl_pmu_events_group.attrs = rapl_init->attrs;
+	rapl_pmu_events_group.attrs = rapl_events_attrs;
 
 	ret = rapl_check_hw_unit(apply_quirk);
 	if (ret)
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 8/8] perf/x86/rapl: Get quirk state from new probe framework
  2019-03-18 18:21 [RFC 0/8] perf/x86: Add msr probe interface Jiri Olsa
                   ` (6 preceding siblings ...)
  2019-03-18 18:21 ` [PATCH 7/8] perf/x86/rapl: Get attributes " Jiri Olsa
@ 2019-03-18 18:21 ` Jiri Olsa
  7 siblings, 0 replies; 12+ messages in thread
From: Jiri Olsa @ 2019-03-18 18:21 UTC (permalink / raw)
  To: Peter Zijlstra, Liang, Kan, Stephane Eranian, Andy Lutomirski
  Cc: lkml, Ingo Molnar, Namhyung Kim, Alexander Shishkin, Andi Kleen,
	Vince Weaver, Thomas Gleixner, Arnaldo Carvalho de Melo

Getting the apply_quirk bool from new rapl_model_match array.

And because apply_quirk was the last remaining piece of data
in rapl_cpu_match, replacing it with rapl_model_match as device
table.

The switch to new perf_msr_probe detection API is done.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 arch/x86/events/intel/rapl.c | 78 ++----------------------------------
 1 file changed, 3 insertions(+), 75 deletions(-)

diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c
index 065c2a8f8f9c..9e14a856e529 100644
--- a/arch/x86/events/intel/rapl.c
+++ b/arch/x86/events/intel/rapl.c
@@ -626,72 +626,6 @@ static int __init init_rapl_pmus(void)
 #define X86_RAPL_MODEL_MATCH(model, init)	\
 	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&init }
 
-struct intel_rapl_init_fun {
-	bool apply_quirk;
-};
-
-static const struct intel_rapl_init_fun snb_rapl_init __initconst = {
-	.apply_quirk = false,
-};
-
-static const struct intel_rapl_init_fun hsx_rapl_init __initconst = {
-	.apply_quirk = true,
-};
-
-static const struct intel_rapl_init_fun hsw_rapl_init __initconst = {
-	.apply_quirk = false,
-};
-
-static const struct intel_rapl_init_fun snbep_rapl_init __initconst = {
-	.apply_quirk = false,
-};
-
-static const struct intel_rapl_init_fun knl_rapl_init __initconst = {
-	.apply_quirk = true,
-};
-
-static const struct intel_rapl_init_fun skl_rapl_init __initconst = {
-	.apply_quirk = false,
-};
-
-static const struct x86_cpu_id rapl_cpu_match[] __initconst = {
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_SANDYBRIDGE,   snb_rapl_init),
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_SANDYBRIDGE_X, snbep_rapl_init),
-
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_IVYBRIDGE,   snb_rapl_init),
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_IVYBRIDGE_X, snbep_rapl_init),
-
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_CORE, hsw_rapl_init),
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_X,    hsx_rapl_init),
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_ULT,  hsw_rapl_init),
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_GT3E, hsw_rapl_init),
-
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_CORE,   hsw_rapl_init),
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_GT3E,   hsw_rapl_init),
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_X,	  hsx_rapl_init),
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_XEON_D, hsx_rapl_init),
-
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNL, knl_rapl_init),
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNM, knl_rapl_init),
-
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_MOBILE,  skl_rapl_init),
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_DESKTOP, skl_rapl_init),
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_X,	 hsx_rapl_init),
-
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_KABYLAKE_MOBILE,  skl_rapl_init),
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_KABYLAKE_DESKTOP, skl_rapl_init),
-
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_CANNONLAKE_MOBILE,  skl_rapl_init),
-
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT, hsw_rapl_init),
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT_X, hsw_rapl_init),
-
-	X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT_PLUS, hsw_rapl_init),
-	{},
-};
-
-MODULE_DEVICE_TABLE(x86cpu, rapl_cpu_match);
-
 static struct rapl_model model_snb = {
 	.events		= BIT(PERF_RAPL_PP0) |
 			  BIT(PERF_RAPL_PKG) |
@@ -763,6 +697,8 @@ static const struct x86_cpu_id rapl_model_match[] __initconst = {
 	{},
 };
 
+MODULE_DEVICE_TABLE(x86cpu, rapl_model_match);
+
 static struct attribute *rapl_events_attrs[PERF_RAPL_MAX*3 + 1] = {
 	NULL,
 };
@@ -770,9 +706,7 @@ static struct attribute *rapl_events_attrs[PERF_RAPL_MAX*3 + 1] = {
 static int __init rapl_pmu_init(void)
 {
 	const struct x86_cpu_id *id;
-	struct intel_rapl_init_fun *rapl_init;
 	struct rapl_model *rm;
-	bool apply_quirk;
 	int ret;
 
 	id = x86_match_cpu(rapl_model_match);
@@ -783,15 +717,9 @@ static int __init rapl_pmu_init(void)
 	rapl_cntr_mask = perf_msr_probe(rapl_msrs, PERF_RAPL_MAX,
 					rapl_events_attrs, (void *) &rm->events);
 
-	id = x86_match_cpu(rapl_cpu_match);
-	if (!id)
-		return -ENODEV;
-
-	rapl_init = (struct intel_rapl_init_fun *)id->driver_data;
-	apply_quirk = rapl_init->apply_quirk;
 	rapl_pmu_events_group.attrs = rapl_events_attrs;
 
-	ret = rapl_check_hw_unit(apply_quirk);
+	ret = rapl_check_hw_unit(rm->apply_quirk);
 	if (ret)
 		return ret;
 
-- 
2.17.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/8] perf/x86: Add msr probe interface
  2019-03-18 18:21 ` [PATCH 1/8] " Jiri Olsa
@ 2019-03-20 15:48   ` Peter Zijlstra
  2019-03-20 16:03     ` Greg Kroah-Hartman
  0 siblings, 1 reply; 12+ messages in thread
From: Peter Zijlstra @ 2019-03-20 15:48 UTC (permalink / raw)
  To: Jiri Olsa, Greg Kroah-Hartman
  Cc: Liang, Kan, Stephane Eranian, Andy Lutomirski, lkml, Ingo Molnar,
	Namhyung Kim, Alexander Shishkin, Andi Kleen, Vince Weaver,
	Thomas Gleixner, Arnaldo Carvalho de Melo

On Mon, Mar 18, 2019 at 07:21:09PM +0100, Jiri Olsa wrote:
> Adding perf_msr_probe function to provide interface for
> checking up on MSR register and add its related event
> attributes if it passes the check.
> 
> User defines following struct for each MSR register:
> 
>   struct perf_msr {
>        u64                       msr;
>        struct attribute        **attrs;
>        bool                    (*test)(int idx, void *data);
>        bool                      no_check;
>   };
> 
> Where:
>   msr      - is the MSR address
>   attrs    - is attributes array to add if the check passed
>   test     - is test function pointer
>   no_check - is bool that bypass the check and adds the
>               attribute without any test
> 
> The array of struct perf_msr is passed into:
> 
>   perf_msr_probe(struct perf_msr *msr, int cnt,
>                 struct attribute **attrs, void *data)
> 
> Together with:
>   cnt   - which is the number of struct msr array elements
>   attrs - which is an array placeholder for added attributes
>           and needs to be big enough
>   data  -which is user pointer passed to the test function
> 
> The perf_msr_probe will executed test code, read the MSR and
> check the value is != 0. If all these tests pass, related
> attributes are added into attrs array.
> 
> Also adding MSR_ATTR macro helper to define attribute array
> from single attribute. It will be used in following patches.

Somewhere along the line you lost the explanation of _why_ we're doing
this; namely: virt sucks.

Also, recently GregKH had a chance to look at perf code and we scored
fairly high on the WTF'o'meter for what we're doing with the attribute
stuff.

He pointed me to sysfs attribute_group::is_visible functions to replace
some of our 'creative' code.

> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  arch/x86/events/Makefile |  2 +-
>  arch/x86/events/probe.c  | 36 ++++++++++++++++++++++++++++++++++++
>  arch/x86/events/probe.h  | 22 ++++++++++++++++++++++
>  3 files changed, 59 insertions(+), 1 deletion(-)
>  create mode 100644 arch/x86/events/probe.c
>  create mode 100644 arch/x86/events/probe.h
> 
> diff --git a/arch/x86/events/Makefile b/arch/x86/events/Makefile
> index b8ccdb5c9244..ec29a466444a 100644
> --- a/arch/x86/events/Makefile
> +++ b/arch/x86/events/Makefile
> @@ -1,4 +1,4 @@
> -obj-y					+= core.o
> +obj-y					+= core.o probe.o
>  obj-y					+= amd/
>  obj-$(CONFIG_X86_LOCAL_APIC)            += msr.o
>  obj-$(CONFIG_CPU_SUP_INTEL)		+= intel/
> diff --git a/arch/x86/events/probe.c b/arch/x86/events/probe.c
> new file mode 100644
> index 000000000000..0052b730c55e
> --- /dev/null
> +++ b/arch/x86/events/probe.c
> @@ -0,0 +1,36 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <linux/export.h>
> +#include <linux/bits.h>
> +#include "probe.h"
> +
> +unsigned long
> +perf_msr_probe(struct perf_msr *msr, int cnt,
> +	       struct attribute **attrs, void *data)
> +{
> +	unsigned long avail = 0;
> +	unsigned int bit;
> +	u64 val;
> +
> +	if (cnt >= BITS_PER_LONG)
> +		return 0;
> +
> +	for (bit = 0; bit < cnt; bit++) {
> +		struct attribute **a = msr[bit].attrs;
> +
> +		if (!msr[bit].no_check) {
> +			if (msr[bit].test && !msr[bit].test(bit, data))
> +				continue;
> +			if (rdmsrl_safe(msr[bit].msr, &val) || !val)
> +				continue;
> +		}
> +
> +		while (*a)
> +			*attrs++ = *a++;
> +
> +		avail |= bit;
> +	}
> +
> +	*attrs = NULL;
> +	return avail;
> +}
> +EXPORT_SYMBOL_GPL(perf_msr_probe);
> diff --git a/arch/x86/events/probe.h b/arch/x86/events/probe.h
> new file mode 100644
> index 000000000000..42dd666533c3
> --- /dev/null
> +++ b/arch/x86/events/probe.h
> @@ -0,0 +1,22 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __ARCH_X86_EVENTS_PROBE_H__
> +#define __ARCH_X86_EVENTS_PROBE_H__
> +#include <linux/sysfs.h>
> +
> +#define MSR_ATTR(__n)				\
> +static struct attribute *msr_##__n[] = {	\
> +	&__n.attr.attr,				\
> +	NULL,					\
> +}
> +
> +struct perf_msr {
> +	u64			  msr;
> +	struct attribute	**attrs;
> +	bool			(*test)(int idx, void *data);
> +	bool			  no_check;
> +};
> +
> +unsigned long
> +perf_msr_probe(struct perf_msr *msr, int cnt,
> +	       struct attribute **attrs, void *data);
> +#endif /* __ARCH_X86_EVENTS_PROBE_H__ */
> -- 
> 2.17.2
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/8] perf/x86: Add msr probe interface
  2019-03-20 15:48   ` Peter Zijlstra
@ 2019-03-20 16:03     ` Greg Kroah-Hartman
  2019-03-21 11:09       ` Jiri Olsa
  0 siblings, 1 reply; 12+ messages in thread
From: Greg Kroah-Hartman @ 2019-03-20 16:03 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Jiri Olsa, Liang, Kan, Stephane Eranian, Andy Lutomirski, lkml,
	Ingo Molnar, Namhyung Kim, Alexander Shishkin, Andi Kleen,
	Vince Weaver, Thomas Gleixner, Arnaldo Carvalho de Melo

On Wed, Mar 20, 2019 at 04:48:33PM +0100, Peter Zijlstra wrote:
> On Mon, Mar 18, 2019 at 07:21:09PM +0100, Jiri Olsa wrote:
> > Adding perf_msr_probe function to provide interface for
> > checking up on MSR register and add its related event
> > attributes if it passes the check.
> > 
> > User defines following struct for each MSR register:
> > 
> >   struct perf_msr {
> >        u64                       msr;
> >        struct attribute        **attrs;

Please use attribute groups where ever possible.  I've been working to
fix up the remaining places that use list of attributes as that is not
flexible at all (and broken in places.)

And this is a device, so why not device attributes?

> >        bool                    (*test)(int idx, void *data);
> >        bool                      no_check;
> >   };
> > 
> > Where:
> >   msr      - is the MSR address
> >   attrs    - is attributes array to add if the check passed
> >   test     - is test function pointer
> >   no_check - is bool that bypass the check and adds the
> >               attribute without any test
> > 
> > The array of struct perf_msr is passed into:
> > 
> >   perf_msr_probe(struct perf_msr *msr, int cnt,
> >                 struct attribute **attrs, void *data)
> > 
> > Together with:
> >   cnt   - which is the number of struct msr array elements
> >   attrs - which is an array placeholder for added attributes
> >           and needs to be big enough
> >   data  -which is user pointer passed to the test function
> > 
> > The perf_msr_probe will executed test code, read the MSR and
> > check the value is != 0. If all these tests pass, related
> > attributes are added into attrs array.
> > 
> > Also adding MSR_ATTR macro helper to define attribute array
> > from single attribute. It will be used in following patches.

Please no, don't we have enough ATTR macros?  Why do you need another
one?  What are you trying to save code on?

> Somewhere along the line you lost the explanation of _why_ we're doing
> this; namely: virt sucks.
> 
> Also, recently GregKH had a chance to look at perf code and we scored
> fairly high on the WTF'o'meter for what we're doing with the attribute
> stuff.
> 
> He pointed me to sysfs attribute_group::is_visible functions to replace
> some of our 'creative' code.

Yes, that would be very good to do.  If no one is working on it, I can
take a look next week as I have long plane rides...

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/8] perf/x86: Add msr probe interface
  2019-03-20 16:03     ` Greg Kroah-Hartman
@ 2019-03-21 11:09       ` Jiri Olsa
  0 siblings, 0 replies; 12+ messages in thread
From: Jiri Olsa @ 2019-03-21 11:09 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Peter Zijlstra, Jiri Olsa, Liang, Kan, Stephane Eranian,
	Andy Lutomirski, lkml, Ingo Molnar, Namhyung Kim,
	Alexander Shishkin, Andi Kleen, Vince Weaver, Thomas Gleixner,
	Arnaldo Carvalho de Melo

On Wed, Mar 20, 2019 at 05:03:29PM +0100, Greg Kroah-Hartman wrote:
> On Wed, Mar 20, 2019 at 04:48:33PM +0100, Peter Zijlstra wrote:
> > On Mon, Mar 18, 2019 at 07:21:09PM +0100, Jiri Olsa wrote:
> > > Adding perf_msr_probe function to provide interface for
> > > checking up on MSR register and add its related event
> > > attributes if it passes the check.
> > > 
> > > User defines following struct for each MSR register:
> > > 
> > >   struct perf_msr {
> > >        u64                       msr;
> > >        struct attribute        **attrs;
> 
> Please use attribute groups where ever possible.  I've been working to
> fix up the remaining places that use list of attributes as that is not
> flexible at all (and broken in places.)
> 
> And this is a device, so why not device attributes?

ok, will check

> 
> > >        bool                    (*test)(int idx, void *data);
> > >        bool                      no_check;
> > >   };
> > > 
> > > Where:
> > >   msr      - is the MSR address
> > >   attrs    - is attributes array to add if the check passed
> > >   test     - is test function pointer
> > >   no_check - is bool that bypass the check and adds the
> > >               attribute without any test
> > > 
> > > The array of struct perf_msr is passed into:
> > > 
> > >   perf_msr_probe(struct perf_msr *msr, int cnt,
> > >                 struct attribute **attrs, void *data)
> > > 
> > > Together with:
> > >   cnt   - which is the number of struct msr array elements
> > >   attrs - which is an array placeholder for added attributes
> > >           and needs to be big enough
> > >   data  -which is user pointer passed to the test function
> > > 
> > > The perf_msr_probe will executed test code, read the MSR and
> > > check the value is != 0. If all these tests pass, related
> > > attributes are added into attrs array.
> > > 
> > > Also adding MSR_ATTR macro helper to define attribute array
> > > from single attribute. It will be used in following patches.
> 
> Please no, don't we have enough ATTR macros?  Why do you need another
> one?  What are you trying to save code on?
> 
> > Somewhere along the line you lost the explanation of _why_ we're doing
> > this; namely: virt sucks.
> > 
> > Also, recently GregKH had a chance to look at perf code and we scored
> > fairly high on the WTF'o'meter for what we're doing with the attribute
> > stuff.
> > 
> > He pointed me to sysfs attribute_group::is_visible functions to replace
> > some of our 'creative' code.
> 
> Yes, that would be very good to do.  If no one is working on it, I can
> take a look next week as I have long plane rides...

if I dont send v2 till then, it's all yours ;-)

thanks,
jirka

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2019-03-21 11:09 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-18 18:21 [RFC 0/8] perf/x86: Add msr probe interface Jiri Olsa
2019-03-18 18:21 ` [PATCH 1/8] " Jiri Olsa
2019-03-20 15:48   ` Peter Zijlstra
2019-03-20 16:03     ` Greg Kroah-Hartman
2019-03-21 11:09       ` Jiri Olsa
2019-03-18 18:21 ` [PATCH 2/8] perf/x86/msr: Use new probe function Jiri Olsa
2019-03-18 18:21 ` [PATCH 3/8] perf/x86/cstate: " Jiri Olsa
2019-03-18 18:21 ` [PATCH 4/8] perf/x86/rapl: Use new msr detection interface Jiri Olsa
2019-03-18 18:21 ` [PATCH 5/8] perf/x86/rapl: Get rapl_cntr_mask from new probe framework Jiri Olsa
2019-03-18 18:21 ` [PATCH 6/8] perf/x86/rapl: Get msr values " Jiri Olsa
2019-03-18 18:21 ` [PATCH 7/8] perf/x86/rapl: Get attributes " Jiri Olsa
2019-03-18 18:21 ` [PATCH 8/8] perf/x86/rapl: Get quirk state " Jiri Olsa

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).