From: Andi Kleen <a...@linux.intel.com>

Add the generic transaction events with aliases to the parser, lexer
and the reverse map code.

Signed-off-by: Andi Kleen <a...@linux.intel.com>
---
 tools/perf/util/evsel.c        |   40 ++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/parse-events.c |   24 ++++++++++++++++++++++++
 tools/perf/util/parse-events.l |   19 ++++++++++++++++++-
 tools/perf/util/parse-events.y |    4 ++--
 4 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index ff084b0..8790069 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -288,6 +288,42 @@ static int perf_evsel__hw_cache_name(struct perf_evsel 
*evsel, char *bf, size_t
        return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret);
 }
 
+static const char *transaction_name[] = {
+ [PERF_COUNT_HW_TRANSACTION_START]  = "transaction-start",
+ [PERF_COUNT_HW_TRANSACTION_COMMIT] = "transaction-commit",
+ [PERF_COUNT_HW_TRANSACTION_ABORT]  = "transaction-abort",
+ [PERF_COUNT_HW_ELISION_START]      = "elision-start",
+ [PERF_COUNT_HW_ELISION_COMMIT]     = "elision-commit",
+ [PERF_COUNT_HW_ELISION_ABORT]      = "elision-abort",
+};
+
+static const char *transaction_reason[] = {
+ [PERF_COUNT_HW_ABORT_ALL]          = "all",
+ [PERF_COUNT_HW_ABORT_CONFLICT]     = "conflict",
+ [PERF_COUNT_HW_ABORT_CAPACITY]     = "capacity",
+};
+
+static int perf_evsel__transaction_name(struct perf_evsel *evsel, char *bf,
+                                       size_t size)
+{
+       u64 config = evsel->attr.config;
+       u8 name = config & 0xff, reason = (config >> 8) & 0xff;
+
+       if (name < PERF_COUNT_HW_TRANSACTION_MAX &&
+           reason < PERF_COUNT_HW_ABORT_MAX) {
+               const char *sep = "", *rtxt = "";
+               if (name == PERF_COUNT_HW_TRANSACTION_ABORT ||
+                   name == PERF_COUNT_HW_ELISION_ABORT) {
+                       sep = "-";
+                       rtxt = transaction_reason[reason];
+               }
+               return scnprintf(bf, size, "%s%s%s", transaction_name[name],
+                                                    sep, rtxt);
+       }
+
+       return scnprintf(bf, size, "invalid-transaction");
+}
+
 static int perf_evsel__raw_name(struct perf_evsel *evsel, char *bf, size_t 
size)
 {
        int ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->attr.config);
@@ -326,6 +362,10 @@ const char *perf_evsel__name(struct perf_evsel *evsel)
                perf_evsel__bp_name(evsel, bf, sizeof(bf));
                break;
 
+       case PERF_TYPE_HW_TRANSACTION:
+               perf_evsel__transaction_name(evsel, bf, sizeof(bf));
+               break;
+
        default:
                scnprintf(bf, sizeof(bf), "%s", "unknown attr type");
                break;
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 5668ca6..e24a490 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -110,6 +110,20 @@ static struct event_symbol 
event_symbols_sw[PERF_COUNT_SW_MAX] = {
        },
 };
 
+static struct event_symbol event_symbols_txn[] = {
+       { .symbol = "transaction-start",          .alias = "tx-start"    },
+       { .symbol = "transaction-commit",         .alias = "tx-commit"   },
+       { .symbol = "transaction-abort-all",      .alias = "tx-abort"    },
+       { .symbol = "transaction-abort-capacity", .alias = "tx-capacity" },
+       { .symbol = "transaction-abort-conflict", .alias = "tx-conflict" },
+       { .symbol = "elision-start",              .alias = "le-start"    },
+       { .symbol = "elision-commit",             .alias = "le-commit"   },
+       { .symbol = "elision-abort-all",          .alias = "le-abort"    },
+       { .symbol = "elision-abort-capacity",     .alias = "le-capacity" },
+       { .symbol = "elision-abort-conflict",     .alias = "le-conflict" },
+
+};
+
 #define __PERF_EVENT_FIELD(config, name) \
        ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT)
 
@@ -232,6 +246,9 @@ const char *event_type(int type)
        case PERF_TYPE_HW_CACHE:
                return "hardware-cache";
 
+       case PERF_TYPE_HW_TRANSACTION:
+               return "hardware-transaction";
+
        default:
                break;
        }
