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



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: robert.richter@xxxxxxx



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



Relevant Pages

  • Re: Need better is_better_time_interpolator() algorithm
    ... diff -r b40794c1ac45 arch/ia64/kernel/cyclone.c ... int __init init_cyclone_clock ... static struct time_interpolator sparc64_cpu_interpolator = { ...
    (Linux-Kernel)
  • [PATCH 1/5] Infiniband: connection abstraction
    ... diff -uprN -X linux-2.6.git/Documentation/dontdiff ... struct ib_cm_req_event_param *kreq) ... * licenses. ... - Redistributions in binary form must reproduce the above ...
    (Linux-Kernel)
  • Re: Audigy Support?
    ... struct emu_memblk { ... +/* audigy supports 12kHz. ... diff -N sys/dev/sound/pci/emu10k1.h ...
    (freebsd-current)
  • Re: 7.0 - ifconfig create is not working as expected?
    ... retrieving revision 1.3 ... In general it is wrong to embed knowledge about one type of cloning op in the common clone code. ... diff -u -r1.134 ifconfig.c ... struct ifaddrs *ifa); ...
    (freebsd-net)
  • [PATCH] [3/6] HUGETLB memory commitment
    ... +static inline void vm_acct_memory ... struct vm_area_struct *start_vma, unsigned long start_addr, ... diff -upN reference/kernel/fork.c current/kernel/fork.c ... struct vm_area_struct *vma, unsigned long start_addr, ...
    (Linux-Kernel)