From patchwork Tue Mar 7 23:33:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13164940 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8468EC6FD1E for ; Tue, 7 Mar 2023 23:33:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229937AbjCGXdT (ORCPT ); Tue, 7 Mar 2023 18:33:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43540 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229812AbjCGXdR (ORCPT ); Tue, 7 Mar 2023 18:33:17 -0500 Received: from mail-pf1-x434.google.com (mail-pf1-x434.google.com [IPv6:2607:f8b0:4864:20::434]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 394314E5EE; Tue, 7 Mar 2023 15:33:15 -0800 (PST) Received: by mail-pf1-x434.google.com with SMTP id b20so9164255pfo.6; Tue, 07 Mar 2023 15:33:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678231994; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=lC+wocJs40E6XIA7vWZUphTNK2raAPi9HIYmbOkjK4k=; b=R+KyO2PJigqcm5w7QTb5A5c8+WJiekkU4DmwBvywIzcUxw9+WDv13aGwDBwwTqmZdq ZDbbwlqCX4Wy44qDuk3KLT4nUV7Kf64lNozZ0ZXrjgNGY42vaMVqFlnP3ZSGAuTnCCSZ SVbtnv4yGfdR/4CWoRhvKPPo9YIg/YuQnWeiWyVSNwM3m1v3+h60GUO31nKTL2aDgvZ5 hbuWW+90atfM8wwXsbX1bUwfjJsAe1x6xNpqSgZqG7V9LUjMTx2DQQ5wsGc71c2LaHEn AcOzseZtDGIXYI/MJg38vM8kjAR5c52N11Rkc6oxd6Y27SINniMODxb/8CdvchfpmhvO XGKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678231994; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=lC+wocJs40E6XIA7vWZUphTNK2raAPi9HIYmbOkjK4k=; b=RS8vHS2TLP5f4uyTYUnMqTNxYQcDhXBg7DWOqZFJs51Y4CMEGO1jkb/l5qoRrCz2fG FRrnz7INYoZZPHk/PuT9VVzpFackn4w1TOpQjRawA33CSXJDOQ8cO290nBRNp90QcbqZ 1lPRYBxE8BtjD39jFMqBQ6U3VXYd14bjhgXlQrcqhdofrmX0WbgYZnP2zg7NJPxbpVIv 7cz8XYctVjXzym8IQ0AkBT0cAWjHgUBgafNQzNcwCGQnJdFfMi4tmYgTeA8UvwmkiQdY EDuy/th45qKifwW6Ikor9XN78byaGSYpU6rRHzf/mn+Ca7kczD0oZ+LYoud1N1XFroa4 2y0Q== X-Gm-Message-State: AO0yUKWhEc4X5ghiYjUX69+ZQhdj5CDd7f6Hm9P4fTtJEo++mN+DUljQ ZN7Un362c1hlQhIvRGbeD0mdmfHLjnE= X-Google-Smtp-Source: AK7set+XPdFvftPziC6pCgxOEdNhRl3FdASXTGbqsYIvV0I5cc/zuKtOQC4UldjEukzNcfVSmE5FOQ== X-Received: by 2002:a62:5e43:0:b0:5de:3c49:b06 with SMTP id s64-20020a625e43000000b005de3c490b06mr11608493pfb.3.1678231994556; Tue, 07 Mar 2023 15:33:14 -0800 (PST) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:15e8:b801:cd55:a496]) by smtp.gmail.com with ESMTPSA id l11-20020a62be0b000000b005da23d8cbffsm8342217pff.158.2023.03.07.15.33.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Mar 2023 15:33:14 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa Cc: Peter Zijlstra , Ingo Molnar , Ian Rogers , Adrian Hunter , Andi Kleen , Kan Liang , Song Liu , Stephane Eranian , Ravi Bangoria , Leo Yan , James Clark , Hao Luo , LKML , linux-perf-users@vger.kernel.org, bpf@vger.kernel.org Subject: [PATCH 1/9] perf bpf filter: Introduce basic BPF filter expression Date: Tue, 7 Mar 2023 15:33:01 -0800 Message-Id: <20230307233309.3546160-2-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230307233309.3546160-1-namhyung@kernel.org> References: <20230307233309.3546160-1-namhyung@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org This implements a tiny parser for the filter expressions used for BPF. Each expression will be converted to struct perf_bpf_filter_expr and be passed to a BPF map. For now, I'd like to start with the very basic comparisons like EQ or GT. The LHS should be a term for sample data and the RHS is a number. The expressions are connected by a comma. For example, period > 10000 ip < 0x1000000000000, cpu == 3 Acked-by: Jiri Olsa Signed-off-by: Namhyung Kim --- tools/perf/util/Build | 16 +++++++ tools/perf/util/bpf-filter.c | 37 ++++++++++++++++ tools/perf/util/bpf-filter.h | 36 ++++++++++++++++ tools/perf/util/bpf-filter.l | 82 ++++++++++++++++++++++++++++++++++++ tools/perf/util/bpf-filter.y | 54 ++++++++++++++++++++++++ 5 files changed, 225 insertions(+) create mode 100644 tools/perf/util/bpf-filter.c create mode 100644 tools/perf/util/bpf-filter.h create mode 100644 tools/perf/util/bpf-filter.l create mode 100644 tools/perf/util/bpf-filter.y diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 918b501f9bd8..6af73fb5c797 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -154,6 +154,9 @@ perf-$(CONFIG_PERF_BPF_SKEL) += bpf_counter.o perf-$(CONFIG_PERF_BPF_SKEL) += bpf_counter_cgroup.o perf-$(CONFIG_PERF_BPF_SKEL) += bpf_ftrace.o perf-$(CONFIG_PERF_BPF_SKEL) += bpf_off_cpu.o +perf-$(CONFIG_PERF_BPF_SKEL) += bpf-filter.o +perf-$(CONFIG_PERF_BPF_SKEL) += bpf-filter-flex.o +perf-$(CONFIG_PERF_BPF_SKEL) += bpf-filter-bison.o ifeq ($(CONFIG_LIBTRACEEVENT),y) perf-$(CONFIG_PERF_BPF_SKEL) += bpf_lock_contention.o @@ -266,6 +269,16 @@ $(OUTPUT)util/pmu-bison.c $(OUTPUT)util/pmu-bison.h: util/pmu.y $(Q)$(call echo-cmd,bison)$(BISON) -v $< -d $(PARSER_DEBUG_BISON) $(BISON_FILE_PREFIX_MAP) \ -o $(OUTPUT)util/pmu-bison.c -p perf_pmu_ +$(OUTPUT)util/bpf-filter-flex.c $(OUTPUT)util/bpf-filter-flex.h: util/bpf-filter.l $(OUTPUT)util/bpf-filter-bison.c + $(call rule_mkdir) + $(Q)$(call echo-cmd,flex)$(FLEX) -o $(OUTPUT)util/bpf-filter-flex.c \ + --header-file=$(OUTPUT)util/bpf-filter-flex.h $(PARSER_DEBUG_FLEX) $< + +$(OUTPUT)util/bpf-filter-bison.c $(OUTPUT)util/bpf-filter-bison.h: util/bpf-filter.y + $(call rule_mkdir) + $(Q)$(call echo-cmd,bison)$(BISON) -v $< -d $(PARSER_DEBUG_BISON) $(BISON_FILE_PREFIX_MAP) \ + -o $(OUTPUT)util/bpf-filter-bison.c -p perf_bpf_filter_ + FLEX_GE_26 := $(shell expr $(shell $(FLEX) --version | sed -e 's/flex \([0-9]\+\).\([0-9]\+\)/\1\2/g') \>\= 26) ifeq ($(FLEX_GE_26),1) flex_flags := -Wno-switch-enum -Wno-switch-default -Wno-unused-function -Wno-redundant-decls -Wno-sign-compare -Wno-unused-parameter -Wno-missing-prototypes -Wno-missing-declarations @@ -279,6 +292,7 @@ endif CFLAGS_parse-events-flex.o += $(flex_flags) CFLAGS_pmu-flex.o += $(flex_flags) CFLAGS_expr-flex.o += $(flex_flags) +CFLAGS_bpf-filter-flex.o += $(flex_flags) bison_flags := -DYYENABLE_NLS=0 BISON_GE_35 := $(shell expr $(shell $(BISON) --version | grep bison | sed -e 's/.\+ \([0-9]\+\).\([0-9]\+\)/\1\2/g') \>\= 35) @@ -290,10 +304,12 @@ endif CFLAGS_parse-events-bison.o += $(bison_flags) CFLAGS_pmu-bison.o += -DYYLTYPE_IS_TRIVIAL=0 $(bison_flags) CFLAGS_expr-bison.o += -DYYLTYPE_IS_TRIVIAL=0 $(bison_flags) +CFLAGS_bpf-filter-bison.o += -DYYLTYPE_IS_TRIVIAL=0 $(bison_flags) $(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c $(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c $(OUTPUT)util/expr.o: $(OUTPUT)util/expr-flex.c $(OUTPUT)util/expr-bison.c +$(OUTPUT)util/bpf-filter.o: $(OUTPUT)util/bpf-filter-flex.c $(OUTPUT)util/bpf-filter-bison.c CFLAGS_bitmap.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" CFLAGS_find_bit.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" diff --git a/tools/perf/util/bpf-filter.c b/tools/perf/util/bpf-filter.c new file mode 100644 index 000000000000..c72e35d51240 --- /dev/null +++ b/tools/perf/util/bpf-filter.c @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include + +#include "util/bpf-filter.h" +#include "util/bpf-filter-flex.h" +#include "util/bpf-filter-bison.h" + +struct perf_bpf_filter_expr *perf_bpf_filter_expr__new(unsigned long sample_flags, + enum perf_bpf_filter_op op, + unsigned long val) +{ + struct perf_bpf_filter_expr *expr; + + expr = malloc(sizeof(*expr)); + if (expr != NULL) { + expr->sample_flags = sample_flags; + expr->op = op; + expr->val = val; + } + return expr; +} + +int perf_bpf_filter__parse(struct list_head *expr_head, const char *str) +{ + YY_BUFFER_STATE buffer; + int ret; + + buffer = perf_bpf_filter__scan_string(str); + + ret = perf_bpf_filter_parse(expr_head); + + perf_bpf_filter__flush_buffer(buffer); + perf_bpf_filter__delete_buffer(buffer); + perf_bpf_filter_lex_destroy(); + + return ret; +} diff --git a/tools/perf/util/bpf-filter.h b/tools/perf/util/bpf-filter.h new file mode 100644 index 000000000000..93a0d3de038c --- /dev/null +++ b/tools/perf/util/bpf-filter.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef PERF_UTIL_BPF_FILTER_H +#define PERF_UTIL_BPF_FILTER_H + +#include + +enum perf_bpf_filter_op { + PBF_OP_EQ, + PBF_OP_NEQ, + PBF_OP_GT, + PBF_OP_GE, + PBF_OP_LT, + PBF_OP_LE, + PBF_OP_AND, +}; + +struct perf_bpf_filter_expr { + struct list_head list; + enum perf_bpf_filter_op op; + unsigned long sample_flags; + unsigned long val; +}; + +#ifdef HAVE_BPF_SKEL +struct perf_bpf_filter_expr *perf_bpf_filter_expr__new(unsigned long sample_flags, + enum perf_bpf_filter_op op, + unsigned long val); +int perf_bpf_filter__parse(struct list_head *expr_head, const char *str); +#else /* !HAVE_BPF_SKEL */ +static inline int perf_bpf_filter__parse(struct list_head *expr_head __maybe_unused, + const char *str __maybe_unused) +{ + return -ENOSYS; +} +#endif /* HAVE_BPF_SKEL*/ +#endif /* PERF_UTIL_BPF_FILTER_H */ diff --git a/tools/perf/util/bpf-filter.l b/tools/perf/util/bpf-filter.l new file mode 100644 index 000000000000..f6c0b74ea285 --- /dev/null +++ b/tools/perf/util/bpf-filter.l @@ -0,0 +1,82 @@ +%option prefix="perf_bpf_filter_" +%option noyywrap + +%{ +#include +#include +#include + +#include "bpf-filter.h" +#include "bpf-filter-bison.h" + +static int sample(unsigned long sample_flag) +{ + perf_bpf_filter_lval.sample = sample_flag; + return BFT_SAMPLE; +} + +static int operator(enum perf_bpf_filter_op op) +{ + perf_bpf_filter_lval.op = op; + return BFT_OP; +} + +static int value(int base) +{ + long num; + + errno = 0; + num = strtoul(perf_bpf_filter_text, NULL, base); + if (errno) + return BFT_ERROR; + + perf_bpf_filter_lval.num = num; + return BFT_NUM; +} + +static int error(const char *str) +{ + printf("perf_bpf_filter: Unexpected filter %s: %s\n", str, perf_bpf_filter_text); + return BFT_ERROR; +} + +%} + +num_dec [0-9]+ +num_hex 0[Xx][0-9a-fA-F]+ +space [ \t]+ +ident [_a-zA-Z][_a-zA-Z0-9]+ + +%% + +{num_dec} { return value(10); } +{num_hex} { return value(16); } +{space} { } + +ip { return sample(PERF_SAMPLE_IP); } +id { return sample(PERF_SAMPLE_ID); } +tid { return sample(PERF_SAMPLE_TID); } +cpu { return sample(PERF_SAMPLE_CPU); } +time { return sample(PERF_SAMPLE_TIME); } +addr { return sample(PERF_SAMPLE_ADDR); } +period { return sample(PERF_SAMPLE_PERIOD); } +txn { return sample(PERF_SAMPLE_TRANSACTION); } +weight { return sample(PERF_SAMPLE_WEIGHT); } +phys_addr { return sample(PERF_SAMPLE_PHYS_ADDR); } +code_pgsz { return sample(PERF_SAMPLE_CODE_PAGE_SIZE); } +data_pgsz { return sample(PERF_SAMPLE_DATA_PAGE_SIZE); } + +"==" { return operator(PBF_OP_EQ); } +"!=" { return operator(PBF_OP_NEQ); } +">" { return operator(PBF_OP_GT); } +"<" { return operator(PBF_OP_LT); } +">=" { return operator(PBF_OP_GE); } +"<=" { return operator(PBF_OP_LE); } +"&" { return operator(PBF_OP_AND); } + +"," { return ','; } + +{ident} { return error("ident"); } +. { return error("input"); } + +%% diff --git a/tools/perf/util/bpf-filter.y b/tools/perf/util/bpf-filter.y new file mode 100644 index 000000000000..13eca612ecca --- /dev/null +++ b/tools/perf/util/bpf-filter.y @@ -0,0 +1,54 @@ +%parse-param {struct list_head *expr_head} +%define parse.error verbose + +%{ + +#include +#include +#include +#include +#include "bpf-filter.h" + +static void perf_bpf_filter_error(struct list_head *expr __maybe_unused, + char const *msg) +{ + printf("perf_bpf_filter: %s\n", msg); +} + +%} + +%union +{ + unsigned long num; + unsigned long sample; + enum perf_bpf_filter_op op; + struct perf_bpf_filter_expr *expr; +} + +%token BFT_SAMPLE BFT_OP BFT_ERROR BFT_NUM +%type filter_term +%destructor { free ($$); } +%type BFT_SAMPLE +%type BFT_OP +%type BFT_NUM + +%% + +filter: +filter ',' filter_term +{ + list_add_tail(&$3->list, expr_head); +} +| +filter_term +{ + list_add_tail(&$1->list, expr_head); +} + +filter_term: +BFT_SAMPLE BFT_OP BFT_NUM +{ + $$ = perf_bpf_filter_expr__new($1, $2, $3); +} + +%% From patchwork Tue Mar 7 23:33:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13164941 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F298CC74A5B for ; Tue, 7 Mar 2023 23:33:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229948AbjCGXdV (ORCPT ); Tue, 7 Mar 2023 18:33:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43638 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229925AbjCGXdS (ORCPT ); Tue, 7 Mar 2023 18:33:18 -0500 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F221D52F7C; Tue, 7 Mar 2023 15:33:16 -0800 (PST) Received: by mail-pj1-x1030.google.com with SMTP id l1so14913758pjt.2; Tue, 07 Mar 2023 15:33:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678231996; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=hGXhvns0Fqsn+j0G+5qIK3kmqbdu5S85FOm2nPL5t1o=; b=nld7nPfMYXjpcSCD2nFGAcf3iRsMkzEx2GJWOTGcKP96lgTmYid395gkSjMDqs6pER dbfAdym/m01Q/39X3Ug2FBEtTxuQtNUjX0wNjOX7yY+ILVCeKg6I2TeVXCFeW+UVyQ4p v6QU+UXFObyJwmGn6jeb4FCC9hv1scoTStDqa70bZQtGimbZmfta3pUn7QTQI1ZDcPDK t+vrEVP2Ig96sVhSnyt/h76WBNNYMmO0qKeqf97AC5yxk/1ZAobB9LdkCEYIrrXPtbpJ w8mcwf95/flQnhlDOwOwd7mT6LqNLYgUGXGm27PZ+yeXxcLKQIpXKoWApNscCWdjJXQh ApTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678231996; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=hGXhvns0Fqsn+j0G+5qIK3kmqbdu5S85FOm2nPL5t1o=; b=zsK1Cp9xs24MRbhBmyfGAYxEp2LukpPsztpxaSgPQvcTB/cdDGuwxbaa3TMSf+d7T2 UCGNYRKAIjNJUi1tgqrz5VCJtsbxdjy9GYTAQ3jfDdf7IYzJaUreS4ITt1OM24lDKslo GWv4PjqFynweOK/a16eucqj40GvK8fRtliAx0szEqK1MrAeH07cj7LPZt4Rvg8BgIp6s 1D85c/w/LSfDLyburbxJbpiMWTTOKNjnos8QrbtfMx8PMp6rYIeBpYPvGQ8+oFzaqLXK nDlOwU4BlhrwB+TRN7/iGevm1jF3DDLtRs/o7kPL+YeMoWghte2boT/DDpp2qaaAlDA1 3Vhw== X-Gm-Message-State: AO0yUKWr0DRTqYB9l5CaME6FSyUJFqrgo4xN6WP5U6p29spHxaiKdUKR XXPkKEtl4cK85LuBNpTI9eM= X-Google-Smtp-Source: AK7set9kPUyO2tqskMFIjmohwHr55/0vIZxq/Rj5e6uD0Tk3TSB06pzUAhxBQ9InphwVnHnP3aNyUw== X-Received: by 2002:a05:6a20:7d88:b0:cc:fa4b:3a6a with SMTP id v8-20020a056a207d8800b000ccfa4b3a6amr21943956pzj.58.1678231996272; Tue, 07 Mar 2023 15:33:16 -0800 (PST) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:15e8:b801:cd55:a496]) by smtp.gmail.com with ESMTPSA id l11-20020a62be0b000000b005da23d8cbffsm8342217pff.158.2023.03.07.15.33.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Mar 2023 15:33:15 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa Cc: Peter Zijlstra , Ingo Molnar , Ian Rogers , Adrian Hunter , Andi Kleen , Kan Liang , Song Liu , Stephane Eranian , Ravi Bangoria , Leo Yan , James Clark , Hao Luo , LKML , linux-perf-users@vger.kernel.org, bpf@vger.kernel.org Subject: [PATCH 2/9] perf bpf filter: Implement event sample filtering Date: Tue, 7 Mar 2023 15:33:02 -0800 Message-Id: <20230307233309.3546160-3-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230307233309.3546160-1-namhyung@kernel.org> References: <20230307233309.3546160-1-namhyung@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org The BPF program will be attached to a perf_event and be triggered when it overflows. It'd iterate the filters map and compare the sample value according to the expression. If any of them fails, the sample would be dropped. Also it needs to have the corresponding sample data for the expression so it compares data->sample_flags with the given value. To access the sample data, it uses the bpf_cast_to_kern_ctx() kfunc which was added in v6.2 kernel. Acked-by: Jiri Olsa Signed-off-by: Namhyung Kim --- tools/perf/Makefile.perf | 2 +- tools/perf/util/bpf-filter.c | 64 ++++++++++ tools/perf/util/bpf-filter.h | 26 ++-- tools/perf/util/bpf_skel/sample-filter.h | 24 ++++ tools/perf/util/bpf_skel/sample_filter.bpf.c | 126 +++++++++++++++++++ tools/perf/util/evsel.h | 7 +- 6 files changed, 236 insertions(+), 13 deletions(-) create mode 100644 tools/perf/util/bpf_skel/sample-filter.h create mode 100644 tools/perf/util/bpf_skel/sample_filter.bpf.c diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index bac9272682b7..474af4adea95 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -1047,7 +1047,7 @@ SKELETONS := $(SKEL_OUT)/bpf_prog_profiler.skel.h SKELETONS += $(SKEL_OUT)/bperf_leader.skel.h $(SKEL_OUT)/bperf_follower.skel.h SKELETONS += $(SKEL_OUT)/bperf_cgroup.skel.h $(SKEL_OUT)/func_latency.skel.h SKELETONS += $(SKEL_OUT)/off_cpu.skel.h $(SKEL_OUT)/lock_contention.skel.h -SKELETONS += $(SKEL_OUT)/kwork_trace.skel.h +SKELETONS += $(SKEL_OUT)/kwork_trace.skel.h $(SKEL_OUT)/sample_filter.skel.h $(SKEL_TMP_OUT) $(LIBAPI_OUTPUT) $(LIBBPF_OUTPUT) $(LIBPERF_OUTPUT) $(LIBSUBCMD_OUTPUT) $(LIBSYMBOL_OUTPUT): $(Q)$(MKDIR) -p $@ diff --git a/tools/perf/util/bpf-filter.c b/tools/perf/util/bpf-filter.c index c72e35d51240..f20e1bc03778 100644 --- a/tools/perf/util/bpf-filter.c +++ b/tools/perf/util/bpf-filter.c @@ -1,10 +1,74 @@ /* SPDX-License-Identifier: GPL-2.0 */ #include +#include +#include +#include + +#include "util/debug.h" +#include "util/evsel.h" + #include "util/bpf-filter.h" #include "util/bpf-filter-flex.h" #include "util/bpf-filter-bison.h" +#include "bpf_skel/sample-filter.h" +#include "bpf_skel/sample_filter.skel.h" + +#define FD(e, x, y) (*(int *)xyarray__entry(e->core.fd, x, y)) + +int perf_bpf_filter__prepare(struct evsel *evsel) +{ + int i, x, y, fd; + struct sample_filter_bpf *skel; + struct bpf_program *prog; + struct bpf_link *link; + struct perf_bpf_filter_expr *expr; + + skel = sample_filter_bpf__open_and_load(); + if (!skel) { + pr_err("Failed to load perf sample-filter BPF skeleton\n"); + return -1; + } + + i = 0; + fd = bpf_map__fd(skel->maps.filters); + list_for_each_entry(expr, &evsel->bpf_filters, list) { + struct perf_bpf_filter_entry entry = { + .op = expr->op, + .flags = expr->sample_flags, + .value = expr->val, + }; + bpf_map_update_elem(fd, &i, &entry, BPF_ANY); + i++; + } + + prog = skel->progs.perf_sample_filter; + for (x = 0; x < xyarray__max_x(evsel->core.fd); x++) { + for (y = 0; y < xyarray__max_y(evsel->core.fd); y++) { + link = bpf_program__attach_perf_event(prog, FD(evsel, x, y)); + if (IS_ERR(link)) { + pr_err("Failed to attach perf sample-filter program\n"); + return PTR_ERR(link); + } + } + } + evsel->bpf_skel = skel; + return 0; +} + +int perf_bpf_filter__destroy(struct evsel *evsel) +{ + struct perf_bpf_filter_expr *expr, *tmp; + + list_for_each_entry_safe(expr, tmp, &evsel->bpf_filters, list) { + list_del(&expr->list); + free(expr); + } + sample_filter_bpf__destroy(evsel->bpf_skel); + return 0; +} + struct perf_bpf_filter_expr *perf_bpf_filter_expr__new(unsigned long sample_flags, enum perf_bpf_filter_op op, unsigned long val) diff --git a/tools/perf/util/bpf-filter.h b/tools/perf/util/bpf-filter.h index 93a0d3de038c..eb8e1ac43cdf 100644 --- a/tools/perf/util/bpf-filter.h +++ b/tools/perf/util/bpf-filter.h @@ -4,15 +4,7 @@ #include -enum perf_bpf_filter_op { - PBF_OP_EQ, - PBF_OP_NEQ, - PBF_OP_GT, - PBF_OP_GE, - PBF_OP_LT, - PBF_OP_LE, - PBF_OP_AND, -}; +#include "bpf_skel/sample-filter.h" struct perf_bpf_filter_expr { struct list_head list; @@ -21,16 +13,30 @@ struct perf_bpf_filter_expr { unsigned long val; }; +struct evsel; + #ifdef HAVE_BPF_SKEL struct perf_bpf_filter_expr *perf_bpf_filter_expr__new(unsigned long sample_flags, enum perf_bpf_filter_op op, unsigned long val); int perf_bpf_filter__parse(struct list_head *expr_head, const char *str); +int perf_bpf_filter__prepare(struct evsel *evsel); +int perf_bpf_filter__destroy(struct evsel *evsel); + #else /* !HAVE_BPF_SKEL */ + static inline int perf_bpf_filter__parse(struct list_head *expr_head __maybe_unused, const char *str __maybe_unused) { - return -ENOSYS; + return -EOPNOTSUPP; +} +static inline int perf_bpf_filter__prepare(struct evsel *evsel __maybe_unused) +{ + return -EOPNOTSUPP; +} +static inline int perf_bpf_filter__destroy(struct evsel *evsel __maybe_unused) +{ + return -EOPNOTSUPP; } #endif /* HAVE_BPF_SKEL*/ #endif /* PERF_UTIL_BPF_FILTER_H */ diff --git a/tools/perf/util/bpf_skel/sample-filter.h b/tools/perf/util/bpf_skel/sample-filter.h new file mode 100644 index 000000000000..862060bfda14 --- /dev/null +++ b/tools/perf/util/bpf_skel/sample-filter.h @@ -0,0 +1,24 @@ +#ifndef PERF_UTIL_BPF_SKEL_SAMPLE_FILTER_H +#define PERF_UTIL_BPF_SKEL_SAMPLE_FILTER_H + +#define MAX_FILTERS 32 + +/* supported filter operations */ +enum perf_bpf_filter_op { + PBF_OP_EQ, + PBF_OP_NEQ, + PBF_OP_GT, + PBF_OP_GE, + PBF_OP_LT, + PBF_OP_LE, + PBF_OP_AND +}; + +/* BPF map entry for filtering */ +struct perf_bpf_filter_entry { + enum perf_bpf_filter_op op; + __u64 flags; + __u64 value; +}; + +#endif /* PERF_UTIL_BPF_SKEL_SAMPLE_FILTER_H */ \ No newline at end of file diff --git a/tools/perf/util/bpf_skel/sample_filter.bpf.c b/tools/perf/util/bpf_skel/sample_filter.bpf.c new file mode 100644 index 000000000000..c07256279c3e --- /dev/null +++ b/tools/perf/util/bpf_skel/sample_filter.bpf.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +// Copyright (c) 2023 Google +#include "vmlinux.h" +#include +#include +#include + +#include "sample-filter.h" + +/* BPF map that will be filled by user space */ +struct filters { + __uint(type, BPF_MAP_TYPE_ARRAY); + __type(key, int); + __type(value, struct perf_bpf_filter_entry); + __uint(max_entries, MAX_FILTERS); +} filters SEC(".maps"); + +int dropped; + +void *bpf_cast_to_kern_ctx(void *) __ksym; + +/* new kernel perf_sample_data definition */ +struct perf_sample_data___new { + __u64 sample_flags; +} __attribute__((preserve_access_index)); + +/* helper function to return the given perf sample data */ +static inline __u64 perf_get_sample(struct bpf_perf_event_data_kern *kctx, + struct perf_bpf_filter_entry *entry) +{ + struct perf_sample_data___new *data = (void *)kctx->data; + + if (!bpf_core_field_exists(data->sample_flags) || + (data->sample_flags & entry->flags) == 0) + return 0; + + switch (entry->flags) { + case PERF_SAMPLE_IP: + return kctx->data->ip; + case PERF_SAMPLE_ID: + return kctx->data->id; + case PERF_SAMPLE_TID: + return kctx->data->tid_entry.tid; + case PERF_SAMPLE_CPU: + return kctx->data->cpu_entry.cpu; + case PERF_SAMPLE_TIME: + return kctx->data->time; + case PERF_SAMPLE_ADDR: + return kctx->data->addr; + case PERF_SAMPLE_PERIOD: + return kctx->data->period; + case PERF_SAMPLE_TRANSACTION: + return kctx->data->txn; + case PERF_SAMPLE_WEIGHT: + return kctx->data->weight.full; + case PERF_SAMPLE_PHYS_ADDR: + return kctx->data->phys_addr; + case PERF_SAMPLE_CODE_PAGE_SIZE: + return kctx->data->code_page_size; + case PERF_SAMPLE_DATA_PAGE_SIZE: + return kctx->data->data_page_size; + default: + break; + } + return 0; +} + +/* BPF program to be called from perf event overflow handler */ +SEC("perf_event") +int perf_sample_filter(void *ctx) +{ + struct bpf_perf_event_data_kern *kctx; + struct perf_bpf_filter_entry *entry; + __u64 sample_data; + int i; + + kctx = bpf_cast_to_kern_ctx(ctx); + + for (i = 0; i < MAX_FILTERS; i++) { + int key = i; /* needed for verifier :( */ + + entry = bpf_map_lookup_elem(&filters, &key); + if (entry == NULL) + break; + sample_data = perf_get_sample(kctx, entry); + + switch (entry->op) { + case PBF_OP_EQ: + if (!(sample_data == entry->value)) + goto drop; + break; + case PBF_OP_NEQ: + if (!(sample_data != entry->value)) + goto drop; + break; + case PBF_OP_GT: + if (!(sample_data > entry->value)) + goto drop; + break; + case PBF_OP_GE: + if (!(sample_data >= entry->value)) + goto drop; + break; + case PBF_OP_LT: + if (!(sample_data < entry->value)) + goto drop; + break; + case PBF_OP_LE: + if (!(sample_data <= entry->value)) + goto drop; + break; + case PBF_OP_AND: + if (!(sample_data & entry->value)) + goto drop; + break; + } + } + /* generate sample data */ + return 1; + +drop: + __sync_fetch_and_add(&dropped, 1); + return 0; +} + +char LICENSE[] SEC("license") = "Dual BSD/GPL"; diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 814a49ebb7e3..d876ea134bf8 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -151,8 +151,10 @@ struct evsel { */ struct bpf_counter_ops *bpf_counter_ops; - /* for perf-stat -b */ - struct list_head bpf_counter_list; + union { + struct list_head bpf_counter_list; /* for perf-stat -b */ + struct list_head bpf_filters; /* for perf-record --filter */ + }; /* for perf-stat --use-bpf */ int bperf_leader_prog_fd; @@ -160,6 +162,7 @@ struct evsel { union { struct bperf_leader_bpf *leader_skel; struct bperf_follower_bpf *follower_skel; + void *bpf_skel; }; unsigned long open_flags; int precise_ip_original; From patchwork Tue Mar 7 23:33:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13164942 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 13335C76188 for ; Tue, 7 Mar 2023 23:33:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229960AbjCGXdX (ORCPT ); Tue, 7 Mar 2023 18:33:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43728 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229940AbjCGXdU (ORCPT ); Tue, 7 Mar 2023 18:33:20 -0500 Received: from mail-pg1-x533.google.com (mail-pg1-x533.google.com [IPv6:2607:f8b0:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6C07E4E5EE; Tue, 7 Mar 2023 15:33:18 -0800 (PST) Received: by mail-pg1-x533.google.com with SMTP id bn17so8610566pgb.10; Tue, 07 Mar 2023 15:33:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678231998; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=ZWY3pu1sUBwgULLA58qBvOo9hTklUr6qi9NkTdBlOtc=; b=bJSqVD/jl+PkfJRGjXymRodsOUSYj3io692pFqwOEEBmN/yAOhuW/eykm05mRRzpez 7eRAFQNs7W/XWARmnqUowH9nFWuoprQFX9UC3C5wBhyq3440yUjBbKQl57rfeSLejIkv uS+7O6K3qmlh4TJs9uryAEH8yxr9S84AqfKpFZYkJFsAa0SerpNdbBCKUqZ+mWMrDEa3 ezOuFCIa/pxWARVOE+OHRuX9oJimyVWeLGPZKs89WaVuz6xxUzG9UOePdx5ShN9BcTLE KPOiOSvwgATBZVpx5nVqw0FBHYQqAR6Ld0zpgnQT5w0JvT+1G0015p2wfQukuimaXQY9 ifCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678231998; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=ZWY3pu1sUBwgULLA58qBvOo9hTklUr6qi9NkTdBlOtc=; b=yEEb2jPYQyqE+4tqyv2mMZ2LzgThHa2Ibo1Wlz1+uYCrfXaNOWKK3RAykXLtAvEC9r BIjbrB1iBlCrzDrsLB+DTxC5eAl9ENGQmcUhMLBOGfDAp+06K6E6EhcSw3VPRuErKNFC 2BYVdjrVudqYcbkHBkSy81NlVz0qw4xoDl2LLBhd6CeY51Mm/hSnw+hlrx30Dz9eRW/t t8HAkfEkuDVMViaIrzvKCJReHEvEUij9XmPRbWojpp4K14vPEmbFxvxdUk7eFBG4j1Kc fLKAPwVEn8fLpVdtGBx29GDonPTme8Wo3WqwchR2ai0uy+2tPY0uxoN0wFEcxW9x5vEu Cqgw== X-Gm-Message-State: AO0yUKXkYnITP18Djh/R5kBK7nr0eDJCIfduQJ/ADv9f2kfm/NvcqQsF 5dp4gQjBjS86IFBcDaUHa4w= X-Google-Smtp-Source: AK7set9rLaCbqxNnlXw1sJRbLyeuvpCGZBY4hj1WshFCtlfJczEMbKp6EoyMzR5lHx1hMTV0rdAiiA== X-Received: by 2002:aa7:940b:0:b0:5a8:b705:4dd3 with SMTP id x11-20020aa7940b000000b005a8b7054dd3mr14090118pfo.13.1678231997817; Tue, 07 Mar 2023 15:33:17 -0800 (PST) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:15e8:b801:cd55:a496]) by smtp.gmail.com with ESMTPSA id l11-20020a62be0b000000b005da23d8cbffsm8342217pff.158.2023.03.07.15.33.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Mar 2023 15:33:17 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa Cc: Peter Zijlstra , Ingo Molnar , Ian Rogers , Adrian Hunter , Andi Kleen , Kan Liang , Song Liu , Stephane Eranian , Ravi Bangoria , Leo Yan , James Clark , Hao Luo , LKML , linux-perf-users@vger.kernel.org, bpf@vger.kernel.org Subject: [PATCH 3/9] perf record: Add BPF event filter support Date: Tue, 7 Mar 2023 15:33:03 -0800 Message-Id: <20230307233309.3546160-4-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230307233309.3546160-1-namhyung@kernel.org> References: <20230307233309.3546160-1-namhyung@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Use --filter option to set BPF filter for generic events other than the tracepoints or Intel PT. The BPF program will check the sample data and filter according to the expression. For example, the below is the typical perf record for frequency mode. The sample period started from 1 and increased gradually. $ sudo ./perf record -e cycles true $ sudo ./perf script perf-exec 2272336 546683.916875: 1 cycles: ffffffff828499b8 perf_event_exec+0x298 ([kernel.kallsyms]) perf-exec 2272336 546683.916892: 1 cycles: ffffffff828499b8 perf_event_exec+0x298 ([kernel.kallsyms]) perf-exec 2272336 546683.916899: 3 cycles: ffffffff828499b8 perf_event_exec+0x298 ([kernel.kallsyms]) perf-exec 2272336 546683.916905: 17 cycles: ffffffff828499b8 perf_event_exec+0x298 ([kernel.kallsyms]) perf-exec 2272336 546683.916911: 100 cycles: ffffffff828499b8 perf_event_exec+0x298 ([kernel.kallsyms]) perf-exec 2272336 546683.916917: 589 cycles: ffffffff828499b8 perf_event_exec+0x298 ([kernel.kallsyms]) perf-exec 2272336 546683.916924: 3470 cycles: ffffffff828499b8 perf_event_exec+0x298 ([kernel.kallsyms]) perf-exec 2272336 546683.916930: 20465 cycles: ffffffff828499b8 perf_event_exec+0x298 ([kernel.kallsyms]) true 2272336 546683.916940: 119873 cycles: ffffffff8283afdd perf_iterate_ctx+0x2d ([kernel.kallsyms]) true 2272336 546683.917003: 461349 cycles: ffffffff82892517 vma_interval_tree_insert+0x37 ([kernel.kallsyms]) true 2272336 546683.917237: 635778 cycles: ffffffff82a11400 security_mmap_file+0x20 ([kernel.kallsyms]) When you add a BPF filter to get samples having periods greater than 1000, the output would look like below: $ sudo ./perf record -e cycles --filter 'period > 1000' true $ sudo ./perf script perf-exec 2273949 546850.708501: 5029 cycles: ffffffff826f9e25 finish_wait+0x5 ([kernel.kallsyms]) perf-exec 2273949 546850.708508: 32409 cycles: ffffffff826f9e25 finish_wait+0x5 ([kernel.kallsyms]) perf-exec 2273949 546850.708526: 143369 cycles: ffffffff82b4cdbf xas_start+0x5f ([kernel.kallsyms]) perf-exec 2273949 546850.708600: 372650 cycles: ffffffff8286b8f7 __pagevec_lru_add+0x117 ([kernel.kallsyms]) perf-exec 2273949 546850.708791: 482953 cycles: ffffffff829190de __mod_memcg_lruvec_state+0x4e ([kernel.kallsyms]) true 2273949 546850.709036: 501985 cycles: ffffffff828add7c tlb_gather_mmu+0x4c ([kernel.kallsyms]) true 2273949 546850.709292: 503065 cycles: 7f2446d97c03 _dl_map_object_deps+0x973 (/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2) Acked-by: Jiri Olsa Signed-off-by: Namhyung Kim --- tools/perf/Documentation/perf-record.txt | 15 +++++++++++--- tools/perf/util/bpf_counter.c | 3 +-- tools/perf/util/evlist.c | 25 +++++++++++++++++------- tools/perf/util/evsel.c | 2 ++ tools/perf/util/parse-events.c | 8 +++----- 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index ff815c2f67e8..9f7b43a3086d 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -119,9 +119,12 @@ OPTIONS "perf report" to view group events together. --filter=:: - Event filter. This option should follow an event selector (-e) which - selects either tracepoint event(s) or a hardware trace PMU - (e.g. Intel PT or CoreSight). + Event filter. This option should follow an event selector (-e). + If the event is a tracepoint, the filter string will be parsed by + the kernel. If the event is a hardware trace PMU (e.g. Intel PT + or CoreSight), it'll be processed as an address filter. Otherwise + it means a general filter using BPF which can be applied for any + kind of event. - tracepoint filters @@ -174,6 +177,12 @@ OPTIONS within a single mapping. MMAP events (or /proc//maps) can be examined to determine if that is a possibility. + - bpf filters + + A BPF filter can access the sample data and make a decision based on the + data. Users need to set an appropriate sample type to use the BPF + filter. + Multiple filters can be separated with space or comma. --exclude-perf:: diff --git a/tools/perf/util/bpf_counter.c b/tools/perf/util/bpf_counter.c index eeee899fcf34..0414385794ee 100644 --- a/tools/perf/util/bpf_counter.c +++ b/tools/perf/util/bpf_counter.c @@ -781,8 +781,7 @@ extern struct bpf_counter_ops bperf_cgrp_ops; static inline bool bpf_counter_skip(struct evsel *evsel) { - return list_empty(&evsel->bpf_counter_list) && - evsel->follower_skel == NULL; + return evsel->bpf_counter_ops == NULL; } int bpf_counter__install_pe(struct evsel *evsel, int cpu_map_idx, int fd) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 817df2504a1e..648bddfb8441 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -31,6 +31,7 @@ #include "util/evlist-hybrid.h" #include "util/pmu.h" #include "util/sample.h" +#include "util/bpf-filter.h" #include #include #include @@ -1086,17 +1087,27 @@ int evlist__apply_filters(struct evlist *evlist, struct evsel **err_evsel) int err = 0; evlist__for_each_entry(evlist, evsel) { - if (evsel->filter == NULL) - continue; - /* * filters only work for tracepoint event, which doesn't have cpu limit. * So evlist and evsel should always be same. */ - err = perf_evsel__apply_filter(&evsel->core, evsel->filter); - if (err) { - *err_evsel = evsel; - break; + if (evsel->filter) { + err = perf_evsel__apply_filter(&evsel->core, evsel->filter); + if (err) { + *err_evsel = evsel; + break; + } + } + + /* + * non-tracepoint events can have BPF filters. + */ + if (!list_empty(&evsel->bpf_filters)) { + err = perf_bpf_filter__prepare(evsel); + if (err) { + *err_evsel = evsel; + break; + } } } diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 51e8ce6edddc..cae624fde026 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -50,6 +50,7 @@ #include "off_cpu.h" #include "../perf-sys.h" #include "util/parse-branch-options.h" +#include "util/bpf-filter.h" #include #include #include @@ -1494,6 +1495,7 @@ void evsel__exit(struct evsel *evsel) assert(list_empty(&evsel->core.node)); assert(evsel->evlist == NULL); bpf_counter__destroy(evsel); + perf_bpf_filter__destroy(evsel); evsel__free_counts(evsel); perf_evsel__free_fd(&evsel->core); perf_evsel__free_id(&evsel->core); diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 0336ff27c15f..4371a2bb2564 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -27,6 +27,7 @@ #include "perf.h" #include "util/parse-events-hybrid.h" #include "util/pmu-hybrid.h" +#include "util/bpf-filter.h" #include "tracepoint.h" #include "thread_map.h" @@ -2537,11 +2538,8 @@ static int set_filter(struct evsel *evsel, const void *arg) perf_pmu__scan_file(pmu, "nr_addr_filters", "%d", &nr_addr_filters); - if (!nr_addr_filters) { - fprintf(stderr, - "This CPU does not support address filtering\n"); - return -1; - } + if (!nr_addr_filters) + return perf_bpf_filter__parse(&evsel->bpf_filters, str); if (evsel__append_addr_filter(evsel, str) < 0) { fprintf(stderr, From patchwork Tue Mar 7 23:33:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13164943 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1E322C74A44 for ; Tue, 7 Mar 2023 23:33:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229975AbjCGXdY (ORCPT ); Tue, 7 Mar 2023 18:33:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43894 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229952AbjCGXdX (ORCPT ); Tue, 7 Mar 2023 18:33:23 -0500 Received: from mail-pg1-x533.google.com (mail-pg1-x533.google.com [IPv6:2607:f8b0:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 327C24ECCA; Tue, 7 Mar 2023 15:33:20 -0800 (PST) Received: by mail-pg1-x533.google.com with SMTP id s18so8649066pgq.1; Tue, 07 Mar 2023 15:33:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678231999; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=CiPCdS7YWLbLvqN+ql4t86Rs7fqQxGYeQIPy6W1tBaw=; b=gTP8xiKt7O/TOcN7c2AuJ2CaxZonWsTkMN399Oq8ErCb5+dGYtbI6auI4R6TiEondz A86R+TLxWMt7CYgwslMP50xyLHQv/fcjJe3AGtJT0vq4Z7gnu0U/62mj7FDQ6vGnO8vY eLk48WuB1l9Rg6C9v0Zl2ri4X+2Rm0GerlgsdRTRtA21TL7isQTDb8Pa+IE+jSsTnwwI OP3bc5BHIXhi4RQBFDnIAmtkRYf5DXHZ5GC50GXAqlwRQ1XDE58cvzhT8vurufYF3fYp 5f5Vf+bxUAVLG7Y24gGNr60V8OiFMNHL/Y0QxtIMtcNF0sTY6yreqZ3SfnDDOvXYQI3I 8jQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678231999; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=CiPCdS7YWLbLvqN+ql4t86Rs7fqQxGYeQIPy6W1tBaw=; b=QEZmu34EagLaF4qjwLSHuhiGCGA9bDq/TSpGCIusv28QL62YU5HiRPCWaQ2VaSl83F 4a7BQxDy6n9TTrvPsOpV/i09aTGjj5tLu8F89ZycU13wg54ipfXFfV/Hsoc4QfNQjNUm ldSyluDN5cOlkLPaFEAYCmShZ7XJnAEDvP8wxUu8xu6nf2JP/kIShd1KA21BniFK7lio DCYZZQHAAWakhxLlMLXnjEIf6BNOxBVIpqCxqxgUWFPoZ+DlmS32JrAsrc43mjmQnKxs /QJKCqMjR+kRvHRpX5qwa5zFPO/5gKOKsA+yhLlYK8+o7Ma0OfmDFnHZqZXbjiPoRYN9 mR4w== X-Gm-Message-State: AO0yUKWwU+gyVlC+/JjLcRtsyUO/a9YwnuTykj46nuMm6xZuHSkoWBzr ilGu5XOcBlEFLQMiIW9wRDg= X-Google-Smtp-Source: AK7set/j3aXuw30R0wzsqrDuf73erFHyMldCeOgBdA3BHON8T2Q/STYKrIgH6+CI41pnLFXugx/10w== X-Received: by 2002:a62:1dd4:0:b0:5d6:138f:5596 with SMTP id d203-20020a621dd4000000b005d6138f5596mr16883881pfd.14.1678231999625; Tue, 07 Mar 2023 15:33:19 -0800 (PST) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:15e8:b801:cd55:a496]) by smtp.gmail.com with ESMTPSA id l11-20020a62be0b000000b005da23d8cbffsm8342217pff.158.2023.03.07.15.33.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Mar 2023 15:33:18 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa Cc: Peter Zijlstra , Ingo Molnar , Ian Rogers , Adrian Hunter , Andi Kleen , Kan Liang , Song Liu , Stephane Eranian , Ravi Bangoria , Leo Yan , James Clark , Hao Luo , LKML , linux-perf-users@vger.kernel.org, bpf@vger.kernel.org Subject: [PATCH 4/9] perf record: Record dropped sample count Date: Tue, 7 Mar 2023 15:33:04 -0800 Message-Id: <20230307233309.3546160-5-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230307233309.3546160-1-namhyung@kernel.org> References: <20230307233309.3546160-1-namhyung@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org When it uses bpf filters, event might drop some samples. It'd be nice if it can report how many samples it lost. As LOST_SAMPLES event can carry the similar information, let's use it for bpf filters. To indicate it's from BPF filters, add a new misc flag for that and do not display cpu load warnings. Acked-by: Jiri Olsa Signed-off-by: Namhyung Kim --- tools/lib/perf/include/perf/event.h | 2 ++ tools/perf/builtin-record.c | 38 ++++++++++++++++++----------- tools/perf/util/bpf-filter.c | 7 ++++++ tools/perf/util/bpf-filter.h | 5 ++++ tools/perf/util/session.c | 3 ++- 5 files changed, 40 insertions(+), 15 deletions(-) diff --git a/tools/lib/perf/include/perf/event.h b/tools/lib/perf/include/perf/event.h index ad47d7b31046..51b9338f4c11 100644 --- a/tools/lib/perf/include/perf/event.h +++ b/tools/lib/perf/include/perf/event.h @@ -70,6 +70,8 @@ struct perf_record_lost { __u64 lost; }; +#define PERF_RECORD_MISC_LOST_SAMPLES_BPF (1 << 15) + struct perf_record_lost_samples { struct perf_event_header header; __u64 lost; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 8374117e66f6..197e802a150b 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -52,6 +52,7 @@ #include "util/pmu-hybrid.h" #include "util/evlist-hybrid.h" #include "util/off_cpu.h" +#include "util/bpf-filter.h" #include "asm/bug.h" #include "perf.h" #include "cputopo.h" @@ -1856,24 +1857,16 @@ record__switch_output(struct record *rec, bool at_exit) return fd; } -static void __record__read_lost_samples(struct record *rec, struct evsel *evsel, +static void __record__save_lost_samples(struct record *rec, struct evsel *evsel, struct perf_record_lost_samples *lost, - int cpu_idx, int thread_idx) + int cpu_idx, int thread_idx, u64 lost_count, + u16 misc_flag) { - struct perf_counts_values count; struct perf_sample_id *sid; struct perf_sample sample = {}; int id_hdr_size; - if (perf_evsel__read(&evsel->core, cpu_idx, thread_idx, &count) < 0) { - pr_err("read LOST count failed\n"); - return; - } - - if (count.lost == 0) - return; - - lost->lost = count.lost; + lost->lost = lost_count; if (evsel->core.ids) { sid = xyarray__entry(evsel->core.sample_id, cpu_idx, thread_idx); sample.id = sid->id; @@ -1882,6 +1875,7 @@ static void __record__read_lost_samples(struct record *rec, struct evsel *evsel, id_hdr_size = perf_event__synthesize_id_sample((void *)(lost + 1), evsel->core.attr.sample_type, &sample); lost->header.size = sizeof(*lost) + id_hdr_size; + lost->header.misc = misc_flag; record__write(rec, NULL, lost, lost->header.size); } @@ -1905,6 +1899,7 @@ static void record__read_lost_samples(struct record *rec) evlist__for_each_entry(session->evlist, evsel) { struct xyarray *xy = evsel->core.sample_id; + u64 lost_count; if (xy == NULL || evsel->core.fd == NULL) continue; @@ -1916,12 +1911,27 @@ static void record__read_lost_samples(struct record *rec) for (int x = 0; x < xyarray__max_x(xy); x++) { for (int y = 0; y < xyarray__max_y(xy); y++) { - __record__read_lost_samples(rec, evsel, lost, x, y); + struct perf_counts_values count; + + if (perf_evsel__read(&evsel->core, x, y, &count) < 0) { + pr_err("read LOST count failed\n"); + goto out; + } + + if (count.lost) { + __record__save_lost_samples(rec, evsel, lost, + x, y, count.lost, 0); + } } } + + lost_count = perf_bpf_filter__lost_count(evsel); + if (lost_count) + __record__save_lost_samples(rec, evsel, lost, 0, 0, lost_count, + PERF_RECORD_MISC_LOST_SAMPLES_BPF); } +out: free(lost); - } static volatile sig_atomic_t workload_exec_errno; diff --git a/tools/perf/util/bpf-filter.c b/tools/perf/util/bpf-filter.c index f20e1bc03778..7bd6f2e41513 100644 --- a/tools/perf/util/bpf-filter.c +++ b/tools/perf/util/bpf-filter.c @@ -69,6 +69,13 @@ int perf_bpf_filter__destroy(struct evsel *evsel) return 0; } +u64 perf_bpf_filter__lost_count(struct evsel *evsel) +{ + struct sample_filter_bpf *skel = evsel->bpf_skel; + + return skel ? skel->bss->dropped : 0; +} + struct perf_bpf_filter_expr *perf_bpf_filter_expr__new(unsigned long sample_flags, enum perf_bpf_filter_op op, unsigned long val) diff --git a/tools/perf/util/bpf-filter.h b/tools/perf/util/bpf-filter.h index eb8e1ac43cdf..f0c66764c6d0 100644 --- a/tools/perf/util/bpf-filter.h +++ b/tools/perf/util/bpf-filter.h @@ -22,6 +22,7 @@ struct perf_bpf_filter_expr *perf_bpf_filter_expr__new(unsigned long sample_flag int perf_bpf_filter__parse(struct list_head *expr_head, const char *str); int perf_bpf_filter__prepare(struct evsel *evsel); int perf_bpf_filter__destroy(struct evsel *evsel); +u64 perf_bpf_filter__lost_count(struct evsel *evsel); #else /* !HAVE_BPF_SKEL */ @@ -38,5 +39,9 @@ static inline int perf_bpf_filter__destroy(struct evsel *evsel __maybe_unused) { return -EOPNOTSUPP; } +static inline u64 perf_bpf_filter__lost_count(struct evsel *evsel __maybe_unused) +{ + return 0; +} #endif /* HAVE_BPF_SKEL*/ #endif /* PERF_UTIL_BPF_FILTER_H */ diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 749d5b5c135b..7d8d057d1772 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1582,7 +1582,8 @@ static int machines__deliver_event(struct machines *machines, evlist->stats.total_lost += event->lost.lost; return tool->lost(tool, event, sample, machine); case PERF_RECORD_LOST_SAMPLES: - if (tool->lost_samples == perf_event__process_lost_samples) + if (tool->lost_samples == perf_event__process_lost_samples && + !(event->header.misc & PERF_RECORD_MISC_LOST_SAMPLES_BPF)) evlist->stats.total_lost_samples += event->lost_samples.lost; return tool->lost_samples(tool, event, sample, machine); case PERF_RECORD_READ: From patchwork Tue Mar 7 23:33:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13164944 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 69272C6FA99 for ; Tue, 7 Mar 2023 23:33:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229972AbjCGXdZ (ORCPT ); Tue, 7 Mar 2023 18:33:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43910 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229966AbjCGXdX (ORCPT ); Tue, 7 Mar 2023 18:33:23 -0500 Received: from mail-pg1-x536.google.com (mail-pg1-x536.google.com [IPv6:2607:f8b0:4864:20::536]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0B97C76F54; Tue, 7 Mar 2023 15:33:22 -0800 (PST) Received: by mail-pg1-x536.google.com with SMTP id z10so8620708pgr.8; Tue, 07 Mar 2023 15:33:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678232001; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=BSYFKW/f4cBllB72XD0Anmg2JAAmUIvfnX1lH/HWE8g=; b=PXqbxPmcykJazCAipqVop4Vgq8LFaDno2vr4y2dpXqgZLGMST1LwAAKXtuauhxZkJ9 e6WqoK7uW8mwFtLjywvT8CYkLGlkYacHiJ4vnEQg97U7q4lPZbpj4nTWWB3AJG6j9/XF icw9rojoLATo22XQv0BjhFOilzpu/B5lIWmY33ltkUXtF+kPmu7fqnyF6O7jZcHfZmPN 2/Q9HM1Ra4bT6iCCy5ZzsY+D7IDtgq9bXPkSoeVRAZOBnDuXXtrySJuqRTB7GttMKMEi +7zpfdQPW35xe7FT7fnhuejXIYWFYKTSgbhm2hWcnflbNkkU1O9gE9lPPQkNCxx+ZypK 4DSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678232001; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=BSYFKW/f4cBllB72XD0Anmg2JAAmUIvfnX1lH/HWE8g=; b=G2GOD2XagFFs80oWuvfS9iaJu6/tBxaTOY7N/BbLIfodeHj7JZDCYNt3lAVi7GO+oY Gfe4ut3CkUIxBlZqak8xEWJiZRFbE7uOZRV0ydL2RM9yS9upfH9xIZ/8sjszrkmLVQUN N+9EvxGzsKw95OYkbc7QXDa1rzNrBOt4n9oL4nVbgdbRNnQPtNcIXNc24hlhkcOat2l8 l/Qx5QJxAI8JbwNAgr9qQ0Q7T5YGlk777PWq6HBlaWns2NkmY+FL+zO7XizaME4XA8HU GJ2Q0OIFv/+9DDSlwP3mKwsRApLtiiiVJTrrSNVbcRvqCV7At853CBjmoFHGfxdi04nH BRQQ== X-Gm-Message-State: AO0yUKXWL8V8t8WZQiO2CbydhiKQCSs5pJNCMz++CjKmoZ28E3GGLH6n HjokW+Q++pp3yUpI2ZxpmG4= X-Google-Smtp-Source: AK7set/yygdmTl2Ud7hNbNr8heUCT5ybTO6ZS2vMDtheV59zz2PQDvMkTyDGtoXM8bOHMPfehAnlfQ== X-Received: by 2002:aa7:941d:0:b0:5f1:f57a:b0c3 with SMTP id x29-20020aa7941d000000b005f1f57ab0c3mr14936637pfo.5.1678232001457; Tue, 07 Mar 2023 15:33:21 -0800 (PST) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:15e8:b801:cd55:a496]) by smtp.gmail.com with ESMTPSA id l11-20020a62be0b000000b005da23d8cbffsm8342217pff.158.2023.03.07.15.33.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Mar 2023 15:33:20 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa Cc: Peter Zijlstra , Ingo Molnar , Ian Rogers , Adrian Hunter , Andi Kleen , Kan Liang , Song Liu , Stephane Eranian , Ravi Bangoria , Leo Yan , James Clark , Hao Luo , LKML , linux-perf-users@vger.kernel.org, bpf@vger.kernel.org Subject: [PATCH 5/9] perf bpf filter: Add 'pid' sample data support Date: Tue, 7 Mar 2023 15:33:05 -0800 Message-Id: <20230307233309.3546160-6-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230307233309.3546160-1-namhyung@kernel.org> References: <20230307233309.3546160-1-namhyung@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org The pid is special because it's saved in the PERF_SAMPLE_TID together. So it needs to differenciate tid and pid using the 'part' field in the perf bpf filter entry struct. Acked-by: Jiri Olsa Signed-off-by: Namhyung Kim --- tools/perf/util/bpf-filter.c | 4 +++- tools/perf/util/bpf-filter.h | 3 ++- tools/perf/util/bpf-filter.l | 11 ++++++++++- tools/perf/util/bpf-filter.y | 7 +++++-- tools/perf/util/bpf_skel/sample-filter.h | 3 ++- tools/perf/util/bpf_skel/sample_filter.bpf.c | 5 ++++- 6 files changed, 26 insertions(+), 7 deletions(-) diff --git a/tools/perf/util/bpf-filter.c b/tools/perf/util/bpf-filter.c index 7bd6f2e41513..743c69fd6cd4 100644 --- a/tools/perf/util/bpf-filter.c +++ b/tools/perf/util/bpf-filter.c @@ -36,6 +36,7 @@ int perf_bpf_filter__prepare(struct evsel *evsel) list_for_each_entry(expr, &evsel->bpf_filters, list) { struct perf_bpf_filter_entry entry = { .op = expr->op, + .part = expr->part, .flags = expr->sample_flags, .value = expr->val, }; @@ -76,7 +77,7 @@ u64 perf_bpf_filter__lost_count(struct evsel *evsel) return skel ? skel->bss->dropped : 0; } -struct perf_bpf_filter_expr *perf_bpf_filter_expr__new(unsigned long sample_flags, +struct perf_bpf_filter_expr *perf_bpf_filter_expr__new(unsigned long sample_flags, int part, enum perf_bpf_filter_op op, unsigned long val) { @@ -85,6 +86,7 @@ struct perf_bpf_filter_expr *perf_bpf_filter_expr__new(unsigned long sample_flag expr = malloc(sizeof(*expr)); if (expr != NULL) { expr->sample_flags = sample_flags; + expr->part = part; expr->op = op; expr->val = val; } diff --git a/tools/perf/util/bpf-filter.h b/tools/perf/util/bpf-filter.h index f0c66764c6d0..3f8827bd965f 100644 --- a/tools/perf/util/bpf-filter.h +++ b/tools/perf/util/bpf-filter.h @@ -9,6 +9,7 @@ struct perf_bpf_filter_expr { struct list_head list; enum perf_bpf_filter_op op; + int part; unsigned long sample_flags; unsigned long val; }; @@ -16,7 +17,7 @@ struct perf_bpf_filter_expr { struct evsel; #ifdef HAVE_BPF_SKEL -struct perf_bpf_filter_expr *perf_bpf_filter_expr__new(unsigned long sample_flags, +struct perf_bpf_filter_expr *perf_bpf_filter_expr__new(unsigned long sample_flags, int part, enum perf_bpf_filter_op op, unsigned long val); int perf_bpf_filter__parse(struct list_head *expr_head, const char *str); diff --git a/tools/perf/util/bpf-filter.l b/tools/perf/util/bpf-filter.l index f6c0b74ea285..ec12fc4d2ab8 100644 --- a/tools/perf/util/bpf-filter.l +++ b/tools/perf/util/bpf-filter.l @@ -11,7 +11,15 @@ static int sample(unsigned long sample_flag) { - perf_bpf_filter_lval.sample = sample_flag; + perf_bpf_filter_lval.sample.type = sample_flag; + perf_bpf_filter_lval.sample.part = 0; + return BFT_SAMPLE; +} + +static int sample_part(unsigned long sample_flag, int part) +{ + perf_bpf_filter_lval.sample.type = sample_flag; + perf_bpf_filter_lval.sample.part = part; return BFT_SAMPLE; } @@ -56,6 +64,7 @@ ident [_a-zA-Z][_a-zA-Z0-9]+ ip { return sample(PERF_SAMPLE_IP); } id { return sample(PERF_SAMPLE_ID); } tid { return sample(PERF_SAMPLE_TID); } +pid { return sample_part(PERF_SAMPLE_TID, 1); } cpu { return sample(PERF_SAMPLE_CPU); } time { return sample(PERF_SAMPLE_TIME); } addr { return sample(PERF_SAMPLE_ADDR); } diff --git a/tools/perf/util/bpf-filter.y b/tools/perf/util/bpf-filter.y index 13eca612ecca..0ca6532afd8d 100644 --- a/tools/perf/util/bpf-filter.y +++ b/tools/perf/util/bpf-filter.y @@ -20,7 +20,10 @@ static void perf_bpf_filter_error(struct list_head *expr __maybe_unused, %union { unsigned long num; - unsigned long sample; + struct { + unsigned long type; + int part; + } sample; enum perf_bpf_filter_op op; struct perf_bpf_filter_expr *expr; } @@ -48,7 +51,7 @@ filter_term filter_term: BFT_SAMPLE BFT_OP BFT_NUM { - $$ = perf_bpf_filter_expr__new($1, $2, $3); + $$ = perf_bpf_filter_expr__new($1.type, $1.part, $2, $3); } %% diff --git a/tools/perf/util/bpf_skel/sample-filter.h b/tools/perf/util/bpf_skel/sample-filter.h index 862060bfda14..6b9fd554ad7b 100644 --- a/tools/perf/util/bpf_skel/sample-filter.h +++ b/tools/perf/util/bpf_skel/sample-filter.h @@ -17,7 +17,8 @@ enum perf_bpf_filter_op { /* BPF map entry for filtering */ struct perf_bpf_filter_entry { enum perf_bpf_filter_op op; - __u64 flags; + __u32 part; /* sub-sample type info when it has multiple values */ + __u64 flags; /* perf sample type flags */ __u64 value; }; diff --git a/tools/perf/util/bpf_skel/sample_filter.bpf.c b/tools/perf/util/bpf_skel/sample_filter.bpf.c index c07256279c3e..dddf38c27bb7 100644 --- a/tools/perf/util/bpf_skel/sample_filter.bpf.c +++ b/tools/perf/util/bpf_skel/sample_filter.bpf.c @@ -40,7 +40,10 @@ static inline __u64 perf_get_sample(struct bpf_perf_event_data_kern *kctx, case PERF_SAMPLE_ID: return kctx->data->id; case PERF_SAMPLE_TID: - return kctx->data->tid_entry.tid; + if (entry->part) + return kctx->data->tid_entry.pid; + else + return kctx->data->tid_entry.tid; case PERF_SAMPLE_CPU: return kctx->data->cpu_entry.cpu; case PERF_SAMPLE_TIME: From patchwork Tue Mar 7 23:33:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13164946 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 84D2DC6FD1E for ; Tue, 7 Mar 2023 23:33:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229994AbjCGXdp (ORCPT ); Tue, 7 Mar 2023 18:33:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44128 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229995AbjCGXdZ (ORCPT ); Tue, 7 Mar 2023 18:33:25 -0500 Received: from mail-pj1-x1032.google.com (mail-pj1-x1032.google.com [IPv6:2607:f8b0:4864:20::1032]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B9CB37BA2A; Tue, 7 Mar 2023 15:33:23 -0800 (PST) Received: by mail-pj1-x1032.google.com with SMTP id m8-20020a17090a4d8800b002377bced051so470788pjh.0; Tue, 07 Mar 2023 15:33:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678232003; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=x3XJiLzYWTl1qdcO6Aoy/MeuV984OrXXQga9tTJym9M=; b=k/ZMLtxDsB+YHPhfeOKHYIWLbC8qdI6ZoY7C2sPPUkIl3TUW1OeJkzWUQdTijzRFDO GhExusyellPgYMqpl4alfdYq9NFrrgu6GUlAOKd03NJOY9x11JoBc9pGxQznHCfw+Vkc 5FT8HDnVzrVhFAB9g2h7otDaInhTm5KRBrOQkLlR31DNoBrNv+QLLhAX/AXG3Kb86Uqq feJZ1nEjMTimEuVqxg6Wlf2+R8vVyi8QN3pnFuFxH4nvbVY5ZQAo6O0qPJI9NbJFrpOa EEFJ5uMniBL+MR72jGxlelEI4gxgxwG6vJP/JH9qp/FTHWGGxuInYjcxa0xACDmz5/i6 eopw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678232003; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=x3XJiLzYWTl1qdcO6Aoy/MeuV984OrXXQga9tTJym9M=; b=18D/Bj9CzvvvpAdwDlQKfNVt/jG7IUH4BiaBzkPD12yGE8hzcMDSRQurqwXQHDU3Db DUbC9HWtHObWcUdWgdnd4vCVFtvFMk64EWWUFf5iEmK1zc7YML1zCv7ZJyGjWbN6veHc x6PLbgQN/IlqlRHbX46ENacUaCwdA7mLv+0szG6aQ/VRjQf9s9dnzYf0N+/OT9xo263m IJHZQenmpamRGhVsd2JDXFYdt+FM1tEj5yo0Jxa5vbu3vgXcAVbzwUEZ9pKlQEIZOldH Ipfqm5l6+WXyDbcqWw2QfcyK2Nux9qpnfSZm3UjlT1rKVGNpsotzttCl3qj+HPUHHeHb Jscw== X-Gm-Message-State: AO0yUKXH5cr7r2ceIhbaDTlXxczc1Hz03vPTUun6/HH3vy4lmskMj9L3 653dtmzXzj8184774o6vEbw= X-Google-Smtp-Source: AK7set//M15swegfo840vAPhluG6X15dTHI61Dzkynwcp3PxVLv8165+EUMgSytQouKSSp4bTw+byA== X-Received: by 2002:a05:6a20:a01a:b0:cc:7967:8a75 with SMTP id p26-20020a056a20a01a00b000cc79678a75mr15029486pzj.46.1678232003035; Tue, 07 Mar 2023 15:33:23 -0800 (PST) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:15e8:b801:cd55:a496]) by smtp.gmail.com with ESMTPSA id l11-20020a62be0b000000b005da23d8cbffsm8342217pff.158.2023.03.07.15.33.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Mar 2023 15:33:22 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa Cc: Peter Zijlstra , Ingo Molnar , Ian Rogers , Adrian Hunter , Andi Kleen , Kan Liang , Song Liu , Stephane Eranian , Ravi Bangoria , Leo Yan , James Clark , Hao Luo , LKML , linux-perf-users@vger.kernel.org, bpf@vger.kernel.org Subject: [PATCH 6/9] perf bpf filter: Add more weight sample data support Date: Tue, 7 Mar 2023 15:33:06 -0800 Message-Id: <20230307233309.3546160-7-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230307233309.3546160-1-namhyung@kernel.org> References: <20230307233309.3546160-1-namhyung@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org The weight data consists of a couple of fields with the PERF_SAMPLE_WEIGHT_STRUCT. Add weight{1,2,3} term to select them separately. Also add their aliases like 'ins_lat', 'p_stage_cyc' and 'retire_lat'. Acked-by: Jiri Olsa Signed-off-by: Namhyung Kim --- tools/perf/util/bpf-filter.l | 6 ++++++ tools/perf/util/bpf_skel/sample_filter.bpf.c | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/tools/perf/util/bpf-filter.l b/tools/perf/util/bpf-filter.l index ec12fc4d2ab8..419f923b35c0 100644 --- a/tools/perf/util/bpf-filter.l +++ b/tools/perf/util/bpf-filter.l @@ -71,6 +71,12 @@ addr { return sample(PERF_SAMPLE_ADDR); } period { return sample(PERF_SAMPLE_PERIOD); } txn { return sample(PERF_SAMPLE_TRANSACTION); } weight { return sample(PERF_SAMPLE_WEIGHT); } +weight1 { return sample_part(PERF_SAMPLE_WEIGHT_STRUCT, 1); } +weight2 { return sample_part(PERF_SAMPLE_WEIGHT_STRUCT, 2); } +weight3 { return sample_part(PERF_SAMPLE_WEIGHT_STRUCT, 3); } +ins_lat { return sample_part(PERF_SAMPLE_WEIGHT_STRUCT, 2); } /* alias for weight2 */ +p_stage_cyc { return sample_part(PERF_SAMPLE_WEIGHT_STRUCT, 3); } /* alias for weight3 */ +retire_lat { return sample_part(PERF_SAMPLE_WEIGHT_STRUCT, 3); } /* alias for weight3 */ phys_addr { return sample(PERF_SAMPLE_PHYS_ADDR); } code_pgsz { return sample(PERF_SAMPLE_CODE_PAGE_SIZE); } data_pgsz { return sample(PERF_SAMPLE_DATA_PAGE_SIZE); } diff --git a/tools/perf/util/bpf_skel/sample_filter.bpf.c b/tools/perf/util/bpf_skel/sample_filter.bpf.c index dddf38c27bb7..d930401c5bfc 100644 --- a/tools/perf/util/bpf_skel/sample_filter.bpf.c +++ b/tools/perf/util/bpf_skel/sample_filter.bpf.c @@ -54,6 +54,14 @@ static inline __u64 perf_get_sample(struct bpf_perf_event_data_kern *kctx, return kctx->data->period; case PERF_SAMPLE_TRANSACTION: return kctx->data->txn; + case PERF_SAMPLE_WEIGHT_STRUCT: + if (entry->part == 1) + return kctx->data->weight.var1_dw; + if (entry->part == 2) + return kctx->data->weight.var2_w; + if (entry->part == 3) + return kctx->data->weight.var3_w; + /* fall through */ case PERF_SAMPLE_WEIGHT: return kctx->data->weight.full; case PERF_SAMPLE_PHYS_ADDR: From patchwork Tue Mar 7 23:33:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13164949 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 61F77C6FA99 for ; Tue, 7 Mar 2023 23:34:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230126AbjCGXeK (ORCPT ); Tue, 7 Mar 2023 18:34:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44126 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229989AbjCGXdn (ORCPT ); Tue, 7 Mar 2023 18:33:43 -0500 Received: from mail-pf1-x42c.google.com (mail-pf1-x42c.google.com [IPv6:2607:f8b0:4864:20::42c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 100E78F719; Tue, 7 Mar 2023 15:33:26 -0800 (PST) Received: by mail-pf1-x42c.google.com with SMTP id c4so9203310pfl.0; Tue, 07 Mar 2023 15:33:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678232005; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=AUz9t3miV/6g18NoyX2KHMC0EiLYl+hvlFPuzWmCtsU=; b=QDQgd8BXom7RVfHsgPHJlBb0eK5ZRzbHLqr7ARFKkWJFG+Es9/7qTcJCV0Cw11/UkE 6ueMj2FkyDMDQDNJTpf6bb+0RRC6eyabWmtxfTU6xUbRK7qq5+QZwk/Yjl6r3S2YQE0I PRZU+mA2ztQn+hsjSxeoQT4nh4sXMJXW7udAW4+xpV35f4XbkcLTvq1jXnjewbNgyuSQ Kb0NjU0u/F8hCcuQscxxKORkI7zgMq0XEQWHUb6Pys3UI/zzJSS2ZRVa/xeKrbEMBOEF BSMM4IripbuhX3CMrwE4GdOf7kd4mdWYfCJWGiLKQsY1YhtfHYL91Nn+mD7xxDItEo8b GLLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678232005; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=AUz9t3miV/6g18NoyX2KHMC0EiLYl+hvlFPuzWmCtsU=; b=zvDzFPg8vHGqINMo6EEMIe2Ya2sOCspGjOJOFOcGqUrMF4wyxN7zUo5nbndxk1NkHc kGIL0dtiePpA5S5FrXSfPZpvQLPNdJGiWuj8831Dm4SM1wn+WWDWp+nsj/3zJ/rZqrxM 1e/VicGH9Z90DsFaDfEcVnLkZzHX31RblnJ1tUoxm33o15jz9V5U2tDXejUCYyx3mAPN xBImTDsLbErDNGg/XJPIG7hfhbyqIK9tdrZBPZVwI/hMGNtJWcKiVW6kv5bqOlAmqMxB tEVQWaT6C0BKf1o7F0ePtJmmIQhfg1SSvr9BKYVCjtKDbPWwkJo4zh8/mlVFK5d69Khe kLcg== X-Gm-Message-State: AO0yUKXCS6ledxpDErEDeCBNlvlqrfrkxMmpC7qY7Ra9FC0wftfwP4O/ q5dtjlIFNR52dTh+MFo2fJk= X-Google-Smtp-Source: AK7set8I740AwmmPZ55XZZrZRiOhoTgJIyrL0e/Js2b6mpEUTfIvuC2eI/4E1YJQ8xsXM+TrRoYRyg== X-Received: by 2002:a62:5210:0:b0:5d9:f3a6:a925 with SMTP id g16-20020a625210000000b005d9f3a6a925mr12317983pfb.24.1678232005281; Tue, 07 Mar 2023 15:33:25 -0800 (PST) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:15e8:b801:cd55:a496]) by smtp.gmail.com with ESMTPSA id l11-20020a62be0b000000b005da23d8cbffsm8342217pff.158.2023.03.07.15.33.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Mar 2023 15:33:24 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa Cc: Peter Zijlstra , Ingo Molnar , Ian Rogers , Adrian Hunter , Andi Kleen , Kan Liang , Song Liu , Stephane Eranian , Ravi Bangoria , Leo Yan , James Clark , Hao Luo , LKML , linux-perf-users@vger.kernel.org, bpf@vger.kernel.org Subject: [PATCH 7/9] perf bpf filter: Add data_src sample data support Date: Tue, 7 Mar 2023 15:33:07 -0800 Message-Id: <20230307233309.3546160-8-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230307233309.3546160-1-namhyung@kernel.org> References: <20230307233309.3546160-1-namhyung@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org The data_src has many entries to express memory behaviors. Add each term separately so that users can combine them for their purpose. I didn't add prefix for the constants for simplicity as they are mostly distinguishable but I had to use l1_miss and l2_hit for mem_dtlb since mem_lvl has different values for the same names. Note that I decided mem_lvl to be used as an alias of mem_lvlnum as it's deprecated now. According to the comment in the UAPI header, users should use the mix of mem_lvlnum, mem_remote and mem_snoop. Also the SNOOPX bits are concatenated to mem_snoop for simplicity. The following terms are used for data_src and the corresponding perf sample data fields: * mem_op : { load, store, pfetch, exec } * mem_lvl: { l1, l2, l3, l4, cxl, io, any_cache, lfb, ram, pmem } * mem_snoop: { none, hit, miss, hitm, fwd, peer } * mem_remote: { remote } * mem_lock: { locked } * mem_dtlb { l1_hit, l1_miss, l2_hit, l2_miss, any_hit, any_miss, walk, fault } * mem_blk { by_data, by_addr } * mem_hops { hops0, hops1, hops2, hops3 } We can now use a filter expression like below: 'mem_op == load, mem_lvl <= l2, mem_dtlb == l1_hit' 'mem_dtlb == l2_miss, mem_hops > hops1' 'mem_lvl == ram, mem_remote == 1' Note that 'na' is shared among the terms as it has the same value except for mem_lvl. I don't have a good idea to handle that for now. Acked-by: Jiri Olsa Signed-off-by: Namhyung Kim --- tools/perf/util/bpf-filter.l | 61 ++++++++++++++++++++ tools/perf/util/bpf_skel/sample_filter.bpf.c | 23 ++++++++ 2 files changed, 84 insertions(+) diff --git a/tools/perf/util/bpf-filter.l b/tools/perf/util/bpf-filter.l index 419f923b35c0..3e66b7a0215e 100644 --- a/tools/perf/util/bpf-filter.l +++ b/tools/perf/util/bpf-filter.l @@ -42,6 +42,12 @@ static int value(int base) return BFT_NUM; } +static int constant(int val) +{ + perf_bpf_filter_lval.num = val; + return BFT_NUM; +} + static int error(const char *str) { printf("perf_bpf_filter: Unexpected filter %s: %s\n", str, perf_bpf_filter_text); @@ -80,6 +86,15 @@ retire_lat { return sample_part(PERF_SAMPLE_WEIGHT_STRUCT, 3); } /* alias for we phys_addr { return sample(PERF_SAMPLE_PHYS_ADDR); } code_pgsz { return sample(PERF_SAMPLE_CODE_PAGE_SIZE); } data_pgsz { return sample(PERF_SAMPLE_DATA_PAGE_SIZE); } +mem_op { return sample_part(PERF_SAMPLE_DATA_SRC, 1); } +mem_lvlnum { return sample_part(PERF_SAMPLE_DATA_SRC, 2); } +mem_lvl { return sample_part(PERF_SAMPLE_DATA_SRC, 2); } /* alias for mem_lvlnum */ +mem_snoop { return sample_part(PERF_SAMPLE_DATA_SRC, 3); } /* include snoopx */ +mem_remote { return sample_part(PERF_SAMPLE_DATA_SRC, 4); } +mem_lock { return sample_part(PERF_SAMPLE_DATA_SRC, 5); } +mem_dtlb { return sample_part(PERF_SAMPLE_DATA_SRC, 6); } +mem_blk { return sample_part(PERF_SAMPLE_DATA_SRC, 7); } +mem_hops { return sample_part(PERF_SAMPLE_DATA_SRC, 8); } "==" { return operator(PBF_OP_EQ); } "!=" { return operator(PBF_OP_NEQ); } @@ -89,6 +104,52 @@ data_pgsz { return sample(PERF_SAMPLE_DATA_PAGE_SIZE); } "<=" { return operator(PBF_OP_LE); } "&" { return operator(PBF_OP_AND); } +na { return constant(PERF_MEM_OP_NA); } +load { return constant(PERF_MEM_OP_LOAD); } +store { return constant(PERF_MEM_OP_STORE); } +pfetch { return constant(PERF_MEM_OP_PFETCH); } +exec { return constant(PERF_MEM_OP_EXEC); } + +l1 { return constant(PERF_MEM_LVLNUM_L1); } +l2 { return constant(PERF_MEM_LVLNUM_L2); } +l3 { return constant(PERF_MEM_LVLNUM_L3); } +l4 { return constant(PERF_MEM_LVLNUM_L4); } +cxl { return constant(PERF_MEM_LVLNUM_CXL); } +io { return constant(PERF_MEM_LVLNUM_IO); } +any_cache { return constant(PERF_MEM_LVLNUM_ANY_CACHE); } +lfb { return constant(PERF_MEM_LVLNUM_LFB); } +ram { return constant(PERF_MEM_LVLNUM_RAM); } +pmem { return constant(PERF_MEM_LVLNUM_PMEM); } + +none { return constant(PERF_MEM_SNOOP_NONE); } +hit { return constant(PERF_MEM_SNOOP_HIT); } +miss { return constant(PERF_MEM_SNOOP_MISS); } +hitm { return constant(PERF_MEM_SNOOP_HITM); } +fwd { return constant(PERF_MEM_SNOOPX_FWD); } +peer { return constant(PERF_MEM_SNOOPX_PEER); } + +remote { return constant(PERF_MEM_REMOTE_REMOTE); } + +locked { return constant(PERF_MEM_LOCK_LOCKED); } + +l1_hit { return constant(PERF_MEM_TLB_L1 | PERF_MEM_TLB_HIT); } +l1_miss { return constant(PERF_MEM_TLB_L1 | PERF_MEM_TLB_MISS); } +l2_hit { return constant(PERF_MEM_TLB_L2 | PERF_MEM_TLB_HIT); } +l2_miss { return constant(PERF_MEM_TLB_L2 | PERF_MEM_TLB_MISS); } +any_hit { return constant(PERF_MEM_TLB_HIT); } +any_miss { return constant(PERF_MEM_TLB_MISS); } +walk { return constant(PERF_MEM_TLB_WK); } +os { return constant(PERF_MEM_TLB_OS); } +fault { return constant(PERF_MEM_TLB_OS); } /* alias for os */ + +by_data { return constant(PERF_MEM_BLK_DATA); } +by_addr { return constant(PERF_MEM_BLK_ADDR); } + +hops0 { return constant(PERF_MEM_HOPS_0); } +hops1 { return constant(PERF_MEM_HOPS_1); } +hops2 { return constant(PERF_MEM_HOPS_2); } +hops3 { return constant(PERF_MEM_HOPS_3); } + "," { return ','; } {ident} { return error("ident"); } diff --git a/tools/perf/util/bpf_skel/sample_filter.bpf.c b/tools/perf/util/bpf_skel/sample_filter.bpf.c index d930401c5bfc..88dbc788d257 100644 --- a/tools/perf/util/bpf_skel/sample_filter.bpf.c +++ b/tools/perf/util/bpf_skel/sample_filter.bpf.c @@ -70,6 +70,29 @@ static inline __u64 perf_get_sample(struct bpf_perf_event_data_kern *kctx, return kctx->data->code_page_size; case PERF_SAMPLE_DATA_PAGE_SIZE: return kctx->data->data_page_size; + case PERF_SAMPLE_DATA_SRC: + if (entry->part == 1) + return kctx->data->data_src.mem_op; + if (entry->part == 2) + return kctx->data->data_src.mem_lvl_num; + if (entry->part == 3) { + __u32 snoop = kctx->data->data_src.mem_snoop; + __u32 snoopx = kctx->data->data_src.mem_snoopx; + + return (snoopx << 5) | snoop; + } + if (entry->part == 4) + return kctx->data->data_src.mem_remote; + if (entry->part == 5) + return kctx->data->data_src.mem_lock; + if (entry->part == 6) + return kctx->data->data_src.mem_dtlb; + if (entry->part == 7) + return kctx->data->data_src.mem_blk; + if (entry->part == 8) + return kctx->data->data_src.mem_hops; + /* return the whole word */ + return kctx->data->data_src.val; default: break; } From patchwork Tue Mar 7 23:33:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13164950 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 41C75C678D5 for ; Tue, 7 Mar 2023 23:34:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230171AbjCGXeY (ORCPT ); Tue, 7 Mar 2023 18:34:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44062 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229965AbjCGXdy (ORCPT ); Tue, 7 Mar 2023 18:33:54 -0500 Received: from mail-pg1-x535.google.com (mail-pg1-x535.google.com [IPv6:2607:f8b0:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 22BB296631; Tue, 7 Mar 2023 15:33:27 -0800 (PST) Received: by mail-pg1-x535.google.com with SMTP id 132so8605075pgh.13; Tue, 07 Mar 2023 15:33:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678232007; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=mHzEdCPWpaY/eH0Xx+geXzySB0PiK8eElCruHy6sF1Y=; b=RpH6elTpz9hGiTv7ncZWQN1s8eoMpj3qIDx275tZO76SsohweHvL3GzuXuefV0d/6Q 5VtmH2WMbZc7Uh3ghj16co0AoB8HVCarO0l2wFAO05iQYFkSpkW2czzxJSR5QVa6Hb3m LGibe0QSPAfNV0BiIEO/Dd8dKbiWnMLjHa6HawPtvPaOCKvCOpP9tamGvHFSg0Fp3ctU URhOeWuVTKpfmOMnwVnO0HTS3aowIDCiUqlsb46gEfKEbzMNpGDChIZTS5L5cwNOYpqT 2wZ+B/TsoGqN2sSKjUQbfd6XMASjaWjYg29U+cxfxWnC4DKl1ij0egF8nH3zArfXyAC6 FJXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678232007; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=mHzEdCPWpaY/eH0Xx+geXzySB0PiK8eElCruHy6sF1Y=; b=EHdKksBEflC/zo3ef5kMK0l/K+QyuZR3Nz2emqi9d7dqmvnchvAdP8jIW3Np84BIiv QbFXlFImcEkWznf4sxCVXoCcCRljenbVdpmXB6t9l9lItV+3ph5N7asx0k2JAS32117/ KTl12I2vsbsx0vz5TuLAuTUY9PtAi5wKHfJVyWhRK4wxMUOg/6WxuqIs/WRdhNZYijwh RGKLsh0PLvE4bJSRREKtqbSvD8aLoF5yvjL8MlWQHBqstQOyVgNx9iCsel9GKZw1CfM+ AReFWns+GGL7/yrxaqQIgkzayRPlc+N0EZU9eXal6ND+dzPxeHgQcZeJXg6EWtVcMItZ /RBw== X-Gm-Message-State: AO0yUKUGcK51p82Vp+4C+iRI3hEO3Bga4cnQIYpOQIqRDm7BGjFJilCh xRAJT1PtdH/RRbT9KkayiZ8= X-Google-Smtp-Source: AK7set+CY0K+zNXyDHZNN1NQK8IkjEcXB+Z8otPqUvW1Gvyx+oa6sr2658LTKXUk6jzXBoR9DEQQ6w== X-Received: by 2002:a62:1748:0:b0:5dc:6dec:e9b9 with SMTP id 69-20020a621748000000b005dc6dece9b9mr15896744pfx.21.1678232007135; Tue, 07 Mar 2023 15:33:27 -0800 (PST) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:15e8:b801:cd55:a496]) by smtp.gmail.com with ESMTPSA id l11-20020a62be0b000000b005da23d8cbffsm8342217pff.158.2023.03.07.15.33.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Mar 2023 15:33:26 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa Cc: Peter Zijlstra , Ingo Molnar , Ian Rogers , Adrian Hunter , Andi Kleen , Kan Liang , Song Liu , Stephane Eranian , Ravi Bangoria , Leo Yan , James Clark , Hao Luo , LKML , linux-perf-users@vger.kernel.org, bpf@vger.kernel.org Subject: [PATCH 8/9] perf bpf filter: Add logical OR operator Date: Tue, 7 Mar 2023 15:33:08 -0800 Message-Id: <20230307233309.3546160-9-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230307233309.3546160-1-namhyung@kernel.org> References: <20230307233309.3546160-1-namhyung@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org It supports two or more expressions connected as a group and the group result is considered true when one of them returns true. The new group operators (GROUP_BEGIN and GROUP_END) are added to setup and check the condition. As it doesn't allow nested groups, the condition is saved in local variables. For example, the following is to get samples only if the data source memory level is L2 cache or the weight value is greater than 30. $ sudo ./perf record -adW -e cpu/mem-loads/pp \ > --filter 'mem_lvl == l2 || weight > 30' -- sleep 1 $ sudo ./perf script -F data_src,weight 10668100842 |OP LOAD|LVL L3 or L3 hit|SNP None|TLB L1 or L2 hit|LCK No|BLK N/A 47 11868100242 |OP LOAD|LVL LFB/MAB or LFB/MAB hit|SNP None|TLB L1 or L2 hit|LCK No|BLK N/A 57 10668100842 |OP LOAD|LVL L3 or L3 hit|SNP None|TLB L1 or L2 hit|LCK No|BLK N/A 56 10650100842 |OP LOAD|LVL L3 or L3 hit|SNP None|TLB L2 miss|LCK No|BLK N/A 144 10468100442 |OP LOAD|LVL L2 or L2 hit|SNP None|TLB L1 or L2 hit|LCK No|BLK N/A 16 10468100442 |OP LOAD|LVL L2 or L2 hit|SNP None|TLB L1 or L2 hit|LCK No|BLK N/A 20 11868100242 |OP LOAD|LVL LFB/MAB or LFB/MAB hit|SNP None|TLB L1 or L2 hit|LCK No|BLK N/A 189 1026a100142 |OP LOAD|LVL L1 or L1 hit|SNP None|TLB L1 or L2 hit|LCK Yes|BLK N/A 193 10468100442 |OP LOAD|LVL L2 or L2 hit|SNP None|TLB L1 or L2 hit|LCK No|BLK N/A 18 ... Acked-by: Jiri Olsa Signed-off-by: Namhyung Kim --- tools/perf/util/bpf-filter.c | 25 +++++++++++++ tools/perf/util/bpf-filter.h | 1 + tools/perf/util/bpf-filter.l | 1 + tools/perf/util/bpf-filter.y | 25 +++++++++++-- tools/perf/util/bpf_skel/sample-filter.h | 6 ++-- tools/perf/util/bpf_skel/sample_filter.bpf.c | 38 +++++++++++++------- 6 files changed, 79 insertions(+), 17 deletions(-) diff --git a/tools/perf/util/bpf-filter.c b/tools/perf/util/bpf-filter.c index 743c69fd6cd4..bd638737e12f 100644 --- a/tools/perf/util/bpf-filter.c +++ b/tools/perf/util/bpf-filter.c @@ -42,8 +42,32 @@ int perf_bpf_filter__prepare(struct evsel *evsel) }; bpf_map_update_elem(fd, &i, &entry, BPF_ANY); i++; + + if (expr->op == PBF_OP_GROUP_BEGIN) { + struct perf_bpf_filter_expr *group; + + list_for_each_entry(group, &expr->groups, list) { + struct perf_bpf_filter_entry group_entry = { + .op = group->op, + .part = group->part, + .flags = group->sample_flags, + .value = group->val, + }; + bpf_map_update_elem(fd, &i, &group_entry, BPF_ANY); + i++; + } + + memset(&entry, 0, sizeof(entry)); + entry.op = PBF_OP_GROUP_END; + bpf_map_update_elem(fd, &i, &entry, BPF_ANY); + i++; + } } + if (i > MAX_FILTERS) { + pr_err("Too many filters: %d (max = %d)\n", i, MAX_FILTERS); + return -1; + } prog = skel->progs.perf_sample_filter; for (x = 0; x < xyarray__max_x(evsel->core.fd); x++) { for (y = 0; y < xyarray__max_y(evsel->core.fd); y++) { @@ -89,6 +113,7 @@ struct perf_bpf_filter_expr *perf_bpf_filter_expr__new(unsigned long sample_flag expr->part = part; expr->op = op; expr->val = val; + INIT_LIST_HEAD(&expr->groups); } return expr; } diff --git a/tools/perf/util/bpf-filter.h b/tools/perf/util/bpf-filter.h index 3f8827bd965f..7afd159411b8 100644 --- a/tools/perf/util/bpf-filter.h +++ b/tools/perf/util/bpf-filter.h @@ -8,6 +8,7 @@ struct perf_bpf_filter_expr { struct list_head list; + struct list_head groups; enum perf_bpf_filter_op op; int part; unsigned long sample_flags; diff --git a/tools/perf/util/bpf-filter.l b/tools/perf/util/bpf-filter.l index 3e66b7a0215e..d4ff0f1345cd 100644 --- a/tools/perf/util/bpf-filter.l +++ b/tools/perf/util/bpf-filter.l @@ -151,6 +151,7 @@ hops2 { return constant(PERF_MEM_HOPS_2); } hops3 { return constant(PERF_MEM_HOPS_3); } "," { return ','; } +"||" { return BFT_LOGICAL_OR; } {ident} { return error("ident"); } . { return error("input"); } diff --git a/tools/perf/util/bpf-filter.y b/tools/perf/util/bpf-filter.y index 0ca6532afd8d..07d6c7926c13 100644 --- a/tools/perf/util/bpf-filter.y +++ b/tools/perf/util/bpf-filter.y @@ -28,8 +28,8 @@ static void perf_bpf_filter_error(struct list_head *expr __maybe_unused, struct perf_bpf_filter_expr *expr; } -%token BFT_SAMPLE BFT_OP BFT_ERROR BFT_NUM -%type filter_term +%token BFT_SAMPLE BFT_OP BFT_ERROR BFT_NUM BFT_LOGICAL_OR +%type filter_term filter_expr %destructor { free ($$); } %type BFT_SAMPLE %type BFT_OP @@ -49,6 +49,27 @@ filter_term } filter_term: +filter_term BFT_LOGICAL_OR filter_expr +{ + struct perf_bpf_filter_expr *expr; + + if ($1->op == PBF_OP_GROUP_BEGIN) { + expr = $1; + } else { + expr = perf_bpf_filter_expr__new(0, 0, PBF_OP_GROUP_BEGIN, 1); + list_add_tail(&$1->list, &expr->groups); + } + expr->val++; + list_add_tail(&$3->list, &expr->groups); + $$ = expr; +} +| +filter_expr +{ + $$ = $1; +} + +filter_expr: BFT_SAMPLE BFT_OP BFT_NUM { $$ = perf_bpf_filter_expr__new($1.type, $1.part, $2, $3); diff --git a/tools/perf/util/bpf_skel/sample-filter.h b/tools/perf/util/bpf_skel/sample-filter.h index 6b9fd554ad7b..2e96e1ab084a 100644 --- a/tools/perf/util/bpf_skel/sample-filter.h +++ b/tools/perf/util/bpf_skel/sample-filter.h @@ -1,7 +1,7 @@ #ifndef PERF_UTIL_BPF_SKEL_SAMPLE_FILTER_H #define PERF_UTIL_BPF_SKEL_SAMPLE_FILTER_H -#define MAX_FILTERS 32 +#define MAX_FILTERS 64 /* supported filter operations */ enum perf_bpf_filter_op { @@ -11,7 +11,9 @@ enum perf_bpf_filter_op { PBF_OP_GE, PBF_OP_LT, PBF_OP_LE, - PBF_OP_AND + PBF_OP_AND, + PBF_OP_GROUP_BEGIN, + PBF_OP_GROUP_END, }; /* BPF map entry for filtering */ diff --git a/tools/perf/util/bpf_skel/sample_filter.bpf.c b/tools/perf/util/bpf_skel/sample_filter.bpf.c index 88dbc788d257..57e3c67d6d37 100644 --- a/tools/perf/util/bpf_skel/sample_filter.bpf.c +++ b/tools/perf/util/bpf_skel/sample_filter.bpf.c @@ -99,6 +99,14 @@ static inline __u64 perf_get_sample(struct bpf_perf_event_data_kern *kctx, return 0; } +#define CHECK_RESULT(data, op, val) \ + if (!(data op val)) { \ + if (!in_group) \ + goto drop; \ + } else if (in_group) { \ + group_result = 1; \ + } + /* BPF program to be called from perf event overflow handler */ SEC("perf_event") int perf_sample_filter(void *ctx) @@ -106,6 +114,8 @@ int perf_sample_filter(void *ctx) struct bpf_perf_event_data_kern *kctx; struct perf_bpf_filter_entry *entry; __u64 sample_data; + int in_group = 0; + int group_result = 0; int i; kctx = bpf_cast_to_kern_ctx(ctx); @@ -120,32 +130,34 @@ int perf_sample_filter(void *ctx) switch (entry->op) { case PBF_OP_EQ: - if (!(sample_data == entry->value)) - goto drop; + CHECK_RESULT(sample_data, ==, entry->value) break; case PBF_OP_NEQ: - if (!(sample_data != entry->value)) - goto drop; + CHECK_RESULT(sample_data, !=, entry->value) break; case PBF_OP_GT: - if (!(sample_data > entry->value)) - goto drop; + CHECK_RESULT(sample_data, >, entry->value) break; case PBF_OP_GE: - if (!(sample_data >= entry->value)) - goto drop; + CHECK_RESULT(sample_data, >=, entry->value) break; case PBF_OP_LT: - if (!(sample_data < entry->value)) - goto drop; + CHECK_RESULT(sample_data, <, entry->value) break; case PBF_OP_LE: - if (!(sample_data <= entry->value)) - goto drop; + CHECK_RESULT(sample_data, <=, entry->value) break; case PBF_OP_AND: - if (!(sample_data & entry->value)) + CHECK_RESULT(sample_data, &, entry->value) + break; + case PBF_OP_GROUP_BEGIN: + in_group = 1; + group_result = 0; + break; + case PBF_OP_GROUP_END: + if (group_result == 0) goto drop; + in_group = 0; break; } } From patchwork Tue Mar 7 23:33:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13164953 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 56E9CC74A44 for ; Tue, 7 Mar 2023 23:34:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230260AbjCGXe2 (ORCPT ); Tue, 7 Mar 2023 18:34:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44130 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230054AbjCGXeC (ORCPT ); Tue, 7 Mar 2023 18:34:02 -0500 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7F99CA8381; Tue, 7 Mar 2023 15:33:30 -0800 (PST) Received: by mail-pj1-x1031.google.com with SMTP id me6-20020a17090b17c600b0023816b0c7ceso434320pjb.2; Tue, 07 Mar 2023 15:33:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678232010; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=lePgVC2revAs5MYaikVkrYflEU1JfVf67vE9njBHVCY=; b=YKJzHaZC0+j+fRV6Dq3o4NrGvaF6eJ8VEHoBAEU03F/LYyBfvqhG242DSDsJSJxTwV t0g4cylrUpfpDiK/lI8TAUmIcAsdjeIhcH0E1DpLonCjsmv2Yxivn9x+3ZSG03sJZ77m tSnYXNmAEGmbUUiBwpWEBlRDcR/MF6rCJyVZbrZKtybYxzBYPXtFs7u1KzlIXolngX8q jr6Ksd8fMGKjSt2EIjoFKu4FEK+jmu4/W1Gpb+LOLXcx1FUswdtVvs3pRypd9x3/x4Px si6UYhkg8jB77c67stPfzp5SElP//raDwAtGd2IV1p6dw5RUaCm/kGMD72rpE4fe2//e 9D3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678232010; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=lePgVC2revAs5MYaikVkrYflEU1JfVf67vE9njBHVCY=; b=bzLl3NkGmIZzKrxRMuzxNe6Z8Vsd4pwOH2LthGnlp5J/esNn+H5aXnNtoGes8RSRcR R6W+R9UAecC/h1dYhINaoDngqwJjoCtPrEY3Wnw5hjWB6OfsTTJGqVxi0LC7Yb7+/QeO vUs9e8UTagzoeG6jC0aanzG2Er1HOJLLevtAAr4VXKHJaTEBEiDe4NrHp/lsnWB7KOPa vThf6T44+uNJTPuZ3P6e/ICxFMTvDJEFGPS/PRKHO3vSbZ+PK04TFH53JXGpXIlvNwu1 nvPcGvJ6PhqFMNm2+9VnIV8F7Dv5M77wvOVLjDB5rCoPUaH3pAW2pqzxHpBkFKvSJ9Oj sgTA== X-Gm-Message-State: AO0yUKVMDZ21VtlDa0WVIGRJ96AZDdKoPVQ+hnazr3WKok+4qwde0svv ovKhEh0zJpAghwcJN63DIg0= X-Google-Smtp-Source: AK7set/ig4stm/MxQBlUPJEKcu27Wz6zyalcG+mesMYOnoRYgwbxIEy7S3/CPVUHtJJcQSCJ8i2++g== X-Received: by 2002:a05:6a20:918a:b0:cd:9664:3d5a with SMTP id v10-20020a056a20918a00b000cd96643d5amr18405629pzd.22.1678232009821; Tue, 07 Mar 2023 15:33:29 -0800 (PST) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:15e8:b801:cd55:a496]) by smtp.gmail.com with ESMTPSA id l11-20020a62be0b000000b005da23d8cbffsm8342217pff.158.2023.03.07.15.33.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Mar 2023 15:33:29 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa Cc: Peter Zijlstra , Ingo Molnar , Ian Rogers , Adrian Hunter , Andi Kleen , Kan Liang , Song Liu , Stephane Eranian , Ravi Bangoria , Leo Yan , James Clark , Hao Luo , LKML , linux-perf-users@vger.kernel.org, bpf@vger.kernel.org Subject: [PATCH 9/9] perf bpf filter: Show warning for missing sample flags Date: Tue, 7 Mar 2023 15:33:09 -0800 Message-Id: <20230307233309.3546160-10-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230307233309.3546160-1-namhyung@kernel.org> References: <20230307233309.3546160-1-namhyung@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org For a BPF filter to work properly, users need to provide appropriate options to enable the sample types. Otherwise the BPF program would see an invalid value (i.e. always 0) and filter won't work well. Show a warning message if sample types are missing like below. $ sudo ./perf record -e cycles --filter 'addr < 100' true Error: cycles event does not have PERF_SAMPLE_ADDR Hint: please add -d option to perf record. failed to set filter "BPF" on event cycles with 22 (Invalid argument) Signed-off-by: Namhyung Kim --- tools/perf/builtin-record.c | 2 +- tools/perf/util/bpf-filter.c | 62 ++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 197e802a150b..3e9de6ad64fd 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1353,7 +1353,7 @@ static int record__open(struct record *rec) if (evlist__apply_filters(evlist, &pos)) { pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n", - pos->filter, evsel__name(pos), errno, + pos->filter ?: "BPF", evsel__name(pos), errno, str_error_r(errno, msg, sizeof(msg))); rc = -1; goto out; diff --git a/tools/perf/util/bpf-filter.c b/tools/perf/util/bpf-filter.c index bd638737e12f..0b30688d78a7 100644 --- a/tools/perf/util/bpf-filter.c +++ b/tools/perf/util/bpf-filter.c @@ -17,6 +17,64 @@ #define FD(e, x, y) (*(int *)xyarray__entry(e->core.fd, x, y)) +#define __PERF_SAMPLE_TYPE(st, opt) { st, #st, opt } +#define PERF_SAMPLE_TYPE(_st, opt) __PERF_SAMPLE_TYPE(PERF_SAMPLE_##_st, opt) + +static const struct perf_sample_info { + u64 type; + const char *name; + const char *option; +} sample_table[] = { + /* default sample flags */ + PERF_SAMPLE_TYPE(IP, NULL), + PERF_SAMPLE_TYPE(TID, NULL), + PERF_SAMPLE_TYPE(PERIOD, NULL), + /* flags mostly set by default, but still have options */ + PERF_SAMPLE_TYPE(ID, "--sample-identifier"), + PERF_SAMPLE_TYPE(CPU, "--sample-cpu"), + PERF_SAMPLE_TYPE(TIME, "-T"), + /* optional sample flags */ + PERF_SAMPLE_TYPE(ADDR, "-d"), + PERF_SAMPLE_TYPE(DATA_SRC, "-d"), + PERF_SAMPLE_TYPE(PHYS_ADDR, "--phys-data"), + PERF_SAMPLE_TYPE(WEIGHT, "-W"), + PERF_SAMPLE_TYPE(WEIGHT_STRUCT, "-W"), + PERF_SAMPLE_TYPE(TRANSACTION, "--transaction"), + PERF_SAMPLE_TYPE(CODE_PAGE_SIZE, "--code-page-size"), + PERF_SAMPLE_TYPE(DATA_PAGE_SIZE, "--data-page-size"), +}; + +static const struct perf_sample_info *get_sample_info(u64 flags) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(sample_table); i++) { + if (sample_table[i].type == flags) + return &sample_table[i]; + } + return NULL; +} + +static int check_sample_flags(struct evsel *evsel, struct perf_bpf_filter_expr *expr) +{ + const struct perf_sample_info *info; + + if (evsel->core.attr.sample_type & expr->sample_flags) + return 0; + + info = get_sample_info(expr->sample_flags); + if (info == NULL) { + pr_err("Error: %s event does not have sample flags %lx\n", + evsel__name(evsel), expr->sample_flags); + return -1; + } + + pr_err("Error: %s event does not have %s\n", evsel__name(evsel), info->name); + if (info->option) + pr_err(" Hint: please add %s option to perf record\n", info->option); + return -1; +} + int perf_bpf_filter__prepare(struct evsel *evsel) { int i, x, y, fd; @@ -40,6 +98,10 @@ int perf_bpf_filter__prepare(struct evsel *evsel) .flags = expr->sample_flags, .value = expr->val, }; + + if (check_sample_flags(evsel, expr) < 0) + return -1; + bpf_map_update_elem(fd, &i, &entry, BPF_ANY); i++;