Add support for the sampling facility to allow hardware-based sampling using
CPU cycles.  The cpum_sf PMU provides two perf events supporting available
sampling functions.

Many existing pfmlib functions of the counter facility support (cpum_cf) have
been reused.

Signed-off-by: Hendrik Brueckner <brueck...@linux.vnet.ibm.com>
---
 include/perfmon/pfmlib.h        |    2 +
 lib/events/s390x_cpumf_events.h |   16 +++++++
 lib/pfmlib_common.c             |    1 +
 lib/pfmlib_priv.h               |    1 +
 lib/pfmlib_s390x_cpumf.c        |   91 ++++++++++++++++++++++++++++-----------
 5 files changed, 86 insertions(+), 25 deletions(-)

diff --git a/include/perfmon/pfmlib.h b/include/perfmon/pfmlib.h
index 5434a96..6a90dd5 100644
--- a/include/perfmon/pfmlib.h
+++ b/include/perfmon/pfmlib.h
@@ -198,6 +198,8 @@ typedef enum {
 
        PFM_PMU_ARM_QCOM_KRAIT,         /* Qualcomm Krait */
 
+       PFM_PMU_S390X_CPUM_SF,          /* s390x: CPU-M sampling facility */
+
        /* MUST ADD NEW PMU MODELS HERE */
 
        PFM_PMU_MAX                     /* end marker */
diff --git a/lib/events/s390x_cpumf_events.h b/lib/events/s390x_cpumf_events.h
index 5e27fe6..e00b088 100644
--- a/lib/events/s390x_cpumf_events.h
+++ b/lib/events/s390x_cpumf_events.h
@@ -840,4 +840,20 @@ static const pme_cpumf_ctr_t cpumcf_zec12_counters[] = {
        },
 };
 
+static const pme_cpumf_ctr_t cpumsf_counters[] = {
+       {
+               .ctrnum = 720896,
+               .ctrset = CPUMF_CTRSET_NONE,
+               .name = "SF_CYCLES_BASIC",
+               .desc = "Sample CPU cycles using basic-sampling mode",
+       },
+       {
+               .ctrnum = 774144,
+               .ctrset = CPUMF_CTRSET_NONE,
+               .name = "SF_CYCLES_BASIC_DIAG",
+               .desc = "Sample CPU cycle using diagnostic-sampling mode"
+                       " (not for ordinary use)",
+       },
+};
+
 #endif /* __S390X_CPUMF_EVENTS_H__ */
diff --git a/lib/pfmlib_common.c b/lib/pfmlib_common.c
index 861f475..987bae4 100644
--- a/lib/pfmlib_common.c
+++ b/lib/pfmlib_common.c
@@ -167,6 +167,7 @@ static pfmlib_pmu_t *pfmlib_pmus[]=
 #endif
 #ifdef CONFIG_PFMLIB_ARCH_S390X
        &s390x_cpum_cf_support,
+       &s390x_cpum_sf_support,
 #endif
 #ifdef __linux__
        &perf_event_support,
diff --git a/lib/pfmlib_priv.h b/lib/pfmlib_priv.h
index 287222d..530f68c 100644
--- a/lib/pfmlib_priv.h
+++ b/lib/pfmlib_priv.h
@@ -294,6 +294,7 @@ extern pfmlib_pmu_t arm_1176_support;
 extern pfmlib_pmu_t arm_qcom_krait_support;
 extern pfmlib_pmu_t mips_74k_support;
 extern pfmlib_pmu_t s390x_cpum_cf_support;
+extern pfmlib_pmu_t s390x_cpum_sf_support;
 
 extern pfmlib_os_t *pfmlib_os;
 extern pfmlib_os_t pfmlib_os_perf;
