Skip to content

Commit ffa0c1c

Browse files
yonghong-songborkmann
authored andcommitted
bpf: enable cgroup local storage map pretty print with kind_flag
Commit 970289fc0a83 ("bpf: add bpffs pretty print for cgroup local storage maps") added bpffs pretty print for cgroup local storage maps. The commit worked for struct without kind_flag set. This patch refactored and made pretty print also work with kind_flag set for the struct. Acked-by: Martin KaFai Lau <kafai@fb.com> Signed-off-by: Yonghong Song <yhs@fb.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
1 parent 9d5f9f7 commit ffa0c1c

File tree

3 files changed

+36
-23
lines changed

3 files changed

+36
-23
lines changed

include/linux/btf.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <linux/types.h>
88

99
struct btf;
10+
struct btf_member;
1011
struct btf_type;
1112
union bpf_attr;
1213

@@ -46,7 +47,9 @@ void btf_type_seq_show(const struct btf *btf, u32 type_id, void *obj,
4647
struct seq_file *m);
4748
int btf_get_fd_by_id(u32 id);
4849
u32 btf_id(const struct btf *btf);
49-
bool btf_type_is_reg_int(const struct btf_type *t, u32 expected_size);
50+
bool btf_member_is_reg_int(const struct btf *btf, const struct btf_type *s,
51+
const struct btf_member *m,
52+
u32 expected_offset, u32 expected_size);
5053

5154
#ifdef CONFIG_BPF_SYSCALL
5255
const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id);

kernel/bpf/btf.c

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -546,22 +546,41 @@ static bool btf_type_int_is_regular(const struct btf_type *t)
546546
}
547547

548548
/*
549-
* Check that given type is a regular int and has the expected size.
549+
* Check that given struct member is a regular int with expected
550+
* offset and size.
550551
*/
551-
bool btf_type_is_reg_int(const struct btf_type *t, u32 expected_size)
552+
bool btf_member_is_reg_int(const struct btf *btf, const struct btf_type *s,
553+
const struct btf_member *m,
554+
u32 expected_offset, u32 expected_size)
552555
{
553-
u8 nr_bits, nr_bytes;
554-
u32 int_data;
556+
const struct btf_type *t;
557+
u32 id, int_data;
558+
u8 nr_bits;
555559

556-
if (!btf_type_is_int(t))
560+
id = m->type;
561+
t = btf_type_id_size(btf, &id, NULL);
562+
if (!t || !btf_type_is_int(t))
557563
return false;
558564

559565
int_data = btf_type_int(t);
560566
nr_bits = BTF_INT_BITS(int_data);
561-
nr_bytes = BITS_ROUNDUP_BYTES(nr_bits);
562-
if (BITS_PER_BYTE_MASKED(nr_bits) ||
563-
BTF_INT_OFFSET(int_data) ||
564-
nr_bytes != expected_size)
567+
if (btf_type_kflag(s)) {
568+
u32 bitfield_size = BTF_MEMBER_BITFIELD_SIZE(m->offset);
569+
u32 bit_offset = BTF_MEMBER_BIT_OFFSET(m->offset);
570+
571+
/* if kflag set, int should be a regular int and
572+
* bit offset should be at byte boundary.
573+
*/
574+
return !bitfield_size &&
575+
BITS_ROUNDUP_BYTES(bit_offset) == expected_offset &&
576+
BITS_ROUNDUP_BYTES(nr_bits) == expected_size;
577+
}
578+
579+
if (BTF_INT_OFFSET(int_data) ||
580+
BITS_PER_BYTE_MASKED(m->offset) ||
581+
BITS_ROUNDUP_BYTES(m->offset) != expected_offset ||
582+
BITS_PER_BYTE_MASKED(nr_bits) ||
583+
BITS_ROUNDUP_BYTES(nr_bits) != expected_size)
565584
return false;
566585

567586
return true;

kernel/bpf/local_storage.c

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -315,9 +315,8 @@ static int cgroup_storage_check_btf(const struct bpf_map *map,
315315
const struct btf_type *key_type,
316316
const struct btf_type *value_type)
317317
{
318-
const struct btf_type *t;
319318
struct btf_member *m;
320-
u32 id, size;
319+
u32 offset, size;
321320

322321
/* Key is expected to be of struct bpf_cgroup_storage_key type,
323322
* which is:
@@ -338,25 +337,17 @@ static int cgroup_storage_check_btf(const struct bpf_map *map,
338337
* The first field must be a 64 bit integer at 0 offset.
339338
*/
340339
m = (struct btf_member *)(key_type + 1);
341-
if (m->offset)
342-
return -EINVAL;
343-
id = m->type;
344-
t = btf_type_id_size(btf, &id, NULL);
345340
size = FIELD_SIZEOF(struct bpf_cgroup_storage_key, cgroup_inode_id);
346-
if (!t || !btf_type_is_reg_int(t, size))
341+
if (!btf_member_is_reg_int(btf, key_type, m, 0, size))
347342
return -EINVAL;
348343

349344
/*
350345
* The second field must be a 32 bit integer at 64 bit offset.
351346
*/
352347
m++;
353-
if (m->offset != offsetof(struct bpf_cgroup_storage_key, attach_type) *
354-
BITS_PER_BYTE)
355-
return -EINVAL;
356-
id = m->type;
357-
t = btf_type_id_size(btf, &id, NULL);
348+
offset = offsetof(struct bpf_cgroup_storage_key, attach_type);
358349
size = FIELD_SIZEOF(struct bpf_cgroup_storage_key, attach_type);
359-
if (!t || !btf_type_is_reg_int(t, size))
350+
if (!btf_member_is_reg_int(btf, key_type, m, offset, size))
360351
return -EINVAL;
361352

362353
return 0;

0 commit comments

Comments
 (0)