Fix for "bpf -m|-M" options to appropriately display MEMLOCK and UID

Kernel commit 80ee81e0403c ("bpf: Eliminate rlimit-based memory
accounting infra for bpf maps") removed the struct bpf_map_memory
member from struct bpf_map at Linux 5.11.  Without the patch, the
"bpf -m|-M" options will print "(unknown)" for MEMLOCK and UID:

crash> bpf -m 1
 ID      BPF_MAP          BPF_MAP_TYPE     MAP_FLAGS
 1   ffff96ba41804400        ARRAY          00000000
     KEY_SIZE: 4  VALUE_SIZE: 8  MAX_ENTRIES: 64  MEMLOCK: (unknown)
     NAME: "dist"  UID: (unknown)

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
This commit is contained in:
Lianbo Jiang 2022-02-14 16:59:10 +08:00 committed by Kazuhito Hagio
parent 5f390ed811
commit 1ecb351309

70
bpf.c
View File

@ -63,6 +63,64 @@ static int do_old_idr(int, ulong, struct list_pair *);
#define PROG_VERBOSE (0x40)
#define MAP_VERBOSE (0x80)
static int map_is_per_cpu(int type)
{
/* See the definition of bpf_map_type: include/uapi/linux/bpf.h */
#define BPF_MAP_TYPE_PERCPU_HASH (5UL)
#define BPF_MAP_TYPE_PERCPU_ARRAY (6UL)
#define BPF_MAP_TYPE_LRU_PERCPU_HASH (10UL)
#define BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE (21UL)
return type == BPF_MAP_TYPE_PERCPU_HASH ||
type == BPF_MAP_TYPE_PERCPU_ARRAY ||
type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE;
}
static int map_is_fd_map(int type)
{
/* See the definition of bpf_map_type: include/uapi/linux/bpf.h */
#define BPF_MAP_TYPE_PROG_ARRAY (3UL)
#define BPF_MAP_TYPE_PERF_EVENT_ARRAY (4UL)
#define BPF_MAP_TYPE_CGROUP_ARRAY (8UL)
#define BPF_MAP_TYPE_ARRAY_OF_MAPS (12UL)
#define BPF_MAP_TYPE_HASH_OF_MAPS (13UL)
return type == BPF_MAP_TYPE_PROG_ARRAY ||
type == BPF_MAP_TYPE_PERF_EVENT_ARRAY ||
type == BPF_MAP_TYPE_CGROUP_ARRAY ||
type == BPF_MAP_TYPE_ARRAY_OF_MAPS ||
type == BPF_MAP_TYPE_HASH_OF_MAPS;
}
static ulong bpf_map_memory_size(int map_type, uint value_size,
uint key_size, uint max_entries)
{
ulong size;
uint valsize;
int cpus = 0;
if (map_is_per_cpu(map_type)) {
cpus = get_cpus_possible();
if (!cpus) {
error(WARNING, "cpu_possible_map does not exist, possible cpus: %d\n", cpus);
return 0;
}
valsize = roundup(value_size, 8) * cpus;
} else if (map_is_fd_map(map_type))
valsize = sizeof(uint);
else
valsize = value_size;
size = roundup((key_size + valsize), 8);
return roundup((max_entries * size), PAGESIZE());
}
void
cmd_bpf(void)
{
@ -332,7 +390,7 @@ do_bpf(ulong flags, ulong prog_id, ulong map_id, int radix)
{
struct bpf_info *bpf;
int i, c, found, entries, type;
uint uid, map_pages, key_size, value_size, max_entries;
uint uid, map_pages, key_size = 0, value_size = 0, max_entries = 0;
ulong bpf_prog_aux, bpf_func, end_func, addr, insnsi, user;
ulong do_progs, do_maps;
ulonglong load_time;
@ -572,6 +630,8 @@ do_map_only:
fprintf(fp, "\n");
if (flags & (MAP_ID|MAP_VERBOSE)) {
ulong msize = 0;
fprintf(fp, " KEY_SIZE: ");
if (VALID_MEMBER(bpf_map_key_size)) {
key_size = UINT(bpf->bpf_map_buf + OFFSET(bpf_map_key_size));
@ -602,8 +662,10 @@ do_map_only:
} else if (VALID_MEMBER(bpf_map_pages)) {
map_pages = UINT(bpf->bpf_map_buf + OFFSET(bpf_map_pages));
fprintf(fp, "%d\n", map_pages * PAGESIZE());
} else
fprintf(fp, "(unknown)\n");
} else if ((msize = bpf_map_memory_size(type, value_size, key_size, max_entries)))
fprintf(fp, "%ld\n", msize);
else
fprintf(fp, "(unknown)");
fprintf(fp, " NAME: ");
if (VALID_MEMBER(bpf_map_name)) {
@ -632,7 +694,7 @@ do_map_only:
else
fprintf(fp, "(unknown)\n");
} else
fprintf(fp, "(unknown)\n");
fprintf(fp, "(unused)\n");
}
if (flags & DUMP_STRUCT) {