diff --git a/lib/pfmlib_s390x_cpumf.c b/lib/pfmlib_s390x_cpumf.c
index e3aaaf0..db2a215 100644
--- a/lib/pfmlib_s390x_cpumf.c
+++ b/lib/pfmlib_s390x_cpumf.c
@@ -1,7 +1,7 @@
 /*
- * PMU support for the CPU-measurement counter facility
+ * PMU support for the CPU-measurement facilities
  *
- * Copyright IBM Corp. 2012
+ * Copyright IBM Corp. 2012, 2014
  * Contributed by Hendrik Brueckner <brueck...@linux.vnet.ibm.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -34,17 +34,25 @@
 #include "events/s390x_cpumf_events.h"
 
 
-#define CPUMF_DEVICE_DIR  "/sys/bus/event_source/devices/cpum_cf"
-#define SYS_INFO         "/proc/sysinfo"
+#define CPUM_CF_DEVICE_DIR  "/sys/bus/event_source/devices/cpum_cf"
+#define CPUM_SF_DEVICE_DIR  "/sys/bus/event_source/devices/cpum_sf"
+#define SYS_INFO           "/proc/sysinfo"
 
 
 /* CPU-measurement counter list (pmu events) */
 static pme_cpumf_ctr_t *cpumcf_pe = NULL;
 
-/* Detect the CPU-measurement facility */
+/* Detect the CPU-measurement counter and sampling facilities */
 static int pfm_cpumcf_detect(void *this)
 {
-       if (access(CPUMF_DEVICE_DIR, R_OK))
+       if (access(CPUM_CF_DEVICE_DIR, R_OK))
+               return PFM_ERR_NOTSUPP;
+       return PFM_SUCCESS;
+}
+
+static int pfm_cpumsf_detect(void *this)
+{
+       if (access(CPUM_SF_DEVICE_DIR, R_OK))
                return PFM_ERR_NOTSUPP;
        return PFM_SUCCESS;
 }
@@ -156,7 +164,7 @@ static void pfm_cpumcf_exit(void *this)
        free(cpumcf_pe);
 }
 
-static int pfm_cpumcf_get_encoding(void *this, pfmlib_event_desc_t *e)
+static int pfm_cpumf_get_encoding(void *this, pfmlib_event_desc_t *e)
 {
        const pme_cpumf_ctr_t *pe = this_pe(this);
 
@@ -167,12 +175,12 @@ static int pfm_cpumcf_get_encoding(void *this, 
pfmlib_event_desc_t *e)
        return PFM_SUCCESS;
 }
 
-static int pfm_cpumcf_get_event_first(void *this)
+static int pfm_cpumf_get_event_first(void *this)
 {
        return 0;
 }
 
-static int pfm_cpumcf_get_event_next(void *this, int idx)
+static int pfm_cpumf_get_event_next(void *this, int idx)
 {
        pfmlib_pmu_t *pmu = this;
 
@@ -181,26 +189,20 @@ static int pfm_cpumcf_get_event_next(void *this, int idx)
        return idx + 1;
 }
 
-static int pfm_cpumcf_event_is_valid(void *this, int idx)
+static int pfm_cpumf_event_is_valid(void *this, int idx)
 {
        pfmlib_pmu_t *pmu = this;
 
        return (idx >= 0 && idx < pmu->pme_count);
 }
 
