Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf bpf-filter: Support separate lost counts for each filter

As the BPF filter is shared between other processes, it should have its
own counter for each invocation. Add a new array map (lost_count) to
save the count using the same index as the filter. It should clear the
count before running the filter.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: KP Singh <kpsingh@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Song Liu <song@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: bpf@vger.kernel.org
Link: https://lore.kernel.org/r/20240703223035.2024586-6-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
1ec6fd34 0715f65e

+48 -4
+35 -2
tools/perf/util/bpf-filter.c
··· 260 260 } 261 261 262 262 if (needs_pid_hash && geteuid() != 0) { 263 + int zero = 0; 264 + 263 265 /* The filters map is shared among other processes */ 264 266 ret = update_pid_hash(evsel, entry); 265 267 if (ret < 0) 266 268 goto err; 269 + 270 + fd = get_pinned_fd("dropped"); 271 + if (fd < 0) { 272 + ret = fd; 273 + goto err; 274 + } 275 + 276 + /* Reset the lost count */ 277 + bpf_map_update_elem(fd, &pinned_filter_idx, &zero, BPF_ANY); 278 + close(fd); 267 279 268 280 fd = get_pinned_fd("perf_sample_filter"); 269 281 if (fd < 0) { ··· 359 347 360 348 u64 perf_bpf_filter__lost_count(struct evsel *evsel) 361 349 { 362 - struct sample_filter_bpf *skel = evsel->bpf_skel; 350 + int count = 0; 363 351 364 - return skel ? skel->bss->dropped : 0; 352 + if (list_empty(&evsel->bpf_filters)) 353 + return 0; 354 + 355 + if (pinned_filter_idx >= 0) { 356 + int fd = get_pinned_fd("dropped"); 357 + 358 + bpf_map_lookup_elem(fd, &pinned_filter_idx, &count); 359 + close(fd); 360 + } else if (evsel->bpf_skel) { 361 + struct sample_filter_bpf *skel = evsel->bpf_skel; 362 + int fd = bpf_map__fd(skel->maps.dropped); 363 + int idx = 0; 364 + 365 + bpf_map_lookup_elem(fd, &idx, &count); 366 + } 367 + 368 + return count; 365 369 } 366 370 367 371 struct perf_bpf_filter_expr *perf_bpf_filter_expr__new(enum perf_bpf_filter_term term, ··· 430 402 /* pinned program will use pid-hash */ 431 403 bpf_map__set_max_entries(skel->maps.filters, MAX_FILTERS); 432 404 bpf_map__set_max_entries(skel->maps.pid_hash, MAX_PIDS); 405 + bpf_map__set_max_entries(skel->maps.dropped, MAX_FILTERS); 433 406 skel->rodata->use_pid_hash = 1; 434 407 435 408 if (sample_filter_bpf__load(skel) < 0) { ··· 486 457 } 487 458 if (fchmodat(dir_fd, "pid_hash", 0666, 0) < 0) { 488 459 pr_debug("chmod for pid_hash failed\n"); 460 + ret = -errno; 461 + } 462 + if (fchmodat(dir_fd, "dropped", 0666, 0) < 0) { 463 + pr_debug("chmod for dropped failed\n"); 489 464 ret = -errno; 490 465 } 491 466
+13 -2
tools/perf/util/bpf_skel/sample_filter.bpf.c
··· 23 23 __uint(max_entries, 1); 24 24 } pid_hash SEC(".maps"); 25 25 26 - int dropped; 26 + /* tgid to filter index */ 27 + struct lost_count { 28 + __uint(type, BPF_MAP_TYPE_ARRAY); 29 + __type(key, int); 30 + __type(value, int); 31 + __uint(max_entries, 1); 32 + } dropped SEC(".maps"); 33 + 27 34 volatile const int use_pid_hash; 28 35 29 36 void *bpf_cast_to_kern_ctx(void *) __ksym; ··· 196 189 int in_group = 0; 197 190 int group_result = 0; 198 191 int i, k; 192 + int *losts; 199 193 200 194 kctx = bpf_cast_to_kern_ctx(ctx); 201 195 ··· 260 252 return 1; 261 253 262 254 drop: 263 - __sync_fetch_and_add(&dropped, 1); 255 + losts = bpf_map_lookup_elem(&dropped, &k); 256 + if (losts != NULL) 257 + __sync_fetch_and_add(losts, 1); 258 + 264 259 return 0; 265 260 } 266 261