@@ -800,6 +817,7 @@ static const char * const event_type_descriptors[] = {
        "Hardware cache event",
        "Raw hardware event descriptor",
        "Hardware breakpoint",
+       "Hardware transaction event",
 };
 
 /*
@@ -909,6 +927,9 @@ void print_events_type(u8 type)
 {
        if (type == PERF_TYPE_SOFTWARE)
                __print_events_type(type, event_symbols_sw, PERF_COUNT_SW_MAX);
+       else if (type == PERF_TYPE_HW_TRANSACTION)
+               __print_events_type(type, event_symbols_txn,
+                                   ARRAY_SIZE(event_symbols_txn));
        else
                __print_events_type(type, event_symbols_hw, PERF_COUNT_HW_MAX);
 }
@@ -984,6 +1005,9 @@ void print_events(const char *event_glob)
 
        print_hwcache_events(event_glob);
 
+       print_symbol_events(event_glob, PERF_TYPE_HW_TRANSACTION,
+                           event_symbols_txn, ARRAY_SIZE(event_symbols_txn));
+
        if (event_glob != NULL)
                return;
 
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 96ab100..2c9dd04 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -56,7 +56,8 @@ static int sym(yyscan_t scanner, int type, int config)
        YYSTYPE *yylval = parse_events_get_lval(scanner);
 
        yylval->num = (type << 16) + config;
-       return type == PERF_TYPE_HARDWARE ? PE_VALUE_SYM_HW : PE_VALUE_SYM_SW;
+       return type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_TRANSACTION ?
+              PE_VALUE_SYM_HW : PE_VALUE_SYM_SW;
 }
 
 static int term(yyscan_t scanner, int type)
@@ -67,6 +68,11 @@ static int term(yyscan_t scanner, int type)
        return PE_TERM;
 }
 
+#define txn(t)         sym(yyscanner, PERF_TYPE_HW_TRANSACTION, \
+                            PERF_COUNT_HW_##t)
+#define txn_abort(t, a) sym(yyscanner, PERF_TYPE_HW_TRANSACTION, \
+                           PERF_COUNT_HW_##t | ((PERF_COUNT_HW_ABORT_##a)<<8))
+
 %}
 
 %x mem
@@ -127,6 +133,17 @@ speculative-read|speculative-load  |
 refs|Reference|ops|access              |
 misses|miss                            { return str(yyscanner, 
PE_NAME_CACHE_OP_RESULT); }
 
+transaction-start|tx-start             { return txn(TRANSACTION_START);  }
+transaction-commit|tx-commit           { return txn(TRANSACTION_COMMIT); }
+transaction-abort-all|tx-aborts?       { return txn_abort(TRANSACTION_ABORT, 
ALL); }
+transaction-abort-conflict|tx-conflict  { return txn_abort(TRANSACTION_ABORT, 
CONFLICT); }
+transaction-abort-capacity|tx-capacity  { return txn_abort(TRANSACTION_ABORT, 
CAPACITY); }
+elision-start|le-start                 { return txn(ELISION_START);  }
+elision-commit|le-commit               { return txn(ELISION_COMMIT); }
+elision-abort-all|le-aborts?           { return txn_abort(ELISION_ABORT, ALL); 
}
+elision-abort-conflict|le-conflict     { return txn_abort(ELISION_ABORT, 
CONFLICT); }
+elision-abort-capacity|le-capacity     { return txn_abort(ELISION_ABORT, 
CAPACITY); }
+
        /*
         * These are event config hardcoded term names to be specified
         * within xxx/.../ syntax. So far we dont clash with other names,
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 2bc5fbf..6485eb3 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -122,7 +122,7 @@ value_sym '/' event_config '/'
        struct parse_events_data__events *data = _data;
        struct list_head *list = NULL;
        int type = $1 >> 16;
-       int config = $1 & 255;
+       int config = $1 & 0xffff;
 
        ABORT_ON(parse_events_add_numeric(&list, &data->idx,
                                          type, config, $3));
@@ -135,7 +135,7 @@ value_sym sep_slash_dc
        struct parse_events_data__events *data = _data;
        struct list_head *list = NULL;
        int type = $1 >> 16;
-       int config = $1 & 255;
+       int config = $1 & 0xffff;
 
        ABORT_ON(parse_events_add_numeric(&list, &data->idx,
                                          type, config, NULL));
-- 
1.7.7.6

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

Reply via email to