Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf expr: Add has_event function

Some events are dependent on firmware/kernel enablement. Allow such
events to be detected when the metric is parsed so that the metric's
event parsing doesn't fail.

Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Namhyung Kim <namhyung@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Eduard Zingerman <eddyz87@gmail.com>
Cc: Sohom Datta <sohomdatta1@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Caleb Biggers <caleb.biggers@intel.com>
Cc: Edward Baker <edward.baker@intel.com>
Cc: Perry Taylor <perry.taylor@intel.com>
Cc: Samantha Alt <samantha.alt@intel.com>
Cc: Weilin Wang <weilin.wang@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Jing Zhang <renyu.zj@linux.alibaba.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Zhengjun Xing <zhengjun.xing@linux.intel.com>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Ingo Molnar <mingo@redhat.com>
Link: https://lore.kernel.org/r/20230623151016.4193660-2-irogers@google.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

authored by

Ian Rogers and committed by
Namhyung Kim
4a4a9bf9 36cee69f

+34 -1
+4
tools/perf/tests/expr.c
··· 254 254 TEST_ASSERT_VAL("source count", hashmap__size(ctx->ids) == 1); 255 255 TEST_ASSERT_VAL("source count", hashmap__find(ctx->ids, "EVENT1", &val_ptr)); 256 256 257 + /* has_event returns 1 when an event exists. */ 258 + expr__add_id_val(ctx, strdup("cycles"), 2); 259 + ret = test(ctx, "has_event(cycles)", 1); 260 + 257 261 expr__ctx_free(ctx); 258 262 259 263 return 0;
+21
tools/perf/util/expr.c
··· 8 8 #include "cpumap.h" 9 9 #include "cputopo.h" 10 10 #include "debug.h" 11 + #include "evlist.h" 11 12 #include "expr.h" 12 13 #include "expr-bison.h" 13 14 #include "expr-flex.h" ··· 474 473 out: 475 474 pr_debug2("literal: %s = %f\n", literal, result); 476 475 return result; 476 + } 477 + 478 + /* Does the event 'id' parse? Determine via ctx->ids if possible. */ 479 + double expr__has_event(const struct expr_parse_ctx *ctx, bool compute_ids, const char *id) 480 + { 481 + struct evlist *tmp; 482 + double ret; 483 + 484 + if (hashmap__find(ctx->ids, id, /*value=*/NULL)) 485 + return 1.0; 486 + 487 + if (!compute_ids) 488 + return 0.0; 489 + 490 + tmp = evlist__new(); 491 + if (!tmp) 492 + return NAN; 493 + ret = parse_event(tmp, id) ? 0 : 1; 494 + evlist__delete(tmp); 495 + return ret; 477 496 }
+1
tools/perf/util/expr.h
··· 54 54 double expr_id_data__value(const struct expr_id_data *data); 55 55 double expr_id_data__source_count(const struct expr_id_data *data); 56 56 double expr__get_literal(const char *literal, const struct expr_scanner_ctx *ctx); 57 + double expr__has_event(const struct expr_parse_ctx *ctx, bool compute_ids, const char *id); 57 58 58 59 #endif
+1
tools/perf/util/expr.l
··· 113 113 if { return IF; } 114 114 else { return ELSE; } 115 115 source_count { return SOURCE_COUNT; } 116 + has_event { return HAS_EVENT; } 116 117 {literal} { return literal(yyscanner, sctx); } 117 118 {number} { return value(yyscanner); } 118 119 {symbol} { return str(yyscanner, ID, sctx->runtime); }
+7 -1
tools/perf/util/expr.y
··· 37 37 } ids; 38 38 } 39 39 40 - %token ID NUMBER MIN MAX IF ELSE LITERAL D_RATIO SOURCE_COUNT EXPR_ERROR 40 + %token ID NUMBER MIN MAX IF ELSE LITERAL D_RATIO SOURCE_COUNT HAS_EVENT EXPR_ERROR 41 41 %left MIN MAX IF 42 42 %left '|' 43 43 %left '^' ··· 199 199 } 200 200 | ID { $$ = handle_id(ctx, $1, compute_ids, /*source_count=*/false); } 201 201 | SOURCE_COUNT '(' ID ')' { $$ = handle_id(ctx, $3, compute_ids, /*source_count=*/true); } 202 + | HAS_EVENT '(' ID ')' 203 + { 204 + $$.val = expr__has_event(ctx, compute_ids, $3); 205 + $$.ids = NULL; 206 + free($3); 207 + } 202 208 | expr '|' expr 203 209 { 204 210 if (is_const($1.val) && is_const($3.val)) {