From patchwork Tue Mar 14 23:42:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13175127 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 64DD6C6FD1D for ; Tue, 14 Mar 2023 23:43:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229970AbjCNXmp (ORCPT ); Tue, 14 Mar 2023 19:42:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56316 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229863AbjCNXmo (ORCPT ); Tue, 14 Mar 2023 19:42:44 -0400 Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E75803D90F; Tue, 14 Mar 2023 16:42:41 -0700 (PDT) Received: by mail-pl1-x636.google.com with SMTP id y11so18310736plg.1; Tue, 14 Mar 2023 16:42:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678837361; 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=Ng1MWyCzMkDu8iEfs313qAodFApakLEUuXv1tmDL5Ng=; b=SoUrUKP17zUGi9KMVACGbSkYT995oK/l+7YxZmY6386F8vjD/esl3djs5XkewySX5F aFlqeMbQDTt5qjG4UYcQsgksIK59mH/zm0ewB+CS4wJBkKwMIEMfvNU3hZyzgrVx8JWH ozWdEWsggyMJam1O3oUuQbhPA9P/sAlSmLp7uZdTDc3obNBDnVP8vtt2yinsiWqmFQwg eBs1fxKJScuxnmDDQX8rI78rX96aW339Fb+gcUpK16lea8kTeWzJSIjHirP9DaI0c6RE MK+ntM4ISShnI5Z6njkCBoRJb9V8e41yJrzxkb+cJecn7R+mhpRz2LM3DSxqYaiBZ6lU v0YA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678837361; 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=Ng1MWyCzMkDu8iEfs313qAodFApakLEUuXv1tmDL5Ng=; b=r8xLFv1SiGJ8ZakLG+76XUMf1ljmk9CuxXwIFLd0flCpP6fxOitorsqftXZ4rPmxvA bsAOYq4+6fIApWZXRiVegQcC0ddDjpmLcWpK961+VB9nZETIman7EfGMwbX6ZUf8w1+K T4pHvywis8f+mFXbef3pD8g/tME4oC/0ufV2+nGpX55PtwLkjXae44OaqivyHXqMnG1B OH0FCcsS5nANEPsGm8NyK2mfgz4zLwoNjWTnbXAXnw/BXtcFJB2HkYjBmFcorIWiqxBg t3EXyXbSf7eoHMPaB1Aa1JivkW05WU386NDq+c2SGOvwavFkArewkNNnZexmlxAdl+Jc Z3IQ== X-Gm-Message-State: AO0yUKXVgCU28qb0upqyeaYQdLjh5S7EMSDUy1QjAlPXDfg3ZdqtRioy fJ+ZuaexwaFsttd1bHlZO+A= X-Google-Smtp-Source: AK7set+vd1TZ6p8LZHjgy0WqeVS2GzMfssiZ166fm8vUh4sd7uCD1/j3oFNH4T/pq1AxNW6teC2Tdw== X-Received: by 2002:a17:903:410a:b0:19f:2b42:5d01 with SMTP id r10-20020a170903410a00b0019f2b425d01mr607074pld.9.1678837361437; Tue, 14 Mar 2023 16:42:41 -0700 (PDT) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:3826:a5cd:1f1d:6c85]) by smtp.gmail.com with ESMTPSA id ik13-20020a170902ab0d00b0019f39e4f120sm2280806plb.18.2023.03.14.16.42.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Mar 2023 16:42:41 -0700 (PDT) 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 01/10] perf bpf filter: Introduce basic BPF filter expression Date: Tue, 14 Mar 2023 16:42:28 -0700 Message-Id: <20230314234237.3008956-2-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230314234237.3008956-1-namhyung@kernel.org> References: <20230314234237.3008956-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 8607575183a9..853ce987eb4f 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 @@ -267,6 +270,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 @@ -280,6 +293,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) @@ -291,10 +305,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 14 23:42:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13175128 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 8954EC6FD1F for ; Tue, 14 Mar 2023 23:43:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229473AbjCNXnL (ORCPT ); Tue, 14 Mar 2023 19:43:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56340 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229939AbjCNXmo (ORCPT ); Tue, 14 Mar 2023 19:42:44 -0400 Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3D3B23D900; Tue, 14 Mar 2023 16:42:43 -0700 (PDT) Received: by mail-pj1-x1029.google.com with SMTP id cn6so4407236pjb.2; Tue, 14 Mar 2023 16:42:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678837363; 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=3ZNquBrBi9AlX+iPxS/L+cEwvDJDq3LRECorUB/FZ18=; b=U6OKE6dsL1IhBz6uz1TozlzQtocMbl8OjCaNQBnE29rPdB5I9Ux6Ns5MlCnmDjBY7V dTPXYuzsiyFGG+PUBI2d1GCPybOqrh9t2Ggz4Pzu8iewKV2ULzWftuARrff4+6f26nwy LArFRQOZiB5DI81K8Dn9zXUxfdC2QgizCxHq/y0rKM9LzF5yvEGKn9WVixlzMx6kInTn XN+pNa5R25KkBkNrDUHJeUCJaQGhRzvqk1xN4pRJmADljB37TCFnhI9WaCZxBcl6IOEw CElvUTxvq9z1T0s9nwfezfvvfvISo73EzNHBkKfH77iR+uFGVhL+cfaMPnmE7KN5+CZ4 frAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678837363; 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=3ZNquBrBi9AlX+iPxS/L+cEwvDJDq3LRECorUB/FZ18=; b=sJPE5dUaDdmKqaENW9Owm93xrIwjPpbaO4oYZamvQN3nPlWNqvCCxo/gDJGXOGvUqX Uwbh6+3RDj+52hyEyv7+pfC2cDFPlgM5RdkQkASs/KX9LwYA6hqQZLD+w3nbouBUTko+ yKk3CiVYZhYO5oJYK3n9BMY3f6ja7YoryP3R+QvCxMgA4tz8dg/HbyhZwDhibfjis+xr nUUCzeJgkySWpUwPRcmpxvIyaz+MhDwQi3Ap+6QEps1y4BxX6S1n/yWLrW/+5natyUu+ homFa6WogwWauTKPIWa4C7BZdVZdg6RbR6+PBOArOLzVYCHiGEdi6EL0/PsGm0U0ShUi 0Bsw== X-Gm-Message-State: AO0yUKWVGbFru4AtFYDifOuU8lKYyn3DH5FJqKglly2JalmTbd9lYr11 5nPDx2v2ZX1uKodDOmkvPEc= X-Google-Smtp-Source: AK7set/aFxwIszjKXNhuGdCS9ibSn/QIVVHougW6WuaaXrf6TUtpBfR8KsE4j5RMlEfwzhP0xfsPKQ== X-Received: by 2002:a17:902:f155:b0:19e:762b:9d49 with SMTP id d21-20020a170902f15500b0019e762b9d49mr514150plb.7.1678837362647; Tue, 14 Mar 2023 16:42:42 -0700 (PDT) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:3826:a5cd:1f1d:6c85]) by smtp.gmail.com with ESMTPSA id ik13-20020a170902ab0d00b0019f39e4f120sm2280806plb.18.2023.03.14.16.42.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Mar 2023 16:42:42 -0700 (PDT) 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 02/10] perf bpf filter: Implement event sample filtering Date: Tue, 14 Mar 2023 16:42:29 -0700 Message-Id: <20230314234237.3008956-3-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230314234237.3008956-1-namhyung@kernel.org> References: <20230314234237.3008956-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 dc9dda09b076..ed6b6a070f79 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -1050,7 +1050,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 c272c06565c0..68072ec655ce 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -150,8 +150,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; @@ -159,6 +161,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 14 23:42:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13175129 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 E39C1C7618B for ; Tue, 14 Mar 2023 23:43:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230242AbjCNXnX (ORCPT ); Tue, 14 Mar 2023 19:43:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56350 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230007AbjCNXmq (ORCPT ); Tue, 14 Mar 2023 19:42:46 -0400 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 71CAB3D0BD; Tue, 14 Mar 2023 16:42:44 -0700 (PDT) Received: by mail-pj1-x1034.google.com with SMTP id 6-20020a17090a190600b00237c5b6ecd7so83808pjg.4; Tue, 14 Mar 2023 16:42:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678837364; 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=m0iyfi/1hHleidl81oNqA/YSDrWcJGps480EcOB3sSs=; b=PnlRh1amO8g8O7V01qNUxPyH1FRY2eoPDzerbAsGNO9Q5qA3bdtHSf/IbZT+J9ytHQ Stp/WCskA4YFzv637/Xwf+oZrIdmHx4+uIXtQlyWxWQkMcvIK36FPuEnWQ8QuF04IRmu 10jNDbZVR9ajhUOluiZITJ+C7PkzZJ9aDW7ZcFEH6B2jYMExPsa833JM9KIsT+InyfsM 6ja7p5t9VL5iI5dWxVMWe1b3+RfH9sTyqPNDQq05SbjFP+yw29H6S4iGunv6Xgef9T5t cz0Ymc9+H4s2pLp15ObkVmx87MN2WuXwb4x9GRYsSGq36KisCrf/7OpgBh4P6AmY+mP3 /phA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678837364; 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=m0iyfi/1hHleidl81oNqA/YSDrWcJGps480EcOB3sSs=; b=PwL6ABv/uMzPMRIj/y4YPlkbl/2arAmI+Rvqi8cof6EgvgOgcd0EyJf8tArIlWL3EP /JXezF7AMJUg6OfS0RP6lWUHWPs3AxP2ubWjkYk9+chllOl/daIx9HUZQMw88q+DxUKL +v4vICNkMeKMOTKqpPfhj7zxSF7ftinEq1IrTeIO1+e0cWfBSSAlBRPR7xp1nqGLu4Hj gz4ZGvDAAbQrLW2mp9/ZJHu/l1jtBPh48BpPYtUJBk2ZED5IC/C/vWMC/s2NePcm5qOO qgeuRoyE2icLNNx6RroFfV38oBdJQssHvuA+KZoU/dfUYUESLwniLi6y8YMci4OBg25b sT8Q== X-Gm-Message-State: AO0yUKU9vWtyAscoBqRyIkbzyx/i/3YLcfjkj47pHzkYCuOOxzHtd0rT V/UpaA6QIAOc6PZfbW1cU7eR/WV54NU= X-Google-Smtp-Source: AK7set/zzJvnjzkPxj0no0CxlUOKOCsJAjxxSzdAQFw10i5O+WJk0gVujWQQZuqueL9lQXIJkNMoCQ== X-Received: by 2002:a17:902:c60a:b0:19c:be09:20d5 with SMTP id r10-20020a170902c60a00b0019cbe0920d5mr608958plr.11.1678837363926; Tue, 14 Mar 2023 16:42:43 -0700 (PDT) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:3826:a5cd:1f1d:6c85]) by smtp.gmail.com with ESMTPSA id ik13-20020a170902ab0d00b0019f39e4f120sm2280806plb.18.2023.03.14.16.42.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Mar 2023 16:42:43 -0700 (PDT) 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 03/10] perf record: Add BPF event filter support Date: Tue, 14 Mar 2023 16:42:30 -0700 Message-Id: <20230314234237.3008956-4-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230314234237.3008956-1-namhyung@kernel.org> References: <20230314234237.3008956-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..122f71726eaa 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 @@ -176,6 +179,12 @@ OPTIONS Multiple filters can be separated with space or comma. + - 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. + --exclude-perf:: Don't record events issued by perf itself. This option should follow an event selector (-e) which selects tracepoint event(s). It adds a diff --git a/tools/perf/util/bpf_counter.c b/tools/perf/util/bpf_counter.c index aa78a15a6f0a..1b77436e067e 100644 --- a/tools/perf/util/bpf_counter.c +++ b/tools/perf/util/bpf_counter.c @@ -763,8 +763,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 b74e12239aec..cc491a037836 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 a83d8cd5eb51..dc3faf005c3b 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 @@ -1517,6 +1518,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 3b2e5bb3e852..6c5cf5244486 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -28,6 +28,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" @@ -2542,11 +2543,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 14 23:42:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13175136 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 38074C76196 for ; Tue, 14 Mar 2023 23:44:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230266AbjCNXoj (ORCPT ); Tue, 14 Mar 2023 19:44:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56366 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230109AbjCNXnL (ORCPT ); Tue, 14 Mar 2023 19:43:11 -0400 Received: from mail-pl1-x62f.google.com (mail-pl1-x62f.google.com [IPv6:2607:f8b0:4864:20::62f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CE3983D900; Tue, 14 Mar 2023 16:42:45 -0700 (PDT) Received: by mail-pl1-x62f.google.com with SMTP id i5so18295490pla.2; Tue, 14 Mar 2023 16:42:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678837365; 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=zUFOE/ZuiUM3Ns/cxvGLc/qAYr4eK2YvuKfQk+NEO2I=; b=GXSiPZagxF/lmkk11W4iBnDUv2s/J10HagCprGYOdGNOb/xOsXPpryTs1N1tFujUJG IsbRzDP5ivzBksxwVzfi1ZPy25VQOyh+qGyWnKgi1BnVAk0Zd8iLwpYB9GirQmBm+zkF U2pVa0FYScZK9ZHEieK0ioaPbn1sAsaFqpB/leeGGi5Awy4Qc83Bzm+wyxAs6ldL983m qJat04N2t9my6xj7y5zv5NpMXLDx8mv2MwE4Ih8D37m/KHhhAMaBw+yBhI3fxamHq7vO qfIKJps6xyBRK0GJau+6AbUt9PoXpKnu31xCknwG31V8AvADI9xYU6ffKOMEbAWqN7ul L9Fg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678837365; 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=zUFOE/ZuiUM3Ns/cxvGLc/qAYr4eK2YvuKfQk+NEO2I=; b=dEDpDlkyN1wBgho97nEyU16j7ttBckZ8SmKXclIO2KqykK8sfXsCCQcTHn2jMhKgQj x0lpKcWdzwOAgM3Alx85Bjt6WrwlIamsbYWCze3vYTqmrem2h+o92Kkn4Uj4msoSyeG5 n9z1QDgBLXy1gGIEEl7fy0lsDI0ZuZjsqRM2OFv3JXx+JMpa2Tc8ywkV1yLsK6qcOaaO NhrwTPz4OFn5bWs7xAIe79uX16ZHy0zN2+tnuGtz2B8BwyPizB30sfvXJ5SvBLYtWp0Q MY2VHrTqFecg9huC+M41pf8Ys/kzEKYdy7t4JNLp25S4dYvxOJLbFKgrcyUh2OCcMQg9 JVbA== X-Gm-Message-State: AO0yUKXXZRu5GlON5526JZlC1U/8YhGO9Ka9CXJ0IrV0JCx2PerzJbb8 WsblKY1N0WXadIEHlLym19I= X-Google-Smtp-Source: AK7set+O5Otba+9dsdXQPxK6ixmfhs94JDzfGvD0Iboa3LR2gf99jYpyHWcQkqaGDz8BVPh+Rsb8Nw== X-Received: by 2002:a17:902:e54c:b0:1a0:428b:d8c5 with SMTP id n12-20020a170902e54c00b001a0428bd8c5mr616734plf.45.1678837365204; Tue, 14 Mar 2023 16:42:45 -0700 (PDT) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:3826:a5cd:1f1d:6c85]) by smtp.gmail.com with ESMTPSA id ik13-20020a170902ab0d00b0019f39e4f120sm2280806plb.18.2023.03.14.16.42.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Mar 2023 16:42:44 -0700 (PDT) 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 04/10] perf record: Record dropped sample count Date: Tue, 14 Mar 2023 16:42:31 -0700 Message-Id: <20230314234237.3008956-5-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230314234237.3008956-1-namhyung@kernel.org> References: <20230314234237.3008956-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 33ebe42b025e..6df8b823859d 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_debug("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_debug("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 14 23:42:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13175135 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 10EA7C6FD1D for ; Tue, 14 Mar 2023 23:44:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230348AbjCNXok (ORCPT ); Tue, 14 Mar 2023 19:44:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56376 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230101AbjCNXnL (ORCPT ); Tue, 14 Mar 2023 19:43:11 -0400 Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D1B203D924; Tue, 14 Mar 2023 16:42:46 -0700 (PDT) Received: by mail-pj1-x1029.google.com with SMTP id cn6so4407341pjb.2; Tue, 14 Mar 2023 16:42:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678837366; 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=iLsxORHVo+Ra5DIY7du9NDDWWr+RXz+zkIusth+YNprZkp8T+WuP/XKvbiZNAN/0Lw xB11nsnCpyPpUWo2c8sdkKdlwKNQlVSJS3wJIgMhdakEAV+xEOh9MqAoLRgg3F//Y9x7 NgyXtl6LgNNAfu9bEg2Uo8CmHFgYhoiEgwVhFtuqog+abb0ibmF2lTfx9ipcOQV6hjZH MhYWY5ZI7/nauAErpmH0/w2g9GOJaVzYmU6OH1FA0DLQHbOwMVODS7Q7IZKeN8/rWrVp ES7vtv8ECazZpaGiLsYUk4cbAmFxUUunnBMbPNhDvvktOT6pLzhWFjHeYzFXQf3GAiis iU0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678837366; 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=s23L3Xd4Ay0SnhYGfyuFPXMkmpG2pIbobSNUzip3QkaR6+P4VPgjWVd5TXqDUwotpt a5/a1By+F10QhGugkoc+PxzzIT5VvKav4TMCdDgq3iMvca/IaVpnSMLsnmsHeaAmY1SC i4FL88wETqiK/T9ggn65cfQoNk2hANguhVXoJ6H2oREMQYFSnTD9xOs6ZW59ayUUC4TR jlnWWm/7nFOw/w81QvnArH2kiEobJ9Vy+GvJJ6yfAKsmLx08d6WdsZKb2D5gzBDLqRkU j7+m8wPOIchdW1y7Op9Xi9LEbBEUCytQH+WRynkUGsEgL90rQAi4aWRqSJU8GzJSufps 09cQ== X-Gm-Message-State: AO0yUKVrcDDCsCPFdKgClmiH4PKNFHekQvaidJ3n6+n1U8T6JtcgCiPI KzI8Of9OjPcpkB//p/DMwtg= X-Google-Smtp-Source: AK7set8NWU5DOrScPYfuACfyzwjn5zb8OkIETS6ULqbmJ7/wc79kiWbNxfa/spzEl0SAnSRIJwDr3Q== X-Received: by 2002:a17:902:d2c4:b0:1a0:7678:5e0b with SMTP id n4-20020a170902d2c400b001a076785e0bmr558305plc.22.1678837366487; Tue, 14 Mar 2023 16:42:46 -0700 (PDT) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:3826:a5cd:1f1d:6c85]) by smtp.gmail.com with ESMTPSA id ik13-20020a170902ab0d00b0019f39e4f120sm2280806plb.18.2023.03.14.16.42.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Mar 2023 16:42:46 -0700 (PDT) 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 05/10] perf bpf filter: Add 'pid' sample data support Date: Tue, 14 Mar 2023 16:42:32 -0700 Message-Id: <20230314234237.3008956-6-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230314234237.3008956-1-namhyung@kernel.org> References: <20230314234237.3008956-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 14 23:42:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13175134 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 1EB35C7619A for ; Tue, 14 Mar 2023 23:44:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229765AbjCNXoj (ORCPT ); Tue, 14 Mar 2023 19:44:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56400 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230110AbjCNXnL (ORCPT ); Tue, 14 Mar 2023 19:43:11 -0400 Received: from mail-pl1-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6781A3D93D; Tue, 14 Mar 2023 16:42:48 -0700 (PDT) Received: by mail-pl1-x62a.google.com with SMTP id p20so18249803plw.13; Tue, 14 Mar 2023 16:42:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678837368; 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=YfwH9F1l3G2eOx+tqRFUa5gB29eIlnIQOrF6uSb9KsL2XpNEOWQmorubCoMqQ57bJP O+AYOeY9gLBRyKGvm4ihpiE3x5jtp+Z7LJVE92OTXUHbWgn0u7w9zu4mjgPmoMHnCBC0 MueAdtYt3bDXEugMhsIC0JihNCyZZ2r1LTVuTWCCgn1kXudjxeJYFKSmQuW6vqy5R0+8 SVk9WBcSSOe0xk7HIQaY4s/o64qHreO0U4Is1N9l3T9FFnL6ARax72VWcwTlkpgh5olu MrduIAWItyaArnbirqCA3f3meGvglTJ3nTjJf1tU1/qD/Vr/FuPxLluDMbQnT+wOo/Fz vQ9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678837368; 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=IdqIUw5JeF21z6SwqPSZnttABGNqVQ+oxnhoVhtSgfM9aev6IZ78bXg/M5qOlvBTRK jbX2UApp9Kd/LbjykEFvIBxuSEoq37bs/EXO3ezug+Ik/ghx8A+4WNbXhgv7Oot7KTck RONj7h1LAM+AFb+GJ+Rki/R6qb615O4cAimG1Xurx0hIucigCetpe5MdNwCI3DtygqBH lrwDGSlDfrz0pUArnMhUj7bcuv1qvzcn5UmVT2rTtnDEtooSR3bJRb9e50dtvyYH6zQI 8teuLzak5PRQnfEHlMnAbHs+rn0cjXQextkY2cWhO2IpgiZNhMVOdjPpbP12L/vU7/P2 /Jtw== X-Gm-Message-State: AO0yUKVteCNQMcSaP7k2MUmhTvmWaOb+GGDFacuMgitTXMoFtzIwL068 JjjQ9j9OlAY9hadhJM7MabI= X-Google-Smtp-Source: AK7set+hAncAWzBZw53gwPAyhS5+8hzUzB7Ef2MSaTxZuoWnhfMfMKXkXTt0J3w5te9i/1Hfk1nDHA== X-Received: by 2002:a17:902:dac1:b0:19e:b6b0:6b3 with SMTP id q1-20020a170902dac100b0019eb6b006b3mr899832plx.15.1678837367776; Tue, 14 Mar 2023 16:42:47 -0700 (PDT) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:3826:a5cd:1f1d:6c85]) by smtp.gmail.com with ESMTPSA id ik13-20020a170902ab0d00b0019f39e4f120sm2280806plb.18.2023.03.14.16.42.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Mar 2023 16:42:47 -0700 (PDT) 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 06/10] perf bpf filter: Add more weight sample data support Date: Tue, 14 Mar 2023 16:42:33 -0700 Message-Id: <20230314234237.3008956-7-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230314234237.3008956-1-namhyung@kernel.org> References: <20230314234237.3008956-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 14 23:42:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13175132 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 CD6EAC7618B for ; Tue, 14 Mar 2023 23:44:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229707AbjCNXoi (ORCPT ); Tue, 14 Mar 2023 19:44:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57144 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230111AbjCNXnM (ORCPT ); Tue, 14 Mar 2023 19:43:12 -0400 Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A12823D902; Tue, 14 Mar 2023 16:42:49 -0700 (PDT) Received: by mail-pl1-x636.google.com with SMTP id v21so8160794ple.9; Tue, 14 Mar 2023 16:42:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678837369; 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=XomfK7jyB3k61EfY5qAfnfRDEZ3ZWHdtMyzPh8jWVWzBgiVOnXqrV6fHKfDymD9WyU K4raOz7T4Frod+/HmNne94Kl42KqEQER5atLtKI7m+uIdVs6+skh2mioVGUhQtkgM4gN mUm/flgUHzBUNTQC6+mAgPfwVnVGI4re2n420OAylxucfbvWonrQheMYb6L3FCEYddov nqYUhc/ZraL6nw9+wqaJzqhwTAZIH9ATmgcHxVpri+HhhsKVlJUVP6v7fzuHAjU7d9V4 I8+dJwwJ/yxP2QB77leav+cqL37eFVXdv0eJjk5CaSBMdInPmrmgimRbcTCvoQ1YXRuY BuwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678837369; 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=v/3RoHVnhJ6fI/WXB8fuXE3pSJ/xEe+jd4xD3xJ4epq6w1t7jZ3P+sBnN17apVonBx Tc61su07zPsB6bStjqQqSq/d4PMw+iasvXEsCPgRm/QWD+Q0I+xj74+qbZmpzOJMrg33 oK71anQyMzBUEbMxYa4xH1NEbTQ5hlm2OTXuwil9ktGdozWpumNuAuZ+DJFpVSnN8iZO dYaSKk6h3Onio8MhzDfsSIbZtbBTRVAywWmoJQPZNaRh7HeR+PnexJaKWrgCpfwpsSoA fFSmOODiZOWkwII3bT16sKXoK7weE4Pr3LSz1fsHtks25ekxzfWvx3OkUdz0KRIIv5Iy EitQ== X-Gm-Message-State: AO0yUKVaqscWIc/VEFEMXZu6+RoJZdFiJ1FQQqBuTxugq6ZKwztEWO+E joHGfNgRoqLyfTc3HiA9lyk= X-Google-Smtp-Source: AK7set/lPJTrFbOOgl/ZD7hgiVjyoz/bxi1eJbzxhfRSZnVtMnMxLmIKpYVxzOJgRaTqqxjTxKEsLA== X-Received: by 2002:a17:903:234a:b0:19f:3797:d8de with SMTP id c10-20020a170903234a00b0019f3797d8demr879742plh.9.1678837369104; Tue, 14 Mar 2023 16:42:49 -0700 (PDT) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:3826:a5cd:1f1d:6c85]) by smtp.gmail.com with ESMTPSA id ik13-20020a170902ab0d00b0019f39e4f120sm2280806plb.18.2023.03.14.16.42.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Mar 2023 16:42:48 -0700 (PDT) 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 07/10] perf bpf filter: Add data_src sample data support Date: Tue, 14 Mar 2023 16:42:34 -0700 Message-Id: <20230314234237.3008956-8-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230314234237.3008956-1-namhyung@kernel.org> References: <20230314234237.3008956-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 14 23:42:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13175133 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 DB803C7618D for ; Tue, 14 Mar 2023 23:44:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229687AbjCNXoh (ORCPT ); Tue, 14 Mar 2023 19:44:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57146 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230113AbjCNXnM (ORCPT ); Tue, 14 Mar 2023 19:43:12 -0400 Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 26E903E0A2; Tue, 14 Mar 2023 16:42:51 -0700 (PDT) Received: by mail-pj1-x102d.google.com with SMTP id h11-20020a17090a2ecb00b00237c740335cso98891pjs.3; Tue, 14 Mar 2023 16:42:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678837370; 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=VC+99Y96mFnic9n2ZvesSjmc+5Pttiidqj3a+wnqCBbtJ50H5zshgsPHjFnL55vOAE CvVzJYNsILY2TLlKptUlSS5TjP1l1PMhQfxVTnge4te50kKy5S0QB8UZ04aioiPhHH2M v7YnGAHpST/h3fg/apkYnZ4LQhI4iuX8WAFwLx4j6AJ/vSOjSn0KBrAfowDvsqW7M2Zq jyDBr92Ng1Fduk8Vhi/XG1x1RljHU3cyGn0P7Hzc4bZtAKQwRjKrFdVUvjDTjgYcmPCe 6o9BOvJvTYj6lHbYHjK7WJM9/cdD0hi22PVrAXI3fta017nc8TBn2jd6aUF+cnt15xnQ Do/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678837370; 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=4y+P8sjKL9V+yN241LB1XRCaStIYkJtUw15e1yrgrROjm3lShL38gW5GATgd0Sf4ju FkpK7v8o7jvzI0gKWECj5Qojew7N4R+04YQwDW2YGcfak/C3qwSWC2j2ZgmPPKAtiKLs hf0VY0pUCsgPZ/7ylY0KimEgAm7CawGPm6NB7XvZy2UfHvVuObIrP/+SPBI6VKw0Q561 pvz9UnLoesnw2ULZIs122hAdUVS0WnwtRBV32GOZMFIUXfp/VzvparsNHOoYCyeLOMoD 9EZqVInK+Bfp6OFfQU79xMWuCURREKwUUO4zOc2/hraneLMXt0crpG1HJ7fQ9xsjuDJv 0fRQ== X-Gm-Message-State: AO0yUKVSc57t97zda3UXr2YEFBqoHaecv5/A3TXEcT9hxu5IZthXJBFB Shb9T0AYwr39qz3MHZZvQjw= X-Google-Smtp-Source: AK7set9JcTu+d89Ca3QQhqyQyZiQ3LafJGqfZwwBWTWJrFdpAorX7s4Uw3UG6lDQR4GAkGdmNDGfiw== X-Received: by 2002:a17:903:2441:b0:19c:e405:4446 with SMTP id l1-20020a170903244100b0019ce4054446mr780141pls.30.1678837370362; Tue, 14 Mar 2023 16:42:50 -0700 (PDT) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:3826:a5cd:1f1d:6c85]) by smtp.gmail.com with ESMTPSA id ik13-20020a170902ab0d00b0019f39e4f120sm2280806plb.18.2023.03.14.16.42.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Mar 2023 16:42:50 -0700 (PDT) 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 08/10] perf bpf filter: Add logical OR operator Date: Tue, 14 Mar 2023 16:42:35 -0700 Message-Id: <20230314234237.3008956-9-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230314234237.3008956-1-namhyung@kernel.org> References: <20230314234237.3008956-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 14 23:42:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13175131 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 0182AC6FD1D for ; Tue, 14 Mar 2023 23:43:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230191AbjCNXnb (ORCPT ); Tue, 14 Mar 2023 19:43:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57218 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230129AbjCNXnN (ORCPT ); Tue, 14 Mar 2023 19:43:13 -0400 Received: from mail-pj1-x102f.google.com (mail-pj1-x102f.google.com [IPv6:2607:f8b0:4864:20::102f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3083C3E618; Tue, 14 Mar 2023 16:42:52 -0700 (PDT) Received: by mail-pj1-x102f.google.com with SMTP id h11-20020a17090a2ecb00b00237c740335cso98923pjs.3; Tue, 14 Mar 2023 16:42:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678837371; 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=jMxL2NHeZsRCM6blhtDc4AW9Gdpz11WHZ6f52Ygl1HM=; b=hFOpgmG+9oZLXQ6Ujq4k3ob30nepb+lX1yE1Ppvn7qFOJfNhU6OAsOLfgOqcQlVgt0 RSlJO8U7ybCppY6tzgqzeE1EoGl7DdkFyvjwiIbd21/KEMUp2OH2H5UK4O5K1obXfN/B WfzmvWNbuh5Vee3ZyjKCiqUWYh1ri/Gpm1zkMP1LL5eXgw2EXJJH2UHXtWozPtY3P+Y6 iguS0GZwuDy6Xv6BWnbqLV5ibQllK8FTyJY9TNma/2HqeWqsMoUYJs8C1bnRPvx/cbPC Ec8/8d2yLtypddxgnIbSp2KbkenRGm/YnYF19ExvVURWVDGk+uJ382e91Y0L/C0jEKi1 331A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678837371; 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=jMxL2NHeZsRCM6blhtDc4AW9Gdpz11WHZ6f52Ygl1HM=; b=BsrT+A8eJlD3WoYGtg6FLtcaEQad+rk4ZNviqH6x1TbGKtJipGg1KUNhZujU3cROST x5jitESCUUKOR86baoO1DVqzpq9UIfTGcWqnazB1nym/EjrrTbbe9Hon0bWxOJoj68BW JJrxk4Lvw86Q3uCJtfFP4zi/ANir9PybFahXxTRlm5pEgPNWqy07ygEK3rB5+I9DphPE MXzq3IKUizTU98IjfEAcjn9hTt+PZHs9QXrUghkyD0UyJ3lfgPl6eHeAmgb2NK8SQvdT gnPix/pONOdn7+r70et7GrE2jHJ6w/mFmat44zgawdszifMmlcIQH4CnPEOTkziXO6Lm WH2Q== X-Gm-Message-State: AO0yUKX0IORcm+YzW4jyzdJwBXXOaJk/d2g9ND367oTOXvbuXYIemoR4 2/us0QqEdy3P1QTch3Du1wY= X-Google-Smtp-Source: AK7set8vh9xqppIpf5fA95KYD5Zk7VVQEXve2fZFcJflST1qVDIZ8jzlmCTcLzC6ZS8jBoK34aYWxw== X-Received: by 2002:a17:903:11c5:b0:19c:ea4d:5995 with SMTP id q5-20020a17090311c500b0019cea4d5995mr761040plh.68.1678837371651; Tue, 14 Mar 2023 16:42:51 -0700 (PDT) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:3826:a5cd:1f1d:6c85]) by smtp.gmail.com with ESMTPSA id ik13-20020a170902ab0d00b0019f39e4f120sm2280806plb.18.2023.03.14.16.42.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Mar 2023 16:42:51 -0700 (PDT) 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 09/10] perf bpf filter: Show warning for missing sample flags Date: Tue, 14 Mar 2023 16:42:36 -0700 Message-Id: <20230314234237.3008956-10-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230314234237.3008956-1-namhyung@kernel.org> References: <20230314234237.3008956-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 6df8b823859d..7b7e74a56346 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++; From patchwork Tue Mar 14 23:42:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13175130 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 CEDB9C6FD1F for ; Tue, 14 Mar 2023 23:43:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230415AbjCNXn3 (ORCPT ); Tue, 14 Mar 2023 19:43:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57310 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230153AbjCNXnP (ORCPT ); Tue, 14 Mar 2023 19:43:15 -0400 Received: from mail-pl1-x634.google.com (mail-pl1-x634.google.com [IPv6:2607:f8b0:4864:20::634]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AC11041095; Tue, 14 Mar 2023 16:42:53 -0700 (PDT) Received: by mail-pl1-x634.google.com with SMTP id x11so18252355pln.12; Tue, 14 Mar 2023 16:42:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1678837373; 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=FFnAoyfpXLJ85wVKVk68j2EdKRKyiS6g/ArZlkxtTRo=; b=RkoV55+De2mUl77Ox/ZtUfAfqdTQAEOjZodzQ+51fsZHCBCRx0Bfo8yi41sxYL9/EY jEsqLFL/r9q+R8YUdR3oe8ztC613oVnhiTdAjoGuGeb5RwDaKL5EOs6Z0UAoUaTy5v+f m98Vm/uKUJZDSdEFv27dtsHcXTlwysILZXEumAWdsgA9O2gOptpwqLoYcoGgGTnR96TA Scly6/RMGzxFeqfs2Oxp2TJJFOx4LhcpOFu2gKz9PCW/wEohWYK/Gcd9YufcW+yhEWeY eNWNy7WLEox0NcQcPmTRhBLliJG3Y2SgkSEBuFtyUBqTBTUWlCWoGcuOrNFqf6mDUxZw j/Zg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678837373; 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=FFnAoyfpXLJ85wVKVk68j2EdKRKyiS6g/ArZlkxtTRo=; b=c4bc0rSR97le3WZZFiSKqSoKa0UwDc5PiYR6ZKgb9fzjSPTlsv6Miy1KNuskicsZEI XpC5nDV7owZHwN4BLJCd/r2D3QsUQCVMnQV7c6OWBWuXiI5KSpGB23cAaAbzkmdHtepI Uj/2clKpiYzFhcdd/NMZVZMDUgaOFybS40Gu+OK4c+BeDhLVtk/3NZHYP3I3DKH/SvVf ur+utbTk+a+GHRZHfqAyoWr63o7pRvRqhxLF/sYdj2J/w8/DPsf9t5geMceq0rggHQr/ xpTuyNdFcIMXroYDiygfRj6qrsJF61L16r00XvmrA4V0JBmFXVBFwQzydcPYrSGAIOEC A7fQ== X-Gm-Message-State: AO0yUKWCqZIIyRpy2upe/axRXqR0ylYBLz/uJMrpuniup6c83atq0A21 lIhx0Nc/SqjsmEsVfLNgb1c= X-Google-Smtp-Source: AK7set80nH9ENZKU/iAEZlc5wGC3RY3TZHfNIZbqmfOa7p2zLrPNLhd16hpi9syDt6IBNcZltbs4ww== X-Received: by 2002:a17:90b:1b52:b0:237:b64c:6bb3 with SMTP id nv18-20020a17090b1b5200b00237b64c6bb3mr41623994pjb.11.1678837372919; Tue, 14 Mar 2023 16:42:52 -0700 (PDT) Received: from moohyul.svl.corp.google.com ([2620:15c:2d4:203:3826:a5cd:1f1d:6c85]) by smtp.gmail.com with ESMTPSA id ik13-20020a170902ab0d00b0019f39e4f120sm2280806plb.18.2023.03.14.16.42.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Mar 2023 16:42:52 -0700 (PDT) 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 10/10] perf record: Update documentation for BPF filters Date: Tue, 14 Mar 2023 16:42:37 -0700 Message-Id: <20230314234237.3008956-11-namhyung@kernel.org> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog In-Reply-To: <20230314234237.3008956-1-namhyung@kernel.org> References: <20230314234237.3008956-1-namhyung@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Add more description and examples. Signed-off-by: Namhyung Kim --- tools/perf/Documentation/perf-record.txt | 47 +++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 122f71726eaa..680396c56bd1 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -183,7 +183,52 @@ OPTIONS 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. + filter. BPF filters need root privilege. + + The sample data field can be specified in lower case letter. Multiple + filters can be separated with comma. For example, + + --filter 'period > 1000, cpu == 1' + or + --filter 'mem_op == load || mem_op == store, mem_lvl > l1' + + The former filter only accept samples with period greater than 1000 AND + CPU number is 1. The latter one accepts either load and store memory + operations but it should have memory level above the L1. Since the + mem_op and mem_lvl fields come from the (memory) data_source, it'd only + work with some events which set the data_source field. + + Also user should request to collect that information (with -d option in + the above case). Otherwise, the following message will be shown. + + $ sudo perf record -e cycles --filter 'mem_op == load' + Error: cycles event does not have PERF_SAMPLE_DATA_SRC + Hint: please add -d option to perf record. + failed to set filter "BPF" on event cycles with 22 (Invalid argument) + + Essentially the BPF filter expression is: + + (("," | "||") )* + + The can be one of: + ip, id, tid, pid, cpu, time, addr, period, txn, weight, phys_addr, + code_pgsz, data_pgsz, weight1, weight2, weight3, ins_lat, retire_lat, + p_stage_cyc, mem_op, mem_lvl, mem_snoop, mem_remote, mem_lock, + mem_dtlb, mem_blk, mem_hops + + The can be one of: + ==, !=, >, >=, <, <=, & + + The can be one of: + (for any term) + na, load, store, pfetch, exec (for mem_op) + l1, l2, l3, l4, cxl, io, any_cache, lfb, ram, pmem (for mem_lvl) + na, none, hit, miss, hitm, fwd, peer (for mem_snoop) + remote (for mem_remote) + na, locked (for mem_locked) + na, l1_hit, l1_miss, l2_hit, l2_miss, any_hit, any_miss, walk, fault (for mem_dtlb) + na, by_data, by_addr (for mem_blk) + hops0, hops1, hops2, hops3 (for mem_hops) --exclude-perf:: Don't record events issued by perf itself. This option should follow