Message ID | 20240703223035.2024586-2-namhyung@kernel.org (mailing list archive) |
---|---|
State | Not Applicable |
Delegated to: | BPF |
Headers | show |
Series | perf record: Use a pinned BPF program for filter | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Not a local patch |
On Wed, Jul 03, 2024 at 03:30:28PM -0700, Namhyung Kim wrote: > And the value is now an array. This is to support multiple filter > entries in the map later. > No functional changes intended. > +++ b/tools/perf/util/bpf-filter.c > @@ -93,71 +93,102 @@ static int check_sample_flags(struct evsel *evsel, struct perf_bpf_filter_expr * > > int perf_bpf_filter__prepare(struct evsel *evsel) > { > - int i, x, y, fd; > + int i, x, y, fd, ret; > struct sample_filter_bpf *skel; > struct bpf_program *prog; > struct bpf_link *link; > struct perf_bpf_filter_expr *expr; > + struct perf_bpf_filter_entry *entry; > + > + entry = calloc(MAX_FILTERS, sizeof(*entry)); > + if (entry == NULL) > + return -1; I'm changing this to -ENOMEM since you use errno values in the other failure cases, ok? This: diff --git a/tools/perf/util/bpf-filter.c b/tools/perf/util/bpf-filter.c index 2510832d83f95e03..e98bacf41a248ced 100644 --- a/tools/perf/util/bpf-filter.c +++ b/tools/perf/util/bpf-filter.c @@ -102,7 +102,7 @@ int perf_bpf_filter__prepare(struct evsel *evsel) entry = calloc(MAX_FILTERS, sizeof(*entry)); if (entry == NULL) - return -1; + return -ENOMEM; skel = sample_filter_bpf__open_and_load(); if (!skel) {
On Wed, Jul 03, 2024 at 03:30:28PM -0700, Namhyung Kim wrote: > And the value is now an array. This is to support multiple filter > entries in the map later. > > No functional changes intended. Hey how can we test this feature these days? With this first patch applied: root@number:~# perf record -a -W -e cycles:p --filter 'period > 100 || weight > 0' sleep 1 Error: cpu_atom/cycles/p event does not have PERF_SAMPLE_WEIGHT Hint: please add -W option to perf record failed to set filter "BPF" on event cpu_atom/cycles/p with 95 (Operation not supported) root@number:~# perf record -a -W -e cpu_core/cycles/p --filter 'period > 100 || weight > 0' sleep 1 Error: cpu_core/cycles/p event does not have PERF_SAMPLE_WEIGHT Hint: please add -W option to perf record failed to set filter "BPF" on event cpu_core/cycles/p with 95 (Operation not supported) root@number:~# perf record -a -W -e cpu_atom/cycles/p --filter 'period > 100 || weight > 0' sleep 1 Error: cpu_atom/cycles/p event does not have PERF_SAMPLE_WEIGHT Hint: please add -W option to perf record failed to set filter "BPF" on event cpu_atom/cycles/p with 95 (Operation not supported) root@number:~# Interesting, it is taking a long time on the BPF prog load: bpf(BPF_MAP_UPDATE_ELEM, {map_fd=49, key=0x7ffcc85a545c, value=0x7fee34bc2000, flags=BPF_ANY}, 32) = 0 bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_PERF_EVENT, insn_cnt=335, insns=0xd1e6480, license="Dual BSD/GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_VERSION(6, 9, 9), prog_flags=0, prog_name="perf_sample_fil", prog_ifindex=0, expected_attach_type=BPF_CGROUP_INET_INGRESS, prog_btf_fd=50, func_info_rec_size=8, func_info=0xd1b9c80, func_info_cnt=1, line_info_rec_size=16, line_info=0xd1e5300, line_info_cnt=135, attach_btf_id=0, attach_prog_fd=0, fd_array=NULL}, 148^Cstrace: Process 2110180 detached <detached ...> <HERE it takes an unusual time, even returning after I cancelled the strace session> root@number:~# root@number:~# Error: cpu_atom/cycles/p event does not have PERF_SAMPLE_WEIGHT Hint: please add -W option to perf record failed to set filter "BPF" on event cpu_atom/cycles/p with 11 (Resource temporarily unavailable) root@number:~# root@number:~# uname -a Linux number 6.9.9-100.fc39.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Jul 11 19:26:10 UTC 2024 x86_64 GNU/Linux root@number:~# root@number:~# perf -v perf version 6.10.g5510fb5c79e9 root@number:~# ⬢[acme@toolbox perf-tools-next]$ git log --oneline -10 5510fb5c79e9f500 (HEAD -> perf-tools-next) perf annotate: Set instruction name to be used with insn-stat when using raw instruction b35a86e53eb496ea perf annotate: Add support to use libcapstone in powerpc f2dc60d11290d53e perf annotate: Use capstone_init and remove open_capstone_handle from disasm.c c5bcba602eeee554 perf annotate: Make capstone_init non-static so that it can be used during symbol disassemble eef369c562510092 perf annotate: Update instruction tracking for powerpc 282701f1d77a3bdb perf annotate: Add more instructions for instruction tracking 758ee468ce5721e4 perf annotate: Add some of the arithmetic instructions to support instruction tracking in powerpc e8e7c1b6a9572bab perf annotate: Add support to identify memory instructions of opcode 31 in powerpc 3b3a0f04c1c6cd10 perf annotate: Add parse function for memory instructions in powerpc a159d2acd44e707f perf annotate: Update parameters for reg extract functions to use raw instruction on powerpc ⬢[acme@toolbox perf-tools-next]$ Ideas? - Arnaldo
On Wed, Jul 24, 2024 at 03:55:15PM -0300, Arnaldo Carvalho de Melo wrote: > On Wed, Jul 03, 2024 at 03:30:28PM -0700, Namhyung Kim wrote: > > And the value is now an array. This is to support multiple filter > > entries in the map later. > > > No functional changes intended. > > > +++ b/tools/perf/util/bpf-filter.c > > @@ -93,71 +93,102 @@ static int check_sample_flags(struct evsel *evsel, struct perf_bpf_filter_expr * > > > > int perf_bpf_filter__prepare(struct evsel *evsel) > > { > > - int i, x, y, fd; > > + int i, x, y, fd, ret; > > struct sample_filter_bpf *skel; > > struct bpf_program *prog; > > struct bpf_link *link; > > struct perf_bpf_filter_expr *expr; > > + struct perf_bpf_filter_entry *entry; > > + > > + entry = calloc(MAX_FILTERS, sizeof(*entry)); > > + if (entry == NULL) > > + return -1; > > I'm changing this to -ENOMEM since you use errno values in the other > failure cases, ok? Sure thing! Thanks, Namhyung > > This: > > diff --git a/tools/perf/util/bpf-filter.c b/tools/perf/util/bpf-filter.c > index 2510832d83f95e03..e98bacf41a248ced 100644 > --- a/tools/perf/util/bpf-filter.c > +++ b/tools/perf/util/bpf-filter.c > @@ -102,7 +102,7 @@ int perf_bpf_filter__prepare(struct evsel *evsel) > > entry = calloc(MAX_FILTERS, sizeof(*entry)); > if (entry == NULL) > - return -1; > + return -ENOMEM; > > skel = sample_filter_bpf__open_and_load(); > if (!skel) {
On Wed, Jul 24, 2024 at 04:32:16PM -0300, Arnaldo Carvalho de Melo wrote: > On Wed, Jul 03, 2024 at 03:30:28PM -0700, Namhyung Kim wrote: > > And the value is now an array. This is to support multiple filter > > entries in the map later. > > > > No functional changes intended. > > Hey how can we test this feature these days? There's a 'perf record sample filtering (by BPF) tests'. $ ./perf test -vv filtering 95: perf record sample filtering (by BPF) tests: --- start --- test child forked, pid 1042594 Checking BPF-filter privilege try 'sudo perf record --setup-filter pin' first. bpf-filter test [Skipped permission] ---- end(-2) ---- 95: perf record sample filtering (by BPF) tests : Skip > > With this first patch applied: > > root@number:~# perf record -a -W -e cycles:p --filter 'period > 100 || weight > 0' sleep 1 > Error: cpu_atom/cycles/p event does not have PERF_SAMPLE_WEIGHT > Hint: please add -W option to perf record > failed to set filter "BPF" on event cpu_atom/cycles/p with 95 (Operation not supported) > root@number:~# perf record -a -W -e cpu_core/cycles/p --filter 'period > 100 || weight > 0' sleep 1 > Error: cpu_core/cycles/p event does not have PERF_SAMPLE_WEIGHT > Hint: please add -W option to perf record > failed to set filter "BPF" on event cpu_core/cycles/p with 95 (Operation not supported) > root@number:~# perf record -a -W -e cpu_atom/cycles/p --filter 'period > 100 || weight > 0' sleep 1 > Error: cpu_atom/cycles/p event does not have PERF_SAMPLE_WEIGHT > Hint: please add -W option to perf record > failed to set filter "BPF" on event cpu_atom/cycles/p with 95 (Operation not supported) > root@number:~# Do you say it's failing after the first patch? It looks like the atom CPU doesn't support PERF_SAMPLE_WEIGHT and should fail already. The above test doesn't check the weight field FYI. > > Interesting, it is taking a long time on the BPF prog load: > > bpf(BPF_MAP_UPDATE_ELEM, {map_fd=49, key=0x7ffcc85a545c, value=0x7fee34bc2000, flags=BPF_ANY}, 32) = 0 > bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_PERF_EVENT, insn_cnt=335, insns=0xd1e6480, license="Dual BSD/GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_VERSION(6, 9, 9), prog_flags=0, prog_name="perf_sample_fil", prog_ifindex=0, expected_attach_type=BPF_CGROUP_INET_INGRESS, prog_btf_fd=50, func_info_rec_size=8, func_info=0xd1b9c80, func_info_cnt=1, line_info_rec_size=16, line_info=0xd1e5300, line_info_cnt=135, attach_btf_id=0, attach_prog_fd=0, fd_array=NULL}, 148^Cstrace: Process 2110180 detached > <detached ...> > > <HERE it takes an unusual time, even returning after I cancelled the strace session> > > root@number:~# > root@number:~# Error: cpu_atom/cycles/p event does not have PERF_SAMPLE_WEIGHT > Hint: please add -W option to perf record > failed to set filter "BPF" on event cpu_atom/cycles/p with 11 (Resource temporarily unavailable) > > root@number:~# > > > root@number:~# uname -a > Linux number 6.9.9-100.fc39.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Jul 11 19:26:10 UTC 2024 x86_64 GNU/Linux > root@number:~# > > root@number:~# perf -v > perf version 6.10.g5510fb5c79e9 > root@number:~# > > ⬢[acme@toolbox perf-tools-next]$ git log --oneline -10 > 5510fb5c79e9f500 (HEAD -> perf-tools-next) perf annotate: Set instruction name to be used with insn-stat when using raw instruction > b35a86e53eb496ea perf annotate: Add support to use libcapstone in powerpc > f2dc60d11290d53e perf annotate: Use capstone_init and remove open_capstone_handle from disasm.c > c5bcba602eeee554 perf annotate: Make capstone_init non-static so that it can be used during symbol disassemble > eef369c562510092 perf annotate: Update instruction tracking for powerpc > 282701f1d77a3bdb perf annotate: Add more instructions for instruction tracking > 758ee468ce5721e4 perf annotate: Add some of the arithmetic instructions to support instruction tracking in powerpc > e8e7c1b6a9572bab perf annotate: Add support to identify memory instructions of opcode 31 in powerpc > 3b3a0f04c1c6cd10 perf annotate: Add parse function for memory instructions in powerpc > a159d2acd44e707f perf annotate: Update parameters for reg extract functions to use raw instruction on powerpc > ⬢[acme@toolbox perf-tools-next]$ > > Ideas? I don't know.. is it changed with this patch? Thanks, Namhyung
On Wed, Jul 24, 2024 at 01:20:27PM -0700, Namhyung Kim wrote: > On Wed, Jul 24, 2024 at 04:32:16PM -0300, Arnaldo Carvalho de Melo wrote: > > On Wed, Jul 03, 2024 at 03:30:28PM -0700, Namhyung Kim wrote: > > > And the value is now an array. This is to support multiple filter > > > entries in the map later. > > > > > > No functional changes intended. > > > > Hey how can we test this feature these days? > > There's a 'perf record sample filtering (by BPF) tests'. > > $ ./perf test -vv filtering > 95: perf record sample filtering (by BPF) tests: > --- start --- > test child forked, pid 1042594 > Checking BPF-filter privilege > try 'sudo perf record --setup-filter pin' first. > bpf-filter test [Skipped permission] > ---- end(-2) ---- > 95: perf record sample filtering (by BPF) tests : Skip > > > > > With this first patch applied: > > > > root@number:~# perf record -a -W -e cycles:p --filter 'period > 100 || weight > 0' sleep 1 > > Error: cpu_atom/cycles/p event does not have PERF_SAMPLE_WEIGHT > > Hint: please add -W option to perf record > > failed to set filter "BPF" on event cpu_atom/cycles/p with 95 (Operation not supported) > > root@number:~# perf record -a -W -e cpu_core/cycles/p --filter 'period > 100 || weight > 0' sleep 1 > > Error: cpu_core/cycles/p event does not have PERF_SAMPLE_WEIGHT > > Hint: please add -W option to perf record > > failed to set filter "BPF" on event cpu_core/cycles/p with 95 (Operation not supported) > > root@number:~# perf record -a -W -e cpu_atom/cycles/p --filter 'period > 100 || weight > 0' sleep 1 > > Error: cpu_atom/cycles/p event does not have PERF_SAMPLE_WEIGHT > > Hint: please add -W option to perf record > > failed to set filter "BPF" on event cpu_atom/cycles/p with 95 (Operation not supported) > > root@number:~# > > Do you say it's failing after the first patch? It looks like the atom yes > CPU doesn't support PERF_SAMPLE_WEIGHT and should fail already. I tried with 'cycles:p', 'cpu_atom/cycles/p' and with 'cpu_core/cycles/p', with and without -W (to use the warning advice) will try again tomorrow. - Arnaldo > The above test doesn't check the weight field FYI. > > > > > Interesting, it is taking a long time on the BPF prog load: > > > > bpf(BPF_MAP_UPDATE_ELEM, {map_fd=49, key=0x7ffcc85a545c, value=0x7fee34bc2000, flags=BPF_ANY}, 32) = 0 > > bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_PERF_EVENT, insn_cnt=335, insns=0xd1e6480, license="Dual BSD/GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_VERSION(6, 9, 9), prog_flags=0, prog_name="perf_sample_fil", prog_ifindex=0, expected_attach_type=BPF_CGROUP_INET_INGRESS, prog_btf_fd=50, func_info_rec_size=8, func_info=0xd1b9c80, func_info_cnt=1, line_info_rec_size=16, line_info=0xd1e5300, line_info_cnt=135, attach_btf_id=0, attach_prog_fd=0, fd_array=NULL}, 148^Cstrace: Process 2110180 detached > > <detached ...> > > > > <HERE it takes an unusual time, even returning after I cancelled the strace session> > > > > root@number:~# > > root@number:~# Error: cpu_atom/cycles/p event does not have PERF_SAMPLE_WEIGHT > > Hint: please add -W option to perf record > > failed to set filter "BPF" on event cpu_atom/cycles/p with 11 (Resource temporarily unavailable) > > > > root@number:~# > > > > > > root@number:~# uname -a > > Linux number 6.9.9-100.fc39.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Jul 11 19:26:10 UTC 2024 x86_64 GNU/Linux > > root@number:~# > > > > root@number:~# perf -v > > perf version 6.10.g5510fb5c79e9 > > root@number:~# > > > > ⬢[acme@toolbox perf-tools-next]$ git log --oneline -10 > > 5510fb5c79e9f500 (HEAD -> perf-tools-next) perf annotate: Set instruction name to be used with insn-stat when using raw instruction > > b35a86e53eb496ea perf annotate: Add support to use libcapstone in powerpc > > f2dc60d11290d53e perf annotate: Use capstone_init and remove open_capstone_handle from disasm.c > > c5bcba602eeee554 perf annotate: Make capstone_init non-static so that it can be used during symbol disassemble > > eef369c562510092 perf annotate: Update instruction tracking for powerpc > > 282701f1d77a3bdb perf annotate: Add more instructions for instruction tracking > > 758ee468ce5721e4 perf annotate: Add some of the arithmetic instructions to support instruction tracking in powerpc > > e8e7c1b6a9572bab perf annotate: Add support to identify memory instructions of opcode 31 in powerpc > > 3b3a0f04c1c6cd10 perf annotate: Add parse function for memory instructions in powerpc > > a159d2acd44e707f perf annotate: Update parameters for reg extract functions to use raw instruction on powerpc > > ⬢[acme@toolbox perf-tools-next]$ > > > > Ideas? > > I don't know.. is it changed with this patch? > > Thanks, > Namhyung
On Wed, Jul 24, 2024 at 06:39:34PM -0300, Arnaldo Carvalho de Melo wrote: > On Wed, Jul 24, 2024 at 01:20:27PM -0700, Namhyung Kim wrote: > > On Wed, Jul 24, 2024 at 04:32:16PM -0300, Arnaldo Carvalho de Melo wrote: > > > On Wed, Jul 03, 2024 at 03:30:28PM -0700, Namhyung Kim wrote: > > > > And the value is now an array. This is to support multiple filter > > > > entries in the map later. > > > > > > > > No functional changes intended. > > > > > > Hey how can we test this feature these days? > > > > There's a 'perf record sample filtering (by BPF) tests'. > > > > $ ./perf test -vv filtering > > 95: perf record sample filtering (by BPF) tests: > > --- start --- > > test child forked, pid 1042594 > > Checking BPF-filter privilege > > try 'sudo perf record --setup-filter pin' first. > > bpf-filter test [Skipped permission] > > ---- end(-2) ---- > > 95: perf record sample filtering (by BPF) tests : Skip > > > > > > > > With this first patch applied: > > > > > > root@number:~# perf record -a -W -e cycles:p --filter 'period > 100 || weight > 0' sleep 1 > > > Error: cpu_atom/cycles/p event does not have PERF_SAMPLE_WEIGHT > > > Hint: please add -W option to perf record > > > failed to set filter "BPF" on event cpu_atom/cycles/p with 95 (Operation not supported) > > > root@number:~# perf record -a -W -e cpu_core/cycles/p --filter 'period > 100 || weight > 0' sleep 1 > > > Error: cpu_core/cycles/p event does not have PERF_SAMPLE_WEIGHT > > > Hint: please add -W option to perf record > > > failed to set filter "BPF" on event cpu_core/cycles/p with 95 (Operation not supported) > > > root@number:~# perf record -a -W -e cpu_atom/cycles/p --filter 'period > 100 || weight > 0' sleep 1 > > > Error: cpu_atom/cycles/p event does not have PERF_SAMPLE_WEIGHT > > > Hint: please add -W option to perf record > > > failed to set filter "BPF" on event cpu_atom/cycles/p with 95 (Operation not supported) > > > root@number:~# > > > > Do you say it's failing after the first patch? It looks like the atom > > yes > > > CPU doesn't support PERF_SAMPLE_WEIGHT and should fail already. > > I tried with 'cycles:p', 'cpu_atom/cycles/p' and with > 'cpu_core/cycles/p', with and without -W (to use the warning advice) > will try again tomorrow. Let me know if you find anything. Maybe it didn't set the flag in the attr. Can you run `perf record -W true && perf evlist -v` ? Thanks, Namhyung
diff --git a/tools/perf/util/bpf-filter.c b/tools/perf/util/bpf-filter.c index 04f98b6bb291..2510832d83f9 100644 --- a/tools/perf/util/bpf-filter.c +++ b/tools/perf/util/bpf-filter.c @@ -93,71 +93,102 @@ static int check_sample_flags(struct evsel *evsel, struct perf_bpf_filter_expr * int perf_bpf_filter__prepare(struct evsel *evsel) { - int i, x, y, fd; + int i, x, y, fd, ret; struct sample_filter_bpf *skel; struct bpf_program *prog; struct bpf_link *link; struct perf_bpf_filter_expr *expr; + struct perf_bpf_filter_entry *entry; + + entry = calloc(MAX_FILTERS, sizeof(*entry)); + if (entry == NULL) + return -1; skel = sample_filter_bpf__open_and_load(); if (!skel) { pr_err("Failed to load perf sample-filter BPF skeleton\n"); - return -1; + ret = -EPERM; + goto err; } 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, - .part = expr->part, - .term = expr->term, - .value = expr->val, - }; + if (check_sample_flags(evsel, expr) < 0) { + ret = -EINVAL; + goto err; + } - if (check_sample_flags(evsel, expr) < 0) - return -1; + if (i == MAX_FILTERS) { + ret = -E2BIG; + goto err; + } - bpf_map_update_elem(fd, &i, &entry, BPF_ANY); + entry[i].op = expr->op; + entry[i].part = expr->part; + entry[i].term = expr->term; + entry[i].value = expr->val; 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, - .term = group->term, - .value = group->val, - }; - bpf_map_update_elem(fd, &i, &group_entry, BPF_ANY); + if (i == MAX_FILTERS) { + ret = -E2BIG; + goto err; + } + + entry[i].op = group->op; + entry[i].part = group->part; + entry[i].term = group->term; + entry[i].value = group->val; i++; } - memset(&entry, 0, sizeof(entry)); - entry.op = PBF_OP_GROUP_END; - bpf_map_update_elem(fd, &i, &entry, BPF_ANY); + if (i == MAX_FILTERS) { + ret = -E2BIG; + goto err; + } + + entry[i].op = PBF_OP_GROUP_END; i++; } } - if (i > MAX_FILTERS) { - pr_err("Too many filters: %d (max = %d)\n", i, MAX_FILTERS); - return -1; + if (i < MAX_FILTERS) { + /* to terminate the loop early */ + entry[i].op = PBF_OP_DONE; + i++; + } + + /* The filters map has only one entry for now */ + i = 0; + if (bpf_map_update_elem(fd, &i, entry, BPF_ANY) < 0) { + ret = -errno; + pr_err("Failed to update the filter map\n"); + goto err; } + 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); + ret = PTR_ERR(link); + goto err; } } } + free(entry); evsel->bpf_skel = skel; return 0; + +err: + free(entry); + sample_filter_bpf__destroy(skel); + return ret; } int perf_bpf_filter__destroy(struct evsel *evsel) diff --git a/tools/perf/util/bpf_skel/sample-filter.h b/tools/perf/util/bpf_skel/sample-filter.h index 350efa121026..bb6a1b91f1df 100644 --- a/tools/perf/util/bpf_skel/sample-filter.h +++ b/tools/perf/util/bpf_skel/sample-filter.h @@ -14,6 +14,7 @@ enum perf_bpf_filter_op { PBF_OP_AND, PBF_OP_GROUP_BEGIN, PBF_OP_GROUP_END, + PBF_OP_DONE, }; enum perf_bpf_filter_term { diff --git a/tools/perf/util/bpf_skel/sample_filter.bpf.c b/tools/perf/util/bpf_skel/sample_filter.bpf.c index f59985101973..0d56e52b922c 100644 --- a/tools/perf/util/bpf_skel/sample_filter.bpf.c +++ b/tools/perf/util/bpf_skel/sample_filter.bpf.c @@ -9,10 +9,10 @@ /* BPF map that will be filled by user space */ struct filters { - __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(type, BPF_MAP_TYPE_HASH); __type(key, int); - __type(value, struct perf_bpf_filter_entry); - __uint(max_entries, MAX_FILTERS); + __type(value, struct perf_bpf_filter_entry[MAX_FILTERS]); + __uint(max_entries, 1); } filters SEC(".maps"); int dropped; @@ -179,39 +179,39 @@ int perf_sample_filter(void *ctx) __u64 sample_data; int in_group = 0; int group_result = 0; - int i; + int i, k; kctx = bpf_cast_to_kern_ctx(ctx); - for (i = 0; i < MAX_FILTERS; i++) { - int key = i; /* needed for verifier :( */ + k = 0; + entry = bpf_map_lookup_elem(&filters, &k); + if (entry == NULL) + goto drop; - entry = bpf_map_lookup_elem(&filters, &key); - if (entry == NULL) - break; - sample_data = perf_get_sample(kctx, entry); + for (i = 0; i < MAX_FILTERS; i++) { + sample_data = perf_get_sample(kctx, &entry[i]); - switch (entry->op) { + switch (entry[i].op) { case PBF_OP_EQ: - CHECK_RESULT(sample_data, ==, entry->value) + CHECK_RESULT(sample_data, ==, entry[i].value) break; case PBF_OP_NEQ: - CHECK_RESULT(sample_data, !=, entry->value) + CHECK_RESULT(sample_data, !=, entry[i].value) break; case PBF_OP_GT: - CHECK_RESULT(sample_data, >, entry->value) + CHECK_RESULT(sample_data, >, entry[i].value) break; case PBF_OP_GE: - CHECK_RESULT(sample_data, >=, entry->value) + CHECK_RESULT(sample_data, >=, entry[i].value) break; case PBF_OP_LT: - CHECK_RESULT(sample_data, <, entry->value) + CHECK_RESULT(sample_data, <, entry[i].value) break; case PBF_OP_LE: - CHECK_RESULT(sample_data, <=, entry->value) + CHECK_RESULT(sample_data, <=, entry[i].value) break; case PBF_OP_AND: - CHECK_RESULT(sample_data, &, entry->value) + CHECK_RESULT(sample_data, &, entry[i].value) break; case PBF_OP_GROUP_BEGIN: in_group = 1; @@ -222,6 +222,9 @@ int perf_sample_filter(void *ctx) goto drop; in_group = 0; break; + case PBF_OP_DONE: + /* no failures so far, accept it */ + return 1; } } /* generate sample data */
And the value is now an array. This is to support multiple filter entries in the map later. No functional changes intended. Signed-off-by: Namhyung Kim <namhyung@kernel.org> --- tools/perf/util/bpf-filter.c | 81 ++++++++++++++------ tools/perf/util/bpf_skel/sample-filter.h | 1 + tools/perf/util/bpf_skel/sample_filter.bpf.c | 39 +++++----- 3 files changed, 78 insertions(+), 43 deletions(-)