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

bpftool: mark orphaned programs during prog show

Commit ef01f4e25c17 ("bpf: restore the ebpf program ID for BPF_AUDIT_UNLOAD
and PERF_BPF_EVENT_PROG_UNLOAD") stopped removing program's id from
idr when the offloaded/bound netdev goes away. I was supposed to
take a look and check in [0], but apparently I did not.

Martin points out it might be useful to keep it that way for
observability sake, but we at least need to mark those programs as
unusable.

Mark those programs as 'orphaned' and keep printing the list when
we encounter ENODEV.

0: unspec tag 0000000000000000
xlated 0B not jited memlock 4096B orphaned

[0]: https://lore.kernel.org/all/CAKH8qBtyR20ZWAc11z1-6pGb3Hd47AQUTbE_cfoktG59TqaJ7Q@mail.gmail.com/

v3:
* use two spaces for " orphaned" (Quentin)

Cc: netdev@vger.kernel.org
Fixes: ef01f4e25c17 ("bpf: restore the ebpf program ID for BPF_AUDIT_UNLOAD and PERF_BPF_EVENT_PROG_UNLOAD")
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Reviewed-by: Quentin Monnet <quentin@isovalent.com>
Link: https://lore.kernel.org/r/20231127182057.1081138-1-sdf@google.com
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>

authored by

Stanislav Fomichev and committed by
Martin KaFai Lau
876843ce b16904fd

+9 -5
+9 -5
tools/bpf/bpftool/prog.c
··· 442 442 jsonw_uint_field(json_wtr, "recursion_misses", info->recursion_misses); 443 443 } 444 444 445 - static void print_prog_json(struct bpf_prog_info *info, int fd) 445 + static void print_prog_json(struct bpf_prog_info *info, int fd, bool orphaned) 446 446 { 447 447 char *memlock; 448 448 ··· 461 461 jsonw_uint_field(json_wtr, "uid", info->created_by_uid); 462 462 } 463 463 464 + jsonw_bool_field(json_wtr, "orphaned", orphaned); 464 465 jsonw_uint_field(json_wtr, "bytes_xlated", info->xlated_prog_len); 465 466 466 467 if (info->jited_prog_len) { ··· 528 527 printf("\n"); 529 528 } 530 529 531 - static void print_prog_plain(struct bpf_prog_info *info, int fd) 530 + static void print_prog_plain(struct bpf_prog_info *info, int fd, bool orphaned) 532 531 { 533 532 char *memlock; 534 533 ··· 554 553 if (memlock) 555 554 printf(" memlock %sB", memlock); 556 555 free(memlock); 556 + 557 + if (orphaned) 558 + printf(" orphaned"); 557 559 558 560 if (info->nr_map_ids) 559 561 show_prog_maps(fd, info->nr_map_ids); ··· 585 581 int err; 586 582 587 583 err = bpf_prog_get_info_by_fd(fd, &info, &len); 588 - if (err) { 584 + if (err && err != -ENODEV) { 589 585 p_err("can't get prog info: %s", strerror(errno)); 590 586 return -1; 591 587 } 592 588 593 589 if (json_output) 594 - print_prog_json(&info, fd); 590 + print_prog_json(&info, fd, err == -ENODEV); 595 591 else 596 - print_prog_plain(&info, fd); 592 + print_prog_plain(&info, fd, err == -ENODEV); 597 593 598 594 return 0; 599 595 }