-static int pfm_cpumcf_validate_table(void *this, FILE *fp)
+static int pfm_cpumf_validate_table(void *this, FILE *fp)
 {
        pfmlib_pmu_t *pmu = this;
        const pme_cpumf_ctr_t *pe = this_pe(this);
        int i, rc;
 
        rc = PFM_ERR_INVAL;
-       if (pmu->pme_count > CPUMF_COUNTER_MAX) {
-               fprintf(fp, "pmu: %s: pme number exceeded maximum\n",
-                       pmu->name);
-               goto failed;
-       }
-
        for (i = 0; i < pmu->pme_count; i++) {
                if (!pe[i].name) {
                        fprintf(fp, "pmu: %s event: %i: No name\n",
@@ -219,7 +221,20 @@ failed:
        return rc;
 }
 
-static int pfm_cpumcf_get_event_info(void *this, int idx,
+static int pfm_cpumcf_validate_table(void *this, FILE *fp)
+{
+       pfmlib_pmu_t *pmu = this;
+
+       if (pmu->pme_count > CPUMF_COUNTER_MAX) {
+               fprintf(fp, "pmu: %s: pme number exceeded maximum\n",
+                       pmu->name);
+               return PFM_ERR_INVAL;
+       }
+
+       return pfm_cpumf_validate_table(this, fp);
+}
+
+static int pfm_cpumf_get_event_info(void *this, int idx,
                                    pfm_event_info_t *info)
 {
        pfmlib_pmu_t *pmu = this;
@@ -238,7 +253,7 @@ static int pfm_cpumcf_get_event_info(void *this, int idx,
        return PFM_SUCCESS;
 }
 
-static int pfm_cpumcf_get_event_attr_info(void *this, int idx, int umask_idx,
+static int pfm_cpumf_get_event_attr_info(void *this, int idx, int umask_idx,
                                         pfm_event_attr_info_t *info)
 {
        /* Attributes are not supported */
@@ -263,12 +278,38 @@ pfmlib_pmu_t s390x_cpum_cf_support = {
        .pmu_init      = pfm_cpumcf_init,
        .pmu_terminate = pfm_cpumcf_exit,
 
-       .get_event_encoding[PFM_OS_NONE] = pfm_cpumcf_get_encoding,
+       .get_event_encoding[PFM_OS_NONE] = pfm_cpumf_get_encoding,
                PFMLIB_ENCODE_PERF(pfm_s390x_get_perf_encoding),
-       .get_event_first        = pfm_cpumcf_get_event_first,
-       .get_event_next         = pfm_cpumcf_get_event_next,
-       .event_is_valid         = pfm_cpumcf_event_is_valid,
+       .get_event_first        = pfm_cpumf_get_event_first,
+       .get_event_next         = pfm_cpumf_get_event_next,
+       .event_is_valid         = pfm_cpumf_event_is_valid,
        .validate_table         = pfm_cpumcf_validate_table,
-       .get_event_info         = pfm_cpumcf_get_event_info,
-       .get_event_attr_info    = pfm_cpumcf_get_event_attr_info,
+       .get_event_info         = pfm_cpumf_get_event_info,
+       .get_event_attr_info    = pfm_cpumf_get_event_attr_info,
+};
+
+pfmlib_pmu_t s390x_cpum_sf_support = {
+       .desc      = "CPU-measurement sampling facility",
+       .name      = "cpum_sf",
+       .pmu       = PFM_PMU_S390X_CPUM_SF,
+       .type      = PFM_PMU_TYPE_CORE,
+       .flags     = PFMLIB_PMU_FL_ARCH_DFL,
+
+       .num_cntrs       = 0,   /* no general-purpose counters */
+       .num_fixed_cntrs = 2,   /* fixed counters only */
+       .max_encoding    = 1,
+
+       .pe        = cpumsf_counters,
+       .pme_count = LIBPFM_ARRAY_SIZE(cpumsf_counters),
+
+       .pmu_detect = pfm_cpumsf_detect,
+
+       .get_event_encoding[PFM_OS_NONE] = pfm_cpumf_get_encoding,
+               PFMLIB_ENCODE_PERF(pfm_s390x_get_perf_encoding),
+       .get_event_first        = pfm_cpumf_get_event_first,
+       .get_event_next         = pfm_cpumf_get_event_next,
+       .event_is_valid         = pfm_cpumf_event_is_valid,
+       .validate_table         = pfm_cpumf_validate_table,
+       .get_event_info         = pfm_cpumf_get_event_info,
+       .get_event_attr_info    = pfm_cpumf_get_event_attr_info,
 };
-- 
1.7.5.4


------------------------------------------------------------------------------
Managing the Performance of Cloud-Based Applications
Take advantage of what the Cloud has to offer - Avoid Common Pitfalls.
Read the Whitepaper.
http://pubads.g.doubleclick.net/gampad/clk?id=121054471&iu=/4140/ostg.clktrk
_______________________________________________
perfmon2-devel mailing list
perfmon2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/perfmon2-devel

Reply via email to