Received: by 2002:a25:23cc:0:0:0:0:0 with SMTP id j195csp1356661ybj; Thu, 7 May 2020 22:38:36 -0700 (PDT) X-Google-Smtp-Source: APiQypIYNLqbs7AIHBFYhSXALgcojvqZfxVK3JpSSZ536C5vyRLSeRI/r/K6fgQizYjnVLuAH7W3 X-Received: by 2002:a50:c3c2:: with SMTP id i2mr713302edf.93.1588916316335; Thu, 07 May 2020 22:38:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1588916316; cv=none; d=google.com; s=arc-20160816; b=C2qUZzPUV6gSj2UGPAnaup73u0z58S2/dEwjp1bIiijtb6gdvAmznSYB4umC3PqOzn zs/uj1WtJBQ/w91iqMDMH2ggprZnAYSBJ1I5OjbNeVRk4YZJqQD/zQ0AyKm7ISB73s8P JdW/0KCBxciVTbzgYPnxijoKqMfobIKzR08BRkazar15K/UnOVxksQzt+Q+wihE82Vd8 /Jd8fpwjl/ooDJFSjNrcaW3g5iHpOJCT8Pk+9GVBW6+kUdNG8cCd7+xB4n6L/HCe6TLD VYi55Jhd50AfP/rCfBgi7pADWjhy+PblMg9Q6w0C2Y1FifsBnCj6oiRuZf5VmFQEn2y0 OLxQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:from:subject:references :mime-version:message-id:in-reply-to:date:dkim-signature; bh=JjOXEdThPrX0ZqK5ziVYe2R9lvfX0D5b1eKQZ5WMkmg=; b=ErOeHUSgMByISgwGYWW5Vb1Bkb5l7jf53164mv63h8EwU7gLM+Gfg5pCDFXJUF+a51 uRRpVAXMRLhJawPJtXcG/EXNz+0NHKRomb4MEXFkk9HiTAg7u5nLQpDihfFH2mxDNMM2 GGd56+xipwmTvl1uJIK6Y1PPi+xqoyl9yygON6yCSWhGyZAsqbiyydxqFFMxY3oMicLa 3ytib7pvhy56uEB7ejbq7sVfX+5kIJMvv+K2OKePBqu4OWFGRQQrjaJ/5MKBzLgp6zjL Nfl/Da1zocRMiNz/zoYJzqEUWHyBKgPUvlCShLwi/eOdiTkt6ywBquuiZb0EeELg/1tq LxqA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=qRFdoz0o; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id p3si322272ejd.471.2020.05.07.22.38.13; Thu, 07 May 2020 22:38:36 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=qRFdoz0o; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727088AbgEHFgo (ORCPT + 99 others); Fri, 8 May 2020 01:36:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49296 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726811AbgEHFgj (ORCPT ); Fri, 8 May 2020 01:36:39 -0400 Received: from mail-qt1-x849.google.com (mail-qt1-x849.google.com [IPv6:2607:f8b0:4864:20::849]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DDD44C05BD43 for ; Thu, 7 May 2020 22:36:37 -0700 (PDT) Received: by mail-qt1-x849.google.com with SMTP id e44so643470qta.9 for ; Thu, 07 May 2020 22:36:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=JjOXEdThPrX0ZqK5ziVYe2R9lvfX0D5b1eKQZ5WMkmg=; b=qRFdoz0oViVdbSdesJ3uOeuhDDOQyvokV4ju81NN6O+S1uHObHDF91I90PuVuFQgd7 KwioLoJmPgoXyy0yyOOiaWRTg8i5QTFA1figp4DmzWUR4OblfDzxzDDygMv5lEcKHNqt a+PFpq6LnOTFsYjiNyCTl/r94BKPcG4G3f9id/nYN9hUComV20GXljR0SRIVt1DBdtkI Jz2fBOqYxLVdpVZqFBDJ+JLPDpFdnHZaFp27mXJx+BpM4kN9Q/xsomKcgGJCgdy6Eeqc 3GQDBDuGMKrfUaor2heUfaiY7zeu6nIwtMauja5FrlQlCPUw+whJtTSWcd5fDBWCKfRH 2dIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=JjOXEdThPrX0ZqK5ziVYe2R9lvfX0D5b1eKQZ5WMkmg=; b=lxXh+O2MD4NxJRd24gAYPpqvqQxLNG5dzLO2g8BMqqms5CxSpRwn205euItl5lV1Th BGOfsQOWB0CdnfOIJvfupGpAKgEtYnLkJY4JVCJQIRk5pQ5k2QXAYZ6QJTazx7lblJpk Bpb5EbqcWXMFdid70yVPVVo4GTqMgMqFKOrC8KDLoppf8G63rz6ryffgdzhKKACKCBKp gtuW3ih4g5Sg6/b3y6Jjy6oGZqBbG4x73VICIFag04VBYr+D+BXY/4ggOXrdRn9kyC08 2s32tETdRFVAKpu62O58AEupu76+Xxkt56BqdJ5778/h8QiUTZ1L1TwAVJHXxr04R6Fi 0lOw== X-Gm-Message-State: AGi0PuZuTdiNo5eM0Z1z+VAJD6l3uTfWQ7vxS/JqxUY0uHLaWdDJxk2F RBRTVIPXxiH5HgBiVQQsrU1uS7ovVCMf X-Received: by 2002:ad4:4a8b:: with SMTP id h11mr1008735qvx.210.1588916196931; Thu, 07 May 2020 22:36:36 -0700 (PDT) Date: Thu, 7 May 2020 22:36:17 -0700 In-Reply-To: <20200508053629.210324-1-irogers@google.com> Message-Id: <20200508053629.210324-3-irogers@google.com> Mime-Version: 1.0 References: <20200508053629.210324-1-irogers@google.com> X-Mailer: git-send-email 2.26.2.645.ge9eca65c58-goog Subject: [RFC PATCH v3 02/14] perf test: improve pmu event metric testing From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andrii Nakryiko , John Fastabend , KP Singh , Kajol Jain , Andi Kleen , John Garry , Jin Yao , Kan Liang , Cong Wang , Kim Phillips , linux-kernel@vger.kernel.org Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, linux-perf-users@vger.kernel.org, Vince Weaver , Stephane Eranian , Ian Rogers Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add a basic floating point number test to expr. Break pmu-events test into 2 and add a test to verify that all pmu metric expressions simply parse. Try to parse all metric ids/events, failing if metrics for the current architecture fail to parse. Tested on skylakex with the patch set in place. May fail on other architectures if metrics are invalid. Signed-off-by: Ian Rogers --- tools/perf/tests/builtin-test.c | 5 + tools/perf/tests/expr.c | 1 + tools/perf/tests/pmu-events.c | 158 ++++++++++++++++++++++++++++++-- tools/perf/tests/tests.h | 2 + 4 files changed, 160 insertions(+), 6 deletions(-) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 3471ec52ea11..8147c17c71ab 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -75,6 +75,11 @@ static struct test generic_tests[] = { { .desc = "PMU events", .func = test__pmu_events, + .subtest = { + .get_nr = test__pmu_events_subtest_get_nr, + .get_desc = test__pmu_events_subtest_get_desc, + }, + }, { .desc = "DSO data read", diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index f9e8e5628836..3f742612776a 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -39,6 +39,7 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused) ret |= test(&ctx, "min(1,2) + 1", 2); ret |= test(&ctx, "max(1,2) + 1", 3); ret |= test(&ctx, "1+1 if 3*4 else 0", 2); + ret |= test(&ctx, "1.1 + 2.1", 3.2); if (ret) return ret; diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index d64261da8bf7..c18b9ce8cace 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -8,6 +8,10 @@ #include #include "debug.h" #include "../pmu-events/pmu-events.h" +#include "util/evlist.h" +#include "util/expr.h" +#include "util/parse-events.h" +#include struct perf_pmu_test_event { struct pmu_event event; @@ -144,7 +148,7 @@ static struct pmu_events_map *__test_pmu_get_events_map(void) } /* Verify generated events from pmu-events.c is as expected */ -static int __test_pmu_event_table(void) +static int test_pmu_event_table(void) { struct pmu_events_map *map = __test_pmu_get_events_map(); struct pmu_event *table; @@ -347,14 +351,11 @@ static int __test__pmu_event_aliases(char *pmu_name, int *count) return res; } -int test__pmu_events(struct test *test __maybe_unused, - int subtest __maybe_unused) + +static int test_aliases(void) { struct perf_pmu *pmu = NULL; - if (__test_pmu_event_table()) - return -1; - while ((pmu = perf_pmu__scan(pmu)) != NULL) { int count = 0; @@ -377,3 +378,148 @@ int test__pmu_events(struct test *test __maybe_unused, return 0; } + +static bool is_number(const char *str) +{ + size_t i; + + for (i = 0; i < strlen(str); i++) { + if (!isdigit(str[i]) && str[i] != '.') + return false; + } + return true; +} + +static int check_parse_id(const char *id, bool same_cpu, struct pmu_event *pe) +{ + struct parse_events_error error; + struct evlist *evlist; + int ret; + + /* Numbers are always valid. */ + if (is_number(id)) + return 0; + + evlist = evlist__new(); + memset(&error, 0, sizeof(error)); + ret = parse_events(evlist, id, &error); + if (ret && same_cpu) { + fprintf(stderr, + "\nWARNING: Parse event failed metric '%s' id '%s' expr '%s'\n", + pe->metric_name, id, pe->metric_expr); + fprintf(stderr, "Error string '%s' help '%s'\n", + error.str, error.help); + } else if (ret) { + pr_debug3("Parse event failed, but for an event that may not be supported by this CPU.\nid '%s' metric '%s' expr '%s'\n", + id, pe->metric_name, pe->metric_expr); + } + evlist__delete(evlist); + free(error.str); + free(error.help); + free(error.first_str); + free(error.first_help); + /* TODO: too many metrics are broken to fail on this test currently. */ + return 0; +} + +static int test_parsing(void) +{ + struct pmu_events_map *cpus_map = perf_pmu__find_map(NULL); + struct pmu_events_map *map; + struct pmu_event *pe; + int i, j, k; + const char **ids; + int idnum; + int ret = 0; + struct expr_parse_ctx ctx; + double result; + + i = 0; + for (;;) { + map = &pmu_events_map[i++]; + if (!map->table) { + map = NULL; + break; + } + j = 0; + for (;;) { + pe = &map->table[j++]; + if (!pe->name && !pe->metric_group && !pe->metric_name) + break; + if (!pe->metric_expr) + continue; + if (expr__find_other(pe->metric_expr, NULL, + &ids, &idnum, 0) < 0) { + pr_debug("Parse other failed for map %s %s %s\n", + map->cpuid, map->version, map->type); + pr_debug("On metric %s\n", pe->metric_name); + pr_debug("On expression %s\n", pe->metric_expr); + ret++; + continue; + } + expr__ctx_init(&ctx); + + /* + * Add all ids with a made up value. The value may + * trigger divide by zero when subtracted and so try to + * make them unique. + */ + for (k = 0; k < idnum; k++) + expr__add_id(&ctx, ids[k], k + 1); + + for (k = 0; k < idnum; k++) { + if (check_parse_id(ids[k], map == cpus_map, pe)) + ret++; + } + + if (expr__parse(&result, &ctx, pe->metric_expr, 0)) { + pr_debug("Parse failed for map %s %s %s\n", + map->cpuid, map->version, map->type); + pr_debug("On metric %s\n", pe->metric_name); + pr_debug("On expression %s\n", pe->metric_expr); + ret++; + } + for (k = 0; k < idnum; k++) + zfree(&ids[k]); + free(ids); + } + } + return ret; +} + +static const struct { + int (*func)(void); + const char *desc; +} pmu_events_testcase_table[] = { + { + .func = test_pmu_event_table, + .desc = "PMU event table sanity", + }, + { + .func = test_aliases, + .desc = "PMU event map aliases", + }, + { + .func = test_parsing, + .desc = "Parsing of PMU event table metrics", + }, +}; + +const char *test__pmu_events_subtest_get_desc(int i) +{ + if (i < 0 || i >= (int)ARRAY_SIZE(pmu_events_testcase_table)) + return NULL; + return pmu_events_testcase_table[i].desc; +} + +int test__pmu_events_subtest_get_nr(void) +{ + return (int)ARRAY_SIZE(pmu_events_testcase_table); +} + +int test__pmu_events(struct test *test __maybe_unused, int i) +{ + if (i < 0 || i >= (int)ARRAY_SIZE(pmu_events_testcase_table)) + return TEST_FAIL; + return pmu_events_testcase_table[i].func(); +} diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index d6d4ac34eeb7..8e316c30ed3c 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -50,6 +50,8 @@ int test__perf_evsel__tp_sched_test(struct test *test, int subtest); int test__syscall_openat_tp_fields(struct test *test, int subtest); int test__pmu(struct test *test, int subtest); int test__pmu_events(struct test *test, int subtest); +const char *test__pmu_events_subtest_get_desc(int subtest); +int test__pmu_events_subtest_get_nr(void); int test__attr(struct test *test, int subtest); int test__dso_data(struct test *test, int subtest); int test__dso_data_cache(struct test *test, int subtest); -- 2.26.2.645.ge9eca65c58-goog