This patch adds support for Instruction Based Sampling (IBS) for AMD's
Barcelona CPUs (family 10h). IBS has been implemented as a model
specifific feature of the AMD64 PMU. Common code has been changed in
function pfm_dispatch_events(). Now it is possible to pass only model
specific input arguments, thus the parameter pfmlib_input_param_t *inp
in the function call can be NULL. This could make additional NULL
pointer checks necessary in other code sections.
Signed-off-by: Robert Richter <[EMAIL PROTECTED]>
---
include/perfmon/pfmlib_amd64.h | 186 +++++++++++++++++++++++++++++++---------
lib/pfmlib_amd64.c | 126 ++++++++++++++++++++++-----
lib/pfmlib_amd64_priv.h | 11 +++
lib/pfmlib_common.c | 30 ++++---
4 files changed, 275 insertions(+), 78 deletions(-)
diff --git a/include/perfmon/pfmlib_amd64.h b/include/perfmon/pfmlib_amd64.h
index f50cb84..4ce4fa3 100644
--- a/include/perfmon/pfmlib_amd64.h
+++ b/include/perfmon/pfmlib_amd64.h
@@ -25,13 +25,14 @@
#ifndef __PFMLIB_AMD64_H__
#define __PFMLIB_AMD64_H__
-#include <perfmon/pfmlib.h>
+#include <stdint.h>
+
/*
* privilege level mask usage for AMD64:
*
* PFM_PLM0 = OS (kernel, hypervisor, ..)
- * PFM_PLM1 = unused (ignored)
- * PFM_PLM2 = unused (ignored)
+ * PFM_PLM1 = invalid parameters
+ * PFM_PLM2 = invalid parameters
* PFM_PLM3 = USR (user level)
*/
@@ -39,51 +40,133 @@
extern "C" {
#endif
-#define PMU_AMD64_NUM_COUNTERS 4 /* total numbers of
EvtSel/EvtCtr */
-#define PMU_AMD64_NUM_PERFSEL 4 /* total number of EvtSel
defined */
-#define PMU_AMD64_NUM_PERFCTR 4 /* total number of EvtCtr
defined */
-#define PMU_AMD64_COUNTER_WIDTH 48 /* hardware counter bit
width */
+#define PMU_AMD64_MAX_COUNTERS 4 /* total numbers of performance
counters */
-#define PMU_AMD64_CNT_MASK_MAX 4 /* max cnt_mask value */
/*
- * This structure provides a detailed way to setup a PMC register.
- * Once value is loaded, it must be copied (via pmu_reg) to the
- * perfmon_req_t and passed to the kernel via perfmonctl().
+ * AMD64 MSR definitions
*/
+
typedef union {
- unsigned long long val; /* complete register
value */
+ uint64_t val; /* complete register value */
struct {
- unsigned long long sel_event_mask:8; /* event mask */
- unsigned long long sel_unit_mask:8; /* unit mask */
- unsigned long long sel_usr:1; /* user level */
- unsigned long long sel_os:1; /* system level
*/
- unsigned long long sel_edge:1; /* edge detec */
- unsigned long long sel_pc:1; /* pin control
*/
- unsigned long long sel_int:1; /* enable APIC intr */
- unsigned long long sel_res1:1; /* reserved */
- unsigned long long sel_en:1; /* enable */
- unsigned long long sel_inv:1; /* invert counter mask
*/
- unsigned long long sel_cnt_mask:8; /* counter mask
*/
- unsigned long long sel_event_mask2:4; /* 10h only: event mask
[11:8] */
- unsigned long long sel_res2:4; /* reserved */
- unsigned long long sel_guest:1; /* 10h only: guest only
counter */
- unsigned long long sel_host:1; /* 10h only: host only
counter */
- unsigned long long sel_res3:22; /* reserved */
+ uint64_t sel_event_mask:8; /* event mask */
+ uint64_t sel_unit_mask:8; /* unit mask */
+ uint64_t sel_usr:1; /* user level */
+ uint64_t sel_os:1; /* system level */
+ uint64_t sel_edge:1; /* edge detec */
+ uint64_t sel_pc:1; /* pin control */
+ uint64_t sel_int:1; /* enable APIC intr */
+ uint64_t sel_res1:1; /* reserved */
+ uint64_t sel_en:1; /* enable */
+ uint64_t sel_inv:1; /* invert counter mask */
+ uint64_t sel_cnt_mask:8; /* counter mask */
+ uint64_t sel_event_mask2:4; /* 10h only: event mask [11:8]
*/
+ uint64_t sel_res2:4; /* reserved */
+ uint64_t sel_guest:1; /* 10h only: guest only counter
*/
+ uint64_t sel_host:1; /* 10h only: host only counter
*/
+ uint64_t sel_res3:22; /* reserved */
} perfsel;
-} pfm_amd64_sel_reg_t;
+} pfm_amd64_sel_reg_t; /* MSR 0xc001000-0xc001003 */
typedef union {
- unsigned long long val; /* counter value */
- /* counting perfctr register */
+ uint64_t val; /* complete register value */
struct {
- unsigned long long ctr_count:48; /* 48-bit hardware
counter */
- unsigned long long ctr_res1:16; /* reserved */
+ uint64_t ctr_count:48; /* 48-bit hardware counter */
+ uint64_t ctr_res1:16; /* reserved */
} perfctr;
-} pfm_amd64_ctr_reg_t;
+} pfm_amd64_ctr_reg_t; /* MSR 0xc001004-0xc001007 */
+
+typedef union {
+ uint64_t val; /* complete register value */
+ struct {
+ uint64_t ibsfetchmaxcnt:16;
+ uint64_t ibsfetchcnt:16;
+ uint64_t ibsfetchlat:16;
+ uint64_t ibsfetchen:1;
+ uint64_t ibsfetchval:1;
+ uint64_t ibsfetchcomp:1;
+ uint64_t ibsicmiss:1;
+ uint64_t ibsphyaddrvalid:1;
+ uint64_t ibsl1tlbpgsz:2;
+ uint64_t ibsl1tlbmiss:1;
+ uint64_t ibsl2tlbmiss:1;
+ uint64_t ibsranden:1;
+ uint64_t reserved:6;
+ } reg;
+} ibsfetchctl_t; /* MSR 0xc0011030 */
+
+typedef union {
+ uint64_t val; /* complete register value */
+ struct {
+ uint64_t ibsopmaxcnt:16;
+ uint64_t reserved1:1;
+ uint64_t ibsopen:1;
+ uint64_t ibsopval:1;
+ uint64_t reserved2:45;
+ } reg;
+} ibsopctl_t; /* MSR 0xc0011033 */
+
+typedef union {
+ uint64_t val; /* complete register value */
+ struct {
+ uint64_t ibscomptoretctr:16;
+ uint64_t ibstagtoretctr:16;
+ uint64_t ibsopbrnresync:1;
+ uint64_t ibsopmispreturn:1;
+ uint64_t ibsopreturn:1;
+ uint64_t ibsopbrntaken:1;
+ uint64_t ibsopbrnmisp:1;
+ uint64_t ibsopbrnret:1;
+ uint64_t reserved:26;
+ } reg;
+} ibsopdata_t; /* MSR 0xc0011035 */
+
+typedef union {
+ uint64_t val; /* complete register value */
+ struct {
+ uint64_t nbibsreqsrc:3;
+ uint64_t reserved1:1;
+ uint64_t nbibsreqdstproc:1;
+ uint64_t nbibsreqcachehitst:1;
+ uint64_t reserved2:58;
+ } reg;
+} ibsopdata2_t; /* MSR 0xc0011036 */
+
+typedef union {
+ uint64_t val; /* complete register value */
+ struct {
+ uint64_t ibsldop:1;
+ uint64_t ibsstop:1;
+ uint64_t ibsdcl1tlbmiss:1;
+ uint64_t ibsdcl2tlbmiss:1;
+ uint64_t ibsdcl1tlbhit2m:1;
+ uint64_t ibsdcl1tlbhit1g:1;
+ uint64_t ibsdcl2tlbhit2m:1;
+ uint64_t ibsdcmiss:1;
+ uint64_t ibsdcmissacc:1;
+ uint64_t ibsdcldbnkcon:1;
+ uint64_t ibsdcstbnkcon:1;
+ uint64_t ibsdcsttoldfwd:1;
+ uint64_t ibsdcsttoldcan:1;
+ uint64_t ibsdcucmemacc:1;
+ uint64_t ibsdcwcmemacc:1;
+ uint64_t ibsdclockedop:1;
+ uint64_t ibsdcmabhit:1;
+ uint64_t ibsdclinaddrvalid:1;
+ uint64_t ibsdcphyaddrvalid:1;
+ uint64_t reserved1:13;
+ uint64_t ibsdcmisslat:16;
+ uint64_t reserved2:16;
+ } reg;
+} ibsopdata3_t; /* MSR 0xc0011037 */
+
+/*
+ * AMD64 specific parameters for the library
+ */
typedef struct {
- unsigned int cnt_mask; /* threshold ([4-255] are reserved) */
- unsigned int flags; /* counter specific flag */
+ uint32_t cnt_mask; /* threshold ([4-255] are reserved) */
+ uint32_t flags; /* counter specific flag */
} pfmlib_amd64_counter_t;
#define PFM_AMD64_SEL_INV 0x1 /* inverse */
@@ -91,18 +174,37 @@ typedef struct {
#define PFM_AMD64_SEL_GUEST 0x4 /* guest only */
#define PFM_AMD64_SEL_HOST 0x8 /* host only */
-/*
- * AMD64 specific parameters for the library
- */
typedef struct {
- pfmlib_amd64_counter_t pfp_amd64_counters[PMU_AMD64_NUM_COUNTERS];
/* extended counter features */
- uint64_t reserved[4]; /* for future
use */
+ pfmlib_amd64_counter_t pfp_amd64_counters[PMU_AMD64_MAX_COUNTERS]; /*
extended counter features */
+ uint32_t flags; /* use flags */
+ uint32_t reserved1; /* for future use */
+ ibsfetchctl_t ibsfetchctl; /* IBS fetch control */
+ ibsopctl_t ibsopctl; /* IBS execution control */
+ uint64_t reserved2; /* for future use */
} pfmlib_amd64_input_param_t;
+/* A bit mask, meaning multiple usage types may be defined */
+#define PFMLIB_AMD64_USE_IBSFETCH 1
+#define PFMLIB_AMD64_USE_IBSOP 2
+
typedef struct {
- uint64_t reserved[8]; /* for future use */
+ uint32_t ibsfetch_base; /* Perfmon2 base register index */
+ uint32_t ibsop_base; /* Perfmon2 base register index */
+ uint64_t reserved[7]; /* for future use */
} pfmlib_amd64_output_param_t;
+/* Perfmon2 registers relative to base register */
+#define PMD_IBSFETCHCTL 0
+#define PMD_IBSFETCHLINAD 1
+#define PMD_IBSFETCHPHYSAD 2
+#define PMD_IBSOPCTL 0
+#define PMD_IBSOPRIP 1
+#define PMD_IBSOPDATA 2
+#define PMD_IBSOPDATA2 3
+#define PMD_IBSOPDATA3 4
+#define PMD_IBSDCLINAD 5
+#define PMD_IBSDCPHYSAD 6
+
#ifdef __cplusplus /* extern C */
}
#endif
diff --git a/lib/pfmlib_amd64.c b/lib/pfmlib_amd64.c
index 2f56205..d6767ca 100644
--- a/lib/pfmlib_amd64.c
+++ b/lib/pfmlib_amd64.c
@@ -120,6 +120,7 @@ pfm_pmu_support_t amd64_support;
#define amd64_events amd64_pmu.events
#define IS_FAMILY_10H() (amd64_pmu.revision >= AMD64_FAM10H)
+#define HAS_IBS() IS_FAMILY_10H()
static amd64_rev_t
amd64_get_revision(int family, int model, int stepping)
@@ -182,22 +183,27 @@ pfm_amd64_setup(int revision)
amd64_pmu.revision = revision;
snprintf(amd64_pmu.name, NAME_SIZE, "AMD64 (%s)",
amd64_cpu_strs[revision]);
+ amd64_support.pmu_name = amd64_pmu.name;
+
+ /* defaults (K8) */
+ amd64_pmu.events = amd64_k8_table.events;
+ amd64_support.pme_count = amd64_k8_table.num;
+ amd64_pmu.cpu_clks = amd64_k8_table.cpu_clks;
+ amd64_pmu.ret_inst = amd64_k8_table.ret_inst;
+ amd64_support.pmu_type = PFMLIB_AMD64_PMU;
+ amd64_support.num_cnt = PMU_AMD64_NUM_COUNTERS;
+ amd64_support.pmc_count = PMU_AMD64_NUM_COUNTERS;
+ amd64_support.pmd_count = PMU_AMD64_NUM_COUNTERS;
+
+ /* additional features */
if (IS_FAMILY_10H()) {
amd64_pmu.events = amd64_fam10h_table.events;
amd64_support.pme_count = amd64_fam10h_table.num;
amd64_pmu.cpu_clks = amd64_fam10h_table.cpu_clks;
amd64_pmu.ret_inst = amd64_fam10h_table.ret_inst;
- } else {
- amd64_pmu.events = amd64_k8_table.events;
- amd64_support.pme_count = amd64_k8_table.num;
- amd64_pmu.cpu_clks = amd64_k8_table.cpu_clks;
- amd64_pmu.ret_inst = amd64_k8_table.ret_inst;
+ amd64_support.pmc_count = PMU_AMD64_NUM_PERFSEL;
+ amd64_support.pmd_count = PMU_AMD64_NUM_PERFCTR;
}
- amd64_support.pmu_name = amd64_pmu.name;
- amd64_support.pmu_type = PFMLIB_AMD64_PMU;
- amd64_support.pmc_count = PMU_AMD64_NUM_PERFSEL;
- amd64_support.pmd_count = PMU_AMD64_NUM_PERFCTR;
- amd64_support.num_cnt = PMU_AMD64_NUM_COUNTERS;
}
static int
@@ -286,7 +292,7 @@ pfm_amd64_dispatch_counters(pfmlib_input_param_t *inp,
pfmlib_amd64_input_param_
pfmlib_regmask_t *r_pmcs;
unsigned long plm;
unsigned int i, j, k, cnt, umask;
- unsigned int assign[PMU_AMD64_NUM_COUNTERS];
+ unsigned int assign[PMU_AMD64_MAX_COUNTERS];
e = inp->pfp_events;
pc = outp->pfp_pmcs;
@@ -295,13 +301,19 @@ pfm_amd64_dispatch_counters(pfmlib_input_param_t *inp,
pfmlib_amd64_input_param_
r_pmcs = &inp->pfp_unavail_pmcs;
cntrs = param ? param->pfp_amd64_counters : NULL;
+ /* priviledge level 1 and 2 are not supported */
+ if (inp->pfp_dfl_plm & (PFM_PLM1|PFM_PLM2)) {
+ DPRINT(("invalid plm=%x\n", inp->pfp_dfl_plm));
+ return PFMLIB_ERR_INVAL;
+ }
+
if (PFMLIB_DEBUG()) {
for (j=0; j < cnt; j++) {
DPRINT(("ev[%d]=%s\n", j,
pfm_amd64_get_event_entry(e[j].event)->pme_name));
}
}
- if (cnt > PMU_AMD64_NUM_COUNTERS) return PFMLIB_ERR_TOOMANY;
+ if (cnt > amd64_support.num_cnt) return PFMLIB_ERR_TOOMANY;
for(i=0, j=0; j < cnt; j++, i++) {
/*
@@ -339,10 +351,10 @@ pfm_amd64_dispatch_counters(pfmlib_input_param_t *inp,
pfmlib_amd64_input_param_
/*
* exclude unavailable registers from assignment
*/
- while(i < PMU_AMD64_NUM_COUNTERS && pfm_regmask_isset(r_pmcs,
i))
+ while(i < amd64_support.num_cnt && pfm_regmask_isset(r_pmcs, i))
i++;
- if (i == PMU_AMD64_NUM_COUNTERS)
+ if (i == amd64_support.num_cnt)
return PFMLIB_ERR_NOASSIGN;
assign[j] = i;
@@ -416,16 +428,82 @@ pfm_amd64_dispatch_counters(pfmlib_input_param_t *inp,
pfmlib_amd64_input_param_
return PFMLIB_SUCCESS;
}
+static int pfm_amd64_dispatch_ibs(
+ pfmlib_input_param_t *inp, pfmlib_amd64_input_param_t *inp_mod,
+ pfmlib_output_param_t *outp, pfmlib_amd64_output_param_t *outp_mod)
+{
+ unsigned int pmc_base, pmd_base;
+
+ if (!inp_mod || !outp || !outp_mod)
+ return PFMLIB_ERR_INVAL;
+
+ if (!HAS_IBS())
+ return PFMLIB_ERR_BADHOST;
+
+ /* IBS fetch profiling */
+ if (inp_mod->flags & PFMLIB_AMD64_USE_IBSFETCH) {
+ /* check availability of a PMC and PMD */
+ if (outp->pfp_pmc_count >= PFMLIB_MAX_PMCS)
+ return PFMLIB_ERR_NOASSIGN;
+ if (outp->pfp_pmd_count >= PFMLIB_MAX_PMDS)
+ return PFMLIB_ERR_NOASSIGN;
+ pmc_base = outp->pfp_pmc_count;
+ pmd_base = outp->pfp_pmd_count;
+ outp->pfp_pmcs[pmc_base].reg_num = PMU_AMD64_IBSFETCHCTL_PMC;
+ outp->pfp_pmcs[pmc_base].reg_value = inp_mod->ibsfetchctl.val;
+ outp->pfp_pmds[pmd_base].reg_num = PMU_AMD64_IBSFETCHCTL_PMD;
+ outp_mod->ibsfetch_base = pmd_base;
+ ++outp->pfp_pmc_count;
+ ++outp->pfp_pmd_count;
+ }
+
+ /* IBS execution profiling */
+ if (inp_mod->flags & PFMLIB_AMD64_USE_IBSOP) {
+ /* check availability of a PMC and PMD */
+ if (outp->pfp_pmc_count >= PFMLIB_MAX_PMCS)
+ return PFMLIB_ERR_NOASSIGN;
+ if (outp->pfp_pmd_count >= PFMLIB_MAX_PMDS)
+ return PFMLIB_ERR_NOASSIGN;
+ pmc_base = outp->pfp_pmc_count;
+ pmd_base = outp->pfp_pmd_count;
+ outp->pfp_pmcs[pmc_base].reg_num = PMU_AMD64_IBSOPCTL_PMC;
+ outp->pfp_pmcs[pmc_base].reg_value = inp_mod->ibsopctl.val;
+ outp->pfp_pmds[pmd_base].reg_num = PMU_AMD64_IBSOPCTL_PMD;
+ outp_mod->ibsop_base = pmd_base;
+ ++outp->pfp_pmc_count;
+ ++outp->pfp_pmd_count;
+ }
+
+ return PFMLIB_SUCCESS;
+}
+
static int
-pfm_amd64_dispatch_events(pfmlib_input_param_t *inp, void *model_in,
pfmlib_output_param_t *outp, void *model_out)
+pfm_amd64_dispatch_events(
+ pfmlib_input_param_t *inp, void *_inp_mod,
+ pfmlib_output_param_t *outp, void *outp_mod)
{
- pfmlib_amd64_input_param_t *mod_in = (pfmlib_amd64_input_param_t
*)model_in;
+ pfmlib_amd64_input_param_t *inp_mod = _inp_mod;
+ int ret = PFMLIB_ERR_INVAL;
- if (inp->pfp_dfl_plm & (PFM_PLM1|PFM_PLM2)) {
- DPRINT(("invalid plm=%x\n", inp->pfp_dfl_plm));
+ if (!outp)
return PFMLIB_ERR_INVAL;
+
+ /*
+ * At least one of the dispatch function calls must return
+ * PFMLIB_SUCCESS
+ */
+
+ if (inp && inp->pfp_event_count) {
+ ret = pfm_amd64_dispatch_counters(inp, inp_mod, outp);
+ if (ret != PFMLIB_SUCCESS)
+ return ret;
}
- return pfm_amd64_dispatch_counters(inp, mod_in, outp);
+
+ if (inp_mod && inp_mod->flags & (PFMLIB_AMD64_USE_IBSOP
+ | PFMLIB_AMD64_USE_IBSFETCH))
+ ret = pfm_amd64_dispatch_ibs(inp, inp_mod, outp, outp_mod);
+
+ return ret;
}
static int
@@ -457,7 +535,7 @@ pfm_amd64_get_event_counters(unsigned int j,
pfmlib_regmask_t *counters)
memset(counters, 0, sizeof(*counters));
- for(i=0; i < PMU_AMD64_NUM_COUNTERS; i++)
+ for(i=0; i < amd64_support.num_cnt; i++)
pfm_regmask_set(counters, i);
}
@@ -467,7 +545,7 @@ pfm_amd64_get_impl_perfsel(pfmlib_regmask_t *impl_pmcs)
unsigned int i = 0;
/* all pmcs are contiguous */
- for(i=0; i < PMU_AMD64_NUM_PERFSEL; i++)
+ for(i=0; i < amd64_support.pmc_count; i++)
pfm_regmask_set(impl_pmcs, i);
}
@@ -477,7 +555,7 @@ pfm_amd64_get_impl_perfctr(pfmlib_regmask_t *impl_pmds)
unsigned int i = 0;
/* all pmds are contiguous */
- for(i=0; i < PMU_AMD64_NUM_PERFCTR; i++)
+ for(i=0; i < amd64_support.pmd_count; i++)
pfm_regmask_set(impl_pmds, i);
}
@@ -568,8 +646,8 @@ pfm_pmu_support_t amd64_support = {
.pmu_name = "AMD64",
.pmu_type = PFMLIB_AMD64_PMU,
.pme_count = 0,
- .pmc_count = PMU_AMD64_NUM_PERFSEL,
- .pmd_count = PMU_AMD64_NUM_PERFCTR,
+ .pmc_count = PMU_AMD64_NUM_COUNTERS,
+ .pmd_count = PMU_AMD64_NUM_COUNTERS,
.num_cnt = PMU_AMD64_NUM_COUNTERS,
.get_event_code = pfm_amd64_get_event_code,
.get_event_name = pfm_amd64_get_event_name,
diff --git a/lib/pfmlib_amd64_priv.h b/lib/pfmlib_amd64_priv.h
index 551f8bb..f5e49f4 100644
--- a/lib/pfmlib_amd64_priv.h
+++ b/lib/pfmlib_amd64_priv.h
@@ -25,6 +25,17 @@
#ifndef __PFMLIB_AMD64_PRIV_H__
#define __PFMLIB_AMD64_PRIV_H__
+/* PERFSEL/PERFCTR include IBS registers of family 10h */
+#define PMU_AMD64_NUM_PERFSEL 6 /* total number of PMCs defined */
+#define PMU_AMD64_NUM_PERFCTR 14 /* total number of PMDs defined */
+#define PMU_AMD64_NUM_COUNTERS 4 /* total numbers of EvtSel/EvtCtr */
+#define PMU_AMD64_COUNTER_WIDTH 48 /* hardware counter bit width */
+#define PMU_AMD64_CNT_MASK_MAX 4 /* max cnt_mask value */
+#define PMU_AMD64_IBSFETCHCTL_PMC 4 /* IBS: fetch PMC base */
+#define PMU_AMD64_IBSFETCHCTL_PMD 4 /* IBS: fetch PMD base */
+#define PMU_AMD64_IBSOPCTL_PMC 5 /* IBS: op PMC base */
+#define PMU_AMD64_IBSOPCTL_PMD 7 /* IBS: op PMD base */
+
#define PFMLIB_AMD64_MAX_UMASK 9
typedef struct {
diff --git a/lib/pfmlib_common.c b/lib/pfmlib_common.c
index 63908b1..37423ed 100644
--- a/lib/pfmlib_common.c
+++ b/lib/pfmlib_common.c
@@ -624,7 +624,9 @@ pfm_check_unavail_pmcs(pfmlib_regmask_t *pmcs)
* registers. In other words, invalid registers are ignored
*/
int
-pfm_dispatch_events(pfmlib_input_param_t *inp, void *model_in,
pfmlib_output_param_t *outp, void *model_out)
+pfm_dispatch_events(
+ pfmlib_input_param_t *inp, void *model_in,
+ pfmlib_output_param_t *outp, void *model_out)
{
unsigned count;
unsigned int i;
@@ -633,21 +635,23 @@ pfm_dispatch_events(pfmlib_input_param_t *inp, void
*model_in, pfmlib_output_par
if (PFMLIB_INITIALIZED() == 0)
return PFMLIB_ERR_NOINIT;
- if (inp == NULL || outp == NULL)
+ /* at least one input and one output set must exist */
+ if (!inp && !model_in)
return PFMLIB_ERR_INVAL;
-
- /*
- * the default priv level must be set to something
- */
- if (inp->pfp_dfl_plm == 0)
+ if (!outp && !model_out)
return PFMLIB_ERR_INVAL;
- if (inp->pfp_event_count >= PFMLIB_MAX_PMCS)
+ if (!inp)
+ count = 0;
+ else if (inp->pfp_dfl_plm == 0)
+ /* the default priv level must be set to something */
return PFMLIB_ERR_INVAL;
-
- count = inp->pfp_event_count;
- if (count > pfm_current->num_cnt)
+ else if (inp->pfp_event_count >= PFMLIB_MAX_PMCS)
+ return PFMLIB_ERR_INVAL;
+ else if (inp->pfp_event_count > pfm_current->num_cnt)
return PFMLIB_ERR_NOASSIGN;
+ else
+ count = inp->pfp_event_count;
/*
* check that event and unit masks descriptors are correct
@@ -657,8 +661,10 @@ pfm_dispatch_events(pfmlib_input_param_t *inp, void
*model_in, pfmlib_output_par
if (ret != PFMLIB_SUCCESS)
return ret;
}
+
/* reset output data structure */
- memset(outp, 0, sizeof(*outp));
+ if (outp)
+ memset(outp, 0, sizeof(*outp));
return pfm_current->dispatch_events(inp, model_in, outp, model_out);
}
--
1.5.3.7
--
Advanced Micro Devices, Inc.
Operating System Research Center
email: [EMAIL PROTECTED]
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
perfmon2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/perfmon2-devel