For AMD64 there are revision ranges available for each event and
mask. This patch adds a revision check. Now, unsupported events and
masks are no longer reported. The functions pfm_amd64_get_event_name()
and pfm_amd64_get_event_mask_name() return a NULL pointer instead of
the name. Generic libpfm functions ignore those unsupported events or
masks and pfm_get_event_mask_name() and pfm_get_event_mask_name()
return PFMLIB_ERR_BADHOST in this case.

Signed-off-by: Robert Richter <robert.rich...@amd.com>
---
 lib/pfmlib_amd64.c      |   33 ++++++++++++++++++++++++--
 lib/pfmlib_amd64_priv.h |    1 +
 lib/pfmlib_common.c     |   58 ++++++++++++++++++++++++++++++----------------
 3 files changed, 69 insertions(+), 23 deletions(-)

diff --git a/lib/pfmlib_amd64.c b/lib/pfmlib_amd64.c
index d2198bd..97259c7 100644
--- a/lib/pfmlib_amd64.c
+++ b/lib/pfmlib_amd64.c
@@ -86,6 +86,13 @@ static struct {
        pme_amd64_entry_t *events;
 } amd64_pmu;
 
+pme_amd64_entry_t unsupported_event = {
+       .pme_name = "<unsupported>",
+       .pme_desc = "This event is not supported be this cpu revision.",
+       .pme_code = ~0,
+       .pme_flags = PFMLIB_AMD64_NOT_SUPP,
+};
+
 pfm_pmu_support_t amd64_support;
 
 #define amd64_revision    amd64_pmu.revision
@@ -303,10 +310,24 @@ is_valid_rev(unsigned int flags, int revision)
 static inline pme_amd64_entry_t
 *pfm_amd64_get_event_entry(unsigned int index)
 {
+       /*
+        * Since there are no NULL pointer checks for the return
+        * value, &unsupported_event is returned instead. Function
+        * is_valid_index() may be used to validate the index.
+        */
+       pme_amd64_entry_t *event;
        if (index >= amd64_event_count)
-               return NULL;
+               return &unsupported_event;
+       event = &amd64_events[index];
+       if (!is_valid_rev(event->pme_flags, amd64_revision))
+               return &unsupported_event;
+       return event;
+}
 
-       return &amd64_events[index];
+static inline int
+is_valid_index(unsigned int index)
+{
+       return (pfm_amd64_get_event_entry(index) != &unsupported_event);
 }
 
 /*
@@ -641,6 +662,8 @@ pfm_amd64_get_hw_counter_width(unsigned int *width)
 static char *
 pfm_amd64_get_event_name(unsigned int i)
 {
+       if (!is_valid_index(i))
+               return NULL;
        return pfm_amd64_get_event_entry(i)->pme_name;
 }
 
@@ -660,7 +683,11 @@ pfm_amd64_get_event_desc(unsigned int ev, char **str)
 static char *
 pfm_amd64_get_event_mask_name(unsigned int ev, unsigned int midx)
 {
-       return pfm_amd64_get_event_entry(ev)->pme_umasks[midx].pme_uname;
+       pme_amd64_umask_t *umask;
+       umask = &pfm_amd64_get_event_entry(ev)->pme_umasks[midx];
+       if (!is_valid_rev(umask->pme_uflags, amd64_revision))
+               return NULL;
+       return umask->pme_uname;
 }
 
 static int
diff --git a/lib/pfmlib_amd64_priv.h b/lib/pfmlib_amd64_priv.h
index bda2dd9..148b5a2 100644
--- a/lib/pfmlib_amd64_priv.h
+++ b/lib/pfmlib_amd64_priv.h
@@ -94,6 +94,7 @@ static const char *amd64_cpu_strs[] = {
 #define PFMLIB_AMD64_UMASK_COMBO       0x1 /* unit mask can be combined */
 #define PFMLIB_AMD64_FROM_REV(rev)     ((rev)<<8)
 #define PFMLIB_AMD64_TILL_REV(rev)     ((rev)<<16)
+#define PFMLIB_AMD64_NOT_SUPP          0x1ff00
 #define PFMLIB_AMD64_K8_REV_D          PFMLIB_AMD64_FROM_REV(AMD64_K8_REV_D)
 #define PFMLIB_AMD64_K8_REV_E          PFMLIB_AMD64_FROM_REV(AMD64_K8_REV_E)
 #define PFMLIB_AMD64_K8_REV_F          PFMLIB_AMD64_FROM_REV(AMD64_K8_REV_F)
