[patch 0/8] 2.6.22-rc3 perfmon2 : IBS implementation for AMD64, version 2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

this is version 2 of the patch series. Thanks to David and James for
reviewing this. Below you can find a diff that shows changes to the
previous version. The patches are relative to Stephane's 2.6.22-rc3
Perfmon2 release.

Regards,
Robert

Index: linux-2.6.22-rc3/arch/i386/perfmon/perfmon.c
===================================================================
--- linux-2.6.22-rc3.orig/arch/i386/perfmon/perfmon.c
+++ linux-2.6.22-rc3/arch/i386/perfmon/perfmon.c
@@ -29,6 +29,12 @@
 
 #include <asm/nmi.h>
 
+#define IBS_CHECK_FETCHCTL	0x01
+#define IBS_CHECK_FETCHCTR	0x02
+#define IBS_CHECK_OPCTL		0x04
+#define IBS_CHECK_OPCTR		0x08
+#define IBS_CHECK_ALL		0x0f
+
 DEFINE_PER_CPU(unsigned long, real_iip);
 
 struct pfm_ds_area {
@@ -83,12 +89,14 @@ static inline void __pfm_pmd_swrite(unsi
 
 /* Context must be locked for atomic read and write operations */
 
+/* hw_addr is used as index for the virtual PMDs. If index is out of
+   range, there is a bug in the PMU description. */
+
 u64 pfm_pmd_sread(struct pfm_context *ctx, unsigned int cnum)
 {
 	unsigned int vpmd = pfm_pmu_conf->pmd_desc[cnum].hw_addr;
 	BUG_ON(! spin_is_locked(&ctx->lock));
-	if (vpmd >= PFM_NUM_VPMDS)
-		return 0;
+	BUG_ON(vpmd >= PFM_NUM_VPMDS);
 	return __pfm_pmd_sread(vpmd);
 }
 
@@ -96,8 +104,7 @@ void pfm_pmd_swrite(struct pfm_context *
 {
 	unsigned int vpmd = pfm_pmu_conf->pmd_desc[cnum].hw_addr;
 	BUG_ON(! spin_is_locked(&ctx->lock));
-	if (vpmd >= PFM_NUM_VPMDS)
-		return;
+	BUG_ON(vpmd >= PFM_NUM_VPMDS);
 	__pfm_pmd_swrite(vpmd, val);
 }
 
@@ -106,8 +113,7 @@ static void pfm_pmd_sinc(struct pfm_cont
 	unsigned int vpmd = pfm_pmu_conf->pmd_desc[cnum].hw_addr;
 	u64 val = 0;
 	BUG_ON(! spin_is_locked(&ctx->lock));
-	if (vpmd >= PFM_NUM_VPMDS)
-		return;
+	BUG_ON(vpmd >= PFM_NUM_VPMDS);
 	val = __pfm_pmd_sread(vpmd);
 	__pfm_pmd_swrite(vpmd, val + 1);
 }
@@ -376,55 +382,51 @@ static int pfm_stop_save_p6(struct pfm_c
 	return 0;
 }
 
+/* Check for IBS events */
+/* ctx->lock must be locked for pfm_check_ibs_event() */
+
+static inline void pfm_check_ibs_event(struct pfm_context *ctx,
+				       struct pfm_event_set *set,
+				       u16 ctl, u64 ctl_mask, u16 ctr)
+{
+	struct pfm_reg_desc *pmc_desc = pfm_pmu_conf->pmc_desc;
+	u64 val = 0;
+
+	if (unlikely(test_bit(ctr, ulp(set->povfl_pmds)))) {
+		PFM_DBG("Warning: IBS event already pending for counter %d", ctr);
+		return;
+	}
+
+	/* Check event bits in control register */
+	rdmsrl(pmc_desc[ctl].hw_addr, val);
+	if (!(val & ctl_mask))
+		return;
+
+	PFM_DBG_ovfl("IBS event occurred for counter %d", ctr);
+	__set_bit(ctr, ulp(set->povfl_pmds));
+	set->npend_ovfls++;
+	/* Increment event counter, update PMD */
+	pfm_pmd_sinc(ctx, ctr);
+	set->view->set_pmds[ctr] = pfm_pmd_sread(ctx, ctr);
+}
+
 static int pfm_stop_save_amd64(struct pfm_context *ctx,
 			       struct pfm_event_set *set)
 {
 	struct pfm_arch_pmu_info *arch_info = pfm_pmu_conf->arch_info;
-	struct pfm_reg_desc *pmc_desc = pfm_pmu_conf->pmc_desc;
-	u64 val = 0;
 
 	if (arch_info->flags & PFM_X86_FL_IBS) {
-		/* Check for IBS events */
 		BUG_ON(!spin_is_locked(&ctx->lock));
-		do {
-			if (unlikely(test_bit(arch_info->ibsfetchctr_idx,
-					      ulp(set->povfl_pmds)))) {
-				PFM_DBG("Warning: IBS fetch data already pending");
-				continue;
-			}
-			rdmsrl(pmc_desc[arch_info->ibsfetchctl_idx].hw_addr,
-			       val);
-			if (!(val & PFM_AMD64_IBSFETCHVAL))
-				continue;
-			PFM_DBG_ovfl("New IBS fetch data available");
-			__set_bit(arch_info->ibsfetchctr_idx,
-				  ulp(set->povfl_pmds));
-			set->npend_ovfls++;
-			/* Increment event counter */
-			pfm_pmd_sinc(ctx, arch_info->ibsfetchctr_idx);
-			/* Update PMD */
-			set->view->set_pmds[arch_info->ibsfetchctr_idx] =
-				pfm_read_pmd(ctx, arch_info->ibsfetchctr_idx);
-		} while (0);
-		do {
-			if (unlikely(test_bit(arch_info->ibsopctr_idx,
-					      ulp(set->povfl_pmds)))) {
-				PFM_DBG("Warning: IBS execution data already pending");
-				continue;
-			}
-			rdmsrl(pmc_desc[arch_info->ibsopctl_idx].hw_addr, val);
-			if (!(val & PFM_AMD64_IBSOPVAL))
-				continue;
-			PFM_DBG_ovfl("New IBS execution data available");
-			__set_bit(arch_info->ibsopctr_idx,
-				  ulp(set->povfl_pmds));
-			set->npend_ovfls++;
-			/* Increment event counter */
-			pfm_pmd_sinc(ctx, arch_info->ibsopctr_idx);
-			/* Update PMD */
-			set->view->set_pmds[arch_info->ibsopctr_idx] =
-				pfm_read_pmd(ctx, arch_info->ibsopctr_idx);
-		} while (0);
+		/* Check for IBS fetch data */
+		pfm_check_ibs_event(ctx, set,
+				    arch_info->ibsfetchctl_idx,
+				    PFM_AMD64_IBSFETCHVAL,
+				    arch_info->ibsfetchctr_idx);
+		/* Check for IBS execution data */
+		pfm_check_ibs_event(ctx, set,
+				    arch_info->ibsopctl_idx,
+				    PFM_AMD64_IBSOPVAL,
+				    arch_info->ibsopctr_idx);
 	}
 
 	/* IbsFetchCtl/IbsOpCtl is cleard in pfm_stop_save_p6() */
@@ -737,7 +739,7 @@ void pfm_arch_start(struct task_struct *
 		    struct pfm_event_set *set)
 {
 	struct pfm_arch_context *ctx_arch;
-	struct pfm_reg_desc* pmc_desc;
+	struct pfm_reg_desc *pmc_desc;
 	u64 *mask;
 	u16 i, num;
 
@@ -1103,12 +1105,7 @@ int pfm_arch_pmu_config_init(struct _pfm
 	struct pfm_arch_ext_reg *pc, *pd;
 	u64 *mask;
 	unsigned int i, num, ena;
-	unsigned int ibs_check = 0;
-#define IBS_CHECK_FETCHCTL	0x01
-#define IBS_CHECK_FETCHCTR	0x02
-#define IBS_CHECK_OPCTL		0x04
-#define IBS_CHECK_OPCTR		0x08
-#define IBS_CHECK_ALL		0x0f
+	unsigned int ibs_check;
 
 	pc = arch_info->pmc_addrs;
 	pd = arch_info->pmd_addrs;
Index: linux-2.6.22-rc3/arch/x86_64/perfmon/perfmon_amd64.c
===================================================================
--- linux-2.6.22-rc3.orig/arch/x86_64/perfmon/perfmon_amd64.c
+++ linux-2.6.22-rc3/arch/x86_64/perfmon/perfmon_amd64.c
@@ -1,5 +1,5 @@
 /*
- * This file contains the PMU description for the Ahtlon64 and Opteron64
+ * This file contains the PMU description for the Athlon64 and Opteron64
  * processors. It supports 32 and 64-bit modes.
  *
  * Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
Index: linux-2.6.22-rc3/include/asm-i386/msr-index.h
===================================================================
--- linux-2.6.22-rc3.orig/include/asm-i386/msr-index.h
+++ linux-2.6.22-rc3/include/asm-i386/msr-index.h
@@ -76,24 +76,24 @@
 /* AMD64 MSRs. Not complete. See the architecture manual for a more
    complete list. */
 
-#define MSR_AMD64_IBSFETCHCTL		0xC0011030
-#define MSR_AMD64_IBSFETCHLINAD		0xC0011031
-#define MSR_AMD64_IBSFETCHPHYSAD	0xC0011032
-#define MSR_AMD64_IBSOPCTL		0xC0011033
-#define MSR_AMD64_IBSOPRIP		0xC0011034
-#define MSR_AMD64_IBSOPDATA		0xC0011035
-#define MSR_AMD64_IBSOPDATA2		0xC0011036
-#define MSR_AMD64_IBSOPDATA3		0xC0011037
-#define MSR_AMD64_IBSDCLINAD		0xC0011038
-#define MSR_AMD64_IBSDCPHYSAD		0xC0011039
-#define MSR_AMD64_IBSCTL		0xC001103A
+#define MSR_AMD64_IBSFETCHCTL		0xc0011030
+#define MSR_AMD64_IBSFETCHLINAD		0xc0011031
+#define MSR_AMD64_IBSFETCHPHYSAD	0xc0011032
+#define MSR_AMD64_IBSOPCTL		0xc0011033
+#define MSR_AMD64_IBSOPRIP		0xc0011034
+#define MSR_AMD64_IBSOPDATA		0xc0011035
+#define MSR_AMD64_IBSOPDATA2		0xc0011036
+#define MSR_AMD64_IBSOPDATA3		0xc0011037
+#define MSR_AMD64_IBSDCLINAD		0xc0011038
+#define MSR_AMD64_IBSDCPHYSAD		0xc0011039
+#define MSR_AMD64_IBSCTL		0xc001103a
 
 /* K8 MSRs */
-#define MSR_K8_TOP_MEM1			0xC001001A
-#define MSR_K8_TOP_MEM2			0xC001001D
-#define MSR_K8_SYSCFG			0xC0010010
-#define MSR_K8_HWCR			0xC0010015
+#define MSR_K8_TOP_MEM1			0xc001001a
+#define MSR_K8_TOP_MEM2			0xc001001d
+#define MSR_K8_SYSCFG			0xc0010010
+#define MSR_K8_HWCR			0xc0010015
 #define MSR_K8_ENABLE_C1E		0xc0010055
 #define K8_MTRRFIXRANGE_DRAM_ENABLE	0x00040000 /* MtrrFixDramEn bit    */
 #define K8_MTRRFIXRANGE_DRAM_MODIFY	0x00080000 /* MtrrFixDramModEn bit */
 

-- 
AMD Saxony, Dresden, Germany
Operating System Research Center
email: [email protected]



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux