From patchwork Thu Apr 30 14:24:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1280453 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=Uk/IVd7J; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49Cd1s6H7Tz9sVW for ; Fri, 1 May 2020 00:24:49 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728139AbgD3OY2 (ORCPT ); Thu, 30 Apr 2020 10:24:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59926 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728068AbgD3OYZ (ORCPT ); Thu, 30 Apr 2020 10:24:25 -0400 Received: from mail-qk1-x74a.google.com (mail-qk1-x74a.google.com [IPv6:2607:f8b0:4864:20::74a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 57CF3C08E934 for ; Thu, 30 Apr 2020 07:24:25 -0700 (PDT) Received: by mail-qk1-x74a.google.com with SMTP id d13so6590672qke.19 for ; Thu, 30 Apr 2020 07:24:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=i/C9Y5GBkF2sbab6q3+mjJTMGZ+JZWwA9+KZOitr3OM=; b=Uk/IVd7JCTjsWFv97jNMCas7BQBBx5POqcL+MxXjSs5PP1g4haTpXWRTtc5NKn2VdK aH5+k3jgElDkEGJcADkiJoy9vdCrRaMX+doMcVWpGMhs8/nxBmGVjoMJyYNAyPz/gTDA hcK542kKVi9f9ClzNsDbt7RwxBYaqrNXTJDLTebYmKCSV+WNszePKqWkzSY6m8+gdgRm wEgWlLmvu19YH9iLb/hqElh/hvLkOby8gWxh9ABfOMqT8SaHGDGrASxql0wYLc/tfnJf KglE1rU7Y2A7vasVj+Qu+t7HYwG42FTTT2CTSEUHBJWdWrm4GATf9BSVkjpvaGI38IIw 4vyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=i/C9Y5GBkF2sbab6q3+mjJTMGZ+JZWwA9+KZOitr3OM=; b=r3enrPlm3sOYXZaN9Pjp8+in58vMLX/1YrdUBlz3xkObfDSjTSv8OD2RMT5AZ7Eny2 5nNkHtxPOjr0/hP2DuqAyZrLFEYgwDv2DFe+cvcefetqO4DD5iCmFoZMQ06Vkj3H8dPo Euime11qN/YRuPDSz46RBX4vwBp7K5pHfPWUxrnuhjpxbgyeABzdhcacH/Zfyzu/7YvW 726oB4tceFsLuLdUH6lf3tWiglw2uMypLTeVaM5zZBGRsxvMjN31X7xeg7Ltx+G4Y86Z 76AAV26c8eyzF24koCkNvwIoVle/BCRuMukZR7lHgCu+Q1dY201aeabafH/+yTGhFIo/ LnZw== X-Gm-Message-State: AGi0PuYqrLM+p96hJAR86fTJ5g8ZE66rG5VZTVfUS89IOF75qY93JRaW js+lMPe0vB2+Vr6m545ckPRfdetMOiPF X-Google-Smtp-Source: APiQypKP1zBW8q2AAwdPS9E/7mblPhFugkRftNjhh+3oJHyi895hdKUfL/Si2nyV7ycNpADdY3f8KYvSloaL X-Received: by 2002:a0c:a8e5:: with SMTP id h37mr3258473qvc.69.1588256664346; Thu, 30 Apr 2020 07:24:24 -0700 (PDT) Date: Thu, 30 Apr 2020 07:24:16 -0700 In-Reply-To: <20200430142419.252180-1-irogers@google.com> Message-Id: <20200430142419.252180-2-irogers@google.com> Mime-Version: 1.0 References: <20200430142419.252180-1-irogers@google.com> X-Mailer: git-send-email 2.26.2.303.gf8c07b1a785-goog Subject: [PATCH v13 1/4] perf doc: pass ASCIIDOC_EXTRA as an argument From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Yonghong Song , Andrii Nakryiko , Greg Kroah-Hartman , Thomas Gleixner , Igor Lubashev , Alexey Budankov , Florian Fainelli , Adrian Hunter , Andi Kleen , Jiwei Sun , yuzhoujian , Kan Liang , Jin Yao , Leo Yan , John Garry , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org commit e9cfa47e687d ("perf doc: allow ASCIIDOC_EXTRA to be an argument") allowed ASCIIDOC_EXTRA to be passed as an option to the Documentation Makefile. This change passes ASCIIDOC_EXTRA, set by detected features or command line options, prior to doing a Documentation build. This is necessary to allow conditional compilation, based on configuration variables, in asciidoc code. Signed-off-by: Ian Rogers --- tools/perf/Makefile.perf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index d15a311408f1..94a495594e99 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -188,7 +188,7 @@ AWK = awk # non-config cases config := 1 -NON_CONFIG_TARGETS := clean python-clean TAGS tags cscope help install-doc install-man install-html install-info install-pdf doc man html info pdf +NON_CONFIG_TARGETS := clean python-clean TAGS tags cscope help ifdef MAKECMDGOALS ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),) @@ -832,7 +832,7 @@ INSTALL_DOC_TARGETS += quick-install-doc quick-install-man quick-install-html # 'make doc' should call 'make -C Documentation all' $(DOC_TARGETS): - $(Q)$(MAKE) -C $(DOC_DIR) O=$(OUTPUT) $(@:doc=all) + $(Q)$(MAKE) -C $(DOC_DIR) O=$(OUTPUT) $(@:doc=all) ASCIIDOC_EXTRA=$(ASCIIDOC_EXTRA) TAG_FOLDERS= . ../lib ../include TAG_FILES= ../../include/uapi/linux/perf_event.h @@ -959,7 +959,7 @@ install-python_ext: # 'make install-doc' should call 'make -C Documentation install' $(INSTALL_DOC_TARGETS): - $(Q)$(MAKE) -C $(DOC_DIR) O=$(OUTPUT) $(@:-doc=) + $(Q)$(MAKE) -C $(DOC_DIR) O=$(OUTPUT) $(@:-doc=) ASCIIDOC_EXTRA=$(ASCIIDOC_EXTRA) ### Cleaning rules From patchwork Thu Apr 30 14:24:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1280454 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=KXWVO5D3; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49Cd200Cghz9sV2 for ; Fri, 1 May 2020 00:24:56 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728309AbgD3OYv (ORCPT ); Thu, 30 Apr 2020 10:24:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59942 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728095AbgD3OY1 (ORCPT ); Thu, 30 Apr 2020 10:24:27 -0400 Received: from mail-qk1-x74a.google.com (mail-qk1-x74a.google.com [IPv6:2607:f8b0:4864:20::74a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 64248C08E934 for ; Thu, 30 Apr 2020 07:24:27 -0700 (PDT) Received: by mail-qk1-x74a.google.com with SMTP id v6so6621421qkd.9 for ; Thu, 30 Apr 2020 07:24:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=eiWqfc49ogrYbZ/4/xuGkLOd4BeleFiuwlczI7sArlo=; b=KXWVO5D3T7Fomi7k+CxkMwTCRn/Gm7qkS3cSTZgrk+kGvtu1xoviEaLbD0Ok51qIQT +K4bHuqIx+5Kk+213YFGQwJ+Kbc4UHVZKhR/Ha5p14s0NafCwnlyN4rad0O6WhgXCocK YoZwxqxyoqERo2uQjbtswlTvdAvG/G8KXRNYcrs/MnatY9lQ3P7L4q4tgrk2suGCIj2v Mk7rUxhqzS42uvRRIZUxTr8F4KDECyHDS0s483Ls1deEvTMNB8nZGDyrMECHMbrKieLS y2xv/taGYsuvY+hN0tMVqkpbh69h1T+ylpvlQA5UoxPDLT1GtGNn9eRSe0OX/LQnefUx 4zKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=eiWqfc49ogrYbZ/4/xuGkLOd4BeleFiuwlczI7sArlo=; b=GVCNYjfpGNu7l/bSAPXxzjSKfLUd5bWzX2bOR+o6NcnxYXYA8feTQbux5avsg4Uh3F O03Tll6oNYExXc0esduVyu8ignO9PdUpdILvA6t9U26SE1mTHiKegh3OhzjZjjWpSdAA u9+LLzf6ri2HfNrtiuF+BMDXDp1mRP4/BknPTkCSbRR9/wGCtn2tEZVb3Kpisr/ZYjbX vDlkrUWALcYp17vOYk9WsOmurgIKG5hYC0hLpZ7G7nPCu321cptwe51X+po3SCMBRDoV /anfSasYwjLYxGPnVXhGACKkIElBq9OwqDCTaKaS13dalAHpS4AiBhEp+mLyST04U41/ nOMw== X-Gm-Message-State: AGi0PuZFTXNdVqORGHEBgIAnovPgLqdbLbhgn9k8znBWuE0fyQGCTbZa htE84agVyGL7/FlzsOWOKe1vZ5q6+AC5 X-Google-Smtp-Source: APiQypJbyuOjdXxvUcI406eMztVyGKYyj6BDRAqVBS2mQxU0HaWiDh+IEUfbY7Ffn3DVN1Ok4X1CvrJwBQEY X-Received: by 2002:a0c:a692:: with SMTP id t18mr3256841qva.56.1588256666426; Thu, 30 Apr 2020 07:24:26 -0700 (PDT) Date: Thu, 30 Apr 2020 07:24:17 -0700 In-Reply-To: <20200430142419.252180-1-irogers@google.com> Message-Id: <20200430142419.252180-3-irogers@google.com> Mime-Version: 1.0 References: <20200430142419.252180-1-irogers@google.com> X-Mailer: git-send-email 2.26.2.303.gf8c07b1a785-goog Subject: [PATCH v13 2/4] tools feature: add support for detecting libpfm4 From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Yonghong Song , Andrii Nakryiko , Greg Kroah-Hartman , Thomas Gleixner , Igor Lubashev , Alexey Budankov , Florian Fainelli , Adrian Hunter , Andi Kleen , Jiwei Sun , yuzhoujian , Kan Liang , Jin Yao , Leo Yan , John Garry , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Stephane Eranian libpfm4 provides an alternate command line encoding of perf events. Signed-off-by: Stephane Eranian Reviewed-by: Ian Rogers --- tools/build/Makefile.feature | 3 ++- tools/build/feature/Makefile | 6 +++++- tools/build/feature/test-libpfm4.c | 9 +++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 tools/build/feature/test-libpfm4.c diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature index 3e0c019ef297..3abd4316cd4f 100644 --- a/tools/build/Makefile.feature +++ b/tools/build/Makefile.feature @@ -98,7 +98,8 @@ FEATURE_TESTS_EXTRA := \ llvm \ llvm-version \ clang \ - libbpf + libbpf \ + libpfm4 FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC) diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile index 92012381393a..84f845b9627d 100644 --- a/tools/build/feature/Makefile +++ b/tools/build/feature/Makefile @@ -69,7 +69,8 @@ FILES= \ test-libaio.bin \ test-libzstd.bin \ test-clang-bpf-global-var.bin \ - test-file-handle.bin + test-file-handle.bin \ + test-libpfm4.bin FILES := $(addprefix $(OUTPUT),$(FILES)) @@ -331,6 +332,9 @@ $(OUTPUT)test-clang-bpf-global-var.bin: $(OUTPUT)test-file-handle.bin: $(BUILD) +$(OUTPUT)test-libpfm4.bin: + $(BUILD) -lpfm + ############################### clean: diff --git a/tools/build/feature/test-libpfm4.c b/tools/build/feature/test-libpfm4.c new file mode 100644 index 000000000000..af49b259459e --- /dev/null +++ b/tools/build/feature/test-libpfm4.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + +int main(void) +{ + pfm_initialize(); + return 0; +} From patchwork Thu Apr 30 14:24:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1280450 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=nTwgcui2; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49Cd1f5G9Hz9sVJ for ; Fri, 1 May 2020 00:24:38 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728124AbgD3OYd (ORCPT ); Thu, 30 Apr 2020 10:24:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59948 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728083AbgD3OY3 (ORCPT ); Thu, 30 Apr 2020 10:24:29 -0400 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 2C323C035494 for ; Thu, 30 Apr 2020 07:24:29 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id l187so7877623ybf.17 for ; Thu, 30 Apr 2020 07:24:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=DpLe2/yxlpy0aFc7LjjFR8EhmIvjlgt7hqTB0OaUzqw=; b=nTwgcui2CiV0+/Jpql/konVUDAJxIwSvypifzKGqEa5N2zt4MIbFjb1mAn7/qwLihf vu0iHY6F0lUJ/lpzYGDHglar1oftRe5QKFNt+SxbDedcCmm3YwssWXQMsdKVrr1yW/L0 hbh2CMDDfsfgS8wpd1ItOELZ2zX2gZZfj9jv7hfUNZD/Cc3RQHB8NT+5HAVgLV5wmXhh KUN8zSWgRRWlB4hEaPTS+sqCnIBgbPDRp47GrFog6FH1+9HvnApAy15WlVS+opecoFkk JN0c9NKlKH12GdzFIkaOkli7Zj9XnFSyHT2bAMW34rF9aCYVPepdqiv+fA60MYvdLQ0C bpWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=DpLe2/yxlpy0aFc7LjjFR8EhmIvjlgt7hqTB0OaUzqw=; b=bIeu4JkvBPw5DF+ov7dJp4RmwK++0etkwiuMBA4yo4VozUqLLAFP+WyHLqxtMmBKKv bnEUErkeEhVflhcziOHtpxdlQywoZDGA2Yvoqnv+E5TPCscmQUkqmyh98z99IYyaA0N2 mr9+ZZNf4Pgr44JXIIy277odlw2sjGKlgGrh6Bj3SyOtxBrk/PvhcgUaieKHL8d7vrOo +1BJIi8QLFtBblaSgglGU4akW2sWqK3EP+ytxt6IcTuaXz+G/74TT8aVzj/jy3bZtW/F XHBgsuenZcwrJbGKdcfsGGZ2X2o5EWR1Rtmvu1hbNDBMm7SRBIKui1bRoQU9PK3M/ZiO TVBA== X-Gm-Message-State: AGi0PuZFP33HHtuCBgXrDRO09PgOr4A67hMg9L0VaWjrM9TXz/XOipMj qA/P12PdlcQorkhVIxQIuD4WOqJc6EPG X-Google-Smtp-Source: APiQypLSBWwmxXdbCXvEwu6BQZ0SdYLx5+Wv2iv/ATKlzHHRCUjvZTfhpTl6ZunjIVWUzi0myR4aFnFZeter X-Received: by 2002:a25:9306:: with SMTP id f6mr5949447ybo.375.1588256668309; Thu, 30 Apr 2020 07:24:28 -0700 (PDT) Date: Thu, 30 Apr 2020 07:24:18 -0700 In-Reply-To: <20200430142419.252180-1-irogers@google.com> Message-Id: <20200430142419.252180-4-irogers@google.com> Mime-Version: 1.0 References: <20200430142419.252180-1-irogers@google.com> X-Mailer: git-send-email 2.26.2.303.gf8c07b1a785-goog Subject: [PATCH v13 3/4] perf pmu: add perf_pmu__find_by_type helper From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Yonghong Song , Andrii Nakryiko , Greg Kroah-Hartman , Thomas Gleixner , Igor Lubashev , Alexey Budankov , Florian Fainelli , Adrian Hunter , Andi Kleen , Jiwei Sun , yuzhoujian , Kan Liang , Jin Yao , Leo Yan , John Garry , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Stephane Eranian This is used by libpfm4 during event parsing to locate the pmu for an event. Signed-off-by: Stephane Eranian Reviewed-by: Ian Rogers --- tools/perf/util/pmu.c | 11 +++++++++++ tools/perf/util/pmu.h | 1 + 2 files changed, 12 insertions(+) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 5642de7f8be7..92bd7fafcce6 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -871,6 +871,17 @@ static struct perf_pmu *pmu_find(const char *name) return NULL; } +struct perf_pmu *perf_pmu__find_by_type(unsigned int type) +{ + struct perf_pmu *pmu; + + list_for_each_entry(pmu, &pmus, list) + if (pmu->type == type) + return pmu; + + return NULL; +} + struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu) { /* diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 1edd214b75a5..cb6fbec50313 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -72,6 +72,7 @@ struct perf_pmu_alias { }; struct perf_pmu *perf_pmu__find(const char *name); +struct perf_pmu *perf_pmu__find_by_type(unsigned int type); int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, struct list_head *head_terms, struct parse_events_error *error); From patchwork Thu Apr 30 14:24:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1280449 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20161025 header.b=CdvHYMeJ; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49Cd1d59lrz9sV2 for ; Fri, 1 May 2020 00:24:37 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728083AbgD3OYg (ORCPT ); Thu, 30 Apr 2020 10:24:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59948 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728141AbgD3OYc (ORCPT ); Thu, 30 Apr 2020 10:24:32 -0400 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 0CCF0C035494 for ; Thu, 30 Apr 2020 07:24:31 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id e17so1522827ybr.21 for ; Thu, 30 Apr 2020 07:24:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=EZQbTgQANg3jy/6THJCQgGh2wwfxfukeJ913Mr3R1EI=; b=CdvHYMeJNYo7X8tPvnUZJnX0YdiyYy9ZOJQxEAj3hzC7RY5sC2HBvfAGq7EGrrhjkO VVQQjc6/XDrBb7QHIxBqU2eacB2pvsDqIidNkAF3iT2aTfsZ//S9x8euZjsO0f+pMy7J Cl0us7Xd5GgN7QEh9+4Ba+4c7iBB47thzsEpblS8ACImvxW9S0wwIzTspDQZDqTaWMm5 lSV6bgXBC3Pc8ioqW7iAd4RTrr5EVfvPeyodxv1MvNk/AhOpPhDaG6FhYpregvvVMjbw odVpA+FeV/vsmTDjfckTJFY0totDMd4JCfZJsirNTEfFG8j6ZrZivc8MMeiQGZglN3qa HRGA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=EZQbTgQANg3jy/6THJCQgGh2wwfxfukeJ913Mr3R1EI=; b=gSTa4nz9O1Z81z0PhrTZf+c6o8reFJlZJxlXkbhIDqyaZEr1Qh+QsOA37mbPkdnxzC hAzs0M2N3dbCTVcmtSoLBTkTq9n2YDZcXDIwJ2gUcKwzLnMcwKF9MprLZEIL7w4jkoJh 4ZRJFlw3oAxhn3Q/ez/w70J8uPG01MlguAQ06gbJIJQpBjuIoTmh+mV8oqd43WlABMy4 5YfnA0cWHBLrjOF/ATPQVsasa02imI4J+M7WyepDsz6H5dlJN88budUsjLpARrZTcx2G F3+LEFgb7LLMOAGDlgb8pe0UjQl9vRMZtXiYM5s/yAgAEA3FGiO2q+qk1jYM5K+H8GJR x1Rw== X-Gm-Message-State: AGi0PuYX4gNy5Xgn1jrXOuDlcOL2R5uQHIDt1Lo2j2x7L/9LTo4FE2qP feAKkexg013sD4614JFFeso9kziik6cG X-Google-Smtp-Source: APiQypI7r/gNRQSd7VK3fMe0dn9OVbOPBIFSljrMVG15p4WwXrJcURVSL/qdt7Zg4M9B1sDbn2fP9VeVVI3t X-Received: by 2002:a25:787:: with SMTP id 129mr6097545ybh.359.1588256670199; Thu, 30 Apr 2020 07:24:30 -0700 (PDT) Date: Thu, 30 Apr 2020 07:24:19 -0700 In-Reply-To: <20200430142419.252180-1-irogers@google.com> Message-Id: <20200430142419.252180-5-irogers@google.com> Mime-Version: 1.0 References: <20200430142419.252180-1-irogers@google.com> X-Mailer: git-send-email 2.26.2.303.gf8c07b1a785-goog Subject: [PATCH v13 4/4] perf tools: add support for libpfm4 From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Yonghong Song , Andrii Nakryiko , Greg Kroah-Hartman , Thomas Gleixner , Igor Lubashev , Alexey Budankov , Florian Fainelli , Adrian Hunter , Andi Kleen , Jiwei Sun , yuzhoujian , Kan Liang , Jin Yao , Leo Yan , John Garry , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org From: Stephane Eranian This patch links perf with the libpfm4 library if it is available and LIBPFM4 is passed to the build. The libpfm4 library contains hardware event tables for all processors supported by perf_events. It is a helper library that helps convert from a symbolic event name to the event encoding required by the underlying kernel interface. This library is open-source and available from: http://perfmon2.sf.net. With this patch, it is possible to specify full hardware events by name. Hardware filters are also supported. Events must be specified via the --pfm-events and not -e option. Both options are active at the same time and it is possible to mix and match: $ perf stat --pfm-events inst_retired:any_p:c=1:i -e cycles .... Signed-off-by: Stephane Eranian Reviewed-by: Ian Rogers --- tools/perf/Documentation/perf-record.txt | 11 + tools/perf/Documentation/perf-stat.txt | 10 + tools/perf/Documentation/perf-top.txt | 11 + tools/perf/Makefile.config | 13 ++ tools/perf/Makefile.perf | 2 + tools/perf/builtin-record.c | 6 + tools/perf/builtin-stat.c | 6 + tools/perf/builtin-top.c | 6 + tools/perf/tests/Build | 1 + tools/perf/tests/builtin-test.c | 9 + tools/perf/tests/pfm.c | 203 ++++++++++++++++ tools/perf/tests/tests.h | 3 + tools/perf/util/Build | 2 + tools/perf/util/evsel.c | 2 +- tools/perf/util/evsel.h | 1 + tools/perf/util/parse-events.c | 30 ++- tools/perf/util/parse-events.h | 4 + tools/perf/util/pfm.c | 281 +++++++++++++++++++++++ tools/perf/util/pfm.h | 37 +++ 19 files changed, 630 insertions(+), 8 deletions(-) create mode 100644 tools/perf/tests/pfm.c create mode 100644 tools/perf/util/pfm.c create mode 100644 tools/perf/util/pfm.h diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 561ef55743e2..492b6b6f2b77 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -613,6 +613,17 @@ appended unit character - B/K/M/G The number of threads to run when synthesizing events for existing processes. By default, the number of threads equals 1. +ifdef::HAVE_LIBPFM[] +--pfm-events events:: +Select a PMU event using libpfm4 syntax (see http://perfmon2.sf.net) +including support for event filters. For example '--pfm-events +inst_retired:any_p:u:c=1:i'. More than one event can be passed to the +option using the comma separator. Hardware events and generic hardware +events cannot be mixed together. The latter must be used with the -e +option. The -e option and this one can be mixed and matched. Events +can be grouped using the {} notation. +endif::HAVE_LIBPFM[] + SEE ALSO -------- linkperf:perf-stat[1], linkperf:perf-list[1], linkperf:perf-intel-pt[1] diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt index 3fb5028aef08..b69af18dccd0 100644 --- a/tools/perf/Documentation/perf-stat.txt +++ b/tools/perf/Documentation/perf-stat.txt @@ -71,6 +71,16 @@ report:: --tid=:: stat events on existing thread id (comma separated list) +ifdef::HAVE_LIBPFM[] +--pfm-events events:: +Select a PMU event using libpfm4 syntax (see http://perfmon2.sf.net) +including support for event filters. For example '--pfm-events +inst_retired:any_p:u:c=1:i'. More than one event can be passed to the +option using the comma separator. Hardware events and generic hardware +events cannot be mixed together. The latter must be used with the -e +option. The -e option and this one can be mixed and matched. Events +can be grouped using the {} notation. +endif::HAVE_LIBPFM[] -a:: --all-cpus:: diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt index 20227dabc208..ee2024691d46 100644 --- a/tools/perf/Documentation/perf-top.txt +++ b/tools/perf/Documentation/perf-top.txt @@ -329,6 +329,17 @@ Default is to monitor all CPUS. The known limitations include exception handing such as setjmp/longjmp will have calls/returns not match. +ifdef::HAVE_LIBPFM[] +--pfm-events events:: +Select a PMU event using libpfm4 syntax (see http://perfmon2.sf.net) +including support for event filters. For example '--pfm-events +inst_retired:any_p:u:c=1:i'. More than one event can be passed to the +option using the comma separator. Hardware events and generic hardware +events cannot be mixed together. The latter must be used with the -e +option. The -e option and this one can be mixed and matched. Events +can be grouped using the {} notation. +endif::HAVE_LIBPFM[] + INTERACTIVE PROMPTING KEYS -------------------------- diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 12a8204d63c6..b67804fee1e3 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -1012,6 +1012,19 @@ ifdef LIBCLANGLLVM endif endif +ifdef LIBPFM4 + $(call feature_check,libpfm4) + ifeq ($(feature-libpfm4), 1) + CFLAGS += -DHAVE_LIBPFM + EXTLIBS += -lpfm + ASCIIDOC_EXTRA = -aHAVE_LIBPFM=1 + $(call detected,CONFIG_LIBPFM4) + else + msg := $(warning libpfm4 not found, disables libpfm4 support. Please install libpfm4-dev); + NO_LIBPFM4 := 1 + endif +endif + # Among the variables below, these: # perfexecdir # perf_include_dir diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 94a495594e99..dc82578c8773 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -118,6 +118,8 @@ include ../scripts/utilities.mak # # Define LIBBPF_DYNAMIC to enable libbpf dynamic linking. # +# Define LIBPFM4 to enable libpfm4 events extension. +# # As per kernel Makefile, avoid funny character set dependencies unexport LC_ALL diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index ee20c2da5e91..828d7d6555e4 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -44,6 +44,7 @@ #include "util/units.h" #include "util/bpf-event.h" #include "util/util.h" +#include "util/pfm.h" #include "asm/bug.h" #include "perf.h" @@ -2506,6 +2507,11 @@ static struct option __record_options[] = { OPT_UINTEGER(0, "num-thread-synthesize", &record.opts.nr_threads_synthesize, "number of threads to run for event synthesis"), +#ifdef HAVE_LIBPFM + OPT_CALLBACK(0, "pfm-events", &record.evlist, "event", + "libpfm4 event selector. use 'perf list' to list available events", + parse_libpfm_events_option), +#endif OPT_END() }; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 6bc1336a0429..12dea169a9b4 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -66,6 +66,7 @@ #include "util/time-utils.h" #include "util/top.h" #include "util/affinity.h" +#include "util/pfm.h" #include "asm/bug.h" #include @@ -937,6 +938,11 @@ static struct option stat_options[] = { "Use with 'percore' event qualifier to show the event " "counts of one hardware thread by sum up total hardware " "threads of same physical core"), +#ifdef HAVE_LIBPFM + OPT_CALLBACK(0, "pfm-events", &evsel_list, "event", + "libpfm4 event selector. use 'perf list' to list available events", + parse_libpfm_events_option), +#endif OPT_END() }; diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 55edab99b05d..75265caa2ed0 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -53,6 +53,7 @@ #include "util/debug.h" #include "util/ordered-events.h" +#include "util/pfm.h" #include #include @@ -1577,6 +1578,11 @@ int cmd_top(int argc, const char **argv) "WARNING: should be used on grouped events."), OPT_BOOLEAN(0, "stitch-lbr", &top.stitch_lbr, "Enable LBR callgraph stitching approach"), +#ifdef HAVE_LIBPFM + OPT_CALLBACK(0, "pfm-events", &top.evlist, "event", + "libpfm4 event selector. use 'perf list' to list available events", + parse_libpfm_events_option), +#endif OPTS_EVSWITCH(&top.evswitch), OPT_END() }; diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index c75557aeef0e..4e74a363b0b0 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -57,6 +57,7 @@ perf-y += maps.o perf-y += time-utils-test.o perf-y += genelf.o perf-y += api-io.o +perf-y += pfm.o $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build $(call rule_mkdir) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 3471ec52ea11..57c6f8b31624 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -317,6 +317,15 @@ static struct test generic_tests[] = { .desc = "maps__merge_in", .func = test__maps__merge_in, }, + { + .desc = "Test libpfm4 support", + .func = test__pfm, + .subtest = { + .skip_if_fail = true, + .get_nr = test__pfm_subtest_get_nr, + .get_desc = test__pfm_subtest_get_desc, + } + }, { .func = NULL, }, diff --git a/tools/perf/tests/pfm.c b/tools/perf/tests/pfm.c new file mode 100644 index 000000000000..76a53126efdf --- /dev/null +++ b/tools/perf/tests/pfm.c @@ -0,0 +1,203 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test support for libpfm4 event encodings. + * + * Copyright 2020 Google LLC. + */ +#include "tests.h" +#include "util/debug.h" +#include "util/evlist.h" +#include "util/pfm.h" + +#include + +#ifdef HAVE_LIBPFM +static int test__pfm_events(void); +static int test__pfm_group(void); +#endif + +static const struct { + int (*func)(void); + const char *desc; +} pfm_testcase_table[] = { +#ifdef HAVE_LIBPFM + { + .func = test__pfm_events, + .desc = "test of individual --pfm-events", + }, + { + .func = test__pfm_group, + .desc = "test groups of --pfm-events", + }, +#endif +}; + +#ifdef HAVE_LIBPFM +static int count_pfm_events(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel; + int count = 0; + + perf_evlist__for_each_entry(evlist, evsel) { + count++; + } + return count; +} + +static int test__pfm_events(void) +{ + struct evlist *evlist; + struct option opt; + size_t i; + const struct { + const char *events; + int nr_events; + } table[] = { + { + .events = "", + .nr_events = 0, + }, + { + .events = "instructions", + .nr_events = 1, + }, + { + .events = "instructions,cycles", + .nr_events = 2, + }, + { + .events = "stereolab", + .nr_events = 0, + }, + { + .events = "instructions,instructions", + .nr_events = 2, + }, + { + .events = "stereolab,instructions", + .nr_events = 0, + }, + { + .events = "instructions,stereolab", + .nr_events = 1, + }, + }; + + for (i = 0; i < ARRAY_SIZE(table); i++) { + evlist = evlist__new(); + if (evlist == NULL) + return -ENOMEM; + + opt.value = evlist; + parse_libpfm_events_option(&opt, + table[i].events, + 0); + TEST_ASSERT_EQUAL(table[i].events, + count_pfm_events(&evlist->core), + table[i].nr_events); + TEST_ASSERT_EQUAL(table[i].events, + evlist->nr_groups, + 0); + + evlist__delete(evlist); + } + return 0; +} + +static int test__pfm_group(void) +{ + struct evlist *evlist; + struct option opt; + size_t i; + const struct { + const char *events; + int nr_events; + int nr_groups; + } table[] = { + { + .events = "{},", + .nr_events = 0, + .nr_groups = 0, + }, + { + .events = "{instructions}", + .nr_events = 1, + .nr_groups = 1, + }, + { + .events = "{instructions},{}", + .nr_events = 1, + .nr_groups = 1, + }, + { + .events = "{},{instructions}", + .nr_events = 0, + .nr_groups = 0, + }, + { + .events = "{instructions},{instructions}", + .nr_events = 2, + .nr_groups = 2, + }, + { + .events = "{instructions,cycles},{instructions,cycles}", + .nr_events = 4, + .nr_groups = 2, + }, + { + .events = "{stereolab}", + .nr_events = 0, + .nr_groups = 0, + }, + { + .events = + "{instructions,cycles},{instructions,stereolab}", + .nr_events = 3, + .nr_groups = 1, + }, + }; + + for (i = 0; i < ARRAY_SIZE(table); i++) { + evlist = evlist__new(); + if (evlist == NULL) + return -ENOMEM; + + opt.value = evlist; + parse_libpfm_events_option(&opt, + table[i].events, + 0); + TEST_ASSERT_EQUAL(table[i].events, + count_pfm_events(&evlist->core), + table[i].nr_events); + TEST_ASSERT_EQUAL(table[i].events, + evlist->nr_groups, + table[i].nr_groups); + + evlist__delete(evlist); + } + return 0; +} +#endif + +const char *test__pfm_subtest_get_desc(int i) +{ + if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table)) + return NULL; + return pfm_testcase_table[i].desc; +} + +int test__pfm_subtest_get_nr(void) +{ + return (int)ARRAY_SIZE(pfm_testcase_table); +} + +int test__pfm(struct test *test __maybe_unused, int i __maybe_unused) +{ +#ifdef HAVE_LIBPFM + if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table)) + return TEST_FAIL; + return pfm_testcase_table[i].func(); +#else + return TEST_SKIP; +#endif +} diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index d6d4ac34eeb7..a2ae0d2e6087 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -113,6 +113,9 @@ int test__maps__merge_in(struct test *t, int subtest); int test__time_utils(struct test *t, int subtest); int test__jit_write_elf(struct test *test, int subtest); int test__api_io(struct test *test, int subtest); +int test__pfm(struct test *test, int subtest); +const char *test__pfm_subtest_get_desc(int subtest); +int test__pfm_subtest_get_nr(void); bool test__bp_signal_is_supported(void); bool test__bp_account_is_supported(void); diff --git a/tools/perf/util/Build b/tools/perf/util/Build index c0cf8dff694e..afd3d2221c83 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -177,6 +177,8 @@ perf-$(CONFIG_LIBBPF) += bpf-event.o perf-$(CONFIG_CXX) += c++/ +perf-$(CONFIG_LIBPFM4) += pfm.o + CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" CFLAGS_llvm-utils.o += -DPERF_INCLUDE_DIR="BUILD_STR($(perf_include_dir_SQ))" diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index aedd554fb4bb..782461cf902d 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2422,7 +2422,7 @@ bool perf_evsel__fallback(struct evsel *evsel, int err, /* Is there already the separator in the name. */ if (strchr(name, '/') || - strchr(name, ':')) + (strchr(name, ':') && !evsel->is_libpfm_event)) sep = ""; if (asprintf(&new_name, "%s%su", name, sep) < 0) diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index d83f7007d6d7..8152f342ca2a 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -76,6 +76,7 @@ struct evsel { bool ignore_missing_thread; bool forced_leader; bool use_uncore_alias; + bool is_libpfm_event; /* parse modifier helper */ int exclude_GH; int sample_read; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 899ced466197..a663670bac1d 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -36,6 +36,7 @@ #include "metricgroup.h" #include "util/evsel_config.h" #include "util/event.h" +#include "util/pfm.h" #define MAX_NAME_LEN 100 @@ -344,6 +345,7 @@ static char *get_config_name(struct list_head *head_terms) static struct evsel * __add_event(struct list_head *list, int *idx, struct perf_event_attr *attr, + bool init_attr, char *name, struct perf_pmu *pmu, struct list_head *config_terms, bool auto_merge_stats, const char *cpu_list) @@ -352,7 +354,8 @@ __add_event(struct list_head *list, int *idx, struct perf_cpu_map *cpus = pmu ? pmu->cpus : cpu_list ? perf_cpu_map__new(cpu_list) : NULL; - event_attr_init(attr); + if (init_attr) + event_attr_init(attr); evsel = perf_evsel__new_idx(attr, *idx); if (!evsel) @@ -370,15 +373,25 @@ __add_event(struct list_head *list, int *idx, if (config_terms) list_splice(config_terms, &evsel->config_terms); - list_add_tail(&evsel->core.node, list); + if (list) + list_add_tail(&evsel->core.node, list); + return evsel; } +struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr, + char *name, struct perf_pmu *pmu) +{ + return __add_event(NULL, &idx, attr, false, name, pmu, NULL, false, + NULL); +} + static int add_event(struct list_head *list, int *idx, struct perf_event_attr *attr, char *name, struct list_head *config_terms) { - return __add_event(list, idx, attr, name, NULL, config_terms, false, NULL) ? 0 : -ENOMEM; + return __add_event(list, idx, attr, true, name, NULL, config_terms, + false, NULL) ? 0 : -ENOMEM; } static int add_event_tool(struct list_head *list, int *idx, @@ -390,7 +403,8 @@ static int add_event_tool(struct list_head *list, int *idx, .config = PERF_COUNT_SW_DUMMY, }; - evsel = __add_event(list, idx, &attr, NULL, NULL, NULL, false, "0"); + evsel = __add_event(list, idx, &attr, true, NULL, NULL, NULL, false, + "0"); if (!evsel) return -ENOMEM; evsel->tool_event = tool_event; @@ -1446,8 +1460,8 @@ int parse_events_add_pmu(struct parse_events_state *parse_state, if (!head_config) { attr.type = pmu->type; - evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu, NULL, - auto_merge_stats, NULL); + evsel = __add_event(list, &parse_state->idx, &attr, true, NULL, + pmu, NULL, auto_merge_stats, NULL); if (evsel) { evsel->pmu_name = name ? strdup(name) : NULL; evsel->use_uncore_alias = use_uncore_alias; @@ -1488,7 +1502,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state, return -EINVAL; } - evsel = __add_event(list, &parse_state->idx, &attr, + evsel = __add_event(list, &parse_state->idx, &attr, true, get_config_name(head_config), pmu, &config_terms, auto_merge_stats, NULL); if (evsel) { @@ -2817,6 +2831,8 @@ void print_events(const char *event_glob, bool name_only, bool quiet_flag, print_sdt_events(NULL, NULL, name_only); metricgroup__print(true, true, NULL, name_only, details_flag); + + print_libpfm_events(name_only, long_desc); } int parse_events__is_hardcoded_term(struct parse_events_term *term) diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 6ead9661238c..04e3f627c081 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -17,6 +17,7 @@ struct evlist; struct parse_events_error; struct option; +struct perf_pmu; struct tracepoint_path { char *system; @@ -187,6 +188,9 @@ int parse_events_add_pmu(struct parse_events_state *parse_state, bool auto_merge_stats, bool use_alias); +struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr, + char *name, struct perf_pmu *pmu); + int parse_events_multi_pmu_add(struct parse_events_state *parse_state, char *str, struct list_head **listp); diff --git a/tools/perf/util/pfm.c b/tools/perf/util/pfm.c new file mode 100644 index 000000000000..d735acb6c29c --- /dev/null +++ b/tools/perf/util/pfm.c @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Support for libpfm4 event encoding. + * + * Copyright 2020 Google LLC. + */ +#include "util/cpumap.h" +#include "util/debug.h" +#include "util/event.h" +#include "util/evlist.h" +#include "util/evsel.h" +#include "util/parse-events.h" +#include "util/pmu.h" +#include "util/pfm.h" + +#include +#include +#include + +static void libpfm_initialize(void) +{ + int ret; + + ret = pfm_initialize(); + if (ret != PFM_SUCCESS) { + ui__warning("libpfm failed to initialize: %s\n", + pfm_strerror(ret)); + } +} + +int parse_libpfm_events_option(const struct option *opt, const char *str, + int unset __maybe_unused) +{ + struct evlist *evlist = *(struct evlist **)opt->value; + struct perf_event_attr attr; + struct perf_pmu *pmu; + struct evsel *evsel, *grp_leader = NULL; + char *p, *q, *p_orig; + const char *sep; + int grp_evt = -1; + int ret; + + libpfm_initialize(); + + p_orig = p = strdup(str); + if (!p) + return -1; + /* + * force loading of the PMU list + */ + perf_pmu__scan(NULL); + + for (q = p; strsep(&p, ",{}"); q = p) { + sep = p ? str + (p - p_orig - 1) : ""; + if (*sep == '{') { + if (grp_evt > -1) { + ui__error( + "nested event groups not supported\n"); + goto error; + } + grp_evt++; + } + + /* no event */ + if (*q == '\0') + continue; + + memset(&attr, 0, sizeof(attr)); + event_attr_init(&attr); + + ret = pfm_get_perf_event_encoding(q, PFM_PLM0|PFM_PLM3, + &attr, NULL, NULL); + + if (ret != PFM_SUCCESS) { + ui__error("failed to parse event %s : %s\n", str, + pfm_strerror(ret)); + goto error; + } + + pmu = perf_pmu__find_by_type((unsigned int)attr.type); + evsel = parse_events__add_event(evlist->core.nr_entries, + &attr, q, pmu); + if (evsel == NULL) + goto error; + + evsel->is_libpfm_event = true; + + evlist__add(evlist, evsel); + + if (grp_evt == 0) + grp_leader = evsel; + + if (grp_evt > -1) { + evsel->leader = grp_leader; + grp_leader->core.nr_members++; + grp_evt++; + } + + if (*sep == '}') { + if (grp_evt < 0) { + ui__error( + "cannot close a non-existing event group\n"); + goto error; + } + evlist->nr_groups++; + grp_leader = NULL; + grp_evt = -1; + } + } + return 0; +error: + free(p_orig); + return -1; +} + +static const char *srcs[PFM_ATTR_CTRL_MAX] = { + [PFM_ATTR_CTRL_UNKNOWN] = "???", + [PFM_ATTR_CTRL_PMU] = "PMU", + [PFM_ATTR_CTRL_PERF_EVENT] = "perf_event", +}; + +static void +print_attr_flags(pfm_event_attr_info_t *info) +{ + int n = 0; + + if (info->is_dfl) { + printf("[default] "); + n++; + } + + if (info->is_precise) { + printf("[precise] "); + n++; + } + + if (!n) + printf("- "); +} + +static void +print_libpfm_events_detailed(pfm_event_info_t *info, bool long_desc) +{ + pfm_event_attr_info_t ainfo; + const char *src; + int j, ret; + + ainfo.size = sizeof(ainfo); + + printf(" %s\n", info->name); + printf(" [%s]\n", info->desc); + if (long_desc) { + if (info->equiv) + printf(" Equiv: %s\n", info->equiv); + + printf(" Code : 0x%"PRIx64"\n", info->code); + } + pfm_for_each_event_attr(j, info) { + ret = pfm_get_event_attr_info(info->idx, j, + PFM_OS_PERF_EVENT_EXT, &ainfo); + if (ret != PFM_SUCCESS) + continue; + + if (ainfo.type == PFM_ATTR_UMASK) { + printf(" %s:%s\n", info->name, ainfo.name); + printf(" [%s]\n", ainfo.desc); + } + + if (!long_desc) + continue; + + if (ainfo.ctrl >= PFM_ATTR_CTRL_MAX) + ainfo.ctrl = PFM_ATTR_CTRL_UNKNOWN; + + src = srcs[ainfo.ctrl]; + switch (ainfo.type) { + case PFM_ATTR_UMASK: + printf(" Umask : 0x%02"PRIx64" : %s: ", + ainfo.code, src); + print_attr_flags(&ainfo); + putchar('\n'); + break; + case PFM_ATTR_MOD_BOOL: + printf(" Modif : %s: [%s] : %s (boolean)\n", src, + ainfo.name, ainfo.desc); + break; + case PFM_ATTR_MOD_INTEGER: + printf(" Modif : %s: [%s] : %s (integer)\n", src, + ainfo.name, ainfo.desc); + break; + case PFM_ATTR_NONE: + case PFM_ATTR_RAW_UMASK: + case PFM_ATTR_MAX: + default: + printf(" Attr : %s: [%s] : %s\n", src, + ainfo.name, ainfo.desc); + } + } +} + +/* + * list all pmu::event:umask, pmu::event + * printed events may not be all valid combinations of umask for an event + */ +static void +print_libpfm_events_raw(pfm_pmu_info_t *pinfo, pfm_event_info_t *info) +{ + pfm_event_attr_info_t ainfo; + int j, ret; + bool has_umask = false; + + ainfo.size = sizeof(ainfo); + + pfm_for_each_event_attr(j, info) { + ret = pfm_get_event_attr_info(info->idx, j, + PFM_OS_PERF_EVENT_EXT, &ainfo); + if (ret != PFM_SUCCESS) + continue; + + if (ainfo.type != PFM_ATTR_UMASK) + continue; + + printf("%s::%s:%s\n", pinfo->name, info->name, ainfo.name); + has_umask = true; + } + if (!has_umask) + printf("%s::%s\n", pinfo->name, info->name); +} + +void print_libpfm_events(bool name_only, bool long_desc) +{ + pfm_event_info_t info; + pfm_pmu_info_t pinfo; + int i, p, ret; + + libpfm_initialize(); + + /* initialize to zero to indicate ABI version */ + info.size = sizeof(info); + pinfo.size = sizeof(pinfo); + + if (!name_only) + puts("\nList of pre-defined events (to be used in --pfm-events):\n"); + + pfm_for_all_pmus(p) { + bool printed_pmu = false; + + ret = pfm_get_pmu_info(p, &pinfo); + if (ret != PFM_SUCCESS) + continue; + + /* only print events that are supported by host HW */ + if (!pinfo.is_present) + continue; + + /* handled by perf directly */ + if (pinfo.pmu == PFM_PMU_PERF_EVENT) + continue; + + for (i = pinfo.first_event; i != -1; + i = pfm_get_event_next(i)) { + + ret = pfm_get_event_info(i, PFM_OS_PERF_EVENT_EXT, + &info); + if (ret != PFM_SUCCESS) + continue; + + if (!name_only && !printed_pmu) { + printf("%s:\n", pinfo.name); + printed_pmu = true; + } + + if (!name_only) + print_libpfm_events_detailed(&info, long_desc); + else + print_libpfm_events_raw(&pinfo, &info); + } + if (!name_only && printed_pmu) + putchar('\n'); + } +} diff --git a/tools/perf/util/pfm.h b/tools/perf/util/pfm.h new file mode 100644 index 000000000000..7d70dda87012 --- /dev/null +++ b/tools/perf/util/pfm.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Support for libpfm4 event encoding. + * + * Copyright 2020 Google LLC. + */ +#ifndef __PERF_PFM_H +#define __PERF_PFM_H + +#include + +#ifdef HAVE_LIBPFM +int parse_libpfm_events_option(const struct option *opt, const char *str, + int unset); + +void print_libpfm_events(bool name_only, bool long_desc); + +#else +#include + +static inline int parse_libpfm_events_option( + const struct option *opt __maybe_unused, + const char *str __maybe_unused, + int unset __maybe_unused) +{ + return 0; +} + +static inline void print_libpfm_events(bool name_only __maybe_unused, + bool long_desc __maybe_unused) +{ +} + +#endif + + +#endif /* __PERF_PFM_H */