Re: [PATCH 0/3] perf/core, x86: unify perfctr bitmasks

Previous thread: Extended partition mapping wrong size by Phillip Susi on Monday, March 29, 2010 - 9:11 am. (5 messages)

Next thread: lots of "bridge window ... (disabled)" messages by Luck, Tony on Monday, March 29, 2010 - 9:57 am. (2 messages)
From: Robert Richter
Date: Monday, March 29, 2010 - 9:36 am

This patch set unifies performance counter bit masks for x86. All mask
are almost the same for all x86 models and thus can use the same macro
definitions in arch/x86/include/asm/perf_event.h. It removes duplicate
code. There is also a patch that reverts some changes of the big
perf_counter -> perf_event rename.

-Robert


--

From: Robert Richter
Date: Monday, March 29, 2010 - 9:36 am

The function is the same as intel_pmu_raw_event(). This patch removes
the duplicate code.

Signed-off-by: Robert Richter <robert.richter@amd.com>
---
 arch/x86/kernel/cpu/perf_event.c       |    2 +-
 arch/x86/kernel/cpu/perf_event_intel.c |    2 ++
 arch/x86/kernel/cpu/perf_event_p6.c    |   20 +-------------------
 3 files changed, 4 insertions(+), 20 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index f2fc2d8..81218d0 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -1320,11 +1320,11 @@ undo:
 }
 
 #include "perf_event_amd.c"
-#include "perf_event_p6.c"
 #include "perf_event_p4.c"
 #include "perf_event_intel_lbr.c"
 #include "perf_event_intel_ds.c"
 #include "perf_event_intel.c"
+#include "perf_event_p6.c"
 
 static int __cpuinit
 x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 0d68531..6c5d83f 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -842,6 +842,8 @@ static __initconst struct x86_pmu intel_pmu = {
 	.cpu_dying		= intel_pmu_cpu_dying,
 };
 