diff --git a/lib/pfmlib_common.c b/lib/pfmlib_common.c
index 8ca229d..6b9ff2a 100644
--- a/lib/pfmlib_common.c
+++ b/lib/pfmlib_common.c
@@ -333,6 +333,8 @@ pfm_find_event_byname(const char *n, unsigned int *idx)
         */
        for(i=0; i < pfm_current->pme_count; i++) {
                e = pfm_current->get_event_name(i);
+               if (!e)
+                       continue;
                if (!strncasecmp(e, n, len)
                    && len == strlen(e))
                        goto found;
@@ -435,13 +437,17 @@ pfm_do_find_event_mask(unsigned int ev, const char *str, 
unsigned int *mask_idx)
        unsigned int i, c, num_masks = 0;
        unsigned long mask_val = -1;
        char *endptr = NULL;
+       char *mask_name;
 
        num_masks = pfm_num_masks(ev);
        for (i = 0; i < num_masks; i++) {
-               if (!strcasecmp(pfm_current->get_event_mask_name(ev, i), str)) {
-                       *mask_idx = i;
-                       return PFMLIB_SUCCESS;
-               }
+               mask_name = pfm_current->get_event_mask_name(ev, i);
+               if (!mask_name)
+                       continue;
+               if (strcasecmp(mask_name, str))
+                       continue;
+               *mask_idx = i;
+               return PFMLIB_SUCCESS;
        }
        /* don't give up yet; check for a exact numerical value */
        mask_val = strtoul(str, &endptr, 0);
@@ -557,6 +563,8 @@ pfm_get_event_name(unsigned int i, char *name, size_t 
maxlen)
                return PFMLIB_ERR_INVAL;
 
        str = pfm_current->get_event_name(i);
+       if (!str)
+               return PFMLIB_ERR_BADHOST;
        l = strlen(str);
 
        /*
@@ -612,7 +620,7 @@ pfm_get_event_counters(unsigned int i, pfmlib_regmask_t 
*counters)
 int
 pfm_get_event_mask_name(unsigned int ev, unsigned int mask, char *name, size_t 
maxlen)
 {
-       char *n;
+       char *str;
        unsigned int num;
        size_t l, j;
 
@@ -629,15 +637,14 @@ pfm_get_event_mask_name(unsigned int ev, unsigned int 
mask, char *name, size_t m
        if (mask >= num)
                return PFMLIB_ERR_INVAL;
 
-       n = pfm_current->get_event_mask_name(ev, mask);
-       if (n == NULL)
-               return PFMLIB_ERR_INVAL;
-
-       l = strlen(n);
+       str = pfm_current->get_event_mask_name(ev, mask);
+       if (!str)
+               return PFMLIB_ERR_BADHOST;
+       l = strlen(str);
        if (l >= (maxlen-1))
                return PFMLIB_ERR_FULL;
 
-       strcpy(name, n);
+       strcpy(name, str);
 
        /*
         * present nice uniform names
@@ -887,6 +894,7 @@ pfm_get_max_event_name_len(size_t *len)
 {
        unsigned int i, j, num_masks;
        size_t max = 0, l;
+       char *str;
 
        if (PFMLIB_INITIALIZED() == 0)
                return PFMLIB_ERR_NOINIT;
@@ -894,7 +902,10 @@ pfm_get_max_event_name_len(size_t *len)
                return PFMLIB_ERR_INVAL;
 
        for(i=0; i < pfm_current->pme_count; i++) {
-               l = strlen(pfm_current->get_event_name(i));
+               str = pfm_current->get_event_name(i);
+               if (!str)
+                       continue;
+               l = strlen(str);
                if (l > max) max = l;
 
                num_masks = pfm_num_masks(i);
@@ -904,7 +915,10 @@ pfm_get_max_event_name_len(size_t *len)
                 * which is inserted as the unit mask separator
                 */
                for (j = 0; j < num_masks; j++) {
-                       l += 1 + strlen(pfm_current->get_event_mask_name(i, j));
+                       str = pfm_current->get_event_mask_name(i, j);
+                       if (!str)
+                               continue;
+                       l += 1 + strlen(str);
                }
                if (l > max) max = l;
        }
@@ -1001,7 +1015,7 @@ pfm_get_event_mask_code(unsigned int event_idx, unsigned 
int mask_idx, unsigned
 int
 pfm_get_full_event_name(pfmlib_event_t *e, char *name, size_t maxlen)
 {
-       char *n;
+       char *str;
        size_t l, j;
        int ret;
 
@@ -1022,21 +1036,25 @@ pfm_get_full_event_name(pfmlib_event_t *e, char *name, 
size_t maxlen)
         */
        *name = '\0';
 
-       n = pfm_current->get_event_name(e->event);
-       l = strlen(n);
+       str = pfm_current->get_event_name(e->event);
+       if (!str)
+               return PFMLIB_ERR_BADHOST;
+       l = strlen(str);
        if (l > (maxlen-1))
                return PFMLIB_ERR_FULL;
 
-       strcpy(name, n);
+       strcpy(name, str);
        maxlen -= l + 1;
        for(j=0; j < e->num_masks; j++) {
-               n = pfm_current->get_event_mask_name(e->event, 
e->unit_masks[j]);
-               l = strlen(n);
+               str = pfm_current->get_event_mask_name(e->event, 
e->unit_masks[j]);
+               if (!str)
+                       continue;
+               l = strlen(str);
                if (l > (maxlen-1))
                        return PFMLIB_ERR_FULL;
 
                strcat(name, ":");
-               strcat(name, n);
+               strcat(name, str);
                maxlen -= l + 1;
        }
        /*
-- 
1.6.1.2



------------------------------------------------------------------------------
_______________________________________________
perfmon2-devel mailing list
perfmon2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/perfmon2-devel

Reply via email to