From patchwork Mon Nov 14 21:07:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 20033 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp2367754wru; Mon, 14 Nov 2022 13:12:54 -0800 (PST) X-Google-Smtp-Source: AA0mqf4pshlzL3rtYo6J0P3uOm7Z6kqqxWoW3nmETDhiWLd7nTdzKTJ8dvJp0v8cYZO4mXGh7th4 X-Received: by 2002:a17:906:ae53:b0:78b:15dc:2355 with SMTP id lf19-20020a170906ae5300b0078b15dc2355mr11524760ejb.306.1668460374462; Mon, 14 Nov 2022 13:12:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668460374; cv=none; d=google.com; s=arc-20160816; b=wZ8GmfWkOrJqxVcMYkaMevOgtPpAvbW2aJAilg0TZrw5S9KZdTY/BZqIU7yaP3hNk4 rWpIcAFrja3p6BESW0mw3dJSms3lErHQj7rQZXIXJwr71WNGZfVhQukDNzo03PAhpxXE UajZul4ZDu0vWZvGTqtkle8x01glNK6LQ4gfiHsjjmeP2Xyet0OBg+/y8E/nzx80/FvE sNx5WS9gOdpoMMcCleKN/hVsbk8HoqvGc1lhgAGTSe0Bn4+dKL/z5cQsrpduWApBuZzu oIL4rMCzo7Ut1cKnaTnB/gGczwDQHL6Z5LHP4Lk6qVjt3Td3ZG2cYYHMDeU79dwfIgxI pJEg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=2OZhfmPm3XVkECYqwzYQM5F2KZdnyo2PlgH8Orm1zuI=; b=oDKND10p7831lYEPEDEk9D9GxYQEbh1I3xb0NNKTK+7imHtbuPMI2UaiFlkHhZ9yx3 9sbBqu03ur3sKRheNU0eYfV5So1naQoJYe/xMWR9kWSEpfrX2bv8O3CDywbrR0wwDnXt XS4NNyYn/5KEwTuMsXhkWrXyupFpYqKQLHrjQgulht/P7oQDvSpAlkKrPwUZD4INkCOT BJnMLaUpLXjJqe3nnAmZADnWYu3pYEBzLfJFD5SvTJg5rgrTq+beL0D1LqcuAn9IvnpU l2FVi3OMbyTDSdGka3o1lATXy1MCsVhsp9MNbnxigha3Jkf/qd319UFppLoA9VG99KuI +nTA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=d03dpv19; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g8-20020a50ee08000000b00461b84a010fsi8987073eds.295.2022.11.14.13.12.30; Mon, 14 Nov 2022 13:12:54 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=d03dpv19; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 S237346AbiKNVH6 (ORCPT + 99 others); Mon, 14 Nov 2022 16:07:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44256 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237361AbiKNVHz (ORCPT ); Mon, 14 Nov 2022 16:07:55 -0500 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BB6E095A3 for ; Mon, 14 Nov 2022 13:07:48 -0800 (PST) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-360b9418f64so114894457b3.7 for ; Mon, 14 Nov 2022 13:07:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=2OZhfmPm3XVkECYqwzYQM5F2KZdnyo2PlgH8Orm1zuI=; b=d03dpv19fKYHRy/o0sTKt3d1Ucz5gD7WCqPFOeFJ2EEnrgHjP1F7o+EV5XjAH7uKXx QlhalH9ep4BgRvy+zz8yAUsQpMYQICs3LDhHwH+q5UgWdAFRboeOgd3gMH2tYFWsbrir cG4OYvkuz0+LBYsnJca4j/6wqAc5/FoKYNwrRbFeCYbtO2extKFVChEEuuP97gu1F4fI YlTRuFCf+JNRttBeHgxKWCxX3NgIWs+sZqDWiZOUtj4kn2NerPrZJua9Y6GmjZVdtqBG N6lPgMczC485QLYAXnM1iuRs4lqjm3b/CbiA6x/obus990if35GiEg2TDCzz9DfLnPBR gVvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=2OZhfmPm3XVkECYqwzYQM5F2KZdnyo2PlgH8Orm1zuI=; b=YW0WSUaOi8HjHOKCxvtc3FPwe+oWIT3+rLwdcA6VlCOD0oyqMm/5sSJy4HNgkc3JFa v6pyFO5RhZCKv57tkn/WGXsaWz/vj29UUZ6znKBYPuaV4qOL9kaPG0rnhw3svowynLlm IQ0tJoLS6Dr6K5kGBGVJ+DYCrjWndG2ZLIwdGVnSAwT+Q+C0Q2PjyPQnFzVamPDi/v4l gZ9hbKt4VL2M+Skc6ZmvXKKuF4leUvWodGJNCqzEho8mZpPTOVgzNoDmHUk++N8yvgtM 9ZoJSM7BK+oOPBxSbjJslPo3qO9a3r97nCMtoqCU5Gphh15vOq4uF9HeCPfq390x4Xbt 0T1g== X-Gm-Message-State: ANoB5pnFdhc449GoM2X5C0XMj4o6jNPVw3HoqYNvV85zPXPHH90/C7FI CL/Ctr2jNsqQOmf6EgWZqFpBi7f2RN+5 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:553:438f:b86a:87f]) (user=irogers job=sendgmr) by 2002:a81:78ca:0:b0:381:22a0:d706 with SMTP id t193-20020a8178ca000000b0038122a0d706mr6329985ywc.440.1668460067934; Mon, 14 Nov 2022 13:07:47 -0800 (PST) Date: Mon, 14 Nov 2022 13:07:14 -0800 In-Reply-To: <20221114210723.2749751-1-irogers@google.com> Message-Id: <20221114210723.2749751-2-irogers@google.com> Mime-Version: 1.0 References: <20221114210723.2749751-1-irogers@google.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog Subject: [PATCH v3 01/10] perf pmu: Remove is_hybrid member From: Ian Rogers To: Weilin Wang , Perry Taylor , Caleb Biggers , Leo Yan , Adrian Hunter , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Sandipan Das , Kajol Jain , Zhengjun Xing , Kan Liang , Ravi Bangoria , Xin Gao , Rob Herring , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749507505666299051?= X-GMAIL-MSGID: =?utf-8?q?1749507505666299051?= Replace usage with perf_pmu__is_hybrid. Suggested-by: Kan Liang Signed-off-by: Ian Rogers --- tools/perf/util/evsel.c | 5 +---- tools/perf/util/evsel.h | 2 +- tools/perf/util/pmu.c | 3 +-- tools/perf/util/pmu.h | 1 - tools/perf/util/stat.c | 11 +++-------- 5 files changed, 6 insertions(+), 16 deletions(-) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index cdde5b5f8ad2..ca6abb64c91d 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -3124,11 +3124,8 @@ void evsel__zero_per_pkg(struct evsel *evsel) } } -bool evsel__is_hybrid(struct evsel *evsel) +bool evsel__is_hybrid(const struct evsel *evsel) { - if (evsel->pmu) - return evsel->pmu->is_hybrid; - return evsel->pmu_name && perf_pmu__is_hybrid(evsel->pmu_name); } diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 989865e16aad..467bb0b32fef 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -498,7 +498,7 @@ struct perf_env *evsel__env(struct evsel *evsel); int evsel__store_ids(struct evsel *evsel, struct evlist *evlist); void evsel__zero_per_pkg(struct evsel *evsel); -bool evsel__is_hybrid(struct evsel *evsel); +bool evsel__is_hybrid(const struct evsel *evsel); struct evsel *evsel__leader(struct evsel *evsel); bool evsel__has_leader(struct evsel *evsel, struct evsel *leader); bool evsel__is_leader(struct evsel *evsel); diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 6a86e6af0903..48e7be6f3baa 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -980,7 +980,6 @@ static struct perf_pmu *pmu_lookup(const char *lookup_name) pmu->is_uncore = pmu_is_uncore(name); if (pmu->is_uncore) pmu->id = pmu_id(name); - pmu->is_hybrid = is_hybrid; pmu->max_precise = pmu_max_precise(name); pmu_add_cpu_aliases(&aliases, pmu); pmu_add_sys_aliases(&aliases, pmu); @@ -992,7 +991,7 @@ static struct perf_pmu *pmu_lookup(const char *lookup_name) list_splice(&aliases, &pmu->aliases); list_add_tail(&pmu->list, &pmus); - if (pmu->is_hybrid) + if (is_hybrid) list_add_tail(&pmu->hybrid_list, &perf_pmu__hybrid_pmus); pmu->default_config = perf_pmu__get_default_config(pmu); diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 68e15c38ae71..0d556d02ce52 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -40,7 +40,6 @@ struct perf_pmu { __u32 type; bool selectable; bool is_uncore; - bool is_hybrid; bool auxtrace; int max_precise; struct perf_event_attr *default_config; diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 3a432a949d46..acf0edf5fdd1 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -604,15 +604,10 @@ static void evsel__merge_aliases(struct evsel *evsel) } } -static bool evsel__should_merge_hybrid(struct evsel *evsel, struct perf_stat_config *config) +static bool evsel__should_merge_hybrid(const struct evsel *evsel, + const struct perf_stat_config *config) { - struct perf_pmu *pmu; - - if (!config->hybrid_merge) - return false; - - pmu = evsel__find_pmu(evsel); - return pmu && pmu->is_hybrid; + return config->hybrid_merge && evsel__is_hybrid(evsel); } static void evsel__merge_stats(struct evsel *evsel, struct perf_stat_config *config) From patchwork Mon Nov 14 21:07:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 20034 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp2367862wru; Mon, 14 Nov 2022 13:13:12 -0800 (PST) X-Google-Smtp-Source: AA0mqf6pnJB5g+qbJdecUleOX/Y+uzkcGUjTL6S0fvJBp1QpZ6+V918MKYrjab3JntLj+3uvub85 X-Received: by 2002:a17:906:5054:b0:79b:413b:d64 with SMTP id e20-20020a170906505400b0079b413b0d64mr11266992ejk.538.1668460391900; Mon, 14 Nov 2022 13:13:11 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668460391; cv=none; d=google.com; s=arc-20160816; b=xjw7CtzGoJGt7MkTHHRBPvIVgHEKUervzUlUlC5Z9zTe8rz7lY/OiHbSaWf+rVox9y pMZo9U+tUqjTnaTAPNGQbTCb/EO/lsSqrTQFigSL8lOyodj4Twrw16cV6r+LZOgLF8JW f/2wlx5F9tsHrpff4fnbyJKODB8gTJ2V6Y1OP8hB0NbkQnw7Y6MH7sKSsOKJQ0KlOB8D ebQG7c+WVTovvIJrgqxcd2rNi6AwnHmvUPh+bS0WdtCL5RTKq6H07iBDtgH0XoMxnai9 USn2zZwCJVciLc0QZhvZRLSQKlzGSmC9MlIEgQT6KrRojV6ax468rXV+aIWAgMEmgLTd KENg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=A43/003qhTsv7CHC/gbD1owyfDC6UmPlxbrZ5F9DYHE=; b=OjNl3zd0Ln1wlSASfULpA55iNhtt2YmzQ2zgy8OPzaItwI7LU6mqhCUYk+NHpR+KnS CNha2i5yYAKLa5SXI7DqXEWMz8dj3dma7NZw2c4nJ5KzpOk3r54ExbpF+cYyyQvUXRdZ 9RD1EXktLC1MthAIYN/4XbPQewQukF8/3ZO7B3k50QEyQuTYtAh+oEKpgHZqD5rYXCvs m2traFqyeaV6dxQpVCYwZe8KlMJeytmIGJHTr8yfFq21C+5rWVE7bQwToGvkTbwAOSt2 yl1pulrXiKaLBHmiQGYxmeJPxHXkl6GagkvgKDo4dpUdjfjCrFCKP02DjXsXs3tpkXga 7MrA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=rhiXYshj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id i23-20020a50fc17000000b00463ba265d95si7931452edr.392.2022.11.14.13.12.47; Mon, 14 Nov 2022 13:13:11 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=rhiXYshj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 S237513AbiKNVIP (ORCPT + 99 others); Mon, 14 Nov 2022 16:08:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44582 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237465AbiKNVIM (ORCPT ); Mon, 14 Nov 2022 16:08:12 -0500 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E67ADF08 for ; Mon, 14 Nov 2022 13:08:06 -0800 (PST) Received: by mail-pj1-x1049.google.com with SMTP id c10-20020a17090aa60a00b00212e91df6acso5298070pjq.5 for ; Mon, 14 Nov 2022 13:08:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=A43/003qhTsv7CHC/gbD1owyfDC6UmPlxbrZ5F9DYHE=; b=rhiXYshjGUJhA/M185y0KXRxAFIdbaKAD3QrfRD1anGpjuQA5GWSsTwg3BBAijbVzn wd5NP29ezESx931htUcdriEcxr8clV6u/URqyID+lKpm/wtxpo6+MLGUtpIwbJj+ctUK xgUpKErT92875LnGyNI0YZJS99XWLRLUTHPLCFS+GsUYiNSUaTq+BHU643NCkHNJAqip l43qsrjQOgq5WNeMVwOCGkISqIieidsvfCXXM6pA7QzpE/YM7diVfV33ToSCLl8m/rTr Y1Ma7jT4qX+YYoNVejap713djXGbd+O7mKCJKaekI3teqI2xHFs9bAcGVy8z8tRTcGMR l91Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=A43/003qhTsv7CHC/gbD1owyfDC6UmPlxbrZ5F9DYHE=; b=zTdp3AK06relnwmPEMA0hBlIjxeZsjKXw3TIK866rsXOab/SeyfJDKK9Y46Ec1v6Gm AQ9pL8YQhsS1xT9OqzyJ2y1egdSQ5Our52QzCu61gKflY24XbIf+dhDEu8MMZmYCxq4T PHXIVMPSp+ETKd9qwyy1JfsGa063pUxvxHdSnN3TPZpfndyWrnaxk/1pV8T9we+PULId Ktk4dcfEeXmpR1jXaDcXXbydrTVsZupN+I2GHIvg5gq4uPr7qYF+9z4IkstLqcjyHyHq FUQZuNBiuuy7mDijMXf53+lwI1mWMsPcKBLtXdArMmcdhojhxuIkWsU9KkKEsdEBnem+ MD4w== X-Gm-Message-State: ANoB5pkRNYFkEbZKnnO1dAt4pTKw3vWhkBG+LQtSiQixLr4JGwJlMxCK +HgGNYRuNeojbo4rcCe1bsbai9Y3gjqZ X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:553:438f:b86a:87f]) (user=irogers job=sendgmr) by 2002:a05:6a00:848:b0:572:4ea6:ddc7 with SMTP id q8-20020a056a00084800b005724ea6ddc7mr2900518pfk.26.1668460085614; Mon, 14 Nov 2022 13:08:05 -0800 (PST) Date: Mon, 14 Nov 2022 13:07:15 -0800 In-Reply-To: <20221114210723.2749751-1-irogers@google.com> Message-Id: <20221114210723.2749751-3-irogers@google.com> Mime-Version: 1.0 References: <20221114210723.2749751-1-irogers@google.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog Subject: [PATCH v3 02/10] perf pmu: Add documentation From: Ian Rogers To: Weilin Wang , Perry Taylor , Caleb Biggers , Leo Yan , Adrian Hunter , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Sandipan Das , Kajol Jain , Zhengjun Xing , Kan Liang , Ravi Bangoria , Xin Gao , Rob Herring , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749507523631333396?= X-GMAIL-MSGID: =?utf-8?q?1749507523631333396?= Add documentation to struct perf_pmu and the associated structs of perf_pmu_alias and perf_pmu_format. Signed-off-by: Ian Rogers --- tools/perf/util/pmu.c | 16 ++++++ tools/perf/util/pmu.h | 122 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 132 insertions(+), 6 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 48e7be6f3baa..057e1528c32f 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -31,10 +31,26 @@ struct perf_pmu perf_pmu__fake; +/** + * struct perf_pmu_format - Values from a format file read from + * /devices/cpu/format/ held in struct perf_pmu. + * + * For example, the contents of /devices/cpu/format/event may be + * "config:0-7" and will be represented here as name="event", + * value=PERF_PMU_FORMAT_VALUE_CONFIG and bits 0 to 7 will be set. + */ struct perf_pmu_format { + /** @name: The modifier/file name. */ char *name; + /** + * @value : Which config value the format relates to. Supported values + * are from PERF_PMU_FORMAT_VALUE_CONFIG to + * PERF_PMU_FORMAT_VALUE_CONFIG_END. + */ int value; + /** @bits: Which config bits are set by this format value. */ DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS); + /** @list: Element on list within struct perf_pmu. */ struct list_head list; }; diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 0d556d02ce52..ee02e1ef9187 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -33,30 +33,101 @@ struct perf_pmu_caps { struct list_head list; }; +/** + * struct perf_pmu - hi + */ struct perf_pmu { + /** @name: The name of the PMU such as "cpu". */ char *name; + /** + * @alias_name: Optional alternate name for the PMU determined in + * architecture specific code. + */ char *alias_name; + /** + * @id: Optional PMU identifier read from + * /bus/event_source/devices//identifier. + */ char *id; + /** + * @type: Perf event attributed type value, read from + * /bus/event_source/devices//type. + */ __u32 type; + /** + * @selectable: Can the PMU name be selected as if it were an event? + */ bool selectable; + /** + * @is_uncore: Is the PMU not within the CPU core? Determined by the + * presence of /bus/event_source/devices//cpumask. + */ bool is_uncore; + /** + * @auxtrace: Are events auxiliary events? Determined in architecture + * specific code. + */ bool auxtrace; + /** + * @max_precise: Number of levels of :ppp precision supported by the + * PMU, read from + * /bus/event_source/devices//caps/max_precise. + */ int max_precise; + /** + * @default_config: Optional default perf_event_attr determined in + * architecture specific code. + */ struct perf_event_attr *default_config; + /** + * @cpus: Empty or the contents of either of: + * /bus/event_source/devices//cpumask. + * /bus/event_source/devices//cpus. + */ struct perf_cpu_map *cpus; - struct list_head format; /* HEAD struct perf_pmu_format -> list */ - struct list_head aliases; /* HEAD struct perf_pmu_alias -> list */ + /** + * @format: Holds the contents of files read from + * /bus/event_source/devices//format/. The contents specify + * which event parameter changes what config, config1 or config2 bits. + */ + struct list_head format; + /** + * @aliases: List of struct perf_pmu_alias. Each alias corresponds to an + * event read from /bus/event_source/devices//events/ or + * from json events in pmu-events.c. + */ + struct list_head aliases; + /** @caps_initialized: Has the list caps been initialized? */ bool caps_initialized; + /** @nr_caps: The length of the list caps. */ u32 nr_caps; - struct list_head caps; /* HEAD struct perf_pmu_caps -> list */ - struct list_head list; /* ELEM */ + /** + * @caps: Holds the contents of files read from + * /bus/event_source/devices//caps/. + * + * The contents are pairs of the filename with the value of its + * contents, for example, max_precise (see above) may have a value of 3. + */ + struct list_head caps; + /** @list: Element on pmus list in pmu.c. */ + struct list_head list; + /** @hybrid_list: Element on perf_pmu__hybrid_pmus. */ struct list_head hybrid_list; + /** + * @missing_features: Features to inhibit when events on this PMU are + * opened. + */ struct { + /** + * @exclude_guest: Disables perf_event_attr exclude_guest and + * exclude_host. + */ bool exclude_guest; } missing_features; }; +/** @perf_pmu__fake: A special global PMU used for testing. */ extern struct perf_pmu perf_pmu__fake; struct perf_pmu_info { @@ -70,21 +141,60 @@ struct perf_pmu_info { #define UNIT_MAX_LEN 31 /* max length for event unit name */ +/** + * struct perf_pmu_alias - An event either read from sysfs or builtin in + * pmu-events.c, created by parsing the pmu-events json files. + */ struct perf_pmu_alias { + /** @name: Name of the event like "mem-loads". */ char *name; + /** @desc: Optional short description of the event. */ char *desc; + /** @long_desc: Optional long description. */ char *long_desc; + /** + * @topic: Optional topic such as cache or pipeline, particularly for + * json events. + */ char *topic; + /** + * @str: Comma separated parameter list like + * "event=0xcd,umask=0x1,ldlat=0x3". + */ char *str; - struct list_head terms; /* HEAD struct parse_events_term -> list */ - struct list_head list; /* ELEM */ + /** @terms: Owned list of the original parsed parameters. */ + struct list_head terms; + /** @list: List element of struct perf_pmu aliases. */ + struct list_head list; + /** @unit: Units for the event, such as bytes or cache lines. */ char unit[UNIT_MAX_LEN+1]; + /** @scale: Value to scale read counter values by. */ double scale; + /** + * @per_pkg: Does the file + * /bus/event_source/devices//events/.per-pkg or + * equivalent json value exist and have the value 1. + */ bool per_pkg; + /** + * @snapshot: Does the file + * /bus/event_source/devices//events/.snapshot + * exist and have the value 1. + */ bool snapshot; + /** + * @deprecated: Is the event hidden and so not shown in perf list by + * default. + */ bool deprecated; + /** + * @metric_expr: A metric expression associated with an event. Doing + * this makes little sense due to scale and unit applying to both. + */ char *metric_expr; + /** @metric_name: A name for the metric. unit applying to both. */ char *metric_name; + /** @pmu_name: The name copied from struct perf_pmu. */ char *pmu_name; }; From patchwork Mon Nov 14 21:07:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 20040 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp2368619wru; Mon, 14 Nov 2022 13:15:22 -0800 (PST) X-Google-Smtp-Source: AA0mqf5zqv574bRPNKTpy0S+ayuZFs2fP/TWMFpN0auii8BYMapG1IifMtPXVS4gb4wOcKX2ifE4 X-Received: by 2002:a17:906:4911:b0:7ad:9891:8756 with SMTP id b17-20020a170906491100b007ad98918756mr11908451ejq.203.1668460522581; Mon, 14 Nov 2022 13:15:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668460522; cv=none; d=google.com; s=arc-20160816; b=qq5GPyHf2IFr5ijQs9o15NyKZvwKa+7PEILSyY5lmanygJS4rjPhg3Uh86astzHSX8 Gs8hWMSngldjK/McmsKScldOrtwRJgSp8Prxq9ltWP1mlKWcUzquYELP2qYcMa2T2zBm FrQz212lz0bO1Lf51q+of8QP8l1/IbkdyoHm8Jpu4bqtObEDHxH4BHKm9pgHxiK4DFKc VgCQ1qbgiPMi44SbrVN4yCIHkjNiS9YtRpdvbJSH6lvBTR9shy4oxJ2WxiJ29Z7FEDsy +FJy3YvJLFEzLuApEU8lHZ+HH90Plrx8/vNnKVByrGUeZktJt16+gweWRzIBC4WRYWye N8DA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=Se2me6lbjg4dS4DNtZbL4NOOrQgzrO1DuLy7bKVPgtE=; b=ll48+f2fRioGeL8FJbLQl2Oe20xOO7BT6mMCiPdOhRpSMjkmgXuKuLut8CLooEmsXi 4ChvdFJfL3Xu1lwtnmaM5GZBIOFExwZwu0bvVPq9B6ZWWCpr/JJ46HmnvI+00ehBfZoy 6Gwgr7DMGcskwttcxe4mkKXHa0xyAhsbgVAWCE2z6oTDN+JtWdZKtMWUyZqdyvE7bQbF zkUSNS1TLua5JIbxZngh4OQdSzbGhqYOdaJ6BQt7LDPuOWyczpAY4BNq6yyqgVwMCAZ+ bpa3Qs8pA+yXQw7J7hg/aZlSLW2z0OL71t29YXAAiDik2Zs4PcDaOEug2DdW6M2G+OKB bPvQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=pSM7kTnm; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e17-20020a17090618f100b00780f0b45416si8043221ejf.622.2022.11.14.13.14.58; Mon, 14 Nov 2022 13:15:22 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=pSM7kTnm; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 S237466AbiKNVIc (ORCPT + 99 others); Mon, 14 Nov 2022 16:08:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44760 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237492AbiKNVIV (ORCPT ); Mon, 14 Nov 2022 16:08:21 -0500 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1E055BCBF for ; Mon, 14 Nov 2022 13:08:15 -0800 (PST) Received: by mail-pj1-x104a.google.com with SMTP id my9-20020a17090b4c8900b002130d29fd7cso10839437pjb.7 for ; Mon, 14 Nov 2022 13:08:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Se2me6lbjg4dS4DNtZbL4NOOrQgzrO1DuLy7bKVPgtE=; b=pSM7kTnmOSbosw8Hcy1wsfrOJtWX0Vk4M1VXbCfpBsnal65+1d2sh4Bhl/sPSG3WjZ oRq//RYKeswTfgFYSJ4Nv7F1CorCaBz6F1obJiSvGR021sk3+MiS3J0CKDoAThtT7mNL c5XvgVjLnyw/ULU0aatlPRu9cxq7LW4TyrQHf9201uJ5GhHD/OrtslM86NlZo0FNpgY0 JcPC2nd67BGMddaSuKOAOFjPZjksyqaw2aj3O89nIhPVu/bl9Ccf1tqlOp2uQFr7akdO lj4Eu321mO/ZVaguwrY9uNagHeDPUAhFSZNIxiC1unT6sMrpC8hTQ/YF+wfl+wWOmNCc RtMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Se2me6lbjg4dS4DNtZbL4NOOrQgzrO1DuLy7bKVPgtE=; b=E6FZ0JyQujwzh97ql+Hj9vlqe+3cvel5vp5d/CuibVlp0vm2ZGq4KNj3V00g48TjMO mq7F5Ogat1BYmSxS46AKo6dTfnekDxAfn/yE8A9I3Dv0764S+rO0+VsFCXvHMJtHALYY k08+z/nWWa2h20iTf1qCQz/7IjH6gE1h69LaOjgwoKOvitrkOHhN17HUYiV+ENbLf/g7 OhNJCvVee9W5kzC27+4N2g+MwtMSrz2Pck7He10D9J1/fHcU48qIsTMKRsoZNyHs4/5C 08YiFeW1k1RjmMuHGiVRHWwz8bQ9GvDIzHc3HfgWzzILxuwoA4dAsV8sFvzxy5bIlFqE Iaiw== X-Gm-Message-State: ANoB5pk+G4kTJ3DmFgtf9Lc3EpN5+TBxX8AcmBYmzozvGTXsSCe+T/rN uZVpEHDH9D5Wyo+jaf1fKcRTs3HdBs2R X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:553:438f:b86a:87f]) (user=irogers job=sendgmr) by 2002:aa7:8a41:0:b0:561:70b3:6a6 with SMTP id n1-20020aa78a41000000b0056170b306a6mr15444394pfa.25.1668460094565; Mon, 14 Nov 2022 13:08:14 -0800 (PST) Date: Mon, 14 Nov 2022 13:07:16 -0800 In-Reply-To: <20221114210723.2749751-1-irogers@google.com> Message-Id: <20221114210723.2749751-4-irogers@google.com> Mime-Version: 1.0 References: <20221114210723.2749751-1-irogers@google.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog Subject: [PATCH v3 03/10] tools lib api fs tracing_path: Add scandir alphasort From: Ian Rogers To: Weilin Wang , Perry Taylor , Caleb Biggers , Leo Yan , Adrian Hunter , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Sandipan Das , Kajol Jain , Zhengjun Xing , Kan Liang , Ravi Bangoria , Xin Gao , Rob Herring , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749507661334336082?= X-GMAIL-MSGID: =?utf-8?q?1749507661334336082?= tracing_events__opendir allows iteration over files in /tracing/events but with an arbitrary sort order. Add a scandir alternative where the results are alphabetically sorted. Signed-off-by: Ian Rogers --- tools/lib/api/fs/tracing_path.c | 16 ++++++++++++++++ tools/lib/api/fs/tracing_path.h | 1 + 2 files changed, 17 insertions(+) diff --git a/tools/lib/api/fs/tracing_path.c b/tools/lib/api/fs/tracing_path.c index 5afb11b30fca..b8e457c841ab 100644 --- a/tools/lib/api/fs/tracing_path.c +++ b/tools/lib/api/fs/tracing_path.c @@ -113,6 +113,22 @@ DIR *tracing_events__opendir(void) return dir; } +int tracing_events__scandir_alphasort(struct dirent ***namelist) +{ + char *path = get_tracing_file("events"); + int ret; + + if (!path) { + *namelist = NULL; + return 0; + } + + ret = scandir(path, namelist, NULL, alphasort); + put_events_file(path); + + return ret; +} + int tracing_path__strerror_open_tp(int err, char *buf, size_t size, const char *sys, const char *name) { diff --git a/tools/lib/api/fs/tracing_path.h b/tools/lib/api/fs/tracing_path.h index a19136b086dc..fc6347c11deb 100644 --- a/tools/lib/api/fs/tracing_path.h +++ b/tools/lib/api/fs/tracing_path.h @@ -6,6 +6,7 @@ #include DIR *tracing_events__opendir(void); +int tracing_events__scandir_alphasort(struct dirent ***namelist); void tracing_path_set(const char *mountpoint); const char *tracing_path_mount(void); From patchwork Mon Nov 14 21:07:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 20035 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp2367975wru; Mon, 14 Nov 2022 13:13:32 -0800 (PST) X-Google-Smtp-Source: AA0mqf4QtdTvaqDDea6yOWce+5VXxGcB61eOfVTBQp1n9gmS+w8rIpkN2CiR4Nq9RpDgiGGlHWTP X-Received: by 2002:a05:6402:1845:b0:461:b4a0:5913 with SMTP id v5-20020a056402184500b00461b4a05913mr12555553edy.323.1668460412308; Mon, 14 Nov 2022 13:13:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668460412; cv=none; d=google.com; s=arc-20160816; b=BJ41+d+HOPfjvKj3fAqfKF/3p81fEXyMwBTugu3VjsOp0EOSOdokOVnvVyMuGVThqH 7FHiQoVTjaJZh4W21Js4rWkqX/4UeuoedxNQFk37si7BPz3MP0RMkMuW+vp9u/gpsFLN RebqI6mitbBgupzw0/I/sfIEuqaXFWhPG6l9gJBxjPwHrjY0k0uLqoItUkNrqAs9woBn a5ruiJSizwRrPnrsnx7W03ibiI5V+lV/e0fGRcV4X1OEeq72KgVLqs2Xk1+ffJB0lAFp ApySNDTlzKLhlwys3SZFqui0JjhgZvvXqI+KAt1s2Rpr1o+K40+k2ycZmzPqxGotYO87 e/Ag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=FAjkIdGz/j9kJ1xDL5dYREJTueL8AT+RXQYxwRGY3ak=; b=GNBIu6/TotwkWRK3hSZXEsUk3FKE6quHnqRc//ftUmhtQdaGJlxGl2xe9cN2p9CWaB TJ/X/CedDU+R7WuW++o88YUX9ElgtOlv6gNXyskU6NeCvNO/u80gurEGFtyThx2czZPY Sx/4Rk2lItNrkc/L7+7HymjmxUka4xKCMml2Su6Knq3pXBB3WL8ufK/YOmucRxLhtr3x NUa46ayZi+8YJeRWYa495gsjTUp6qtcM56sOsvxAewcr2uvx5hacDeB0/B8gpH9kQSjG c3RnLWwTY9pXeZecJu3HpftG2W26tMl/PEwDb/HVvQfIIfo+lQOW4oYxpUkymVeUEzpe Vo7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=FQaZu3Cb; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id nb36-20020a1709071ca400b007a45e4f4ff2si11654436ejc.853.2022.11.14.13.13.08; Mon, 14 Nov 2022 13:13:32 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=FQaZu3Cb; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 S237395AbiKNVIj (ORCPT + 99 others); Mon, 14 Nov 2022 16:08:39 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44620 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237333AbiKNVI1 (ORCPT ); Mon, 14 Nov 2022 16:08:27 -0500 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 449D7B5D for ; Mon, 14 Nov 2022 13:08:24 -0800 (PST) Received: by mail-pg1-x54a.google.com with SMTP id i19-20020a63e913000000b004705d1506a6so6390324pgh.13 for ; Mon, 14 Nov 2022 13:08:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=FAjkIdGz/j9kJ1xDL5dYREJTueL8AT+RXQYxwRGY3ak=; b=FQaZu3Cbsd2gHnYi5Gx+2DWoUegFSW+qx8oogpEOsCl0/itsxpNpL6S4L435rIus3u q6b3Ob2ArneyTeF0HA+YgEFmbvuDtumr1ySUmpoIIs10e/TfKb/wxXOvpbDlrTyhbOhq XHOyWp/5FngUxk72sQjlstVXlwRWYDUyo3omNZgRnkD0XaUi4OGDXcIMbYfJjvKLlzGe ymzdCAvMa9dZG53WnXm49bUsYWPufMfzD355LyDc/gdh2TuDHlhuiUwmEjUjeeYOijs2 1HIlBxJy6UzLN9xOmiR/Hyk0xKXUFEsAbmRtdqoOUfJSCQkucg8x5AqsWJXJhRpCRS/q HPUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=FAjkIdGz/j9kJ1xDL5dYREJTueL8AT+RXQYxwRGY3ak=; b=WJ59a0rcHtY+LEuB0YdDCY6CjoNKQ3cPnZRyRK4Sjgj7iCNgusisvZOtXsQe8pwJlg IWB3uBigYm6TpCAU+jCIJ1NVJ4ytCxA5KDPOW1qGSeQH5sgK8j1AreI2FwjOv3gzyoN4 a6IXSEKCxEntvsrVYkYVcf+ZY0A39IK/5IyX8RzV4F6V7imVpamXcXDoyvFiJL3A7hzq K9Iin48My5n7zYBMlzIu0Y1AqeILXh076zLWrqoSv6hQ4j8UURCkgAawToygSETUNqD+ 63FVOXqgapAzBS0kZuerKSbPFA25s4oO+z/5+Yjy0GZ73zosrOWD86/knSoxQbxoNVaS V9DA== X-Gm-Message-State: ANoB5pm/0qZXlrojApMiw9f/PottB/WKzNQoYmIVCZwazqnbBfxmtSev JH9cyPEpRWG/R9Q2fkBhVbWSUpWy/yht X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:553:438f:b86a:87f]) (user=irogers job=sendgmr) by 2002:a17:90b:2415:b0:212:cf2e:2b0b with SMTP id nr21-20020a17090b241500b00212cf2e2b0bmr15213568pjb.169.1668460104133; Mon, 14 Nov 2022 13:08:24 -0800 (PST) Date: Mon, 14 Nov 2022 13:07:17 -0800 In-Reply-To: <20221114210723.2749751-1-irogers@google.com> Message-Id: <20221114210723.2749751-5-irogers@google.com> Mime-Version: 1.0 References: <20221114210723.2749751-1-irogers@google.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog Subject: [PATCH v3 04/10] perf tracepoint: Sort events in iterator From: Ian Rogers To: Weilin Wang , Perry Taylor , Caleb Biggers , Leo Yan , Adrian Hunter , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Sandipan Das , Kajol Jain , Zhengjun Xing , Kan Liang , Ravi Bangoria , Xin Gao , Rob Herring , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749507545044044802?= X-GMAIL-MSGID: =?utf-8?q?1749507545044044802?= In print_tracepoint_events use tracing_events__scandir_alphasort and scandir alphasort so that the subsystem and events are sorted and don't need a secondary qsort. Locally this results in the following change: ... ext4:ext4_zero_range [Tracepoint event] - fib6:fib6_table_lookup [Tracepoint event] fib:fib_table_lookup [Tracepoint event] + fib6:fib6_table_lookup [Tracepoint event] filelock:break_lease_block [Tracepoint event] ... ie fib6 now is after fib and not before it. This is more consistent with how numbers are more generally sorted, such as: ... syscalls:sys_enter_renameat [Tracepoint event] syscalls:sys_enter_renameat2 [Tracepoint event] ... and so an improvement over the qsort approach. Signed-off-by: Ian Rogers --- tools/perf/util/print-events.c | 108 +++++++++++---------------------- 1 file changed, 37 insertions(+), 71 deletions(-) diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index c4d5d87fae2f..fefc025bc259 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -66,26 +66,21 @@ static int cmp_string(const void *a, const void *b) void print_tracepoint_events(const char *subsys_glob, const char *event_glob, bool name_only) { - DIR *sys_dir, *evt_dir; - struct dirent *sys_dirent, *evt_dirent; - char evt_path[MAXPATHLEN]; - char *dir_path; - char **evt_list = NULL; - unsigned int evt_i = 0, evt_num = 0; - bool evt_num_known = false; - -restart: - sys_dir = tracing_events__opendir(); - if (!sys_dir) - return; - - if (evt_num_known) { - evt_list = zalloc(sizeof(char *) * evt_num); - if (!evt_list) - goto out_close_sys_dir; - } + struct dirent **sys_namelist = NULL; + bool printed = false; + int sys_items = tracing_events__scandir_alphasort(&sys_namelist); + + for (int i = 0; i < sys_items; i++) { + struct dirent *sys_dirent = sys_namelist[i]; + struct dirent **evt_namelist = NULL; + char *dir_path; + int evt_items; + + if (sys_dirent->d_type != DT_DIR || + !strcmp(sys_dirent->d_name, ".") || + !strcmp(sys_dirent->d_name, "..")) + continue; - for_each_subsystem(sys_dir, sys_dirent) { if (subsys_glob != NULL && !strglobmatch(sys_dirent->d_name, subsys_glob)) continue; @@ -93,69 +88,40 @@ void print_tracepoint_events(const char *subsys_glob, dir_path = get_events_file(sys_dirent->d_name); if (!dir_path) continue; - evt_dir = opendir(dir_path); - if (!evt_dir) - goto next; - for_each_event(dir_path, evt_dir, evt_dirent) { - if (event_glob != NULL && - !strglobmatch(evt_dirent->d_name, event_glob)) + evt_items = scandir(dir_path, &evt_namelist, NULL, alphasort); + for (int j = 0; j < evt_items; j++) { + struct dirent *evt_dirent = evt_namelist[j]; + char evt_path[MAXPATHLEN]; + + if (evt_dirent->d_type != DT_DIR || + !strcmp(evt_dirent->d_name, ".") || + !strcmp(evt_dirent->d_name, "..")) continue; - if (!evt_num_known) { - evt_num++; + if (tp_event_has_id(dir_path, evt_dirent) != 0) + continue; + + if (event_glob != NULL && + !strglobmatch(evt_dirent->d_name, event_glob)) continue; - } snprintf(evt_path, MAXPATHLEN, "%s:%s", sys_dirent->d_name, evt_dirent->d_name); - - evt_list[evt_i] = strdup(evt_path); - if (evt_list[evt_i] == NULL) { - put_events_file(dir_path); - goto out_close_evt_dir; + if (name_only) + printf("%s ", evt_path); + else { + printf(" %-50s [%s]\n", evt_path, + event_type_descriptors[PERF_TYPE_TRACEPOINT]); } - evt_i++; + printed = true; } - closedir(evt_dir); -next: - put_events_file(dir_path); + free(dir_path); + free(evt_namelist); } - closedir(sys_dir); - - if (!evt_num_known) { - evt_num_known = true; - goto restart; - } - qsort(evt_list, evt_num, sizeof(char *), cmp_string); - evt_i = 0; - while (evt_i < evt_num) { - if (name_only) { - printf("%s ", evt_list[evt_i++]); - continue; - } - printf(" %-50s [%s]\n", evt_list[evt_i++], - event_type_descriptors[PERF_TYPE_TRACEPOINT]); - } - if (evt_num && pager_in_use()) + free(sys_namelist); + if (printed && pager_in_use()) printf("\n"); - -out_free: - evt_num = evt_i; - for (evt_i = 0; evt_i < evt_num; evt_i++) - zfree(&evt_list[evt_i]); - zfree(&evt_list); - return; - -out_close_evt_dir: - closedir(evt_dir); -out_close_sys_dir: - closedir(sys_dir); - - printf("FATAL: not enough memory to print %s\n", - event_type_descriptors[PERF_TYPE_TRACEPOINT]); - if (evt_list) - goto out_free; } void print_sdt_events(const char *subsys_glob, const char *event_glob, From patchwork Mon Nov 14 21:07:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 20036 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp2368129wru; Mon, 14 Nov 2022 13:14:01 -0800 (PST) X-Google-Smtp-Source: AA0mqf6JJYZcNjDuqJqYzxxntsPsmJtknyNmOOhfhZx5qSiQ/qe0XYpAqoa7PkCCifRdZOT5QCJK X-Received: by 2002:a05:6402:4498:b0:461:b754:ac3c with SMTP id er24-20020a056402449800b00461b754ac3cmr12421903edb.241.1668460441254; Mon, 14 Nov 2022 13:14:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668460441; cv=none; d=google.com; s=arc-20160816; b=dkDNI04iS4lso8cr/Hd/Ex/DhhxKrY1VrbWCwInwit/+gYswV0RBYLP17505bK9xpy T6iKXTNS2Mj4zPGnmXjc1pqTtJK4MlNWonufkSFgJlDQ8WKIXcblQyBU5dPicy6JZJDT I3aNtru/6OlyS5yPNa8PGhDNnDM8rnpJhf2+AftPsur2Y7suHWI2nBrgzNTT/bATJok+ w8K4Tyz9cVVD7epPdoOLp87pMqIYIWrhhF89Ze1mk+lAa1cAcPvKrDr5uM335KQ6kHtZ 4S0N3zCwV3q7pQB6I9RzKLTegOC/RXmBDbgJEfZx6v7HqyQNFKeH9jqqdE4qhHo2F/zV Fr5g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=xTvigGR2TZpPyDR4wvE6cl7h65F616i4JiHpM7NGI4g=; b=Nk/RfMiTRePpHcrAfAgC0UNyFkxx96Kz3zkeZm7wiJPsruz96nc4GUtUp4TDnvqPQd sdGJ4K8ga6qo4eYWNyVdMQDAevwJ2BDc1rjKfkh5xAv3UXHZQIMVcXU+xfnk14Iut2WM s390XM9TrsnRF9Loudl/gSEBvrL0uHu3xXnXn74Ch2zsf7QU7ULaIilCvcsnDLyd4j+i 93xe774nnbumDyxVYIQcuwYtpPue1MEND6nzh3DsZSSVqpjodqKqepvyw384Yh4YkdCO ZG9IaI8kFQ3x5i48/8z3fUgWATqEXfIcmRsmMG4X0kzxIOh+islAEl5Wg/L1WJesUD/x Cb0A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=qh+bQXa8; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id nb36-20020a1709071ca400b007a45e4f4ff2si11653212ejc.853.2022.11.14.13.13.37; Mon, 14 Nov 2022 13:14:01 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=qh+bQXa8; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 S237618AbiKNVIw (ORCPT + 99 others); Mon, 14 Nov 2022 16:08:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44648 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237606AbiKNVIf (ORCPT ); Mon, 14 Nov 2022 16:08:35 -0500 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DD1C6B5D for ; Mon, 14 Nov 2022 13:08:33 -0800 (PST) Received: by mail-pj1-x1049.google.com with SMTP id pj8-20020a17090b4f4800b002140219b2b3so50324pjb.0 for ; Mon, 14 Nov 2022 13:08:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=xTvigGR2TZpPyDR4wvE6cl7h65F616i4JiHpM7NGI4g=; b=qh+bQXa8qXtlPKafIbt/qub27YV/6bwdGsur0mog3yFgqhnOu8lpu+FinXZBNRnkh8 GRYVjsVviqHBLQJJwqIK5e/d05fGmLi3qoC4eDX0QINmKP2TbRxN/xi9z+WgVa4hSuPh 2oefMp99D68M0gjQB58HPclQ3d5RjmtPh66ZPEzzu5fyyMUIq+fIS9rNVBebAz4bc514 dqaSAVg6Yz3rc6Xku+nHmKDCCXboQIck5vwSPw35NGGOhHqjLbsdGiIGY+mo5dIP4alF Ug8q0wkajQ4pQsQmCWaDYHDmVW7lgpFJLpc1Da12UF79YVnYy+YCIknYU5uVlDifNew+ fBNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=xTvigGR2TZpPyDR4wvE6cl7h65F616i4JiHpM7NGI4g=; b=ZTlLdNQl3roLE/QbyxR193gtnscZxvv6Wd/3KT0G0txF3N0JvdM4BiUnSR+WYsBQUn n2EgA9ftSOK8uXfH//fmXngJp37kO9beMl/dZukic0zJwzXqJaELUeT5GNIKl/b9k8qU fDf1hCdE/NhS13R3ipkVeGz4N+vF2NZSidFGJapbqN4jYGVieSLskD/wBgnDbRysbotS gfJWekIPSoh6iUSzDWTYaZm+NMyWSkuBbmDoG9jSd6D/K5EjHHrWqJW0DzL0cScC2nms IJCAKk+0uGWGvkiIE5nkL8MhlbgaZKfE/kxbxK9RRrAzQ+z2yEPN3Aafhmt4eKlDKIXr J7dQ== X-Gm-Message-State: ANoB5pnbr1a+usgu2PHJkHaqkHi5Xpl/vnjQq/rAjs2BJkPvhSwQ0ijG R2n9oF1+0Kc3140hBShLW3Z4JtbxZ8oB X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:553:438f:b86a:87f]) (user=irogers job=sendgmr) by 2002:aa7:86d5:0:b0:56d:3de3:c401 with SMTP id h21-20020aa786d5000000b0056d3de3c401mr15620037pfo.6.1668460113210; Mon, 14 Nov 2022 13:08:33 -0800 (PST) Date: Mon, 14 Nov 2022 13:07:18 -0800 In-Reply-To: <20221114210723.2749751-1-irogers@google.com> Message-Id: <20221114210723.2749751-6-irogers@google.com> Mime-Version: 1.0 References: <20221114210723.2749751-1-irogers@google.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog Subject: [PATCH v3 05/10] perf list: Generalize limiting to a PMU name From: Ian Rogers To: Weilin Wang , Perry Taylor , Caleb Biggers , Leo Yan , Adrian Hunter , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Sandipan Das , Kajol Jain , Zhengjun Xing , Kan Liang , Ravi Bangoria , Xin Gao , Rob Herring , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749507575645289266?= X-GMAIL-MSGID: =?utf-8?q?1749507575645289266?= Deprecate the --cputype option and add a --unit option where '--unit cpu_atom' behaves like '--cputype atom'. The --unit option can be used with arbitrary PMUs, for example: ``` $ perf list --unit msr pmu List of pre-defined events (to be used in -e or -M): msr/aperf/ [Kernel PMU event] msr/cpu_thermal_margin/ [Kernel PMU event] msr/mperf/ [Kernel PMU event] msr/pperf/ [Kernel PMU event] msr/smi/ [Kernel PMU event] msr/tsc/ [Kernel PMU event] ``` Signed-off-by: Ian Rogers --- tools/perf/Documentation/perf-list.txt | 6 +++--- tools/perf/builtin-list.c | 18 ++++++++++++------ tools/perf/util/metricgroup.c | 3 ++- tools/perf/util/pmu.c | 4 +--- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt index 57384a97c04f..44a819af573d 100644 --- a/tools/perf/Documentation/perf-list.txt +++ b/tools/perf/Documentation/perf-list.txt @@ -39,9 +39,9 @@ any extra expressions computed by perf stat. --deprecated:: Print deprecated events. By default the deprecated events are hidden. ---cputype:: -Print events applying cpu with this type for hybrid platform -(e.g. --cputype core or --cputype atom) +--unit:: +Print PMU events and metrics limited to the specific PMU name. +(e.g. --unit cpu, --unit msr, --unit cpu_core, --unit cpu_atom) [[EVENT_MODIFIERS]] EVENT MODIFIERS diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 58e1ec1654ef..cc84ced6da26 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -21,7 +21,6 @@ static bool desc_flag = true; static bool details_flag; -static const char *hybrid_type; int cmd_list(int argc, const char **argv) { @@ -30,6 +29,8 @@ int cmd_list(int argc, const char **argv) bool long_desc_flag = false; bool deprecated = false; char *pmu_name = NULL; + const char *hybrid_name = NULL; + const char *unit_name = NULL; struct option list_options[] = { OPT_BOOLEAN(0, "raw-dump", &raw_dump, "Dump raw events"), OPT_BOOLEAN('d', "desc", &desc_flag, @@ -40,9 +41,10 @@ int cmd_list(int argc, const char **argv) "Print information on the perf event names and expressions used internally by events."), OPT_BOOLEAN(0, "deprecated", &deprecated, "Print deprecated events."), - OPT_STRING(0, "cputype", &hybrid_type, "hybrid cpu type", - "Print events applying cpu with this type for hybrid platform " - "(e.g. core or atom)"), + OPT_STRING(0, "cputype", &hybrid_name, "hybrid cpu type", + "Limit PMU or metric printing to the given hybrid PMU (e.g. core or atom)."), + OPT_STRING(0, "unit", &unit_name, "PMU name", + "Limit PMU or metric printing to the specified PMU."), OPT_INCR(0, "debug", &verbose, "Enable debugging output"), OPT_END() @@ -53,6 +55,8 @@ int cmd_list(int argc, const char **argv) }; set_option_flag(list_options, 0, "raw-dump", PARSE_OPT_HIDDEN); + /* Hide hybrid flag for the more generic 'unit' flag. */ + set_option_flag(list_options, 0, "cputype", PARSE_OPT_HIDDEN); argc = parse_options(argc, argv, list_options, list_usage, PARSE_OPT_STOP_AT_NON_OPTION); @@ -62,8 +66,10 @@ int cmd_list(int argc, const char **argv) if (!raw_dump && pager_in_use()) printf("\nList of pre-defined events (to be used in -e or -M):\n\n"); - if (hybrid_type) { - pmu_name = perf_pmu__hybrid_type_to_pmu(hybrid_type); + if (unit_name) + pmu_name = strdup(unit_name); + else if (hybrid_name) { + pmu_name = perf_pmu__hybrid_type_to_pmu(hybrid_name); if (!pmu_name) pr_warning("WARNING: hybrid cputype is not supported!\n"); } diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 4c98ac29ee13..1943fed9b6d9 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -556,11 +556,12 @@ static int metricgroup__print_callback(const struct pmu_event *pe, void *vdata) { struct metricgroup_print_data *data = vdata; + const char *pmu = pe->pmu ?: "cpu"; if (!pe->metric_expr) return 0; - if (data->pmu_name && perf_pmu__is_hybrid(pe->pmu) && strcmp(data->pmu_name, pe->pmu)) + if (data->pmu_name && strcmp(data->pmu_name, pmu)) return 0; return metricgroup__print_pmu_event(pe, data->metricgroups, data->filter, diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 057e1528c32f..e6790175307b 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1695,10 +1695,8 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, pmu = NULL; j = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) { - if (pmu_name && perf_pmu__is_hybrid(pmu->name) && - strcmp(pmu_name, pmu->name)) { + if (pmu_name && pmu->name && strcmp(pmu_name, pmu->name)) continue; - } list_for_each_entry(alias, &pmu->aliases, list) { char *name = alias->desc ? alias->name : From patchwork Mon Nov 14 21:07:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 20037 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp2368175wru; Mon, 14 Nov 2022 13:14:12 -0800 (PST) X-Google-Smtp-Source: AA0mqf7j8rGcmy7qSxjXGE00Tj1nwqKRW+E1Mv/C2erbMODxXVAa+rUZce2ngpgbNuRUf2MhA94P X-Received: by 2002:a17:906:e0d4:b0:7ad:d1ab:2431 with SMTP id gl20-20020a170906e0d400b007add1ab2431mr10970007ejb.213.1668460452345; Mon, 14 Nov 2022 13:14:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668460452; cv=none; d=google.com; s=arc-20160816; b=UgjBnjGoe3g+x9+cConZLeFT3ytR4/hvhbXRBfPDohcM4iArwmBZzigSz43XGmDxk3 z6s72aN2Tu488LJbj5ReI6n8D0VbcO9qjqFNWzG3/ktiw+5LDHeX1fLMyIKOOTY7Jhof r5R8ItgSYE7T9HH9QoO8kBCftaVKfoDtlSdBmcg2Ar4crnXncszvOvheGlgOi78lGF3N pFdyw4lVf6iX2JKE/Bk3YqHSobMcdtuX94GQt6vbB05zKqStJyrwojRfFLBtPEFXzuIq 4075kIL/meeIIcv+/z+XZUPBNpYdR4mpJAB0BgKroy88HkNXLfGpMD4PS6ieHpeuygbX U0UA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=05I6atWVl+qVT8yMUMb7x3GwtdO61HeIYnH9Cn+25jQ=; b=JENJR4ed957Vd5ma8eCF2X9lD6BfhYs9nKyPZyLU1vUUptvCoT0WQOU/d/5+XkPyMT lujg/2GjhUdilPxZRBtoSXHw6xE0/PW6W604qs6/KICS5p1b3afCBgWLAqVRPLCSgK3q 0EMY10yh/QF3ieYMNzZZhEvO8dImMdtoo4A/LFb/npEPd9gGI8n0wUorLDuOj+VhTGdo opFBgKphsXMw0q7d8RGdBANzjblxn1wSKUO2k/8W1ZBqBwCmK6mMhA4ZCYKv1VM+gmhf wcbQiY6ob2Xx6HIvRpWBX77yMT2cKnnp3GghERCxDycSccRhS6vg6BkCrRNC7XQP50+M N6Ww== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=YnLoANQu; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id hz3-20020a1709072ce300b007824b85978asi9661757ejc.81.2022.11.14.13.13.48; Mon, 14 Nov 2022 13:14:12 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=YnLoANQu; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 S237592AbiKNVJC (ORCPT + 99 others); Mon, 14 Nov 2022 16:09:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45050 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237661AbiKNVIr (ORCPT ); Mon, 14 Nov 2022 16:08:47 -0500 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F0ED71570E for ; Mon, 14 Nov 2022 13:08:43 -0800 (PST) Received: by mail-pg1-x54a.google.com with SMTP id x23-20020a634857000000b0043c700f6441so6399223pgk.21 for ; Mon, 14 Nov 2022 13:08:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=05I6atWVl+qVT8yMUMb7x3GwtdO61HeIYnH9Cn+25jQ=; b=YnLoANQuFjbetHt540UCbpDWKoJh/exzhEQ66FkM0DNj43cS9FdHbXR77YM17jew7x cHvBVFfd+dNUoPSAda91AwQEle/wJoTXMWWSZvQLZpo0WJW7L6mbFQTUaFiZk8Dbot0X ca/91q3+zmW0juc/Ptg3A2A/zfY3FAu6hG26oCaPRIUJ1+ROCn3MLhVGjJyvZrK0e2Pq 7uGzqvVeoni2IXJxk2C4+mqpYpU7FH0vRRkcW01pLZ4l8itOTntfwtgunfq5UUJ68aBq u74OZ02gIHZw/xIg5mxa82EKl9QveFHNCgZA+AJaCTw/1zA4nueSyfnrheYNWnIk5IHL dPhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=05I6atWVl+qVT8yMUMb7x3GwtdO61HeIYnH9Cn+25jQ=; b=ILFXRjqDZl0CYojT3sXnvqawrWVFm6SDuUxE7S3Dq4UuWU/7csaD0r/YZpaSokXTa7 7XZr9WP8sEngVCooik5TedZ/Eqsz2d4A+QVEhTUmYBVcF/BF1JMmoMJktaxTr3KKgdsa CHplDJSZbKPnc4LcmJ7UGJ7V0iT7d83FXI3V52LAP4+O2pohtZuV4SGp5oS9XpvQqQ6e BRNboVhQ+CJN0i7KQIdOiOrTo4pB1WwtBpMnTCnciUUchmh/7vg1srYjHMGZEw8+YRaS MdVrOAdJK+ZygjaEvfY2upaqBH11PKNDrgOvDs60zj05f9/dKFL0uHxPElpWDLK1QE01 jfBg== X-Gm-Message-State: ANoB5pk5ORSUIqS/vusAvo9oFvt+lP3g6QeNCvI3Dq5dhYzE1X/NYq2D R0MsYsiNzOFHR/jmznkdxo8S72RGfcKG X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:553:438f:b86a:87f]) (user=irogers job=sendgmr) by 2002:a05:6a00:4211:b0:56b:6936:ddfb with SMTP id cd17-20020a056a00421100b0056b6936ddfbmr15534031pfb.15.1668460123402; Mon, 14 Nov 2022 13:08:43 -0800 (PST) Date: Mon, 14 Nov 2022 13:07:19 -0800 In-Reply-To: <20221114210723.2749751-1-irogers@google.com> Message-Id: <20221114210723.2749751-7-irogers@google.com> Mime-Version: 1.0 References: <20221114210723.2749751-1-irogers@google.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog Subject: [PATCH v3 06/10] perf list: Simplify cache event printing From: Ian Rogers To: Weilin Wang , Perry Taylor , Caleb Biggers , Leo Yan , Adrian Hunter , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Sandipan Das , Kajol Jain , Zhengjun Xing , Kan Liang , Ravi Bangoria , Xin Gao , Rob Herring , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749507586875897691?= X-GMAIL-MSGID: =?utf-8?q?1749507586875897691?= The current code computes an array of cache names then sorts and prints them. Use a strlist to create a list of names that is sorted. Keep the hybrid names, it is unclear how to generalize it, but drop the computation of evt_pmus that is never used. Signed-off-by: Ian Rogers --- tools/perf/util/print-events.c | 132 +++++++-------------------------- 1 file changed, 27 insertions(+), 105 deletions(-) diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index fefc025bc259..ff7793944246 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -206,137 +206,59 @@ void print_sdt_events(const char *subsys_glob, const char *event_glob, int print_hwcache_events(const char *event_glob, bool name_only) { - unsigned int type, op, i, evt_i = 0, evt_num = 0, npmus = 0; - char name[64], new_name[128]; - char **evt_list = NULL, **evt_pmus = NULL; - bool evt_num_known = false; - struct perf_pmu *pmu = NULL; - - if (perf_pmu__has_hybrid()) { - npmus = perf_pmu__hybrid_pmu_num(); - evt_pmus = zalloc(sizeof(char *) * npmus); - if (!evt_pmus) - goto out_enomem; - } + struct strlist *evt_name_list = strlist__new(NULL, NULL); + struct str_node *nd; -restart: - if (evt_num_known) { - evt_list = zalloc(sizeof(char *) * evt_num); - if (!evt_list) - goto out_enomem; + if (!evt_name_list) { + pr_debug("Failed to allocate new strlist for hwcache events\n"); + return -ENOMEM; } - - for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { - for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { + for (int type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { + for (int op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { /* skip invalid cache type */ if (!evsel__is_cache_op_valid(type, op)) continue; - for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { - unsigned int hybrid_supported = 0, j; - bool supported; + for (int i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { + struct perf_pmu *pmu = NULL; + char name[64]; __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name)); if (event_glob != NULL && !strglobmatch(name, event_glob)) continue; if (!perf_pmu__has_hybrid()) { - if (!is_event_supported(PERF_TYPE_HW_CACHE, - type | (op << 8) | (i << 16))) { - continue; - } - } else { - perf_pmu__for_each_hybrid_pmu(pmu) { - if (!evt_num_known) { - evt_num++; - continue; - } - - supported = is_event_supported( - PERF_TYPE_HW_CACHE, - type | (op << 8) | (i << 16) | - ((__u64)pmu->type << PERF_PMU_TYPE_SHIFT)); - if (supported) { - snprintf(new_name, sizeof(new_name), - "%s/%s/", pmu->name, name); - evt_pmus[hybrid_supported] = - strdup(new_name); - hybrid_supported++; - } - } - - if (hybrid_supported == 0) - continue; - } - - if (!evt_num_known) { - evt_num++; + if (is_event_supported(PERF_TYPE_HW_CACHE, + type | (op << 8) | (i << 16))) + strlist__add(evt_name_list, name); continue; } - - if ((hybrid_supported == 0) || - (hybrid_supported == npmus)) { - evt_list[evt_i] = strdup(name); - if (npmus > 0) { - for (j = 0; j < npmus; j++) - zfree(&evt_pmus[j]); - } - } else { - for (j = 0; j < hybrid_supported; j++) { - evt_list[evt_i++] = evt_pmus[j]; - evt_pmus[j] = NULL; + perf_pmu__for_each_hybrid_pmu(pmu) { + if (is_event_supported(PERF_TYPE_HW_CACHE, + type | (op << 8) | (i << 16) | + ((__u64)pmu->type << PERF_PMU_TYPE_SHIFT))) { + char new_name[128]; + snprintf(new_name, sizeof(new_name), + "%s/%s/", pmu->name, name); + strlist__add(evt_name_list, new_name); } - continue; } - - if (evt_list[evt_i] == NULL) - goto out_enomem; - evt_i++; } } } - if (!evt_num_known) { - evt_num_known = true; - goto restart; - } - - for (evt_i = 0; evt_i < evt_num; evt_i++) { - if (!evt_list[evt_i]) - break; - } - - evt_num = evt_i; - qsort(evt_list, evt_num, sizeof(char *), cmp_string); - evt_i = 0; - while (evt_i < evt_num) { + strlist__for_each_entry(nd, evt_name_list) { if (name_only) { - printf("%s ", evt_list[evt_i++]); + printf("%s ", nd->s); continue; } - printf(" %-50s [%s]\n", evt_list[evt_i++], - event_type_descriptors[PERF_TYPE_HW_CACHE]); + printf(" %-50s [%s]\n", nd->s, event_type_descriptors[PERF_TYPE_HW_CACHE]); } - if (evt_num && pager_in_use()) + if (!strlist__empty(evt_name_list) && pager_in_use()) printf("\n"); -out_free: - evt_num = evt_i; - for (evt_i = 0; evt_i < evt_num; evt_i++) - zfree(&evt_list[evt_i]); - zfree(&evt_list); - - for (evt_i = 0; evt_i < npmus; evt_i++) - zfree(&evt_pmus[evt_i]); - zfree(&evt_pmus); - return evt_num; - -out_enomem: - printf("FATAL: not enough memory to print %s\n", - event_type_descriptors[PERF_TYPE_HW_CACHE]); - if (evt_list) - goto out_free; - return evt_num; + strlist__delete(evt_name_list); + return 0; } static void print_tool_event(const struct event_symbol *syms, const char *event_glob, From patchwork Mon Nov 14 21:07:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 20042 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp2369363wru; Mon, 14 Nov 2022 13:17:26 -0800 (PST) X-Google-Smtp-Source: AA0mqf7VTDf+Hl35LGfSMSHcbKFHczZQomf4vbGROSZsFp6fH2OYAsfitPbvqPgdp+OWZV+ObaC3 X-Received: by 2002:a05:6402:1ada:b0:461:beb2:76e with SMTP id ba26-20020a0564021ada00b00461beb2076emr12611539edb.5.1668460646347; Mon, 14 Nov 2022 13:17:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668460646; cv=none; d=google.com; s=arc-20160816; b=btmUI1b5e0lJHhuWtz+lNmgLiudbZuNnktY75Mw5vN48UyfidCkhtBBlzMJCDQVwla CcnElUDmKKgpd/jhlgvLUtuix1E+TgiItnOkzqA+bGK1mHfKPVkK9GS59R2QduAWTpLT EXwNpzdzuJSj61CCuoF2xev7U6FFqI6LdK8r3Af6qfJpQ/h8UUdrTXfFlSgIm5xrSU7I EmGWuph53Duzapm6nVzsSQbDHHBSVAS6G86eigkFFGMPi+vrMhpu8Z7dyuSdKMLffrdO W4SyRse013OD8ta7Vmca5alntViowXbr5ZxYcSjYZlrzF8FNMoaD1CGpAqmugvbSKnh1 ndzA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=HIf5Y9gptGCDfzfHbnNjnA19mp6qRpBDngBttcXhem0=; b=MrsjPPCqSlHzoLwxjy+MEyurHcHS7wBPRv6OfgBDmjOUr4KUu3KAUA6ULGQeVnm03Z 3N5uNO8JXXVJl4UiC4DrlSE/5Pv+kgAxYUTalrBKH9xzBpdKoiOcb+KMjpQr2nbE02eG afvttU+bZ21Slu4nWTqrxthK9w8bJLqGWOy2QyjV3AUj3FsEXzP3w97J5Io7QlH2Ybkg gVFXn+FDz1xvNq0bvAPWDxG4XiE0i/jZQp535lY7pRVzEqrnkdIGNZepAWRS86I0Iz9K z2DEDxNeBJTvKz3c5rlKKVcHitL4H2VfRmd4daJk8bi8KTvwS7YWwNcrAEV3hBoSNlcy p2LA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=GZZvStXH; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id s8-20020a056402014800b004593895fb89si8823295edu.390.2022.11.14.13.17.02; Mon, 14 Nov 2022 13:17:26 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=GZZvStXH; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 S237333AbiKNVJW (ORCPT + 99 others); Mon, 14 Nov 2022 16:09:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45708 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237712AbiKNVIz (ORCPT ); Mon, 14 Nov 2022 16:08:55 -0500 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EC2236556 for ; Mon, 14 Nov 2022 13:08:52 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id b17-20020a25b851000000b006e32b877068so1820852ybm.16 for ; Mon, 14 Nov 2022 13:08:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=HIf5Y9gptGCDfzfHbnNjnA19mp6qRpBDngBttcXhem0=; b=GZZvStXHmV1H/jsQ47y9n//yaqltl/vwRLrf6lcIZ4n2MbmDx8/ILodhf/TEK75Z8h vXUnxC0uMPqpB2vpMCDlnHSYpQa3dRDuEOq5vKovpKq+6HygbUCE6CxFPDJH2gM7E1Qi FLLrolhCv9gq604BrlQkqDDkLA0ofnmSvLMWXDxOFhh1tp3dzVRpVhvk+6L+WKvrsVor lZZe4gUEvOzHpoof7kQuiiR3Iu6mUFZeHXN9XKZ/SHkRgkMgQxrKpvFCK5p45B5IA+sK mZuaxZ2n64tLPPGQlcOe5C8WIbk7k11MRMslThYNuZJYNMKQH3QxYYmA0Xhgz2/jqeDP fDLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=HIf5Y9gptGCDfzfHbnNjnA19mp6qRpBDngBttcXhem0=; b=WCfiHuyAtsPUTrVStbc+Yz+7cK/RGJfsgJXkMbpYv4H4aVzu+7frNHrdjx4Xp1Papn fZNyT4p8pY6QzW8hJgfIGyGzm/sbvABP1WFEUngd+Ujof2LrfaiKmHDaZgLTAK41xD2v EcyG5TJ71ZhOgknlbhlVflNyvMzmIlMpI0jMDZrNoKAXWUFVLIXJoD8xCHmA4Q5AsJck yxibkQ3CFgsI+VcQrtWLYNkq2ZUm5DCL0czVKa/jJ3R+fHjNw3R9gfiZqMENr4+8tPG0 JVxm4luREzMM+VbUxeR8jK+AZe9hgn0EQxh2EH/Ovo1Gu4l4nccL9UF7jox2VvxUke8b PrrA== X-Gm-Message-State: ANoB5pmxIfWZ7tDaIPkE0xWT5vrKLxYoF8tiNai591flU/tn1vJ7m1JB lNveU19gU+FILTX+T1f6zMAWzRhgBWUc X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:553:438f:b86a:87f]) (user=irogers job=sendgmr) by 2002:a0d:d596:0:b0:36a:bc93:587c with SMTP id x144-20020a0dd596000000b0036abc93587cmr15112789ywd.59.1668460132140; Mon, 14 Nov 2022 13:08:52 -0800 (PST) Date: Mon, 14 Nov 2022 13:07:20 -0800 In-Reply-To: <20221114210723.2749751-1-irogers@google.com> Message-Id: <20221114210723.2749751-8-irogers@google.com> Mime-Version: 1.0 References: <20221114210723.2749751-1-irogers@google.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog Subject: [PATCH v3 07/10] perf list: Simplify symbol event printing From: Ian Rogers To: Weilin Wang , Perry Taylor , Caleb Biggers , Leo Yan , Adrian Hunter , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Sandipan Das , Kajol Jain , Zhengjun Xing , Kan Liang , Ravi Bangoria , Xin Gao , Rob Herring , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749507790707619540?= X-GMAIL-MSGID: =?utf-8?q?1749507790707619540?= The current code computes an array of symbol names then sorts and prints them. Use a strlist to create a list of names that is sorted and then print it. Signed-off-by: Ian Rogers --- tools/perf/util/print-events.c | 79 +++++++++------------------------- 1 file changed, 21 insertions(+), 58 deletions(-) diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index ff7793944246..d53dba033597 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -52,14 +52,6 @@ static const struct event_symbol event_symbols_tool[PERF_TOOL_MAX] = { }, }; -static int cmp_string(const void *a, const void *b) -{ - const char * const *as = a; - const char * const *bs = b; - - return strcmp(*as, *bs); -} - /* * Print the events from /tracing/events */ @@ -298,77 +290,48 @@ void print_symbol_events(const char *event_glob, unsigned int type, struct event_symbol *syms, unsigned int max, bool name_only) { - unsigned int i, evt_i = 0, evt_num = 0; - char name[MAX_NAME_LEN]; - char **evt_list = NULL; - bool evt_num_known = false; - -restart: - if (evt_num_known) { - evt_list = zalloc(sizeof(char *) * evt_num); - if (!evt_list) - goto out_enomem; - syms -= max; - } + struct strlist *evt_name_list = strlist__new(NULL, NULL); + struct str_node *nd; - for (i = 0; i < max; i++, syms++) { + if (!evt_name_list) { + pr_debug("Failed to allocate new strlist for symbol events\n"); + return; + } + for (unsigned int i = 0; i < max; i++) { /* * New attr.config still not supported here, the latest * example was PERF_COUNT_SW_CGROUP_SWITCHES */ - if (syms->symbol == NULL) + if (syms[i].symbol == NULL) continue; - if (event_glob != NULL && !(strglobmatch(syms->symbol, event_glob) || - (syms->alias && strglobmatch(syms->alias, event_glob)))) + if (event_glob != NULL && !(strglobmatch(syms[i].symbol, event_glob) || + (syms[i].alias && strglobmatch(syms[i].alias, event_glob)))) continue; if (!is_event_supported(type, i)) continue; - if (!evt_num_known) { - evt_num++; - continue; - } - - if (!name_only && strlen(syms->alias)) - snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); - else - strlcpy(name, syms->symbol, MAX_NAME_LEN); + if (strlen(syms[i].alias)) { + char name[MAX_NAME_LEN]; - evt_list[evt_i] = strdup(name); - if (evt_list[evt_i] == NULL) - goto out_enomem; - evt_i++; + snprintf(name, MAX_NAME_LEN, "%s OR %s", syms[i].symbol, syms[i].alias); + strlist__add(evt_name_list, name); + } else + strlist__add(evt_name_list, syms[i].symbol); } - if (!evt_num_known) { - evt_num_known = true; - goto restart; - } - qsort(evt_list, evt_num, sizeof(char *), cmp_string); - evt_i = 0; - while (evt_i < evt_num) { + strlist__for_each_entry(nd, evt_name_list) { if (name_only) { - printf("%s ", evt_list[evt_i++]); + printf("%s ", nd->s); continue; } - printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]); + printf(" %-50s [%s]\n", nd->s, event_type_descriptors[type]); } - if (evt_num && pager_in_use()) + if (!strlist__empty(evt_name_list) && pager_in_use()) printf("\n"); -out_free: - evt_num = evt_i; - for (evt_i = 0; evt_i < evt_num; evt_i++) - zfree(&evt_list[evt_i]); - zfree(&evt_list); - return; - -out_enomem: - printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]); - if (evt_list) - goto out_free; + strlist__delete(evt_name_list); } /* From patchwork Mon Nov 14 21:07:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 20038 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp2368414wru; Mon, 14 Nov 2022 13:14:56 -0800 (PST) X-Google-Smtp-Source: AA0mqf5us35vD4DmEgda/BM/TY1/LNknAnIQRko3ZSA9eukSH80c7nel14G6VkxtwUVzCJ1l04vX X-Received: by 2002:a05:6402:12c8:b0:457:f052:6009 with SMTP id k8-20020a05640212c800b00457f0526009mr12594702edx.388.1668460496758; Mon, 14 Nov 2022 13:14:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668460496; cv=none; d=google.com; s=arc-20160816; b=tXVI4uyNEzi4Ktp7zj477q00FPqYx99lnIp6KJ6kYB4IjpcuRbH2GhO2ri9jx1VqBM bWc907/YbDrHhL+RmBs4aMXRfP5DBJ6McQWRM8hD7myPw3nT+inhacpSkHv8Ko/s8tUZ wfJjF7NS0RCEUm6ZVt/irVRMJ8cRAbyypDelMbXxOqNfLDk3Che81vh/MDhEdDrw09pT DJVl47bxHlNE4U2STUJoKtY3fQcYniU3OHTJtGMKJfCEc4J60Pciw3lYQJNIWV96hv4j Z+qOW6Bti3434vEIYurnrnOKxFrwE/mGGrTH86QWPr6Oma/FIZ8bKlg3F5zeRjrgPEkN bjsA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=Ti+JlRPlvf29szNKHd8D87Ic6A2ZX1BqgklOcnqMgNY=; b=MUSsWbmwpsfaX+wbosgR6XIvRS5mLrjtWWQjyycSlDrJkgCOTN2I30ZUnNYNQ9Ebha HrZvUKT/40EzipAytDtum45X+AbbtEJWy0vuqt7d42ttJXbf6BzD6B0/YjVhf3ruGEsr y7CZMrkIWJCeQ5CScB8LDYL9ZEKu8eTnsaYFYFDEU6Zj1nxhtV0f7q3InWRzPR1ZWAoo A8zscE/Qv6HiKvoJhG+DPP86YZEhRcpa5/WgRI0XsVm815QN6KCDKHqoM00BVSgaZs0E ixAXeujUqViTWpOvOMMtQGBJT3ezr+2KIrBaAsRdp9yR4wmrjJ+YaqjIRHeNULyuvbP2 nggg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=blPMmboz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id hd42-20020a17090796aa00b007ae5fa9b603si11520370ejc.374.2022.11.14.13.14.32; Mon, 14 Nov 2022 13:14:56 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=blPMmboz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 S237543AbiKNVJZ (ORCPT + 99 others); Mon, 14 Nov 2022 16:09:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45354 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237545AbiKNVJC (ORCPT ); Mon, 14 Nov 2022 16:09:02 -0500 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 21E0BD53 for ; Mon, 14 Nov 2022 13:09:01 -0800 (PST) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-36810cfa61fso115082497b3.6 for ; Mon, 14 Nov 2022 13:09:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Ti+JlRPlvf29szNKHd8D87Ic6A2ZX1BqgklOcnqMgNY=; b=blPMmbozMTkHt9hp+lIjTvLkVtmuKQN72BdaX1ZrrC4/mqEMliU4ct4X4K0d2HE6Wb RZ8KZo+3fKrtkWvRvBmKO7BKz6UvRefkUq4Ug06Za2uyaavxbPbL3zItrcRTugkT5RrA VIiISazbCGrzbB+tK4hGwH3p5VnH9qu6C5lM4EZBboTmB/ppKHRNg4dprTe2pUx54akA BOWSMWMYM3HGlF4BE7wrOAz+ELlzzj0xXOpgJszbkdTwk7I78JGRZE3VoeLPk8/u4+YZ 206IgQip3UhQVm7TCrVlnJsURVzINvFdsxb2V8WuvMT/I4hCezRUF80KDcjhFEB9Xonn qiDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Ti+JlRPlvf29szNKHd8D87Ic6A2ZX1BqgklOcnqMgNY=; b=FS6zkAqw6Yr6MMSOI1vEjq/FOliiIfwA+PK1lDnCFlNV8iBf0vhJMtrXxE3JKgXJqj a6dhuiCzPa/ufqiq82jYpOHAqLCYq4S5DvSlNkN2vqYT1FdGwOhet+I2sWvLJeM8JXe7 HGgOELyuQEoPp3F6UMJ3j04/JOxVaUAqk6PIyUvL9Yur1N3hEGUFewSRflDRsuvLjeQG gVgfwtxK5km2FxeBpgHvexmdumdtpzNpjSiuJ5wwWjmoxIHbojaTYAS4vkGgxqI7r32/ 5a13OEoZOu7btaOTccWrpHZ6dUPo+YEEDe87cta3SBTqyveqqcYCI2DcUP28ir5EIUxb 2U2A== X-Gm-Message-State: ANoB5pnkq5B3hEhVU5GUYJKha2XnezMcwkm4r96Wme8jvC3pAGCtitjy iYy4GD0Oib79mWGsbsG+QbTrfK29tiJO X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:553:438f:b86a:87f]) (user=irogers job=sendgmr) by 2002:a25:e812:0:b0:679:6725:3e2c with SMTP id k18-20020a25e812000000b0067967253e2cmr13188809ybd.425.1668460140801; Mon, 14 Nov 2022 13:09:00 -0800 (PST) Date: Mon, 14 Nov 2022 13:07:21 -0800 In-Reply-To: <20221114210723.2749751-1-irogers@google.com> Message-Id: <20221114210723.2749751-9-irogers@google.com> Mime-Version: 1.0 References: <20221114210723.2749751-1-irogers@google.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog Subject: [PATCH v3 08/10] perf pmu: Restructure print_pmu_events From: Ian Rogers To: Weilin Wang , Perry Taylor , Caleb Biggers , Leo Yan , Adrian Hunter , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Sandipan Das , Kajol Jain , Zhengjun Xing , Kan Liang , Ravi Bangoria , Xin Gao , Rob Herring , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749507633570094549?= X-GMAIL-MSGID: =?utf-8?q?1749507633570094549?= Previously print_pmu_events would compute the values to be printed, place them in struct sevent, sort them and then print them. Modify the code so that struct sevent holds just the PMU and event, sort these and then in the main print loop calculate aliases for names, etc. This avoids memory allocations for copied values as they are computed then printed. Signed-off-by: Ian Rogers --- tools/perf/util/pmu.c | 208 ++++++++++++++++++++++-------------------- 1 file changed, 110 insertions(+), 98 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index e6790175307b..075c82dd1347 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1553,8 +1553,8 @@ static int sub_non_neg(int a, int b) return a - b; } -static char *format_alias(char *buf, int len, struct perf_pmu *pmu, - struct perf_pmu_alias *alias) +static char *format_alias(char *buf, int len, const struct perf_pmu *pmu, + const struct perf_pmu_alias *alias) { struct parse_events_term *term; int used = snprintf(buf, len, "%s/%s", pmu->name, alias->name); @@ -1579,51 +1579,67 @@ static char *format_alias(char *buf, int len, struct perf_pmu *pmu, return buf; } -static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu, - struct perf_pmu_alias *alias) +static char *format_alias_or(char *buf, int len, const struct perf_pmu *pmu, + const struct perf_pmu_alias *alias) { snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name); return buf; } +/** Struct for ordering events as output in perf list. */ struct sevent { - char *name; - char *desc; - char *topic; - char *str; - char *pmu; - char *metric_expr; - char *metric_name; - int is_cpu; + /** PMU for event. */ + const struct perf_pmu *pmu; + /** + * Optional event for name, desc, etc. If not present then this is a + * selectable PMU and the event name is shown as "//". + */ + const struct perf_pmu_alias *event; + /** Is the PMU for the CPU? */ + bool is_cpu; }; static int cmp_sevent(const void *a, const void *b) { const struct sevent *as = a; const struct sevent *bs = b; + const char *a_pmu_name, *b_pmu_name; + const char *a_name = "//", *a_desc = NULL, *a_topic = ""; + const char *b_name = "//", *b_desc = NULL, *b_topic = ""; int ret; - /* Put extra events last */ - if (!!as->desc != !!bs->desc) - return !!as->desc - !!bs->desc; - if (as->topic && bs->topic) { - int n = strcmp(as->topic, bs->topic); - - if (n) - return n; + if (as->event) { + a_name = as->event->name; + a_desc = as->event->desc; + a_topic = as->event->topic ?: ""; } + if (bs->event) { + b_name = bs->event->name; + b_desc = bs->event->desc; + b_topic = bs->event->topic ?: ""; + } + /* Put extra events last. */ + if (!!a_desc != !!b_desc) + return !!a_desc - !!b_desc; + + /* Order by topics. */ + ret = strcmp(a_topic, b_topic); + if (ret) + return ret; /* Order CPU core events to be first */ if (as->is_cpu != bs->is_cpu) return bs->is_cpu - as->is_cpu; - ret = strcmp(as->name, bs->name); - if (!ret) { - if (as->pmu && bs->pmu) - return strcmp(as->pmu, bs->pmu); - } + /* Order by PMU name. */ + a_pmu_name = as->pmu->name ?: ""; + b_pmu_name = bs->pmu->name ?: ""; + ret = strcmp(a_pmu_name, b_pmu_name); + if (ret) + return ret; - return ret; + /* Order by event name. */ + return strcmp(a_name, b_name); } static void wordwrap(char *s, int start, int max, int corr) @@ -1655,16 +1671,18 @@ bool is_pmu_core(const char *name) static bool pmu_alias_is_duplicate(struct sevent *alias_a, struct sevent *alias_b) { - /* Different names -> never duplicates */ - if (strcmp(alias_a->name, alias_b->name)) - return false; + const char *a_pmu_name, *b_pmu_name; + const char *a_name = alias_a->event ? alias_a->event->name : "//"; + const char *b_name = alias_b->event ? alias_b->event->name : "//"; - /* Don't remove duplicates for hybrid PMUs */ - if (perf_pmu__is_hybrid(alias_a->pmu) && - perf_pmu__is_hybrid(alias_b->pmu)) + /* Different names -> never duplicates */ + if (strcmp(a_name, b_name)) return false; - return true; + /* Don't remove duplicates for different PMUs */ + a_pmu_name = alias_a->pmu->name ?: ""; + b_pmu_name = alias_b->pmu->name ?: ""; + return strcmp(a_pmu_name, b_pmu_name) == 0; } void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, @@ -1690,110 +1708,104 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, len++; } aliases = zalloc(sizeof(struct sevent) * len); - if (!aliases) - goto out_enomem; + if (!aliases) { + pr_err("FATAL: not enough memory to print PMU events\n"); + return; + } pmu = NULL; j = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) { + bool is_cpu; + if (pmu_name && pmu->name && strcmp(pmu_name, pmu->name)) continue; - list_for_each_entry(alias, &pmu->aliases, list) { - char *name = alias->desc ? alias->name : - format_alias(buf, sizeof(buf), pmu, alias); - bool is_cpu = is_pmu_core(pmu->name) || - perf_pmu__is_hybrid(pmu->name); + is_cpu = is_pmu_core(pmu->name) || perf_pmu__is_hybrid(pmu->name); + list_for_each_entry(alias, &pmu->aliases, list) { if (alias->deprecated && !deprecated) continue; if (event_glob != NULL && - !(strglobmatch_nocase(name, event_glob) || - (!is_cpu && strglobmatch_nocase(alias->name, - event_glob)) || + !(strglobmatch_nocase(alias->name, event_glob) || + (!is_cpu && + strglobmatch_nocase(alias->name, event_glob)) || (alias->topic && strglobmatch_nocase(alias->topic, event_glob)))) continue; - if (is_cpu && !name_only && !alias->desc) - name = format_alias_or(buf, sizeof(buf), pmu, alias); - - aliases[j].name = name; - if (is_cpu && !name_only && !alias->desc) - aliases[j].name = format_alias_or(buf, - sizeof(buf), - pmu, alias); - aliases[j].name = strdup(aliases[j].name); - if (!aliases[j].name) - goto out_enomem; - - aliases[j].desc = long_desc ? alias->long_desc : - alias->desc; - aliases[j].topic = alias->topic; - aliases[j].str = alias->str; - aliases[j].pmu = pmu->name; - aliases[j].metric_expr = alias->metric_expr; - aliases[j].metric_name = alias->metric_name; + aliases[j].event = alias; + aliases[j].pmu = pmu; aliases[j].is_cpu = is_cpu; j++; } if (pmu->selectable && (event_glob == NULL || strglobmatch(pmu->name, event_glob))) { - char *s; - if (asprintf(&s, "%s//", pmu->name) < 0) - goto out_enomem; - aliases[j].name = s; + aliases[j].event = NULL; + aliases[j].pmu = pmu; + aliases[j].is_cpu = is_cpu; j++; } } len = j; qsort(aliases, len, sizeof(struct sevent), cmp_sevent); for (j = 0; j < len; j++) { + char *name, *desc; + /* Skip duplicates */ if (j > 0 && pmu_alias_is_duplicate(&aliases[j], &aliases[j - 1])) continue; + if (!aliases[j].event) { + /* A selectable event. */ + snprintf(buf, sizeof(buf), "%s//", aliases[j].pmu->name); + name = buf; + } else if (aliases[j].event->desc) { + name = aliases[j].event->name; + } else { + if (!name_only && aliases[j].is_cpu) { + name = format_alias_or(buf, sizeof(buf), aliases[j].pmu, + aliases[j].event); + } else { + name = format_alias(buf, sizeof(buf), aliases[j].pmu, + aliases[j].event); + } + } if (name_only) { - printf("%s ", aliases[j].name); + printf("%s ", name); continue; } - if (aliases[j].desc && !quiet_flag) { - if (numdesc++ == 0) - printf("\n"); - if (aliases[j].topic && (!topic || - strcmp(topic, aliases[j].topic))) { - printf("%s%s:\n", topic ? "\n" : "", - aliases[j].topic); - topic = aliases[j].topic; - } - printf(" %-50s\n", aliases[j].name); - printf("%*s", 8, "["); - wordwrap(aliases[j].desc, 8, columns, 0); - printf("]\n"); - if (details_flag) { - printf("%*s%s/%s/ ", 8, "", aliases[j].pmu, aliases[j].str); - if (aliases[j].metric_name) - printf(" MetricName: %s", aliases[j].metric_name); - if (aliases[j].metric_expr) - printf(" MetricExpr: %s", aliases[j].metric_expr); - putchar('\n'); - } - } else - printf(" %-50s [Kernel PMU event]\n", aliases[j].name); printed++; + if (!aliases[j].event || !aliases[j].event->desc || quiet_flag) { + printf(" %-50s [Kernel PMU event]\n", name); + continue; + } + if (numdesc++ == 0) + printf("\n"); + if (aliases[j].event->topic && (!topic || + strcmp(topic, aliases[j].event->topic))) { + printf("%s%s:\n", topic ? "\n" : "", aliases[j].event->topic); + topic = aliases[j].event->topic; + } + printf(" %-50s\n", name); + printf("%*s", 8, "["); + desc = long_desc ? aliases[j].event->long_desc : aliases[j].event->desc; + wordwrap(desc, 8, columns, 0); + printf("]\n"); + if (details_flag) { + printf("%*s%s/%s/ ", 8, "", aliases[j].pmu->name, aliases[j].event->str); + if (aliases[j].event->metric_name) + printf(" MetricName: %s", aliases[j].event->metric_name); + if (aliases[j].event->metric_expr) + printf(" MetricExpr: %s", aliases[j].event->metric_expr); + putchar('\n'); + } } if (printed && pager_in_use()) printf("\n"); -out_free: - for (j = 0; j < len; j++) - zfree(&aliases[j].name); + zfree(&aliases); return; - -out_enomem: - printf("FATAL: not enough memory to print PMU events\n"); - if (aliases) - goto out_free; } bool pmu_have_event(const char *pname, const char *name) From patchwork Mon Nov 14 21:07:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 20043 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp2369364wru; Mon, 14 Nov 2022 13:17:26 -0800 (PST) X-Google-Smtp-Source: AA0mqf55birI5OMMg0qCZ7FD0PprS8WkpRpCPiV53ALnlgiJFVI1lHBPYQm+K5QAhi15YImfW6Pv X-Received: by 2002:a17:906:504a:b0:78d:6655:d12e with SMTP id e10-20020a170906504a00b0078d6655d12emr11673570ejk.260.1668460646447; Mon, 14 Nov 2022 13:17:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668460646; cv=none; d=google.com; s=arc-20160816; b=p0j5SCkD9jm9yhB3mdKuNhUaWgL4FCN//uB0/Z8zQx+Iq2AdPsprc12d6NJ1XSfNgX 5JeCftIgAeCwobw8WoY7QW7zH35qq8AkAvRYGGac6762Uz+NKnmQhHbSniZ3olBv0nF5 ZbPZG+xBqsJpR8H5/Pgg8pxcDXYaGksE5nu3M87NLcSU3P/HD2Go1nJu7sJM9y7bCy9p vIM6NTRSQxZZ/3Wk//dUrSnUkUT0C3YJTvgzesGi3xgfS74KhYreaXm5rxIYYZ4s0yj+ NS5IeU/LtF0ZkWcyVuk4zd6lQQulSDuS51e8k3EFZbL5OI+EMbvct/r60acxu4T1bg61 /DdQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=FbMkm7eVZJ8nydJV3cn0i53k8FmaD8baom4/w9HSfEE=; b=OT80uGk90pLT8R3xYzGZcmiqNRXWiTgQD6prMWr3lQ5SApTWarFfAzyv4RBFPwpp0R 86QluVHTiOg1xl2K0bCUBMJwjqyiYihyQjToCUjzecfH9XvooQM/0pzJQkVNXNf/6fe2 TwaqJV/1hs94WqqXLqg60eF13J5+cPFvSwgXDOjdbdI9ifSGkalxvuZyUc/9emxI86OV Pg9H9OAazQqXxNyPWuhX+sXMcSRcDAfpBAr4ICyA7/z9mqYa6rJuy6kOSYmIBe+ksnJ6 fHq62/bvaoOzWAnwBRErQ9ds4s0bIXNB/nj5dWRkWuZZTrIbqX+n9XWGGImFEo18pvDH SUvA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=LjetKudP; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id y21-20020a056402359500b00461a144e980si11370526edc.379.2022.11.14.13.17.02; Mon, 14 Nov 2022 13:17:26 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=LjetKudP; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 S237774AbiKNVJk (ORCPT + 99 others); Mon, 14 Nov 2022 16:09:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46426 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237745AbiKNVJO (ORCPT ); Mon, 14 Nov 2022 16:09:14 -0500 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E0040E084 for ; Mon, 14 Nov 2022 13:09:09 -0800 (PST) Received: by mail-pg1-x54a.google.com with SMTP id 186-20020a6300c3000000b004702c90a4bdso6295521pga.9 for ; Mon, 14 Nov 2022 13:09:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=FbMkm7eVZJ8nydJV3cn0i53k8FmaD8baom4/w9HSfEE=; b=LjetKudPNIvXrNpXy/AjczqbA9ifx6Gj7JIVF/vAMwOuclvOBkxLBWUMAmSQVMrR67 pW+QlOc94yeLtDsDkXtPS2Crnps6f6PHP0E7oQtHwUte1lpucOVa9Vb6jONCUKo0e7o1 S3+rgiosQBBkd2K/kPTxZ9jNBfRJGV+4CCoII1RT03TpqbrlPXRm+cBMB3yzUXXHv82e ehAcFk/jXTLBTSvO4FuWUAIzBJ8j5mUVs+LEQdG5YnnQPgiEMhRTbr914cr3PAq5EAbx PCicNQdxXWrL+A7B0ISYJTwbwyC4AVqr73LM0ns8X5EFpy48BjT17TXYSwrrh5flH8Lw 7Ytw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=FbMkm7eVZJ8nydJV3cn0i53k8FmaD8baom4/w9HSfEE=; b=kHB+YwAA4MSgPOEd/0e3fi9XVmOD1/ui078pKc9KBZlu4AoLzF3eoyKbAZ+QjsYDCS 5bpmVPyPgRVkBYUKq7nnf6TH7bzjxqxWsIfksD29rQZrR52n9/0s32XnccM+4Npnful3 d6rn4m2mFaKjLIzU+rxiLaJIJi8MBGNlcP3gpnqfkLcYPd/K+R+vfdzJ7t2tuNzqZzN3 0piJ33BCI9gwr06p1qGCtYYY1GB1UHOCRiJEgdwBENEdMkdxn9/nitKDtKUACZcGa+yP d5RmHBh4yN8JcxTJt6Dp7qusoICR+cvyzhjSDCmAqaPuTfsggOqmS41JKO0AFrL8BPrz 4nzQ== X-Gm-Message-State: ANoB5pk0sBY33fdgJyuHIJmOwImxzoTW7JrWj/JaHemTGUvrz99STDHA CDk2vRoiZaNeJHe54RVdhWUU3SJum29u X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:553:438f:b86a:87f]) (user=irogers job=sendgmr) by 2002:a17:90b:4a8b:b0:212:ca89:41c9 with SMTP id lp11-20020a17090b4a8b00b00212ca8941c9mr15267825pjb.244.1668460149444; Mon, 14 Nov 2022 13:09:09 -0800 (PST) Date: Mon, 14 Nov 2022 13:07:22 -0800 In-Reply-To: <20221114210723.2749751-1-irogers@google.com> Message-Id: <20221114210723.2749751-10-irogers@google.com> Mime-Version: 1.0 References: <20221114210723.2749751-1-irogers@google.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog Subject: [PATCH v3 09/10] perf list: Reorganize to use callbacks From: Ian Rogers To: Weilin Wang , Perry Taylor , Caleb Biggers , Leo Yan , Adrian Hunter , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Sandipan Das , Kajol Jain , Zhengjun Xing , Kan Liang , Ravi Bangoria , Xin Gao , Rob Herring , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749507790802730347?= X-GMAIL-MSGID: =?utf-8?q?1749507790802730347?= Rather than controlling the list output with passed flags, add callbacks that are called when an event or metric are encountered. State is passed to the callback so that command line options can be respected, alternatively the callbacks can be changed. Fix a few bugs: - wordwrap to columns metric descriptions and expressions; - remove unnecessary whitespace after PMU event names; - the metric filter is a glob but matched using strstr which will always fail, switch to using a proper globmatch, - the detail flag gives details for extra kernel PMU events like branch-instructions. In metricgroup.c switch from struct mep being a rbtree of metricgroups containing a list of metrics, to the tree directly containing all the metrics. In general the alias for a name is passed to the print routine rather than being contained in the name with OR. Signed-off-by: Ian Rogers --- tools/perf/builtin-list.c | 331 +++++++++++++++++++++++++----- tools/perf/util/metricgroup.c | 243 ++++++---------------- tools/perf/util/metricgroup.h | 4 +- tools/perf/util/pmu.c | 145 +++++-------- tools/perf/util/pmu.h | 5 +- tools/perf/util/print-events.c | 363 +++++++++++++++++---------------- tools/perf/util/print-events.h | 42 ++-- 7 files changed, 621 insertions(+), 512 deletions(-) diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index cc84ced6da26..12811fc40a30 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -15,31 +15,240 @@ #include "util/pmu-hybrid.h" #include "util/debug.h" #include "util/metricgroup.h" +#include "util/string2.h" +#include "util/strlist.h" #include #include #include -static bool desc_flag = true; -static bool details_flag; +/** + * struct print_state - State and configuration passed to the default_print + * functions. + */ +struct print_state { + /** + * @pmu_glob: Optionally restrict PMU and metric matching to PMU or + * debugfs subsystem name. + */ + char *pmu_glob; + /** @event_glob: Optional pattern matching glob. */ + char *event_glob; + /** @name_only: Print event or metric names only. */ + bool name_only; + /** @desc: Print the event or metric description. */ + bool desc; + /** @long_desc: Print longer event or metric description. */ + bool long_desc; + /** @deprecated: Print deprecated events or metrics. */ + bool deprecated; + /** + * @detailed: Print extra information on the perf event such as names + * and expressions used internally by events. + */ + bool detailed; + /** @metrics: Controls printing of metric and metric groups. */ + bool metrics; + /** @metricgroups: Controls printing of metric and metric groups. */ + bool metricgroups; + /** @last_topic: The last printed event topic. */ + char *last_topic; + /** @last_metricgroups: The last printed metric group. */ + char *last_metricgroups; + /** @visited_metrics: Metrics that are printed to avoid duplicates. */ + struct strlist *visited_metrics; +}; + +static void default_print_start(void *ps) +{ + struct print_state *print_state = ps; + + if (!print_state->name_only && pager_in_use()) + printf("\nList of pre-defined events (to be used in -e or -M):\n\n"); +} + +static void default_print_end(void *print_state __maybe_unused) {} + +static void wordwrap(const char *s, int start, int max, int corr) +{ + int column = start; + int n; + + while (*s) { + int wlen = strcspn(s, " \t"); + + if (column + wlen >= max && column > start) { + printf("\n%*s", start, ""); + column = start + corr; + } + n = printf("%s%.*s", column > start ? " " : "", wlen, s); + if (n <= 0) + break; + s += wlen; + column += n; + s = skip_spaces(s); + } +} + +static void default_print_event(void *ps, const char *pmu_name, const char *topic, + const char *event_name, const char *event_alias, + const char *scale_unit __maybe_unused, + bool deprecated, const char *event_type_desc, + const char *desc, const char *long_desc, + const char *encoding_desc, + const char *metric_name, const char *metric_expr) +{ + struct print_state *print_state = ps; + int pos; + + if (deprecated && !print_state->deprecated) + return; + + if (print_state->pmu_glob && !strglobmatch(pmu_name, print_state->pmu_glob)) + return; + + if (print_state->event_glob && + (!event_name || !strglobmatch(event_name, print_state->event_glob)) && + (!event_alias || !strglobmatch(event_alias, print_state->event_glob)) && + (!topic || !strglobmatch_nocase(topic, print_state->event_glob))) + return; + + if (print_state->name_only) { + if (event_alias && strlen(event_alias)) + printf("%s ", event_alias); + else + printf("%s ", event_name); + return; + } + + if (strcmp(print_state->last_topic, topic ?: "")) { + if (topic) + printf("\n%s:\n", topic); + free(print_state->last_topic); + print_state->last_topic = strdup(topic ?: ""); + } + + if (event_alias && strlen(event_alias)) + pos = printf(" %s OR %s", event_name, event_alias); + else + pos = printf(" %s", event_name); + + if (!topic && event_type_desc) { + for (; pos < 53; pos++) + putchar(' '); + printf("[%s]\n", event_type_desc); + } else + putchar('\n'); + + if (desc && print_state->desc) { + printf("%*s", 8, "["); + wordwrap(desc, 8, pager_get_columns(), 0); + printf("]\n"); + } + + if (long_desc && print_state->long_desc) { + printf("%*s", 8, "["); + wordwrap(long_desc, 8, pager_get_columns(), 0); + printf("]\n"); + } + + if (print_state->detailed && encoding_desc) { + printf("%*s%s", 8, "", encoding_desc); + if (metric_name) + printf(" MetricName: %s", metric_name); + if (metric_expr) + printf(" MetricExpr: %s", metric_expr); + putchar('\n'); + } +} + +static void default_print_metric(void *ps, + const char *group, + const char *name, + const char *desc, + const char *long_desc, + const char *expr, + const char *unit __maybe_unused) +{ + struct print_state *print_state = ps; + + if (print_state->event_glob && + (!print_state->metrics || !name || !strglobmatch(name, print_state->event_glob)) && + (!print_state->metricgroups || !group || !strglobmatch(group, print_state->event_glob))) + return; + + if (!print_state->name_only && !print_state->last_metricgroups) { + if (print_state->metricgroups) { + printf("\nMetric Groups:\n"); + if (!print_state->metrics) + putchar('\n'); + } else { + printf("\nMetrics:\n\n"); + } + } + if (!print_state->last_metricgroups || + strcmp(print_state->last_metricgroups, group ?: "")) { + if (group && print_state->metricgroups) { + if (print_state->name_only) + printf("%s ", group); + else if (print_state->metrics) + printf("\n%s:\n", group); + else + printf("%s\n", group); + } + free(print_state->last_metricgroups); + print_state->last_metricgroups = strdup(group ?: ""); + } + if (!print_state->metrics) + return; + + if (print_state->name_only) { + if (print_state->metrics && + !strlist__has_entry(print_state->visited_metrics, name)) { + printf("%s ", name); + strlist__add(print_state->visited_metrics, name); + } + return; + } + printf(" %s\n", name); + + if (desc && print_state->desc) { + printf("%*s", 8, "["); + wordwrap(desc, 8, pager_get_columns(), 0); + printf("]\n"); + } + if (long_desc && print_state->long_desc) { + printf("%*s", 8, "["); + wordwrap(long_desc, 8, pager_get_columns(), 0); + printf("]\n"); + } + if (expr && print_state->detailed) { + printf("%*s", 8, "["); + wordwrap(expr, 8, pager_get_columns(), 0); + printf("]\n"); + } +} int cmd_list(int argc, const char **argv) { int i, ret = 0; - bool raw_dump = false; - bool long_desc_flag = false; - bool deprecated = false; - char *pmu_name = NULL; + struct print_state ps = {}; + struct print_callbacks print_cb = { + .print_start = default_print_start, + .print_end = default_print_end, + .print_event = default_print_event, + .print_metric = default_print_metric, + }; const char *hybrid_name = NULL; const char *unit_name = NULL; struct option list_options[] = { - OPT_BOOLEAN(0, "raw-dump", &raw_dump, "Dump raw events"), - OPT_BOOLEAN('d', "desc", &desc_flag, + OPT_BOOLEAN(0, "raw-dump", &ps.name_only, "Dump raw events"), + OPT_BOOLEAN('d', "desc", &ps.desc, "Print extra event descriptions. --no-desc to not print."), - OPT_BOOLEAN('v', "long-desc", &long_desc_flag, + OPT_BOOLEAN('v', "long-desc", &ps.long_desc, "Print longer event descriptions."), - OPT_BOOLEAN(0, "details", &details_flag, + OPT_BOOLEAN(0, "details", &ps.detailed, "Print information on the perf event names and expressions used internally by events."), - OPT_BOOLEAN(0, "deprecated", &deprecated, + OPT_BOOLEAN(0, "deprecated", &ps.deprecated, "Print deprecated events."), OPT_STRING(0, "cputype", &hybrid_name, "hybrid cpu type", "Limit PMU or metric printing to the given hybrid PMU (e.g. core or atom)."), @@ -63,20 +272,28 @@ int cmd_list(int argc, const char **argv) setup_pager(); - if (!raw_dump && pager_in_use()) - printf("\nList of pre-defined events (to be used in -e or -M):\n\n"); + if (!ps.name_only) + setup_pager(); + ps.desc = !ps.long_desc; + ps.last_topic = strdup(""); + assert(ps.last_topic); + ps.visited_metrics = strlist__new(NULL, NULL); + assert(ps.visited_metrics); if (unit_name) - pmu_name = strdup(unit_name); + ps.pmu_glob = strdup(unit_name); else if (hybrid_name) { - pmu_name = perf_pmu__hybrid_type_to_pmu(hybrid_name); - if (!pmu_name) + ps.pmu_glob = perf_pmu__hybrid_type_to_pmu(hybrid_name); + if (!ps.pmu_glob) pr_warning("WARNING: hybrid cputype is not supported!\n"); } + print_cb.print_start(&ps); + if (argc == 0) { - print_events(NULL, raw_dump, !desc_flag, long_desc_flag, - details_flag, deprecated, pmu_name); + ps.metrics = true; + ps.metricgroups = true; + print_events(&print_cb, &ps); goto out; } @@ -84,30 +301,33 @@ int cmd_list(int argc, const char **argv) char *sep, *s; if (strcmp(argv[i], "tracepoint") == 0) - print_tracepoint_events(NULL, NULL, raw_dump); + print_tracepoint_events(&print_cb, &ps); else if (strcmp(argv[i], "hw") == 0 || strcmp(argv[i], "hardware") == 0) - print_symbol_events(NULL, PERF_TYPE_HARDWARE, - event_symbols_hw, PERF_COUNT_HW_MAX, raw_dump); + print_symbol_events(&print_cb, &ps, PERF_TYPE_HARDWARE, + event_symbols_hw, PERF_COUNT_HW_MAX); else if (strcmp(argv[i], "sw") == 0 || strcmp(argv[i], "software") == 0) { - print_symbol_events(NULL, PERF_TYPE_SOFTWARE, - event_symbols_sw, PERF_COUNT_SW_MAX, raw_dump); - print_tool_events(NULL, raw_dump); + print_symbol_events(&print_cb, &ps, PERF_TYPE_SOFTWARE, + event_symbols_sw, PERF_COUNT_SW_MAX); + print_tool_events(&print_cb, &ps); } else if (strcmp(argv[i], "cache") == 0 || strcmp(argv[i], "hwcache") == 0) - print_hwcache_events(NULL, raw_dump); + print_hwcache_events(&print_cb, &ps); else if (strcmp(argv[i], "pmu") == 0) - print_pmu_events(NULL, raw_dump, !desc_flag, - long_desc_flag, details_flag, - deprecated, pmu_name); + print_pmu_events(&print_cb, &ps); else if (strcmp(argv[i], "sdt") == 0) - print_sdt_events(NULL, NULL, raw_dump); - else if (strcmp(argv[i], "metric") == 0 || strcmp(argv[i], "metrics") == 0) - metricgroup__print(true, false, NULL, raw_dump, details_flag, pmu_name); - else if (strcmp(argv[i], "metricgroup") == 0 || strcmp(argv[i], "metricgroups") == 0) - metricgroup__print(false, true, NULL, raw_dump, details_flag, pmu_name); - else if ((sep = strchr(argv[i], ':')) != NULL) { + print_sdt_events(&print_cb, &ps); + else if (strcmp(argv[i], "metric") == 0 || strcmp(argv[i], "metrics") == 0) { + ps.metricgroups = false; + ps.metrics = true; + metricgroup__print(&print_cb, &ps); + } else if (strcmp(argv[i], "metricgroup") == 0 || + strcmp(argv[i], "metricgroups") == 0) { + ps.metricgroups = true; + ps.metrics = false; + metricgroup__print(&print_cb, &ps); + } else if ((sep = strchr(argv[i], ':')) != NULL) { int sep_idx; sep_idx = sep - argv[i]; @@ -118,34 +338,41 @@ int cmd_list(int argc, const char **argv) } s[sep_idx] = '\0'; - print_tracepoint_events(s, s + sep_idx + 1, raw_dump); - print_sdt_events(s, s + sep_idx + 1, raw_dump); - metricgroup__print(true, true, s, raw_dump, details_flag, pmu_name); + ps.pmu_glob = s; + ps.event_glob = s + sep_idx + 1; + print_tracepoint_events(&print_cb, &ps); + print_sdt_events(&print_cb, &ps); + ps.metrics = true; + ps.metricgroups = true; + metricgroup__print(&print_cb, &ps); free(s); } else { if (asprintf(&s, "*%s*", argv[i]) < 0) { printf("Critical: Not enough memory! Trying to continue...\n"); continue; } - print_symbol_events(s, PERF_TYPE_HARDWARE, - event_symbols_hw, PERF_COUNT_HW_MAX, raw_dump); - print_symbol_events(s, PERF_TYPE_SOFTWARE, - event_symbols_sw, PERF_COUNT_SW_MAX, raw_dump); - print_tool_events(s, raw_dump); - print_hwcache_events(s, raw_dump); - print_pmu_events(s, raw_dump, !desc_flag, - long_desc_flag, - details_flag, - deprecated, - pmu_name); - print_tracepoint_events(NULL, s, raw_dump); - print_sdt_events(NULL, s, raw_dump); - metricgroup__print(true, true, s, raw_dump, details_flag, pmu_name); + ps.event_glob = s; + print_symbol_events(&print_cb, &ps, PERF_TYPE_HARDWARE, + event_symbols_hw, PERF_COUNT_HW_MAX); + print_symbol_events(&print_cb, &ps, PERF_TYPE_SOFTWARE, + event_symbols_sw, PERF_COUNT_SW_MAX); + print_tool_events(&print_cb, &ps); + print_hwcache_events(&print_cb, &ps); + print_pmu_events(&print_cb, &ps); + print_tracepoint_events(&print_cb, &ps); + print_sdt_events(&print_cb, &ps); + ps.metrics = true; + ps.metricgroups = true; + metricgroup__print(&print_cb, &ps); free(s); } } out: - free(pmu_name); + print_cb.print_end(&ps); + free(ps.pmu_glob); + free(ps.last_topic); + free(ps.last_metricgroups); + strlist__delete(ps.visited_metrics); return ret; } diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 1943fed9b6d9..76501009ead5 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -12,6 +12,7 @@ #include "strbuf.h" #include "pmu.h" #include "pmu-hybrid.h" +#include "print-events.h" #include "expr.h" #include "rblist.h" #include @@ -352,51 +353,65 @@ static bool match_pe_metric(const struct pmu_event *pe, const char *metric) match_metric(pe->metric_name, metric); } +/** struct mep - RB-tree node for building printing information. */ struct mep { + /** nd - RB-tree element. */ struct rb_node nd; - const char *name; - struct strlist *metrics; + /** @metric_group: Owned metric group name, separated others with ';'. */ + char *metric_group; + const char *metric_name; + const char *metric_desc; + const char *metric_long_desc; + const char *metric_expr; + const char *metric_unit; }; static int mep_cmp(struct rb_node *rb_node, const void *entry) { struct mep *a = container_of(rb_node, struct mep, nd); struct mep *b = (struct mep *)entry; + int ret; - return strcmp(a->name, b->name); + ret = strcmp(a->metric_group, b->metric_group); + if (ret) + return ret; + + return strcmp(a->metric_name, b->metric_name); } -static struct rb_node *mep_new(struct rblist *rl __maybe_unused, - const void *entry) +static struct rb_node *mep_new(struct rblist *rl __maybe_unused, const void *entry) { struct mep *me = malloc(sizeof(struct mep)); if (!me) return NULL; + memcpy(me, entry, sizeof(struct mep)); - me->name = strdup(me->name); - if (!me->name) - goto out_me; - me->metrics = strlist__new(NULL, NULL); - if (!me->metrics) - goto out_name; return &me->nd; -out_name: - zfree(&me->name); -out_me: +} + +static void mep_delete(struct rblist *rl __maybe_unused, + struct rb_node *nd) +{ + struct mep *me = container_of(nd, struct mep, nd); + + zfree(&me->metric_group); free(me); - return NULL; } -static struct mep *mep_lookup(struct rblist *groups, const char *name) +static struct mep *mep_lookup(struct rblist *groups, const char *metric_group, + const char *metric_name) { struct rb_node *nd; struct mep me = { - .name = name + .metric_group = strdup(metric_group), + .metric_name = metric_name, }; nd = rblist__find(groups, &me); - if (nd) + if (nd) { + free(me.metric_group); return container_of(nd, struct mep, nd); + } rblist__add_node(groups, &me); nd = rblist__find(groups, &me); if (nd) @@ -404,107 +419,37 @@ static struct mep *mep_lookup(struct rblist *groups, const char *name) return NULL; } -static void mep_delete(struct rblist *rl __maybe_unused, - struct rb_node *nd) -{ - struct mep *me = container_of(nd, struct mep, nd); - - strlist__delete(me->metrics); - zfree(&me->name); - free(me); -} - -static void metricgroup__print_strlist(struct strlist *metrics, bool raw) -{ - struct str_node *sn; - int n = 0; - - strlist__for_each_entry (sn, metrics) { - if (raw) - printf("%s%s", n > 0 ? " " : "", sn->s); - else - printf(" %s\n", sn->s); - n++; - } - if (raw) - putchar('\n'); -} - -static int metricgroup__print_pmu_event(const struct pmu_event *pe, - bool metricgroups, char *filter, - bool raw, bool details, - struct rblist *groups, - struct strlist *metriclist) +static int metricgroup__add_to_mep_groups(const struct pmu_event *pe, + struct rblist *groups) { const char *g; char *omg, *mg; - g = pe->metric_group; - if (!g && pe->metric_name) { - if (pe->name) - return 0; - g = "No_group"; - } - - if (!g) - return 0; - - mg = strdup(g); - + mg = strdup(pe->metric_group ?: "No_group"); if (!mg) return -ENOMEM; omg = mg; while ((g = strsep(&mg, ";")) != NULL) { struct mep *me; - char *s; g = skip_spaces(g); - if (*g == 0) - g = "No_group"; - if (filter && !strstr(g, filter)) - continue; - if (raw) - s = (char *)pe->metric_name; - else { - if (asprintf(&s, "%s\n%*s%s]", - pe->metric_name, 8, "[", pe->desc) < 0) - return -1; - if (details) { - if (asprintf(&s, "%s\n%*s%s]", - s, 8, "[", pe->metric_expr) < 0) - return -1; - } - } - - if (!s) - continue; + if (strlen(g)) + me = mep_lookup(groups, g, pe->metric_name); + else + me = mep_lookup(groups, "No_group", pe->metric_name); - if (!metricgroups) { - strlist__add(metriclist, s); - } else { - me = mep_lookup(groups, g); - if (!me) - continue; - strlist__add(me->metrics, s); + if (me) { + me->metric_desc = pe->desc; + me->metric_long_desc = pe->long_desc; + me->metric_expr = pe->metric_expr; + me->metric_unit = pe->unit; } - - if (!raw) - free(s); } free(omg); return 0; } -struct metricgroup_print_sys_idata { - struct strlist *metriclist; - char *filter; - struct rblist *groups; - bool metricgroups; - bool raw; - bool details; -}; - struct metricgroup_iter_data { pmu_event_iter_fn fn; void *data; @@ -527,61 +472,26 @@ static int metricgroup__sys_event_iter(const struct pmu_event *pe, return d->fn(pe, table, d->data); } - return 0; } -static int metricgroup__print_sys_event_iter(const struct pmu_event *pe, - const struct pmu_events_table *table __maybe_unused, - void *data) -{ - struct metricgroup_print_sys_idata *d = data; - - return metricgroup__print_pmu_event(pe, d->metricgroups, d->filter, d->raw, - d->details, d->groups, d->metriclist); -} - -struct metricgroup_print_data { - const char *pmu_name; - struct strlist *metriclist; - char *filter; - struct rblist *groups; - bool metricgroups; - bool raw; - bool details; -}; - -static int metricgroup__print_callback(const struct pmu_event *pe, - const struct pmu_events_table *table __maybe_unused, - void *vdata) +static int metricgroup__add_to_mep_groups_callback(const struct pmu_event *pe, + const struct pmu_events_table *table __maybe_unused, + void *vdata) { - struct metricgroup_print_data *data = vdata; - const char *pmu = pe->pmu ?: "cpu"; + struct rblist *groups = vdata; - if (!pe->metric_expr) - return 0; - - if (data->pmu_name && strcmp(data->pmu_name, pmu)) + if (!pe->metric_name) return 0; - return metricgroup__print_pmu_event(pe, data->metricgroups, data->filter, - data->raw, data->details, data->groups, - data->metriclist); + return metricgroup__add_to_mep_groups(pe, groups); } -void metricgroup__print(bool metrics, bool metricgroups, char *filter, - bool raw, bool details, const char *pmu_name) +void metricgroup__print(const struct print_callbacks *print_cb, void *print_state) { struct rblist groups; - struct rb_node *node, *next; - struct strlist *metriclist = NULL; const struct pmu_events_table *table; - - if (!metricgroups) { - metriclist = strlist__new(NULL, NULL); - if (!metriclist) - return; - } + struct rb_node *node, *next; rblist__init(&groups); groups.node_new = mep_new; @@ -589,56 +499,31 @@ void metricgroup__print(bool metrics, bool metricgroups, char *filter, groups.node_delete = mep_delete; table = pmu_events_table__find(); if (table) { - struct metricgroup_print_data data = { - .pmu_name = pmu_name, - .metriclist = metriclist, - .metricgroups = metricgroups, - .filter = filter, - .raw = raw, - .details = details, - .groups = &groups, - }; - pmu_events_table_for_each_event(table, - metricgroup__print_callback, - &data); + metricgroup__add_to_mep_groups_callback, + &groups); } { struct metricgroup_iter_data data = { - .fn = metricgroup__print_sys_event_iter, - .data = (void *) &(struct metricgroup_print_sys_idata){ - .metriclist = metriclist, - .metricgroups = metricgroups, - .filter = filter, - .raw = raw, - .details = details, - .groups = &groups, - }, + .fn = metricgroup__add_to_mep_groups_callback, + .data = &groups, }; - pmu_for_each_sys_event(metricgroup__sys_event_iter, &data); } - if (!filter || !rblist__empty(&groups)) { - if (metricgroups && !raw) - printf("\nMetric Groups:\n\n"); - else if (metrics && !raw) - printf("\nMetrics:\n\n"); - } - for (node = rb_first_cached(&groups.entries); node; node = next) { struct mep *me = container_of(node, struct mep, nd); - if (metricgroups) - printf("%s%s%s", me->name, metrics && !raw ? ":" : "", raw ? " " : "\n"); - if (metrics) - metricgroup__print_strlist(me->metrics, raw); + print_cb->print_metric(print_state, + me->metric_group, + me->metric_name, + me->metric_desc, + me->metric_long_desc, + me->metric_expr, + me->metric_unit); next = rb_next(node); rblist__remove_node(&groups, node); } - if (!metricgroups) - metricgroup__print_strlist(metriclist, raw); - strlist__delete(metriclist); } static const char *code_characters = ",-=@"; diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index 732d3a0d3334..0013cf582173 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h @@ -10,6 +10,7 @@ struct evlist; struct evsel; struct option; +struct print_callbacks; struct rblist; struct cgroup; @@ -78,8 +79,7 @@ int metricgroup__parse_groups_test(struct evlist *evlist, bool metric_no_merge, struct rblist *metric_events); -void metricgroup__print(bool metrics, bool groups, char *filter, - bool raw, bool details, const char *pmu_name); +void metricgroup__print(const struct print_callbacks *print_cb, void *print_state); bool metricgroup__has_metric(const char *metric); int arch_get_runtimeparam(const struct pmu_event *pe __maybe_unused); void metricgroup__rblist_exit(struct rblist *metric_events); diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 075c82dd1347..e9a4f31926bf 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -23,6 +23,7 @@ #include "evsel.h" #include "pmu.h" #include "parse-events.h" +#include "print-events.h" #include "header.h" #include "string2.h" #include "strbuf.h" @@ -1579,13 +1580,6 @@ static char *format_alias(char *buf, int len, const struct perf_pmu *pmu, return buf; } -static char *format_alias_or(char *buf, int len, const struct perf_pmu *pmu, - const struct perf_pmu_alias *alias) -{ - snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name); - return buf; -} - /** Struct for ordering events as output in perf list. */ struct sevent { /** PMU for event. */ @@ -1629,7 +1623,7 @@ static int cmp_sevent(const void *a, const void *b) /* Order CPU core events to be first */ if (as->is_cpu != bs->is_cpu) - return bs->is_cpu - as->is_cpu; + return as->is_cpu ? -1 : 1; /* Order by PMU name. */ a_pmu_name = as->pmu->name ?: ""; @@ -1642,27 +1636,6 @@ static int cmp_sevent(const void *a, const void *b) return strcmp(a_name, b_name); } -static void wordwrap(char *s, int start, int max, int corr) -{ - int column = start; - int n; - - while (*s) { - int wlen = strcspn(s, " \t"); - - if (column + wlen >= max && column > start) { - printf("\n%*s", start, ""); - column = start + corr; - } - n = printf("%s%.*s", column > start ? " " : "", wlen, s); - if (n <= 0) - break; - s += wlen; - column += n; - s = skip_spaces(s); - } -} - bool is_pmu_core(const char *name) { return !strcmp(name, "cpu") || is_arm_pmu_core(name); @@ -1685,24 +1658,19 @@ static bool pmu_alias_is_duplicate(struct sevent *alias_a, return strcmp(a_pmu_name, b_pmu_name) == 0; } -void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, - bool long_desc, bool details_flag, bool deprecated, - const char *pmu_name) +void print_pmu_events(const struct print_callbacks *print_cb, void *print_state) { struct perf_pmu *pmu; - struct perf_pmu_alias *alias; + struct perf_pmu_alias *event; char buf[1024]; int printed = 0; int len, j; struct sevent *aliases; - int numdesc = 0; - int columns = pager_get_columns(); - char *topic = NULL; pmu = NULL; len = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) { - list_for_each_entry(alias, &pmu->aliases, list) + list_for_each_entry(event, &pmu->aliases, list) len++; if (pmu->selectable) len++; @@ -1715,32 +1683,15 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, pmu = NULL; j = 0; while ((pmu = perf_pmu__scan(pmu)) != NULL) { - bool is_cpu; + bool is_cpu = is_pmu_core(pmu->name) || perf_pmu__is_hybrid(pmu->name); - if (pmu_name && pmu->name && strcmp(pmu_name, pmu->name)) - continue; - - is_cpu = is_pmu_core(pmu->name) || perf_pmu__is_hybrid(pmu->name); - - list_for_each_entry(alias, &pmu->aliases, list) { - if (alias->deprecated && !deprecated) - continue; - - if (event_glob != NULL && - !(strglobmatch_nocase(alias->name, event_glob) || - (!is_cpu && - strglobmatch_nocase(alias->name, event_glob)) || - (alias->topic && - strglobmatch_nocase(alias->topic, event_glob)))) - continue; - - aliases[j].event = alias; + list_for_each_entry(event, &pmu->aliases, list) { + aliases[j].event = event; aliases[j].pmu = pmu; aliases[j].is_cpu = is_cpu; j++; } - if (pmu->selectable && - (event_glob == NULL || strglobmatch(pmu->name, event_glob))) { + if (pmu->selectable) { aliases[j].event = NULL; aliases[j].pmu = pmu; aliases[j].is_cpu = is_cpu; @@ -1750,7 +1701,12 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, len = j; qsort(aliases, len, sizeof(struct sevent), cmp_sevent); for (j = 0; j < len; j++) { - char *name, *desc; + const char *name, *alias = NULL, *scale_unit = NULL, + *desc = NULL, *long_desc = NULL, + *encoding_desc = NULL, *topic = NULL, + *metric_name = NULL, *metric_expr = NULL; + bool deprecated = false; + size_t buf_used; /* Skip duplicates */ if (j > 0 && pmu_alias_is_duplicate(&aliases[j], &aliases[j - 1])) @@ -1758,48 +1714,51 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, if (!aliases[j].event) { /* A selectable event. */ - snprintf(buf, sizeof(buf), "%s//", aliases[j].pmu->name); + buf_used = snprintf(buf, sizeof(buf), "%s//", aliases[j].pmu->name) + 1; name = buf; - } else if (aliases[j].event->desc) { - name = aliases[j].event->name; } else { - if (!name_only && aliases[j].is_cpu) { - name = format_alias_or(buf, sizeof(buf), aliases[j].pmu, - aliases[j].event); + if (aliases[j].event->desc) { + name = aliases[j].event->name; + buf_used = 0; } else { name = format_alias(buf, sizeof(buf), aliases[j].pmu, aliases[j].event); + if (aliases[j].is_cpu) { + alias = name; + name = aliases[j].event->name; + } + buf_used = strlen(buf) + 1; } - } - if (name_only) { - printf("%s ", name); - continue; - } - printed++; - if (!aliases[j].event || !aliases[j].event->desc || quiet_flag) { - printf(" %-50s [Kernel PMU event]\n", name); - continue; - } - if (numdesc++ == 0) - printf("\n"); - if (aliases[j].event->topic && (!topic || - strcmp(topic, aliases[j].event->topic))) { - printf("%s%s:\n", topic ? "\n" : "", aliases[j].event->topic); + if (strlen(aliases[j].event->unit) || aliases[j].event->scale != 1.0) { + scale_unit = buf + buf_used; + buf_used += snprintf(buf + buf_used, sizeof(buf) - buf_used, + "%G%s", aliases[j].event->scale, + aliases[j].event->unit) + 1; + } + desc = aliases[j].event->desc; + long_desc = aliases[j].event->long_desc; topic = aliases[j].event->topic; + encoding_desc = buf + buf_used; + buf_used += snprintf(buf + buf_used, sizeof(buf) - buf_used, + "%s/%s/", aliases[j].pmu->name, + aliases[j].event->str) + 1; + metric_name = aliases[j].event->metric_name; + metric_expr = aliases[j].event->metric_expr; + deprecated = aliases[j].event->deprecated; } - printf(" %-50s\n", name); - printf("%*s", 8, "["); - desc = long_desc ? aliases[j].event->long_desc : aliases[j].event->desc; - wordwrap(desc, 8, columns, 0); - printf("]\n"); - if (details_flag) { - printf("%*s%s/%s/ ", 8, "", aliases[j].pmu->name, aliases[j].event->str); - if (aliases[j].event->metric_name) - printf(" MetricName: %s", aliases[j].event->metric_name); - if (aliases[j].event->metric_expr) - printf(" MetricExpr: %s", aliases[j].event->metric_expr); - putchar('\n'); - } + print_cb->print_event(print_state, + aliases[j].pmu->name, + topic, + name, + alias, + scale_unit, + deprecated, + "Kernel PMU event", + desc, + long_desc, + encoding_desc, + metric_name, + metric_expr); } if (printed && pager_in_use()) printf("\n"); diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index ee02e1ef9187..69ca0004f94f 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -12,6 +12,7 @@ struct evsel_config_term; struct perf_cpu_map; +struct print_callbacks; enum { PERF_PMU_FORMAT_VALUE_CONFIG, @@ -225,9 +226,7 @@ void perf_pmu__del_formats(struct list_head *formats); struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu); bool is_pmu_core(const char *name); -void print_pmu_events(const char *event_glob, bool name_only, bool quiet, - bool long_desc, bool details_flag, - bool deprecated, const char *pmu_name); +void print_pmu_events(const struct print_callbacks *print_cb, void *print_state); bool pmu_have_event(const char *pname, const char *name); int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, ...) __scanf(3, 4); diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index d53dba033597..5210a168d54f 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -28,6 +28,7 @@ #define MAX_NAME_LEN 100 +/** Strings corresponding to enum perf_type_id. */ static const char * const event_type_descriptors[] = { "Hardware event", "Software event", @@ -55,11 +56,9 @@ static const struct event_symbol event_symbols_tool[PERF_TOOL_MAX] = { /* * Print the events from /tracing/events */ -void print_tracepoint_events(const char *subsys_glob, - const char *event_glob, bool name_only) +void print_tracepoint_events(const struct print_callbacks *print_cb, void *print_state) { struct dirent **sys_namelist = NULL; - bool printed = false; int sys_items = tracing_events__scandir_alphasort(&sys_namelist); for (int i = 0; i < sys_items; i++) { @@ -73,10 +72,6 @@ void print_tracepoint_events(const char *subsys_glob, !strcmp(sys_dirent->d_name, "..")) continue; - if (subsys_glob != NULL && - !strglobmatch(sys_dirent->d_name, subsys_glob)) - continue; - dir_path = get_events_file(sys_dirent->d_name); if (!dir_path) continue; @@ -94,41 +89,41 @@ void print_tracepoint_events(const char *subsys_glob, if (tp_event_has_id(dir_path, evt_dirent) != 0) continue; - if (event_glob != NULL && - !strglobmatch(evt_dirent->d_name, event_glob)) - continue; - snprintf(evt_path, MAXPATHLEN, "%s:%s", sys_dirent->d_name, evt_dirent->d_name); - if (name_only) - printf("%s ", evt_path); - else { - printf(" %-50s [%s]\n", evt_path, - event_type_descriptors[PERF_TYPE_TRACEPOINT]); - } - printed = true; + print_cb->print_event(print_state, + /*topic=*/NULL, + /*pmu_name=*/NULL, + evt_path, + /*event_alias=*/NULL, + /*scale_unit=*/NULL, + /*deprecated=*/false, + "Tracepoint event", + /*desc=*/NULL, + /*long_desc=*/NULL, + /*encoding_desc=*/NULL, + /*metric_name=*/NULL, + /*metric_expr=*/NULL); } free(dir_path); free(evt_namelist); } free(sys_namelist); - if (printed && pager_in_use()) - printf("\n"); } -void print_sdt_events(const char *subsys_glob, const char *event_glob, - bool name_only) +void print_sdt_events(const struct print_callbacks *print_cb, void *print_state) { - struct probe_cache *pcache; - struct probe_cache_entry *ent; struct strlist *bidlist, *sdtlist; - struct strlist_config cfg = {.dont_dupstr = true}; - struct str_node *nd, *nd2; - char *buf, *path, *ptr = NULL; - bool show_detail = false; - int ret; - - sdtlist = strlist__new(NULL, &cfg); + struct str_node *bid_nd, *sdt_name, *next_sdt_name; + const char *last_sdt_name = NULL; + + /* + * The implicitly sorted sdtlist will hold the tracepoint name followed + * by @. If the tracepoint name is unique (determined by + * looking at the adjacent nodes) the @ is dropped otherwise + * the executable path and buildid are added to the name. + */ + sdtlist = strlist__new(NULL, NULL); if (!sdtlist) { pr_debug("Failed to allocate new strlist for SDT\n"); return; @@ -138,65 +133,77 @@ void print_sdt_events(const char *subsys_glob, const char *event_glob, pr_debug("Failed to get buildids: %d\n", errno); return; } - strlist__for_each_entry(nd, bidlist) { - pcache = probe_cache__new(nd->s, NULL); + strlist__for_each_entry(bid_nd, bidlist) { + struct probe_cache *pcache; + struct probe_cache_entry *ent; + + pcache = probe_cache__new(bid_nd->s, NULL); if (!pcache) continue; list_for_each_entry(ent, &pcache->entries, node) { - if (!ent->sdt) - continue; - if (subsys_glob && - !strglobmatch(ent->pev.group, subsys_glob)) - continue; - if (event_glob && - !strglobmatch(ent->pev.event, event_glob)) - continue; - ret = asprintf(&buf, "%s:%s@%s", ent->pev.group, - ent->pev.event, nd->s); - if (ret > 0) - strlist__add(sdtlist, buf); + char buf[1024]; + + snprintf(buf, sizeof(buf), "%s:%s@%s", + ent->pev.group, ent->pev.event, bid_nd->s); + strlist__add(sdtlist, buf); } probe_cache__delete(pcache); } strlist__delete(bidlist); - strlist__for_each_entry(nd, sdtlist) { - buf = strchr(nd->s, '@'); - if (buf) - *(buf++) = '\0'; - if (name_only) { - printf("%s ", nd->s); - continue; - } - nd2 = strlist__next(nd); - if (nd2) { - ptr = strchr(nd2->s, '@'); - if (ptr) - *ptr = '\0'; - if (strcmp(nd->s, nd2->s) == 0) - show_detail = true; + strlist__for_each_entry(sdt_name, sdtlist) { + bool show_detail = false; + char *bid = strchr(sdt_name->s, '@'); + char *evt_name = NULL; + + if (bid) + *(bid++) = '\0'; + + if (last_sdt_name && !strcmp(last_sdt_name, sdt_name->s)) { + show_detail = true; + } else { + next_sdt_name = strlist__next(sdt_name); + if (next_sdt_name) { + char *bid2 = strchr(next_sdt_name->s, '@'); + + if (bid2) + *bid2 = '\0'; + if (strcmp(sdt_name->s, next_sdt_name->s) == 0) + show_detail = true; + if (bid2) + *bid2 = '@'; + } } + last_sdt_name = sdt_name->s; + if (show_detail) { - path = build_id_cache__origname(buf); - ret = asprintf(&buf, "%s@%s(%.12s)", nd->s, path, buf); - if (ret > 0) { - printf(" %-50s [%s]\n", buf, "SDT event"); - free(buf); + char *path = build_id_cache__origname(bid); + + if (path) { + asprintf(&evt_name, "%s@%s(%.12s)", sdt_name->s, path, bid); + free(path); } - free(path); - } else - printf(" %-50s [%s]\n", nd->s, "SDT event"); - if (nd2) { - if (strcmp(nd->s, nd2->s) != 0) - show_detail = false; - if (ptr) - *ptr = '@'; } + print_cb->print_event(print_state, + /*topic=*/NULL, + /*pmu_name=*/NULL, + evt_name ?: sdt_name->s, + /*event_alias=*/NULL, + /*deprecated=*/false, + /*scale_unit=*/NULL, + "SDT event", + /*desc=*/NULL, + /*long_desc=*/NULL, + /*encoding_desc=*/NULL, + /*metric_name=*/NULL, + /*metric_expr=*/NULL); + + free(evt_name); } strlist__delete(sdtlist); } -int print_hwcache_events(const char *event_glob, bool name_only) +int print_hwcache_events(const struct print_callbacks *print_cb, void *print_state) { struct strlist *evt_name_list = strlist__new(NULL, NULL); struct str_node *nd; @@ -216,9 +223,6 @@ int print_hwcache_events(const char *event_glob, bool name_only) char name[64]; __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name)); - if (event_glob != NULL && !strglobmatch(name, event_glob)) - continue; - if (!perf_pmu__has_hybrid()) { if (is_event_supported(PERF_TYPE_HW_CACHE, type | (op << 8) | (i << 16))) @@ -240,55 +244,47 @@ int print_hwcache_events(const char *event_glob, bool name_only) } strlist__for_each_entry(nd, evt_name_list) { - if (name_only) { - printf("%s ", nd->s); - continue; - } - printf(" %-50s [%s]\n", nd->s, event_type_descriptors[PERF_TYPE_HW_CACHE]); + print_cb->print_event(print_state, + "cache", + /*pmu_name=*/NULL, + nd->s, + /*event_alias=*/NULL, + /*scale_unit=*/NULL, + /*deprecated=*/false, + event_type_descriptors[PERF_TYPE_HW_CACHE], + /*desc=*/NULL, + /*long_desc=*/NULL, + /*encoding_desc=*/NULL, + /*metric_name=*/NULL, + /*metric_expr=*/NULL); } - if (!strlist__empty(evt_name_list) && pager_in_use()) - printf("\n"); - strlist__delete(evt_name_list); return 0; } -static void print_tool_event(const struct event_symbol *syms, const char *event_glob, - bool name_only) -{ - if (syms->symbol == NULL) - return; - - if (event_glob && !(strglobmatch(syms->symbol, event_glob) || - (syms->alias && strglobmatch(syms->alias, event_glob)))) - return; - - if (name_only) - printf("%s ", syms->symbol); - else { - char name[MAX_NAME_LEN]; - - if (syms->alias && strlen(syms->alias)) - snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); - else - strlcpy(name, syms->symbol, MAX_NAME_LEN); - printf(" %-50s [%s]\n", name, "Tool event"); - } -} - -void print_tool_events(const char *event_glob, bool name_only) +void print_tool_events(const struct print_callbacks *print_cb, void *print_state) { // Start at 1 because the first enum entry means no tool event. - for (int i = 1; i < PERF_TOOL_MAX; ++i) - print_tool_event(event_symbols_tool + i, event_glob, name_only); - - if (pager_in_use()) - printf("\n"); + for (int i = 1; i < PERF_TOOL_MAX; ++i) { + print_cb->print_event(print_state, + "tool", + /*pmu_name=*/NULL, + event_symbols_tool[i].symbol, + event_symbols_tool[i].alias, + /*scale_unit=*/NULL, + /*deprecated=*/false, + "Tool event", + /*desc=*/NULL, + /*long_desc=*/NULL, + /*encoding_desc=*/NULL, + /*metric_name=*/NULL, + /*metric_expr=*/NULL); + } } -void print_symbol_events(const char *event_glob, unsigned int type, - struct event_symbol *syms, unsigned int max, - bool name_only) +void print_symbol_events(const struct print_callbacks *print_cb, void *print_state, + unsigned int type, const struct event_symbol *syms, + unsigned int max) { struct strlist *evt_name_list = strlist__new(NULL, NULL); struct str_node *nd; @@ -305,10 +301,6 @@ void print_symbol_events(const char *event_glob, unsigned int type, if (syms[i].symbol == NULL) continue; - if (event_glob != NULL && !(strglobmatch(syms[i].symbol, event_glob) || - (syms[i].alias && strglobmatch(syms[i].alias, event_glob)))) - continue; - if (!is_event_supported(type, i)) continue; @@ -322,63 +314,92 @@ void print_symbol_events(const char *event_glob, unsigned int type, } strlist__for_each_entry(nd, evt_name_list) { - if (name_only) { - printf("%s ", nd->s); - continue; + char *alias = strstr(nd->s, " OR "); + + if (alias) { + *alias = '\0'; + alias += 4; } - printf(" %-50s [%s]\n", nd->s, event_type_descriptors[type]); + print_cb->print_event(print_state, + /*topic=*/NULL, + /*pmu_name=*/NULL, + nd->s, + alias, + /*scale_unit=*/NULL, + /*deprecated=*/false, + event_type_descriptors[type], + /*desc=*/NULL, + /*long_desc=*/NULL, + /*encoding_desc=*/NULL, + /*metric_name=*/NULL, + /*metric_expr=*/NULL); } - if (!strlist__empty(evt_name_list) && pager_in_use()) - printf("\n"); - strlist__delete(evt_name_list); } /* * Print the help text for the event symbols: */ -void print_events(const char *event_glob, bool name_only, bool quiet_flag, - bool long_desc, bool details_flag, bool deprecated, - const char *pmu_name) +void print_events(const struct print_callbacks *print_cb, void *print_state) { - print_symbol_events(event_glob, PERF_TYPE_HARDWARE, - event_symbols_hw, PERF_COUNT_HW_MAX, name_only); - - print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, - event_symbols_sw, PERF_COUNT_SW_MAX, name_only); - print_tool_events(event_glob, name_only); - - print_hwcache_events(event_glob, name_only); - - print_pmu_events(event_glob, name_only, quiet_flag, long_desc, - details_flag, deprecated, pmu_name); - - if (event_glob != NULL) - return; - - if (!name_only) { - printf(" %-50s [%s]\n", - "rNNN", - event_type_descriptors[PERF_TYPE_RAW]); - printf(" %-50s [%s]\n", - "cpu/t1=v1[,t2=v2,t3 ...]/modifier", - event_type_descriptors[PERF_TYPE_RAW]); - if (pager_in_use()) - printf(" (see 'man perf-list' on how to encode it)\n\n"); - - printf(" %-50s [%s]\n", - "mem:[/len][:access]", - event_type_descriptors[PERF_TYPE_BREAKPOINT]); - if (pager_in_use()) - printf("\n"); - } - - print_tracepoint_events(NULL, NULL, name_only); - - print_sdt_events(NULL, NULL, name_only); - - metricgroup__print(true, true, NULL, name_only, details_flag, - pmu_name); - - print_libpfm_events(name_only, long_desc); + print_symbol_events(print_cb, print_state, PERF_TYPE_HARDWARE, + event_symbols_hw, PERF_COUNT_HW_MAX); + print_symbol_events(print_cb, print_state, PERF_TYPE_SOFTWARE, + event_symbols_sw, PERF_COUNT_SW_MAX); + + print_tool_events(print_cb, print_state); + + print_hwcache_events(print_cb, print_state); + + print_pmu_events(print_cb, print_state); + + print_cb->print_event(print_state, + /*topic=*/NULL, + /*pmu_name=*/NULL, + "rNNN", + /*event_alias=*/NULL, + /*scale_unit=*/NULL, + /*deprecated=*/false, + event_type_descriptors[PERF_TYPE_RAW], + /*desc=*/NULL, + /*long_desc=*/NULL, + /*encoding_desc=*/NULL, + /*metric_name=*/NULL, + /*metric_expr=*/NULL); + + print_cb->print_event(print_state, + /*topic=*/NULL, + /*pmu_name=*/NULL, + "cpu/t1=v1[,t2=v2,t3 ...]/modifier", + /*event_alias=*/NULL, + /*scale_unit=*/NULL, + /*deprecated=*/false, + event_type_descriptors[PERF_TYPE_RAW], + "(see 'man perf-list' on how to encode it)", + /*long_desc=*/NULL, + /*encoding_desc=*/NULL, + /*metric_name=*/NULL, + /*metric_expr=*/NULL); + + print_cb->print_event(print_state, + /*topic=*/NULL, + /*pmu_name=*/NULL, + "mem:[/len][:access]", + /*scale_unit=*/NULL, + /*event_alias=*/NULL, + /*deprecated=*/false, + event_type_descriptors[PERF_TYPE_BREAKPOINT], + /*desc=*/NULL, + /*long_desc=*/NULL, + /*encoding_desc=*/NULL, + /*metric_name=*/NULL, + /*metric_expr=*/NULL); + + print_tracepoint_events(print_cb, print_state); + + print_sdt_events(print_cb, print_state); + + metricgroup__print(print_cb, print_state); + + print_libpfm_events(print_cb, print_state); } diff --git a/tools/perf/util/print-events.h b/tools/perf/util/print-events.h index 1da9910d83a6..c237e53c4487 100644 --- a/tools/perf/util/print-events.h +++ b/tools/perf/util/print-events.h @@ -2,21 +2,39 @@ #ifndef __PERF_PRINT_EVENTS_H #define __PERF_PRINT_EVENTS_H +#include #include struct event_symbol; -void print_events(const char *event_glob, bool name_only, bool quiet_flag, - bool long_desc, bool details_flag, bool deprecated, - const char *pmu_name); -int print_hwcache_events(const char *event_glob, bool name_only); -void print_sdt_events(const char *subsys_glob, const char *event_glob, - bool name_only); -void print_symbol_events(const char *event_glob, unsigned int type, - struct event_symbol *syms, unsigned int max, - bool name_only); -void print_tool_events(const char *event_glob, bool name_only); -void print_tracepoint_events(const char *subsys_glob, const char *event_glob, - bool name_only); +struct print_callbacks { + void (*print_start)(void *print_state); + void (*print_end)(void *print_state); + void (*print_event)(void *print_state, const char *topic, + const char *pmu_name, + const char *event_name, const char *event_alias, + const char *scale_unit, + bool deprecated, const char *event_type_desc, + const char *desc, const char *long_desc, + const char *encoding_desc, + const char *metric_name, const char *metric_expr); + void (*print_metric)(void *print_state, + const char *group, + const char *name, + const char *desc, + const char *long_desc, + const char *expr, + const char *unit); +}; + +/** Print all events, the default when no options are specified. */ +void print_events(const struct print_callbacks *print_cb, void *print_state); +int print_hwcache_events(const struct print_callbacks *print_cb, void *print_state); +void print_sdt_events(const struct print_callbacks *print_cb, void *print_state); +void print_symbol_events(const struct print_callbacks *print_cb, void *print_state, + unsigned int type, const struct event_symbol *syms, + unsigned int max); +void print_tool_events(const struct print_callbacks *print_cb, void *print_state); +void print_tracepoint_events(const struct print_callbacks *print_cb, void *print_state); #endif /* __PERF_PRINT_EVENTS_H */ From patchwork Mon Nov 14 21:07:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 20041 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp2369066wru; Mon, 14 Nov 2022 13:16:38 -0800 (PST) X-Google-Smtp-Source: AA0mqf5Fl3fIAhg9LWDiFWRx5B8WkMpdQXIOU6wggdu2fqYp1ajTE4czfhvGjRxRDeS5X39gh2hQ X-Received: by 2002:a05:6402:1944:b0:462:d288:16f8 with SMTP id f4-20020a056402194400b00462d28816f8mr12889614edz.170.1668460598399; Mon, 14 Nov 2022 13:16:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668460598; cv=none; d=google.com; s=arc-20160816; b=0qSduVlVLhHCtiSCeI6qdc5Kmb0JvPsvM9IV3GsHA1GZAHR8eKpFhvOK0LIM8j83Me dUgMwFNjgXWYscOvhnoQlMbBcSnR8G73LmMWmr4E9NxyXEqmzyOiUhDlsw//VXPOpNsc FDYCkR1y9RCZ6HeKGCWv1161hRJ7oZw/uS2KMzwNZklbXv/XyFTbpROoL8vWDWpH9OdP xsQiW3DE/dbEzxZGubZnNKj+0kTOdBer9ZezeAMIXxyqBf6LdkAYbGBuDSJuplZz8zGz JwzqKJ2kU38KiHftMGUaydmTe9kRUtjpl741+X8hE4/6dRybNB90tM5aC00pPoUABcwY 3x5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=EZnzM6HV3BgbBycTCsM2gbe0FFNFRdGwj//bA/m+O8Y=; b=G2/0onUrOhX7IgGhrWI/T4ECWcSvvIsKP2ra8EwyzGTaKxCd6Tf+tyB6SKHzUv3OvH zkI0VfkZ8MzmDQ/svlfkzu6k/zrWLbGRvik689QQhUYFCOMRVGJ+YAtQnOjDYUA4Y1sa OO0N7O0Gx4Mx+vIAX5f2Y52drD+JDL50TFzwV6DF9KXkJj8opIkLNeaB+KT9OY9nXlvs M362WlcqWG+uZczBJ+DjNB1kSDtN4c/EH4dGODuaJ+7OqT9rp6CSUGBzsaKn+QSFozad k6FIZWfRZAxhFD/g44iL6bGUfZScEoYpcAWloSDFKi4/rNs6xev3e4JqeEus18QEs+Td IHjA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=eRkzWvFL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id z2-20020a1709063ac200b0079bf804c0c4si7273982ejd.103.2022.11.14.13.16.14; Mon, 14 Nov 2022 13:16:38 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=eRkzWvFL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 S237593AbiKNVJp (ORCPT + 99 others); Mon, 14 Nov 2022 16:09:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45702 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237556AbiKNVJU (ORCPT ); Mon, 14 Nov 2022 16:09:20 -0500 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 38AE7F01C for ; Mon, 14 Nov 2022 13:09:18 -0800 (PST) Received: by mail-pf1-x44a.google.com with SMTP id cw4-20020a056a00450400b00561ec04e77aso6671790pfb.12 for ; Mon, 14 Nov 2022 13:09:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=EZnzM6HV3BgbBycTCsM2gbe0FFNFRdGwj//bA/m+O8Y=; b=eRkzWvFLUemkH6BcT+JLRuVOTwZY5HaqVQUVJsjop2oOPdRwgcYwOc/2o/EKY762K8 qJEDKBgHgRZNp6e81MxqPjSwZ3cqHtmmycDj4l+YJygUhBmEJRWOp+mex2uTmAQVLrh9 9kJByM4oXQ+gWZbXdrLfgKi8PRgNRLqwqOHnNGmWtocEyisQdy71kqAl2WQcF8XGoIxY hVSeb0iQ5Wf4nw9cZoH9yfx/d4DI6pIwrO61Jk4qrRvzARYP+G4BR8I5UVJAg2FgOxye zX11sBlS+/Ba3XsqQliSus04XyHVjvVwkuMquby/mQt6fXfYixf2mTuNpUqCP4L4HB0Q 125A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=EZnzM6HV3BgbBycTCsM2gbe0FFNFRdGwj//bA/m+O8Y=; b=V5mTXaG4qP+ksRBfcva3i7HLrfzTqX4T0RCeM2RFtoKHg9NxlJx1a465+bSwhX6qYW QCUn9NoXbVzbTLdOrRKgNTT3dOl/kz4SGHHvoyw6edB0x+N4bAvMFpJBE4Et/AcCA13E LRArOJS3MJz1Ni9UPrRsspYUOvXXcrEnTpurGL3qOJpYI7fB7pNnLqU8Opue38GbcQLd lPNL/1VHY3yfsS+Y9FP3KVcJC1q6yhv5mYMScsrw+rFJMxcLjOyXCGYb7vwbBI+bfmmU HfG0rO/N2AVKxhsb9ETNeEKVW4HlmjiX99pYBwfnC13L2cherWmgigBgZm/CFXnjV928 5THg== X-Gm-Message-State: ANoB5pm4MzVFCnEZmmKccfNG7PfMBmG46X0+wE11xKXl1haXLqeKNCkp BtoF3QA43CcMbcGIyaMl3wQi42jgp5zm X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:553:438f:b86a:87f]) (user=irogers job=sendgmr) by 2002:a62:6446:0:b0:565:c122:b63 with SMTP id y67-20020a626446000000b00565c1220b63mr14979790pfb.49.1668460157676; Mon, 14 Nov 2022 13:09:17 -0800 (PST) Date: Mon, 14 Nov 2022 13:07:23 -0800 In-Reply-To: <20221114210723.2749751-1-irogers@google.com> Message-Id: <20221114210723.2749751-11-irogers@google.com> Mime-Version: 1.0 References: <20221114210723.2749751-1-irogers@google.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog Subject: [PATCH v3 10/10] perf list: Add json output option From: Ian Rogers To: Weilin Wang , Perry Taylor , Caleb Biggers , Leo Yan , Adrian Hunter , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Sandipan Das , Kajol Jain , Zhengjun Xing , Kan Liang , Ravi Bangoria , Xin Gao , Rob Herring , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749507740762648902?= X-GMAIL-MSGID: =?utf-8?q?1749507740762648902?= Output events and metrics in a json format by overriding the print callbacks. Currently other command line options aren't supported and metrics are repeated once per metric group. Signed-off-by: Ian Rogers --- tools/perf/Documentation/perf-list.txt | 4 + tools/perf/builtin-list.c | 294 ++++++++++++++++++++----- 2 files changed, 240 insertions(+), 58 deletions(-) diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt index 44a819af573d..43263ca88ff7 100644 --- a/tools/perf/Documentation/perf-list.txt +++ b/tools/perf/Documentation/perf-list.txt @@ -43,6 +43,10 @@ Print deprecated events. By default the deprecated events are hidden. Print PMU events and metrics limited to the specific PMU name. (e.g. --unit cpu, --unit msr, --unit cpu_core, --unit cpu_atom) +-j:: +--json:: +Output in json format. + [[EVENT_MODIFIERS]] EVENT MODIFIERS --------------- diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 12811fc40a30..aec139f7fbb2 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -19,6 +19,7 @@ #include "util/strlist.h" #include #include +#include #include /** @@ -228,10 +229,176 @@ static void default_print_metric(void *ps, } } +struct json_print_state { + /** Should a separator be printed prior to the next item? */ + bool need_sep; +}; + +static void json_print_start(void *print_state __maybe_unused) +{ + printf("[\n"); +} + +static void json_print_end(void *ps) +{ + struct json_print_state *print_state = ps; + + printf("%s]\n", print_state->need_sep ? "\n" : ""); +} + +static void fix_escape_printf(const char *fmt, ...) +{ + va_list args; + char buf[2048]; + size_t buf_pos = 0; + + va_start(args, fmt); + for (size_t fmt_pos = 0; fmt_pos < strlen(fmt); fmt_pos++) { + switch (fmt[fmt_pos]) { + case '%': { + const char *s = va_arg(args, const char*); + + fmt_pos++; + assert(fmt[fmt_pos] == 's'); + for (size_t s_pos = 0; s_pos < strlen(s); s_pos++) { + switch (s[s_pos]) { + case '\\': + __fallthrough; + case '\"': + buf[buf_pos++] = '\\'; + assert(buf_pos < sizeof(buf)); + __fallthrough; + default: + buf[buf_pos++] = s[s_pos]; + assert(buf_pos < sizeof(buf)); + break; + } + } + break; + } + default: + buf[buf_pos++] = fmt[fmt_pos]; + assert(buf_pos < sizeof(buf)); + break; + } + } + va_end(args); + buf[buf_pos] = '\0'; + fputs(buf, stdout); +} + +static void json_print_event(void *ps, const char *pmu_name, const char *topic, + const char *event_name, const char *event_alias, + const char *scale_unit, + bool deprecated, const char *event_type_desc, + const char *desc, const char *long_desc, + const char *encoding_desc, + const char *metric_name, const char *metric_expr) +{ + struct json_print_state *print_state = ps; + bool need_sep = false; + + printf("%s{\n", print_state->need_sep ? ",\n" : ""); + print_state->need_sep = true; + if (pmu_name) { + fix_escape_printf("\t\"Unit\": \"%s\"", pmu_name); + need_sep = true; + } + if (topic) { + fix_escape_printf("%s\t\"Topic\": \"%s\"", need_sep ? ",\n" : "", topic); + need_sep = true; + } + if (event_name) { + fix_escape_printf("%s\t\"EventName\": \"%s\"", need_sep ? ",\n" : "", event_name); + need_sep = true; + } + if (event_alias && strlen(event_alias)) { + fix_escape_printf("%s\t\"EventAlias\": \"%s\"", need_sep ? ",\n" : "", event_alias); + need_sep = true; + } + if (scale_unit && strlen(scale_unit)) { + fix_escape_printf("%s\t\"ScaleUnit\": \"%s\"", need_sep ? ",\n" : "", + scale_unit); + need_sep = true; + } + if (event_type_desc) { + fix_escape_printf("%s\t\"EventType\": \"%s\"", need_sep ? ",\n" : "", + event_type_desc); + need_sep = true; + } + if (deprecated) { + fix_escape_printf("%s\t\"Deprecated\": \"%s\"", need_sep ? ",\n" : "", + deprecated ? "1" : "0"); + need_sep = true; + } + if (desc) { + fix_escape_printf("%s\t\"BriefDescription\": \"%s\"", need_sep ? ",\n" : "", desc); + need_sep = true; + } + if (long_desc) { + fix_escape_printf("%s\t\"PublicDescription\": \"%s\"", need_sep ? ",\n" : "", + long_desc); + need_sep = true; + } + if (encoding_desc) { + fix_escape_printf("%s\t\"Encoding\": \"%s\"", need_sep ? ",\n" : "", encoding_desc); + need_sep = true; + } + if (metric_name) { + fix_escape_printf("%s\t\"MetricName\": \"%s\"", need_sep ? ",\n" : "", metric_name); + need_sep = true; + } + if (metric_expr) { + fix_escape_printf("%s\t\"MetricExpr\": \"%s\"", need_sep ? ",\n" : "", metric_expr); + need_sep = true; + } + printf("%s}", need_sep ? "\n" : ""); +} + +static void json_print_metric(void *ps __maybe_unused, const char *group, + const char *name, const char *desc, + const char *long_desc, const char *expr, + const char *unit) +{ + struct json_print_state *print_state = ps; + bool need_sep = false; + + printf("%s{\n", print_state->need_sep ? ",\n" : ""); + print_state->need_sep = true; + if (group) { + fix_escape_printf("\t\"MetricGroup\": \"%s\"", group); + need_sep = true; + } + if (name) { + fix_escape_printf("%s\t\"MetricName\": \"%s\"", need_sep ? ",\n" : "", name); + need_sep = true; + } + if (expr) { + fix_escape_printf("%s\t\"MetricExpr\": \"%s\"", need_sep ? ",\n" : "", expr); + need_sep = true; + } + if (unit) { + fix_escape_printf("%s\t\"ScaleUnit\": \"%s\"", need_sep ? ",\n" : "", unit); + need_sep = true; + } + if (desc) { + fix_escape_printf("%s\t\"BriefDescription\": \"%s\"", need_sep ? ",\n" : "", desc); + need_sep = true; + } + if (long_desc) { + fix_escape_printf("%s\t\"PublicDescription\": \"%s\"", need_sep ? ",\n" : "", + long_desc); + need_sep = true; + } + printf("%s}", need_sep ? "\n" : ""); +} + int cmd_list(int argc, const char **argv) { int i, ret = 0; - struct print_state ps = {}; + struct print_state default_ps = {}; + struct print_state json_ps = {}; + void *ps = &default_ps; struct print_callbacks print_cb = { .print_start = default_print_start, .print_end = default_print_end, @@ -240,15 +407,17 @@ int cmd_list(int argc, const char **argv) }; const char *hybrid_name = NULL; const char *unit_name = NULL; + bool json = false; struct option list_options[] = { - OPT_BOOLEAN(0, "raw-dump", &ps.name_only, "Dump raw events"), - OPT_BOOLEAN('d', "desc", &ps.desc, + OPT_BOOLEAN(0, "raw-dump", &default_ps.name_only, "Dump raw events"), + OPT_BOOLEAN('j', "json", &json, "JSON encode events and metrics"), + OPT_BOOLEAN('d', "desc", &default_ps.desc, "Print extra event descriptions. --no-desc to not print."), - OPT_BOOLEAN('v', "long-desc", &ps.long_desc, + OPT_BOOLEAN('v', "long-desc", &default_ps.long_desc, "Print longer event descriptions."), - OPT_BOOLEAN(0, "details", &ps.detailed, + OPT_BOOLEAN(0, "details", &default_ps.detailed, "Print information on the perf event names and expressions used internally by events."), - OPT_BOOLEAN(0, "deprecated", &ps.deprecated, + OPT_BOOLEAN(0, "deprecated", &default_ps.deprecated, "Print deprecated events."), OPT_STRING(0, "cputype", &hybrid_name, "hybrid cpu type", "Limit PMU or metric printing to the given hybrid PMU (e.g. core or atom)."), @@ -272,28 +441,37 @@ int cmd_list(int argc, const char **argv) setup_pager(); - if (!ps.name_only) + if (!default_ps.name_only) setup_pager(); - ps.desc = !ps.long_desc; - ps.last_topic = strdup(""); - assert(ps.last_topic); - ps.visited_metrics = strlist__new(NULL, NULL); - assert(ps.visited_metrics); - if (unit_name) - ps.pmu_glob = strdup(unit_name); - else if (hybrid_name) { - ps.pmu_glob = perf_pmu__hybrid_type_to_pmu(hybrid_name); - if (!ps.pmu_glob) - pr_warning("WARNING: hybrid cputype is not supported!\n"); + if (json) { + print_cb = (struct print_callbacks){ + .print_start = json_print_start, + .print_end = json_print_end, + .print_event = json_print_event, + .print_metric = json_print_metric, + }; + ps = &json_ps; + } else { + default_ps.desc = !default_ps.long_desc; + default_ps.last_topic = strdup(""); + assert(default_ps.last_topic); + default_ps.visited_metrics = strlist__new(NULL, NULL); + assert(default_ps.visited_metrics); + if (unit_name) + default_ps.pmu_glob = strdup(unit_name); + else if (hybrid_name) { + default_ps.pmu_glob = perf_pmu__hybrid_type_to_pmu(hybrid_name); + if (!default_ps.pmu_glob) + pr_warning("WARNING: hybrid cputype is not supported!\n"); + } } - print_cb.print_start(&ps); if (argc == 0) { - ps.metrics = true; - ps.metricgroups = true; - print_events(&print_cb, &ps); + default_ps.metrics = true; + default_ps.metricgroups = true; + print_events(&print_cb, ps); goto out; } @@ -301,32 +479,32 @@ int cmd_list(int argc, const char **argv) char *sep, *s; if (strcmp(argv[i], "tracepoint") == 0) - print_tracepoint_events(&print_cb, &ps); + print_tracepoint_events(&print_cb, ps); else if (strcmp(argv[i], "hw") == 0 || strcmp(argv[i], "hardware") == 0) - print_symbol_events(&print_cb, &ps, PERF_TYPE_HARDWARE, + print_symbol_events(&print_cb, ps, PERF_TYPE_HARDWARE, event_symbols_hw, PERF_COUNT_HW_MAX); else if (strcmp(argv[i], "sw") == 0 || strcmp(argv[i], "software") == 0) { - print_symbol_events(&print_cb, &ps, PERF_TYPE_SOFTWARE, + print_symbol_events(&print_cb, ps, PERF_TYPE_SOFTWARE, event_symbols_sw, PERF_COUNT_SW_MAX); - print_tool_events(&print_cb, &ps); + print_tool_events(&print_cb, ps); } else if (strcmp(argv[i], "cache") == 0 || strcmp(argv[i], "hwcache") == 0) - print_hwcache_events(&print_cb, &ps); + print_hwcache_events(&print_cb, ps); else if (strcmp(argv[i], "pmu") == 0) - print_pmu_events(&print_cb, &ps); + print_pmu_events(&print_cb, ps); else if (strcmp(argv[i], "sdt") == 0) - print_sdt_events(&print_cb, &ps); + print_sdt_events(&print_cb, ps); else if (strcmp(argv[i], "metric") == 0 || strcmp(argv[i], "metrics") == 0) { - ps.metricgroups = false; - ps.metrics = true; - metricgroup__print(&print_cb, &ps); + default_ps.metricgroups = false; + default_ps.metrics = true; + metricgroup__print(&print_cb, ps); } else if (strcmp(argv[i], "metricgroup") == 0 || strcmp(argv[i], "metricgroups") == 0) { - ps.metricgroups = true; - ps.metrics = false; - metricgroup__print(&print_cb, &ps); + default_ps.metricgroups = true; + default_ps.metrics = false; + metricgroup__print(&print_cb, ps); } else if ((sep = strchr(argv[i], ':')) != NULL) { int sep_idx; @@ -338,41 +516,41 @@ int cmd_list(int argc, const char **argv) } s[sep_idx] = '\0'; - ps.pmu_glob = s; - ps.event_glob = s + sep_idx + 1; - print_tracepoint_events(&print_cb, &ps); - print_sdt_events(&print_cb, &ps); - ps.metrics = true; - ps.metricgroups = true; - metricgroup__print(&print_cb, &ps); + default_ps.pmu_glob = s; + default_ps.event_glob = s + sep_idx + 1; + print_tracepoint_events(&print_cb, ps); + print_sdt_events(&print_cb, ps); + default_ps.metrics = true; + default_ps.metricgroups = true; + metricgroup__print(&print_cb, ps); free(s); } else { if (asprintf(&s, "*%s*", argv[i]) < 0) { printf("Critical: Not enough memory! Trying to continue...\n"); continue; } - ps.event_glob = s; - print_symbol_events(&print_cb, &ps, PERF_TYPE_HARDWARE, + default_ps.event_glob = s; + print_symbol_events(&print_cb, ps, PERF_TYPE_HARDWARE, event_symbols_hw, PERF_COUNT_HW_MAX); - print_symbol_events(&print_cb, &ps, PERF_TYPE_SOFTWARE, + print_symbol_events(&print_cb, ps, PERF_TYPE_SOFTWARE, event_symbols_sw, PERF_COUNT_SW_MAX); - print_tool_events(&print_cb, &ps); - print_hwcache_events(&print_cb, &ps); - print_pmu_events(&print_cb, &ps); - print_tracepoint_events(&print_cb, &ps); - print_sdt_events(&print_cb, &ps); - ps.metrics = true; - ps.metricgroups = true; - metricgroup__print(&print_cb, &ps); + print_tool_events(&print_cb, ps); + print_hwcache_events(&print_cb, ps); + print_pmu_events(&print_cb, ps); + print_tracepoint_events(&print_cb, ps); + print_sdt_events(&print_cb, ps); + default_ps.metrics = true; + default_ps.metricgroups = true; + metricgroup__print(&print_cb, ps); free(s); } } out: - print_cb.print_end(&ps); - free(ps.pmu_glob); - free(ps.last_topic); - free(ps.last_metricgroups); - strlist__delete(ps.visited_metrics); + print_cb.print_end(ps); + free(default_ps.pmu_glob); + free(default_ps.last_topic); + free(default_ps.last_metricgroups); + strlist__delete(default_ps.visited_metrics); return ret; }