+static __init int p6_pmu_init(void);
+
 static void intel_clovertown_quirks(void)
 {
 	/*
diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c
index b26fbc7..8cdd054 100644
--- a/arch/x86/kernel/cpu/perf_event_p6.c
+++ b/arch/x86/kernel/cpu/perf_event_p6.c
@@ -27,24 +27,6 @@ static u64 p6_pmu_event_map(int hw_event)
  */
 #define P6_NOP_EVENT			0x0000002EULL
 
-static u64 p6_pmu_raw_event(u64 hw_event)
-{
-#define P6_EVNTSEL_EVENT_MASK		0x000000FFULL
-#define P6_EVNTSEL_UNIT_MASK		0x0000FF00ULL
-#define P6_EVNTSEL_EDGE_MASK		0x00040000ULL
-#define P6_EVNTSEL_INV_MASK		0x00800000ULL
-#define P6_EVNTSEL_REG_MASK		0xFF000000ULL
-
-#define P6_EVNTSEL_MASK			\
-	(P6_EVNTSEL_EVENT_MASK |	\
-	 ...
From: Robert Richter
Date: Monday, March 29, 2010 - 9:36 am

ARCH_PERFMON_EVENTSEL bit masks are offen used in the kernel. This
patch adds macros for the bit masks and removes local defines.

Signed-off-by: Robert Richter <robert.richter@amd.com>
---
 arch/x86/include/asm/perf_event.h      |   58 ++++++++++++++------------------
 arch/x86/kernel/cpu/perf_event.c       |   14 ++++++--
 arch/x86/kernel/cpu/perf_event_amd.c   |   15 +--------
 arch/x86/kernel/cpu/perf_event_intel.c |   15 +--------
 4 files changed, 38 insertions(+), 64 deletions(-)

diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 987bf67..f6d43db 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -18,39 +18,31 @@
 #define MSR_ARCH_PERFMON_EVENTSEL0			     0x186
 #define MSR_ARCH_PERFMON_EVENTSEL1			     0x187
 
-#define ARCH_PERFMON_EVENTSEL_ENABLE			  (1 << 22)
-#define ARCH_PERFMON_EVENTSEL_ANY			  (1 << 21)
-#define ARCH_PERFMON_EVENTSEL_INT			  (1 << 20)
-#define ARCH_PERFMON_EVENTSEL_OS			  (1 << 17)
-#define ARCH_PERFMON_EVENTSEL_USR			  (1 << 16)
-
-/*
- * Includes eventsel and unit mask as well:
- */
-
-
-#define INTEL_ARCH_EVTSEL_MASK		0x000000FFULL
-#define INTEL_ARCH_UNIT_MASK		0x0000FF00ULL
-#define INTEL_ARCH_EDGE_MASK		0x00040000ULL
-#define INTEL_ARCH_INV_MASK		0x00800000ULL
-#define INTEL_ARCH_CNT_MASK		0xFF000000ULL
-#define INTEL_ARCH_EVENT_MASK	(INTEL_ARCH_UNIT_MASK|INTEL_ARCH_EVTSEL_MASK)
-
-/*
- * filter mask to validate fixed counter events.
- * the following filters disqualify for fixed counters:
- *  - inv
- *  - edge
- *  - cnt-mask
- *  The other filters are supported by fixed counters.
- *  The any-thread option is supported starting with v3.
- */
-#define INTEL_ARCH_FIXED_MASK \
-	(INTEL_ARCH_CNT_MASK| \
-	 INTEL_ARCH_INV_MASK| \
-	 INTEL_ARCH_EDGE_MASK|\
-	 INTEL_ARCH_UNIT_MASK|\
-	 INTEL_ARCH_EVENT_MASK)
+#define ARCH_PERFMON_EVENTSEL_EVENT			0x000000FFULL
+#define ARCH_PERFMON_EVENTSEL_UMASK			0x0000FF00ULL
+#define ...
From: Peter Zijlstra
Date: Monday, March 29, 2010 - 9:48 am

Could you fold this with your 2/3 and create x86_pmu_raw_event() which
lives in arch/x86/kernel/cpu/perf_event.c, that's more consistent wrt
the X86_RAW_EVENT_MASK name and that way you don't need to re-order the
#include ""s either.

--

From: Robert Richter
Date: Monday, March 29, 2010 - 10:01 am

Ah, yes. Will do this and resend the patches.

-Robert

-- 
Advanced Micro Devices, Inc.
Operating System Research Center
email: robert.richter@amd.com

--

From: Robert Richter
Date: Tuesday, March 30, 2010 - 2:28 am

The patch below replaces patches 2 and 3.

-Robert

---

From 2d77650a4dc5ded763dc3c120381bdbe5a0be911 Mon Sep 17 00:00:00 2001
From: Robert Richter <robert.richter@amd.com>
Date: Wed, 17 Mar 2010 12:32:37 +0100
Subject: [PATCH] perf/core, x86: implement ARCH_PERFMON_EVENTSEL bit masks

ARCH_PERFMON_EVENTSEL bit masks are often used in the kernel. This
patch adds macros for the bit masks and removes local defines. The
function intel_pmu_raw_event() becomes x86_pmu_raw_event() which is
generic for x86 models and same also for p6. Duplicate code is
removed.

Signed-off-by: Robert Richter <robert.richter@amd.com>
---
 arch/x86/include/asm/perf_event.h      |   58 ++++++++++++++------------------
 arch/x86/kernel/cpu/perf_event.c       |   19 +++++++++--
 arch/x86/kernel/cpu/perf_event_amd.c   |   15 +--------
 arch/x86/kernel/cpu/perf_event_intel.c |   22 +-----------
 arch/x86/kernel/cpu/perf_event_p6.c    |   20 +----------
 5 files changed, 45 insertions(+), 89 deletions(-)

diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 987bf67..f6d43db 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -18,39 +18,31 @@
 #define MSR_ARCH_PERFMON_EVENTSEL0			     0x186
 #define MSR_ARCH_PERFMON_EVENTSEL1			     0x187
 
-#define ARCH_PERFMON_EVENTSEL_ENABLE			  (1 << 22)
-#define ARCH_PERFMON_EVENTSEL_ANY			  (1 << 21)
-#define ARCH_PERFMON_EVENTSEL_INT			  (1 << 20)
-#define ARCH_PERFMON_EVENTSEL_OS			  (1 << 17)
-#define ARCH_PERFMON_EVENTSEL_USR			  (1 << 16)
-
-/*
- * Includes eventsel and unit mask as well:
- */
-
-
-#define INTEL_ARCH_EVTSEL_MASK		0x000000FFULL
-#define INTEL_ARCH_UNIT_MASK		0x0000FF00ULL
-#define INTEL_ARCH_EDGE_MASK		0x00040000ULL
-#define INTEL_ARCH_INV_MASK		0x00800000ULL
-#define INTEL_ARCH_CNT_MASK		0xFF000000ULL
-#define INTEL_ARCH_EVENT_MASK	(INTEL_ARCH_UNIT_MASK|INTEL_ARCH_EVTSEL_MASK)
-
-/*
- * filter mask to validate fixed counter events.
- * the following ...
From: tip-bot for Robert Richter
Date: Friday, April 2, 2010 - 12:09 pm

Commit-ID:  a098f4484bc7dae23f5b62360954007b99b64600
Gitweb:     http://git.kernel.org/tip/a098f4484bc7dae23f5b62360954007b99b64600
Author:     Robert Richter <robert.richter@amd.com>
AuthorDate: Tue, 30 Mar 2010 11:28:21 +0200
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Fri, 2 Apr 2010 19:52:03 +0200

perf, x86: implement ARCH_PERFMON_EVENTSEL bit masks

ARCH_PERFMON_EVENTSEL bit masks are often used in the kernel. This
patch adds macros for the bit masks and removes local defines. The
function intel_pmu_raw_event() becomes x86_pmu_raw_event() which is
generic for x86 models and same also for p6. Duplicate code is
removed.

Signed-off-by: Robert Richter <robert.richter@amd.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <20100330092821.GH11907@erda.amd.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 arch/x86/include/asm/perf_event.h      |   58 ++++++++++++++------------------
 arch/x86/kernel/cpu/perf_event.c       |   19 +++++++++--
 arch/x86/kernel/cpu/perf_event_amd.c   |   15 +--------
 arch/x86/kernel/cpu/perf_event_intel.c |   22 +-----------
 arch/x86/kernel/cpu/perf_event_p6.c    |   20 +----------
 5 files changed, 45 insertions(+), 89 deletions(-)

diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 987bf67..f6d43db 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -18,39 +18,31 @@
 #define MSR_ARCH_PERFMON_EVENTSEL0			     0x186
 #define MSR_ARCH_PERFMON_EVENTSEL1			     0x187
 
-#define ARCH_PERFMON_EVENTSEL_ENABLE			  (1 << 22)
-#define ARCH_PERFMON_EVENTSEL_ANY			  (1 << 21)
-#define ARCH_PERFMON_EVENTSEL_INT			  (1 << 20)
-#define ARCH_PERFMON_EVENTSEL_OS			  (1 << 17)
-#define ARCH_PERFMON_EVENTSEL_USR			  (1 << 16)
-
-/*
- * Includes eventsel and unit mask as well:
- */
-
-
-#define INTEL_ARCH_EVTSEL_MASK		0x000000FFULL
-#define INTEL_ARCH_UNIT_MASK		0x0000FF00ULL
-#define INTEL_ARCH_EDGE_MASK		0x00040000ULL
-#define ...
From: Robert Richter
Date: Monday, March 29, 2010 - 9:36 am

The big rename

 cdd6c48 perf: Do the big rename: Performance Counters -> Performance Events

accidentally renamed some members of stucts that were named after
registers in the spec. To avoid confusion this patch reverts some
changes. The related specs are MSR descriptions in AMD's BKDGs and the
ARCHITECTURAL PERFORMANCE MONITORING section in the Intel 64 and IA-32
Architectures Software Developer's Manuals.

This patch does:

 $ sed -i -e 's:num_events:num_counters:g' \
   arch/x86/include/asm/perf_event.h \
   arch/x86/kernel/cpu/perf_event_amd.c \
   arch/x86/kernel/cpu/perf_event.c \
   arch/x86/kernel/cpu/perf_event_intel.c \
   arch/x86/kernel/cpu/perf_event_p6.c \
   arch/x86/kernel/cpu/perf_event_p4.c \
   arch/x86/oprofile/op_model_ppro.c

 $ sed -i -e 's:event_bits:cntval_bits:g' -e 's:event_mask:cntval_mask:g' \
   arch/x86/kernel/cpu/perf_event_amd.c \
   arch/x86/kernel/cpu/perf_event.c \
   arch/x86/kernel/cpu/perf_event_intel.c \
   arch/x86/kernel/cpu/perf_event_p6.c \
   arch/x86/kernel/cpu/perf_event_p4.c

Signed-off-by: Robert Richter <robert.richter@amd.com>
---
 arch/x86/include/asm/perf_event.h      |    4 +-
 arch/x86/kernel/cpu/perf_event.c       |   74 ++++++++++++++++----------------
 arch/x86/kernel/cpu/perf_event_amd.c   |   12 +++---
 arch/x86/kernel/cpu/perf_event_intel.c |   14 +++---
 arch/x86/kernel/cpu/perf_event_p4.c    |   14 +++---
 arch/x86/kernel/cpu/perf_event_p6.c    |    6 +-
 arch/x86/oprofile/op_model_ppro.c      |    4 +-
 7 files changed, 64 insertions(+), 64 deletions(-)

diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 124dddd..987bf67 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -67,7 +67,7 @@
 union cpuid10_eax {
 	struct {
 		unsigned int version_id:8;
-		unsigned int num_events:8;
+		unsigned int num_counters:8;
 		unsigned int bit_width:8;
 		unsigned int mask_length:8;
 	} split;
@@ -76,7 +76,7 @@ union cpuid10_eax {
 
 ...
From: tip-bot for Robert Richter
Date: Friday, April 2, 2010 - 12:09 pm

Commit-ID:  948b1bb89a44561560531394c18da4a99215f772
Gitweb:     http://git.kernel.org/tip/948b1bb89a44561560531394c18da4a99215f772
Author:     Robert Richter <robert.richter@amd.com>
AuthorDate: Mon, 29 Mar 2010 18:36:50 +0200
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Fri, 2 Apr 2010 19:52:02 +0200

perf, x86: Undo some some *_counter* -> *_event* renames

The big rename:

 cdd6c48 perf: Do the big rename: Performance Counters -> Performance Events

accidentally renamed some members of stucts that were named after
registers in the spec. To avoid confusion this patch reverts some
changes. The related specs are MSR descriptions in AMD's BKDGs and the
ARCHITECTURAL PERFORMANCE MONITORING section in the Intel 64 and IA-32
Architectures Software Developer's Manuals.

This patch does:

 $ sed -i -e 's:num_events:num_counters:g' \
   arch/x86/include/asm/perf_event.h \
   arch/x86/kernel/cpu/perf_event_amd.c \
   arch/x86/kernel/cpu/perf_event.c \
   arch/x86/kernel/cpu/perf_event_intel.c \
   arch/x86/kernel/cpu/perf_event_p6.c \
   arch/x86/kernel/cpu/perf_event_p4.c \
   arch/x86/oprofile/op_model_ppro.c

 $ sed -i -e 's:event_bits:cntval_bits:g' -e 's:event_mask:cntval_mask:g' \
   arch/x86/kernel/cpu/perf_event_amd.c \
   arch/x86/kernel/cpu/perf_event.c \
   arch/x86/kernel/cpu/perf_event_intel.c \
   arch/x86/kernel/cpu/perf_event_p6.c \
   arch/x86/kernel/cpu/perf_event_p4.c

Signed-off-by: Robert Richter <robert.richter@amd.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1269880612-25800-2-git-send-email-robert.richter@amd.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 arch/x86/include/asm/perf_event.h      |    4 +-
 arch/x86/kernel/cpu/perf_event.c       |   74 ++++++++++++++++----------------
 arch/x86/kernel/cpu/perf_event_amd.c   |   12 +++---
 arch/x86/kernel/cpu/perf_event_intel.c |   16 +++---
 arch/x86/kernel/cpu/perf_event_p4.c    |   14 +++---
 arch/x86/kernel/cpu/perf_event_p6.c    |    6 +-
 ...
From: Stephane Eranian
Date: Tuesday, March 30, 2010 - 3:11 am

But there are still fields which are unique to each vendor:
- GUEST vs. HOST on AMD
- ANY_THREAD on Intel.

For instance, I noticed that in

arch/x86/kernel/cpu/perf_event.c:__hw_perf_event_init():

      if (attr->type == PERF_TYPE_RAW) {
                hwc->config |= x86_pmu.raw_event(attr->config);
                if ((hwc->config & ARCH_PERFMON_EVENTSEL_ANY) &&
                    perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
                        return -EACCES;
                return 0;
        }

Assumes ANY also exists on AMD processors. That is not the case.
This check needs to be moved into an Intel specific function.
--

From: Robert Richter
Date: Tuesday, March 30, 2010 - 6:41 am

Generally, ARCH_PERFMON_EVENTSEL_* refers to:

 Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume
 3B: System Programming Guide, Part 2
 30.2 ARCHITECTURAL PERFORMANCE MONITORING
 Appendix A: Performance-Monitoring Events
 Appendix B: Model-Specific Registers (MSRs) 

and AMD64_EVENTSEL_* to:

 AMD64 Architecture Programmer's Manual Volume 2: System Programming
 13.3.1 Performance Counters

X86_* is generic.

If a feature is available from both vendors, the names shouln't be
changed. Instead the first introduced mask should be used (at least
this is my suggestion).

So, there are some ARCH_PERFMON_EVENTSEL_* masks that are Intel only,
which is true for ARCH_PERFMON_EVENTSEL_ANY. And indead, the code
should be checked for this. ARCH_PERFMON_EVENTSEL_ANY is always
cleared on AMD cpus, so this code is ok. Actually the bit is cleared
for *all* cpus in x86_pmu_raw_event(), the code was and is broken for
this.

-Robert

-- 
Advanced Micro Devices, Inc.
Operating System Research Center
email: robert.richter@amd.com

--

From: Stephane Eranian
Date: Tuesday, March 30, 2010 - 6:53 am

Until AMD uses that bit too and you won't notice this test. This is a security
--

From: Peter Zijlstra
Date: Tuesday, March 30, 2010 - 8:00 am

So how about something like this on top of Robert's patches?

---
 arch/x86/kernel/cpu/perf_event.c       |   16 ++++++----------
 arch/x86/kernel/cpu/perf_event_amd.c   |    5 +++--
 arch/x86/kernel/cpu/perf_event_intel.c |   15 ++++++++++++++-
 arch/x86/kernel/cpu/perf_event_p4.c    |    5 +++--
 4 files changed, 26 insertions(+), 15 deletions(-)

Index: linux-2.6/arch/x86/kernel/cpu/perf_event.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_event.c
+++ linux-2.6/arch/x86/kernel/cpu/perf_event.c
@@ -201,7 +201,7 @@ struct x86_pmu {
 	unsigned	eventsel;
 	unsigned	perfctr;
 	u64		(*event_map)(int);
-	u64		(*raw_event)(u64);
+	int		(*raw_event)(struct perf_event *event);
 	int		max_events;
 	int		num_counters;
 	int		num_counters_fixed;
@@ -445,9 +445,10 @@ static int x86_hw_config(struct perf_eve
 	return 0;
 }
 
-static u64 x86_pmu_raw_event(u64 hw_event)
+static int x86_pmu_raw_event(struct perf_event *event)
 {
-	return hw_event & X86_RAW_EVENT_MASK;
+	event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK;
+	return 0;
 }
 
 /*
@@ -511,13 +512,8 @@ static int __hw_perf_event_init(struct p
 	/*
 	 * Raw hw_event type provide the config in the hw_event structure
 	 */
-	if (attr->type == PERF_TYPE_RAW) {
-		hwc->config |= x86_pmu.raw_event(attr->config);
-		if ((hwc->config & ARCH_PERFMON_EVENTSEL_ANY) &&
-		    perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
-			return -EACCES;
-		return 0;
-	}
+	if (attr->type == PERF_TYPE_RAW)
+		return x86_pmu.raw_event(event);
 
 	if (attr->type == PERF_TYPE_HW_CACHE)
 		return set_ext_hw_attr(hwc, attr);
Index: linux-2.6/arch/x86/kernel/cpu/perf_event_amd.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_event_amd.c
+++ linux-2.6/arch/x86/kernel/cpu/perf_event_amd.c
@@ -111,9 +111,10 @@ static u64 amd_pmu_event_map(int hw_even
 	return amd_perfmon_event_map[hw_event];
 }
 ...
From: Cyrill Gorcunov
Date: Tuesday, March 30, 2010 - 8:11 am

[...]

Looks good for me! Thanks Peter!

	-- Cyrill
--

From: Stephane Eranian
Date: Tuesday, March 30, 2010 - 8:31 am

Looks better. Thanks.

Acked-by: Stephane Eranian <eranian@google.com>
--

From: Robert Richter
Date: Tuesday, March 30, 2010 - 8:59 am

We could go on with this and move this into *_hw_config(), but so far
this change is fine to me. This would then remove .raw_event() at all.


Maybe this?

	if (!(event->attr.config & ARCH_PERFMON_EVENTSEL_ANY))
		return 0;
	if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
		return -EACCES;
	event->hw.config |= ARCH_PERFMON_EVENTSEL_ANY;
	return 0;

-Robert

-- 
Advanced Micro Devices, Inc.
Operating System Research Center
email: robert.richter@amd.com

--

From: Peter Zijlstra
Date: Tuesday, March 30, 2010 - 9:55 am

Right, I did have a brief look at that, you mentioned this before to

You're right..



---
 arch/x86/kernel/cpu/perf_event.c       |   35 +++++++++-------------------
 arch/x86/kernel/cpu/perf_event_amd.c   |   17 ++++++++++----
 arch/x86/kernel/cpu/perf_event_intel.c |   30 +++++++++++++++++++++---
 arch/x86/kernel/cpu/perf_event_p4.c    |   40 ++++++++++++++++++---------------
 4 files changed, 73 insertions(+), 49 deletions(-)

Index: linux-2.6/arch/x86/kernel/cpu/perf_event.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_event.c
+++ linux-2.6/arch/x86/kernel/cpu/perf_event.c
@@ -196,12 +196,11 @@ struct x86_pmu {
 	void		(*enable_all)(int added);
 	void		(*enable)(struct perf_event *);
 	void		(*disable)(struct perf_event *);
-	int		(*hw_config)(struct perf_event_attr *attr, struct hw_perf_event *hwc);
+	int		(*hw_config)(struct perf_event *event);
 	int		(*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign);
 	unsigned	eventsel;
 	unsigned	perfctr;
 	u64		(*event_map)(int);
-	u64		(*raw_event)(u64);
 	int		max_events;
 	int		num_counters;
 	int		num_counters_fixed;
@@ -426,28 +425,26 @@ set_ext_hw_attr(struct hw_perf_event *hw
 	return 0;
 }
 
-static int x86_hw_config(struct perf_event_attr *attr, struct hw_perf_event *hwc)
+static int x86_pmu_hw_config(struct perf_event *event)
 {
 	/*
 	 * Generate PMC IRQs:
 	 * (keep 'enabled' bit clear for now)
 	 */
-	hwc->config = ARCH_PERFMON_EVENTSEL_INT;
+	event->hw.config = ARCH_PERFMON_EVENTSEL_INT;
 
 	/*
 	 * Count user and OS events unless requested not to
 	 */
-	if (!attr->exclude_user)
-		hwc->config |= ARCH_PERFMON_EVENTSEL_USR;
-	if (!attr->exclude_kernel)
-		hwc->config |= ARCH_PERFMON_EVENTSEL_OS;
+	if (!event->attr.exclude_user)
+		event->hw.config |= ARCH_PERFMON_EVENTSEL_USR;
+	if (!event->attr.exclude_kernel)
+		event->hw.config |= ARCH_PERFMON_EVENTSEL_OS;
 
-	return 0;
-}
+	if (event->attr.type == ...
From: Cyrill Gorcunov
Date: Tuesday, March 30, 2010 - 10:11 am

Yeah, Robert sais me about eliminating raw_event, just remember :)

[...]

I'll update P4 snippet.

	-- Cyrill
--

From: Robert Richter
Date: Tuesday, March 30, 2010 - 10:24 am

I like your patch, thanks Peter.

-Robert

-- 
Advanced Micro Devices, Inc.
Operating System Research Center
email: robert.richter@amd.com

--

From: Cyrill Gorcunov
Date: Tuesday, March 30, 2010 - 11:29 am

On Tue, Mar 30, 2010 at 06:55:13PM +0200, Peter Zijlstra wrote:
[...]

P4 events thread specific is a bit more messy in compare with
architectural events. There are thread specific (TS) and thread
independent (TI) events. The exact effect of mixing flags from
what we call "ANY" bit is described in two matrix in SDM.

So to make code simplier I chose to just bind events to a
particular logical cpu, when event migrate to say a second cpu
the bits just flipped in accordance on which cpu the event is
going to run. Pretty simple. Even more -- if there was some
RAW event which have set "ANY" bit -- they all will be just stripped
and event get bound to a single cpu.

I'll try to find out an easy way to satisfy this "ANY" bit request
though it would require some time (perhaps today later or rather
tomorrow).

	-- Cyrill
--

From: Peter Zijlstra
Date: Tuesday, March 30, 2010 - 12:04 pm

Right, so don't worry about actively supporting ANY on regular events,
wider than logical cpu counting is a daft thing.

What would be nice to detect is if the raw event provided would be a TI
(ANY) event, in which case we should apply the extra paranoia.

--

From: Cyrill Gorcunov
Date: Tuesday, March 30, 2010 - 12:18 pm

Well, there is a side effect would be anyway, so I think it should be
fixed via the way like: if a caller wanna get ANY event and this caller
has enough rights for that -- go ahead you'll get what you want,
kernel is not going to do a dirty work for you :) so I would need only
fix two procedures -- event assignment (where permission will be checked
as well) and event migration where I will not do any additional work for
the caller.

At least if I not miss anything it should not be quite difficult and
invasive. Will check and send patch... later a bit. At moment we're
on a safe side anyway, ie the former patch is fine for me!

	-- Cyrill
--

From: Cyrill Gorcunov
Date: Wednesday, March 31, 2010 - 9:15 am

ok, here is a version ot top of your patches. Compile tested
only (have no p4 under my hands)

	-- Cyrill
---
x86, perf: P4 PMU -- check for permission granted on ANY event requested

In case if a caller (user) asked us to count events with
some weird mask we should check if this priviledge has been
granted since this could be a mix of mask bits we not like
which but allow if caller insist.

By ANY event term the combination of USR/OS bits in ESCR
register is assumed.

CC: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
---
 arch/x86/include/asm/perf_event_p4.h |   19 +++++++++++++++++++
 arch/x86/kernel/cpu/perf_event_p4.c  |   24 +++++++++++++++++++++---
 2 files changed, 40 insertions(+), 3 deletions(-)

Index: linux-2.6.git/arch/x86/include/asm/perf_event_p4.h
=====================================================================
--- linux-2.6.git.orig/arch/x86/include/asm/perf_event_p4.h
+++ linux-2.6.git/arch/x86/include/asm/perf_event_p4.h
@@ -33,6 +33,9 @@
 #define P4_ESCR_T1_OS		0x00000002U
 #define P4_ESCR_T1_USR		0x00000001U
 
+#define P4_ESCR_T0_ANY		(P4_ESCR_T0_OS | P4_ESCR_T0_USR)
+#define P4_ESCR_T1_ANY		(P4_ESCR_T1_OS | P4_ESCR_T1_USR)
+
 #define P4_ESCR_EVENT(v)	((v) << P4_ESCR_EVENT_SHIFT)
 #define P4_ESCR_EMASK(v)	((v) << P4_ESCR_EVENTMASK_SHIFT)
 #define P4_ESCR_TAG(v)		((v) << P4_ESCR_TAG_SHIFT)
@@ -134,6 +137,22 @@
 #define P4_CONFIG_HT_SHIFT		63
 #define P4_CONFIG_HT			(1ULL << P4_CONFIG_HT_SHIFT)
 
+/*
+ * typically we set USR or/and OS bits for one of the
+ * threads only at once, any other option is treated
+ * as "odd"
+ */
+static inline bool p4_is_odd_cpl(u32 escr)
+{
+	unsigned int t0 = (escr & P4_ESCR_T0_ANY) << 0;
+	unsigned int t1 = (escr & P4_ESCR_T1_ANY) << 2;
+
+	if ((t0 ^ t1) != t0)
+		return true;
+
+	return false;
+}
+
 static inline bool p4_is_event_cascaded(u64 config)
 {
 	u32 cccr = p4_config_unpack_cccr(config);
Index: ...
From: Cyrill Gorcunov
Date: Wednesday, March 31, 2010 - 9:26 am

[...]

	-- Cyrill
--

From: Cyrill Gorcunov
Date: Wednesday, March 31, 2010 - 10:05 am

Updated
 
	-- Cyrill
---
x86, perf: P4 PMU -- check for permission granted on ANY event v2

In case if a caller (user) asked us to count events with
some weird mask we should check if this priviledge has been
granted since this could be a mix of bitmasks we not like
which but allow if caller insist.

By ANY event term the combination of USR/OS bits in ESCR
register is assumed.

CC: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
---
 arch/x86/include/asm/perf_event_p4.h |   17 +++++++++++++++++
 arch/x86/kernel/cpu/perf_event_p4.c  |   24 +++++++++++++++++++++---
 2 files changed, 38 insertions(+), 3 deletions(-)

Index: linux-2.6.git/arch/x86/include/asm/perf_event_p4.h
=====================================================================
--- linux-2.6.git.orig/arch/x86/include/asm/perf_event_p4.h
+++ linux-2.6.git/arch/x86/include/asm/perf_event_p4.h
@@ -33,6 +33,9 @@
 #define P4_ESCR_T1_OS		0x00000002U
 #define P4_ESCR_T1_USR		0x00000001U
 
+#define P4_ESCR_T0_ANY		(P4_ESCR_T0_OS | P4_ESCR_T0_USR)
+#define P4_ESCR_T1_ANY		(P4_ESCR_T1_OS | P4_ESCR_T1_USR)
+
 #define P4_ESCR_EVENT(v)	((v) << P4_ESCR_EVENT_SHIFT)
 #define P4_ESCR_EMASK(v)	((v) << P4_ESCR_EVENTMASK_SHIFT)
 #define P4_ESCR_TAG(v)		((v) << P4_ESCR_TAG_SHIFT)
@@ -134,6 +137,20 @@
 #define P4_CONFIG_HT_SHIFT		63
 #define P4_CONFIG_HT			(1ULL << P4_CONFIG_HT_SHIFT)
 
+/*
+ * typically we set USR or/and OS bits for one of the
+ * threads only at once, any other option is treated
+ * as "any"
+ */
+static inline bool p4_is_any_cpl(u32 escr)
+{
+	if ((escr & P4_ESCR_T0_ANY) &&
+	    (escr & P4_ESCR_T1_ANY))
+		return true;
+
+	return false;
+}
+
 static inline bool p4_is_event_cascaded(u64 config)
 {
 	u32 cccr = p4_config_unpack_cccr(config);
Index: linux-2.6.git/arch/x86/kernel/cpu/perf_event_p4.c
=====================================================================
--- linux-2.6.git.orig/arch/x86/kernel/cpu/perf_event_p4.c
+++ ...
From: Lin Ming
Date: Wednesday, March 31, 2010 - 7:14 pm

I'll test this patch.
Does it need to be applied on top of Robert's patch?


--

From: Lin Ming
Date: Wednesday, March 31, 2010 - 11:47 pm

I tested this patch on top of Peter's and Robert's patch.
Works well on P4.

Only some build error, fixed by below patch.

In file included from arch/x86/kernel/cpu/perf_event.c:1326:
arch/x86/kernel/cpu/perf_event_p6.c:94: error: ‘x86_hw_config’ undeclared here (not in a function)
arch/x86/kernel/cpu/perf_event_p6.c:99: error: unknown field ‘raw_event’ specified in initializer
arch/x86/kernel/cpu/perf_event_p6.c:99: error: ‘x86_pmu_raw_event’ undeclared here (not in a function)
make[3]: *** [arch/x86/kernel/cpu/perf_event.o] Error 1

diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c
index 626abc0..4ec9680 100644
--- a/arch/x86/kernel/cpu/perf_event_p6.c
+++ b/arch/x86/kernel/cpu/perf_event_p6.c
@@ -91,12 +91,11 @@ static __initconst struct x86_pmu p6_pmu = {
 	.enable_all		= p6_pmu_enable_all,
 	.enable			= p6_pmu_enable_event,
 	.disable		= p6_pmu_disable_event,
-	.hw_config		= x86_hw_config,
+	.hw_config		= x86_pmu_hw_config,
 	.schedule_events	= x86_schedule_events,
 	.eventsel		= MSR_P6_EVNTSEL0,
 	.perfctr		= MSR_P6_PERFCTR0,
 	.event_map		= p6_pmu_event_map,
-	.raw_event		= x86_pmu_raw_event,
 	.max_events		= ARRAY_SIZE(p6_perfmon_event_map),
 	.apic			= 1,
 	.max_period		= (1ULL << 31) - 1,



--

From: Peter Zijlstra
Date: Thursday, April 1, 2010 - 3:36 am

egads, that hunk seems to have tunneled into another patch in my
queue,.. /me goes fix.

Thanks Lin.

--

From: tip-bot for Peter Zijlstra
Date: Friday, April 2, 2010 - 12:09 pm

Commit-ID:  b4cdc5c264b35c67007800dec3928e9547a9d70b
Gitweb:     http://git.kernel.org/tip/b4cdc5c264b35c67007800dec3928e9547a9d70b
Author:     Peter Zijlstra <a.p.zijlstra@chello.nl>
AuthorDate: Tue, 30 Mar 2010 17:00:06 +0200
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Fri, 2 Apr 2010 19:52:04 +0200

perf, x86: Fix up the ANY flag stuff

Stephane noticed that the ANY flag was in generic arch code, and Cyrill
reported that it broke the P4 code.

Solve this by merging x86_pmu::raw_event into x86_pmu::hw_config and
provide intel_pmu and amd_pmu specific versions of this callback.

The intel_pmu one deals with the ANY flag, the amd_pmu adds the few extra
event bits AMD64 has.

Reported-by: Stephane Eranian <eranian@google.com>
Reported-by: Cyrill Gorcunov <gorcunov@gmail.com>
Acked-by: Robert Richter <robert.richter@amd.com>
Acked-by: Cyrill Gorcunov <gorcunov@gmail.com>
Acked-by: Stephane Eranian <eranian@google.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1269968113.5258.442.camel@laptop>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 arch/x86/kernel/cpu/perf_event.c       |   35 +++++++++------------------
 arch/x86/kernel/cpu/perf_event_amd.c   |   17 ++++++++++---
 arch/x86/kernel/cpu/perf_event_intel.c |   30 ++++++++++++++++++++---
 arch/x86/kernel/cpu/perf_event_p4.c    |   40 +++++++++++++++++--------------
 arch/x86/kernel/cpu/perf_event_p6.c    |    3 +-
 5 files changed, 74 insertions(+), 51 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 1dd42c1..65e9c5e 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -196,12 +196,11 @@ struct x86_pmu {
 	void		(*enable_all)(int added);
 	void		(*enable)(struct perf_event *);
 	void		(*disable)(struct perf_event *);
-	int		(*hw_config)(struct perf_event_attr *attr, struct hw_perf_event *hwc);
+	int		(*hw_config)(struct perf_event *event);
 	int		(*schedule_events)(struct cpu_hw_events ...
Previous thread: Extended partition mapping wrong size by Phillip Susi on Monday, March 29, 2010 - 9:11 am. (5 messages)

Next thread: lots of "bridge window ... (disabled)" messages by Luck, Tony on Monday, March 29, 2010 - 9:57 am. (2 messages)