Skip to contentSkip to conversation

perf_events: update PEBS event constraints

PATCH In review Stephane Eranian 2 participants 2 messages Mar 1, 2011

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 perf_events: update PEBS event constraints

This patch updates PEBS event constraints for Intel Atom, Nehalem, Westmere.

This patch also reorganizes the PEBS format/constraint detection code. It is now based on processor model and not PEBS format. Two processors may use the same PEBS format without have the same list of PEBS events.

---

arch/x86/kernel/cpu/perf_event_intel_ds.c +89 -21
index b7dcd9f..9b7ca73 100644
@@ -361,30 +361,49 @@ static int intel_pmu_drain_bts_buffer(void)
 /*
  * PEBS
  */
-
 static struct event_constraint intel_core_pebs_events[] = {
 	PEBS_EVENT_CONSTRAINT(0x00c0, 0x1), /* INSTR_RETIRED.ANY */
 	PEBS_EVENT_CONSTRAINT(0xfec1, 0x1), /* X87_OPS_RETIRED.ANY */
 	PEBS_EVENT_CONSTRAINT(0x00c5, 0x1), /* BR_INST_RETIRED.MISPRED */
 	PEBS_EVENT_CONSTRAINT(0x1fc7, 0x1), /* SIMD_INST_RETURED.ANY */
-	PEBS_EVENT_CONSTRAINT(0x01cb, 0x1), /* MEM_LOAD_RETIRED.L1D_MISS */
-	PEBS_EVENT_CONSTRAINT(0x02cb, 0x1), /* MEM_LOAD_RETIRED.L1D_LINE_MISS */
-	PEBS_EVENT_CONSTRAINT(0x04cb, 0x1), /* MEM_LOAD_RETIRED.L2_MISS */
-	PEBS_EVENT_CONSTRAINT(0x08cb, 0x1), /* MEM_LOAD_RETIRED.L2_LINE_MISS */
-	PEBS_EVENT_CONSTRAINT(0x10cb, 0x1), /* MEM_LOAD_RETIRED.DTLB_MISS */
+	INTEL_EVENT_CONSTRAINT(0xcb, 0x1),  /* MEM_LOAD_RETIRED.* */
+	EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_atom_pebs_events[] = {
+	PEBS_EVENT_CONSTRAINT(0x00c0, 0x1), /* INSTR_RETIRED.ANY */
+	PEBS_EVENT_CONSTRAINT(0x00c5, 0x1), /* BR_INST_RETIRED.MISPRED */
+	PEBS_EVENT_CONSTRAINT(0x0ac4, 0x1), /* BR_INST_RETIRED.MISPRED */
+	INTEL_EVENT_CONSTRAINT(0xcb, 0x1),  /* MEM_LOAD_RETIRED.* */
 	EVENT_CONSTRAINT_END
 };
 
 static struct event_constraint intel_nehalem_pebs_events[] = {
-	PEBS_EVENT_CONSTRAINT(0x00c0, 0xf), /* INSTR_RETIRED.ANY */
-	PEBS_EVENT_CONSTRAINT(0xfec1, 0xf), /* X87_OPS_RETIRED.ANY */
-	PEBS_EVENT_CONSTRAINT(0x00c5, 0xf), /* BR_INST_RETIRED.MISPRED */
-	PEBS_EVENT_CONSTRAINT(0x1fc7, 0xf), /* SIMD_INST_RETURED.ANY */
-	PEBS_EVENT_CONSTRAINT(0x01cb, 0xf), /* MEM_LOAD_RETIRED.L1D_MISS */
-	PEBS_EVENT_CONSTRAINT(0x02cb, 0xf), /* MEM_LOAD_RETIRED.L1D_LINE_MISS */
-	PEBS_EVENT_CONSTRAINT(0x04cb, 0xf), /* MEM_LOAD_RETIRED.L2_MISS */
-	PEBS_EVENT_CONSTRAINT(0x08cb, 0xf), /* MEM_LOAD_RETIRED.L2_LINE_MISS */
-	PEBS_EVENT_CONSTRAINT(0x10cb, 0xf), /* MEM_LOAD_RETIRED.DTLB_MISS */
+	INTEL_EVENT_CONSTRAINT(0x0b, 0xf),  /* MEM_INST_RETIRED.* */
+	INTEL_EVENT_CONSTRAINT(0x0f, 0xf),  /* MEM_UNCORE_RETIRED.* */
+	PEBS_EVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */
+	INTEL_EVENT_CONSTRAINT(0xc0, 0xf),  /* INST_RETIRED.ANY */
+	INTEL_EVENT_CONSTRAINT(0xc2, 0xf),  /* UOPS_RETIRED.* */
+	INTEL_EVENT_CONSTRAINT(0x00c4, 0xf),/* BR_INST_RETIRED.* */
+	PEBS_EVENT_CONSTRAINT(0x02c5, 0xf), /* BR_MISP_RETIRED.NEAR_CALL */
+	INTEL_EVENT_CONSTRAINT(0xc7, 0xf),  /* SSEX_UOPS_RETIRED.* */
+	PEBS_EVENT_CONSTRAINT(0x20c8, 0xf), /* ITLB_MISS_RETIRED */
+	INTEL_EVENT_CONSTRAINT(0xcb, 0xf),  /* MEM_LOAD_RETIRED.* */
+	EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_westmere_pebs_events[] = {
+	INTEL_EVENT_CONSTRAINT(0x0b, 0xf), /* MEM_INST_RETIRED.* */
+	INTEL_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */
+	PEBS_EVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */
+	INTEL_EVENT_CONSTRAINT(0xc0, 0xf),  /* INSTR_RETIRED.* */
+	INTEL_EVENT_CONSTRAINT(0xc2, 0xf),  /* UOPS_RETIRED.* */
+
+	INTEL_EVENT_CONSTRAINT(0xc4, 0xf),  /* BR_INST_RETIRED.* */
+	INTEL_EVENT_CONSTRAINT(0xc5, 0xf),  /* BR_MISP_RETIRED.* */
+	INTEL_EVENT_CONSTRAINT(0xc7, 0xf),  /* SSEX_UOPS_RETIRED.* */
+	PEBS_EVENT_CONSTRAINT(0x20c8, 0xf), /* ITLB_MISS_RETIRED */
+	INTEL_EVENT_CONSTRAINT(0xcb, 0xf),  /* MEM_LOAD_RETIRED.* */
 	EVENT_CONSTRAINT_END
 };
 
@@ -676,6 +695,55 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
  * BTS, PEBS probe and setup
  */
 
+static void intel_ds_init_pebs_constraints(void)
+{
+	/*
+	 * we only know hwo to deal with Family 6
+	 */
+	if (boot_cpu_data.x86 != 6) {
+		x86_pmu.pebs = 0;
+		return;
+	}
+
+	switch (boot_cpu_data.x86_model) {
+	case 14: /* 65 nm core solo/duo, "Yonah" */
+		/* do not have PEBS */
+		x86_pmu.pebs = 0;
+		break;
+
+	case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
+	case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */
+	case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */
+	case 29: /* six-core 45 nm xeon "Dunnington" */
+		x86_pmu.pebs_constraints = intel_core_pebs_events;
+		pr_cont("(Core2), ");
+		break;
+
+	case 26: /* 45 nm nehalem, "Bloomfield" */
+	case 30: /* 45 nm nehalem, "Lynnfield" */
+	case 46: /* 45 nm nehalem-ex, "Beckton" */
+		x86_pmu.pebs_constraints = intel_nehalem_pebs_events;
+		pr_cont("(Nehalem), ");
+		break;
+
+	case 28: /* Atom */
+		x86_pmu.pebs_constraints = intel_atom_pebs_events;
+		pr_cont("(Atom), ");
+		break;
+
+	case 37: /* 32 nm nehalem, "Clarkdale" */
+	case 44: /* 32 nm nehalem, "Gulftown" */
+		x86_pmu.pebs_constraints = intel_westmere_pebs_events;
+		pr_cont("(Westmere), ");
+		break;
+
+	default:
+		printk(KERN_CONT "PEBS not yet supported for model %d,",
+		       boot_cpu_data.x86_model);
+		x86_pmu.pebs = 0;
+	}
+}
+
 static void intel_ds_init(void)
 {
 	/*
@@ -692,24 +760,24 @@ static void intel_ds_init(void)
 
 		switch (format) {
 		case 0:
-			printk(KERN_CONT "PEBS fmt0%c, ", pebs_type);
+			printk(KERN_CONT "PEBS fmt0%c ", pebs_type);
 			x86_pmu.pebs_record_size = sizeof(struct pebs_record_core);
 			x86_pmu.drain_pebs = intel_pmu_drain_pebs_core;
-			x86_pmu.pebs_constraints = intel_core_pebs_events;
 			break;
 
 		case 1:
-			printk(KERN_CONT "PEBS fmt1%c, ", pebs_type);
+			printk(KERN_CONT "PEBS fmt1%c ", pebs_type);
 			x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm);
 			x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
-			x86_pmu.pebs_constraints = intel_nehalem_pebs_events;
 			break;
 
 		default:
-			printk(KERN_CONT "no PEBS fmt%d%c, ", format, pebs_type);
+			printk(KERN_CONT "no PEBS fmt%d%c\n",
+			       format, pebs_type);
 			x86_pmu.pebs = 0;
-			break;
+			return;
 		}
+		intel_ds_init_pebs_constraints();
 	}
 }
 
maintainer
#1 lore raw
Quoted 38 lines · Stephane Eranian
arch/x86/kernel/cpu/perf_event_intel_ds.c +38 -0
+static void intel_ds_init_pebs_constraints(void)
+{
+       /*
+        * we only know hwo to deal with Family 6
+        */
+       if (boot_cpu_data.x86 != 6) {
+               x86_pmu.pebs = 0;
+               return;
+       }
+
+       switch (boot_cpu_data.x86_model) {
+       case 14: /* 65 nm core solo/duo, "Yonah" */
+               /* do not have PEBS */
+               x86_pmu.pebs = 0;
+               break;
+
+       case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
+       case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */
+       case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */
+       case 29: /* six-core 45 nm xeon "Dunnington" */
+               x86_pmu.pebs_constraints = intel_core_pebs_events;
+               pr_cont("(Core2), ");
+               break;
+
+       case 26: /* 45 nm nehalem, "Bloomfield" */
+       case 30: /* 45 nm nehalem, "Lynnfield" */
+       case 46: /* 45 nm nehalem-ex, "Beckton" */
+               x86_pmu.pebs_constraints = intel_nehalem_pebs_events;
+               pr_cont("(Nehalem), ");
+               break;
+
+       case 28: /* Atom */
+               x86_pmu.pebs_constraints = intel_atom_pebs_events;
+               pr_cont("(Atom), ");
+               break;
+
+       case 37: /* 32 nm nehalem, "Clarkdale" */
+       case 44: /* 32 nm nehalem, "Gulftown" */

arch/x86/kernel/cpu/perf_event_intel_ds.c static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) · line 745

Quoted 10 lines
arch/x86/kernel/cpu/perf_event_intel_ds.c +10 -0
+               x86_pmu.pebs_constraints = intel_westmere_pebs_events;
+               pr_cont("(Westmere), ");
+               break;
+
+       default:
+               printk(KERN_CONT "PEBS not yet supported for model %d,",
+                      boot_cpu_data.x86_model);
+               x86_pmu.pebs = 0;
+       }
+} 

Right so you mentioned you had something like this, but could we please use the one model switch in perf_event_intel.c and not replicate that, otherwise its too easy to miss a model someplace.