History

bpf: Add 'owner' field to bpf_{list,rb}_node

As described by Kumar in [0], in shared ownership scenarios it is necessary to do runtime tracking of {rb,list} node ownership - and synchronize updates using this ownership information - in order to prevent races. This patch adds an 'owner' field to struct bpf_list_node and bpf_rb_node to implement such runtime tracking. The owner field is a void * that describes the ownership state of a node. It can have the following values: NULL - the node is not owned by any data structure BPF_PTR_POISON - the node is in the process of being added to a data structure ptr_to_root - the pointee is a data structure 'root' (bpf_rb_root / bpf_list_head) which owns this node The field is initially NULL (set by bpf_obj_init_field default behavior) and transitions states in the following sequence: Insertion: NULL -> BPF_PTR_POISON -> ptr_to_root Removal: ptr_to_root -> NULL Before a node has been successfully inserted, it is not protected by any root's lock, and therefore two programs can attempt to add the same node to different roots simultaneously. For this reason the intermediate BPF_PTR_POISON state is necessary. For removal, the node is protected by some root's lock so this intermediate hop isn't necessary. Note that bpf_list_pop_{front,back} helpers don't need to check owner before removing as the node-to-be-removed is not passed in as input and is instead taken directly from the list. Do the check anyways and WARN_ON_ONCE in this unexpected scenario. Selftest changes in this patch are entirely mechanical: some BTF tests have hardcoded struct sizes for structs that contain bpf_{list,rb}_node fields, those were adjusted to account for the new sizes. Selftest additions to validate the owner field are added in a further patch in the series. [0]: https://lore.kernel.org/bpf/d7hyspcow5wtjcmw4fugdgyp3fwhljwuscp3xyut5qnwivyeru@ysdq543otzv2

Dave Marchevsky committed 3 years ago

Commit c3c510c1 parent 0a1f7bf4 files · +68 −43Browse files

Unified · Split

4 files
  1. include/linux/bpf.h +2 −0
  2. include/uapi/linux/bpf.h +2 −0
  3. kernel/bpf/helpers.c +25 −4
  4. tools/testing/selftests/bpf/prog_tests/linked_list.c +39 −39
include/linux/bpf.h+2−0
@@ -231,11 +231,13 @@ struct btf_record { · 230 unmodified lines
231231 /* Non-opaque version of bpf_rb_node in uapi/linux/bpf.h */
232232 struct bpf_rb_node_kern {
233233 struct rb_node rb_node;
234+ void *owner;
234235 } __attribute__((aligned(8)));
235236
236237 /* Non-opaque version of bpf_list_node in uapi/linux/bpf.h */
237238 struct bpf_list_node_kern {
238239 struct list_head list_head;
240+ void *owner;
239241 } __attribute__((aligned(8)));
240242
241243 struct bpf_map {
include/uapi/linux/bpf.h+2−0
@@ -7052,6 +7052,7 @@ struct bpf_list_head { · 7051 unmodified lines
70527052 struct bpf_list_node {
70537053 __u64 :64;
70547054 __u64 :64;
7055+ __u64 :64;
70557056 } __attribute__((aligned(8)));
70567057
70577058 struct bpf_rb_root {
@@ -7063,6 +7064,7 @@ struct bpf_rb_node { · 5 unmodified lines
70637064 __u64 :64;
70647065 __u64 :64;
70657066 __u64 :64;
7067+ __u64 :64;
70667068 } __attribute__((aligned(8)));
70677069
70687070 struct bpf_refcount {
kernel/bpf/helpers.c+25−4
@@ -1953,13 +1953,18 @@ static int __bpf_list_add(struct bpf_list_node_kern *node, · 1952 unmodified lines
19531953 */
19541954 if (unlikely(!h->next))
19551955 INIT_LIST_HEAD(h);
1956− if (!list_empty(n)) {
1956+
1957+ /* node->owner != NULL implies !list_empty(n), no need to separately
1958+ * check the latter
1959+ */
1960+ if (cmpxchg(&node->owner, NULL, BPF_PTR_POISON)) {
19571961 /* Only called from BPF prog, no need to migrate_disable */
19581962 __bpf_obj_drop_impl((void *)n - off, rec);
19591963 return -EINVAL;
19601964 }
19611965
19621966 tail ? list_add_tail(n, h) : list_add(n, h);
1967+ WRITE_ONCE(node->owner, head);
19631968
19641969 return 0;
19651970 }
@@ -1987,6 +1992,7 @@ __bpf_kfunc int bpf_list_push_back_impl(struct bpf_list_head *head, · 21 unmodified lines
19871992 static struct bpf_list_node *__bpf_list_del(struct bpf_list_head *head, bool tail)
19881993 {
19891994 struct list_head *n, *h = (void *)head;
1995+ struct bpf_list_node_kern *node;
19901996
19911997 /* If list_head was 0-initialized by map, bpf_obj_init_field wasn't
19921998 * called on its fields, so init here
@@ -1995,8 +2001,14 @@ static struct bpf_list_node *__bpf_list_del(struct bpf_list_head *head, bool tai · 2 unmodified lines
19952001 INIT_LIST_HEAD(h);
19962002 if (list_empty(h))
19972003 return NULL;
2004+
19982005 n = tail ? h->prev : h->next;
2006+ node = container_of(n, struct bpf_list_node_kern, list_head);
2007+ if (WARN_ON_ONCE(READ_ONCE(node->owner) != head))
2008+ return NULL;
2009+
19992010 list_del_init(n);
2011+ WRITE_ONCE(node->owner, NULL);
20002012 return (struct bpf_list_node *)n;
20012013 }
20022014
@@ -2013,14 +2025,19 @@ __bpf_kfunc struct bpf_list_node *bpf_list_pop_back(struct bpf_list_head *head) · 10 unmodified lines
20132025 __bpf_kfunc struct bpf_rb_node *bpf_rbtree_remove(struct bpf_rb_root *root,
20142026 struct bpf_rb_node *node)
20152027 {
2028+ struct bpf_rb_node_kern *node_internal = (struct bpf_rb_node_kern *)node;
20162029 struct rb_root_cached *r = (struct rb_root_cached *)root;
2017− struct rb_node *n = &((struct bpf_rb_node_kern *)node)->rb_node;
2030+ struct rb_node *n = &node_internal->rb_node;
20182031
2019− if (RB_EMPTY_NODE(n))
2032+ /* node_internal->owner != root implies either RB_EMPTY_NODE(n) or
2033+ * n is owned by some other tree. No need to check RB_EMPTY_NODE(n)
2034+ */
2035+ if (READ_ONCE(node_internal->owner) != root)
20202036 return NULL;
20212037
20222038 rb_erase_cached(n, r);
20232039 RB_CLEAR_NODE(n);
2040+ WRITE_ONCE(node_internal->owner, NULL);
20242041 return (struct bpf_rb_node *)n;
20252042 }
20262043
@@ -2036,7 +2053,10 @@ static int __bpf_rbtree_add(struct bpf_rb_root *root, · 9 unmodified lines
20362053 bpf_callback_t cb = (bpf_callback_t)less;
20372054 bool leftmost = true;
20382055
2039− if (!RB_EMPTY_NODE(n)) {
2056+ /* node->owner != NULL implies !RB_EMPTY_NODE(n), no need to separately
2057+ * check the latter
2058+ */
2059+ if (cmpxchg(&node->owner, NULL, BPF_PTR_POISON)) {
20402060 /* Only called from BPF prog, no need to migrate_disable */
20412061 __bpf_obj_drop_impl((void *)n - off, rec);
20422062 return -EINVAL;
@@ -2054,6 +2074,7 @@ static int __bpf_rbtree_add(struct bpf_rb_root *root, · 11 unmodified lines
20542074
20552075 rb_link_node(n, parent, link);
20562076 rb_insert_color_cached(n, (struct rb_root_cached *)root, leftmost);
2077+ WRITE_ONCE(node->owner, root);
20572078 return 0;
20582079 }
20592080
tools/testing/selftests/bpf/prog_tests/linked_list.c+39−39
@@ -23,7 +23,7 @@ static struct { · 22 unmodified lines
2323 "bpf_spin_lock at off=" #off " must be held for bpf_list_head" }, \
2424 { #test "_missing_lock_pop_back", \
2525 "bpf_spin_lock at off=" #off " must be held for bpf_list_head" },
26− TEST(kptr, 32)
26+ TEST(kptr, 40)
2727 TEST(global, 16)
2828 TEST(map, 0)
2929 TEST(inner_map, 0)
@@ -31,7 +31,7 @@ static struct { · 1 unmodified line
3131 #define TEST(test, op) \
3232 { #test "_kptr_incorrect_lock_" #op, \
3333 "held lock and object are not in the same allocation\n" \
34− "bpf_spin_lock at off=32 must be held for bpf_list_head" }, \
34+ "bpf_spin_lock at off=40 must be held for bpf_list_head" }, \
3535 { #test "_global_incorrect_lock_" #op, \
3636 "held lock and object are not in the same allocation\n" \
3737 "bpf_spin_lock at off=16 must be held for bpf_list_head" }, \
@@ -84,23 +84,23 @@ static struct { · 46 unmodified lines
8484 { "double_push_back", "arg#1 expected pointer to allocated object" },
8585 { "no_node_value_type", "bpf_list_node not found at offset=0" },
8686 { "incorrect_value_type",
87− "operation on bpf_list_head expects arg#1 bpf_list_node at offset=40 in struct foo, "
87+ "operation on bpf_list_head expects arg#1 bpf_list_node at offset=48 in struct foo, "
8888 "but arg is at offset=0 in struct bar" },
8989 { "incorrect_node_var_off", "variable ptr_ access var_off=(0x0; 0xffffffff) disallowed" },
90− { "incorrect_node_off1", "bpf_list_node not found at offset=41" },
91− { "incorrect_node_off2", "arg#1 offset=0, but expected bpf_list_node at offset=40 in struct foo" },
90+ { "incorrect_node_off1", "bpf_list_node not found at offset=49" },
91+ { "incorrect_node_off2", "arg#1 offset=0, but expected bpf_list_node at offset=48 in struct foo" },
9292 { "no_head_type", "bpf_list_head not found at offset=0" },
9393 { "incorrect_head_var_off1", "R1 doesn't have constant offset" },
9494 { "incorrect_head_var_off2", "variable ptr_ access var_off=(0x0; 0xffffffff) disallowed" },
95− { "incorrect_head_off1", "bpf_list_head not found at offset=17" },
95+ { "incorrect_head_off1", "bpf_list_head not found at offset=25" },
9696 { "incorrect_head_off2", "bpf_list_head not found at offset=1" },
9797 { "pop_front_off",
98− "15: (bf) r1 = r6 ; R1_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=40,imm=0) "
99− "R6_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=40,imm=0) refs=2,4\n"
98+ "15: (bf) r1 = r6 ; R1_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=48,imm=0) "
99+ "R6_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=48,imm=0) refs=2,4\n"
100100 "16: (85) call bpf_this_cpu_ptr#154\nR1 type=ptr_or_null_ expected=percpu_ptr_" },
101101 { "pop_back_off",
102− "15: (bf) r1 = r6 ; R1_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=40,imm=0) "
103− "R6_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=40,imm=0) refs=2,4\n"
102+ "15: (bf) r1 = r6 ; R1_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=48,imm=0) "
103+ "R6_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=48,imm=0) refs=2,4\n"
104104 "16: (85) call bpf_this_cpu_ptr#154\nR1 type=ptr_or_null_ expected=percpu_ptr_" },
105105 };
106106
@@ -257,7 +257,7 @@ static struct btf *init_btf(void) · 150 unmodified lines
257257 hid = btf__add_struct(btf, "bpf_list_head", 16);
258258 if (!ASSERT_EQ(hid, LIST_HEAD, "btf__add_struct bpf_list_head"))
259259 goto end;
260− nid = btf__add_struct(btf, "bpf_list_node", 16);
260+ nid = btf__add_struct(btf, "bpf_list_node", 24);
261261 if (!ASSERT_EQ(nid, LIST_NODE, "btf__add_struct bpf_list_node"))
262262 goto end;
263263 return btf;
@@ -276,7 +276,7 @@ static void list_and_rb_node_same_struct(bool refcount_field) · 12 unmodified lines
276276 if (!ASSERT_OK_PTR(btf, "init_btf"))
277277 return;
278278
279− bpf_rb_node_btf_id = btf__add_struct(btf, "bpf_rb_node", 24);
279+ bpf_rb_node_btf_id = btf__add_struct(btf, "bpf_rb_node", 32);
280280 if (!ASSERT_GT(bpf_rb_node_btf_id, 0, "btf__add_struct bpf_rb_node"))
281281 return;
282282
@@ -286,17 +286,17 @@ static void list_and_rb_node_same_struct(bool refcount_field) · 3 unmodified lines
286286 return;
287287 }
288288
289− id = btf__add_struct(btf, "bar", refcount_field ? 44 : 40);
289+ id = btf__add_struct(btf, "bar", refcount_field ? 60 : 56);
290290 if (!ASSERT_GT(id, 0, "btf__add_struct bar"))
291291 return;
292292 err = btf__add_field(btf, "a", LIST_NODE, 0, 0);
293293 if (!ASSERT_OK(err, "btf__add_field bar::a"))
294294 return;
295− err = btf__add_field(btf, "c", bpf_rb_node_btf_id, 128, 0);
295+ err = btf__add_field(btf, "c", bpf_rb_node_btf_id, 192, 0);
296296 if (!ASSERT_OK(err, "btf__add_field bar::c"))
297297 return;
298298 if (refcount_field) {
299− err = btf__add_field(btf, "ref", bpf_refcount_btf_id, 320, 0);
299+ err = btf__add_field(btf, "ref", bpf_refcount_btf_id, 448, 0);
300300 if (!ASSERT_OK(err, "btf__add_field bar::ref"))
301301 return;
302302 }
@@ -527,7 +527,7 @@ static void test_btf(void) · 224 unmodified lines
527527 btf = init_btf();
528528 if (!ASSERT_OK_PTR(btf, "init_btf"))
529529 break;
530− id = btf__add_struct(btf, "foo", 36);
530+ id = btf__add_struct(btf, "foo", 44);
531531 if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
532532 break;
533533 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
@@ -536,7 +536,7 @@ static void test_btf(void) · 2 unmodified lines
536536 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
537537 if (!ASSERT_OK(err, "btf__add_field foo::b"))
538538 break;
539− err = btf__add_field(btf, "c", SPIN_LOCK, 256, 0);
539+ err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
540540 if (!ASSERT_OK(err, "btf__add_field foo::c"))
541541 break;
542542 id = btf__add_decl_tag(btf, "contains:foo:b", 5, 0);
@@ -553,7 +553,7 @@ static void test_btf(void) · 10 unmodified lines
553553 btf = init_btf();
554554 if (!ASSERT_OK_PTR(btf, "init_btf"))
555555 break;
556− id = btf__add_struct(btf, "foo", 36);
556+ id = btf__add_struct(btf, "foo", 44);
557557 if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
558558 break;
559559 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
@@ -562,13 +562,13 @@ static void test_btf(void) · 2 unmodified lines
562562 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
563563 if (!ASSERT_OK(err, "btf__add_field foo::b"))
564564 break;
565− err = btf__add_field(btf, "c", SPIN_LOCK, 256, 0);
565+ err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
566566 if (!ASSERT_OK(err, "btf__add_field foo::c"))
567567 break;
568568 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0);
569569 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b"))
570570 break;
571− id = btf__add_struct(btf, "bar", 36);
571+ id = btf__add_struct(btf, "bar", 44);
572572 if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))
573573 break;
574574 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
@@ -577,7 +577,7 @@ static void test_btf(void) · 2 unmodified lines
577577 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
578578 if (!ASSERT_OK(err, "btf__add_field bar::b"))
579579 break;
580− err = btf__add_field(btf, "c", SPIN_LOCK, 256, 0);
580+ err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
581581 if (!ASSERT_OK(err, "btf__add_field bar::c"))
582582 break;
583583 id = btf__add_decl_tag(btf, "contains:foo:b", 7, 0);
@@ -594,19 +594,19 @@ static void test_btf(void) · 10 unmodified lines
594594 btf = init_btf();
595595 if (!ASSERT_OK_PTR(btf, "init_btf"))
596596 break;
597− id = btf__add_struct(btf, "foo", 20);
597+ id = btf__add_struct(btf, "foo", 28);
598598 if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
599599 break;
600600 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
601601 if (!ASSERT_OK(err, "btf__add_field foo::a"))
602602 break;
603− err = btf__add_field(btf, "b", SPIN_LOCK, 128, 0);
603+ err = btf__add_field(btf, "b", SPIN_LOCK, 192, 0);
604604 if (!ASSERT_OK(err, "btf__add_field foo::b"))
605605 break;
606606 id = btf__add_decl_tag(btf, "contains:bar:a", 5, 0);
607607 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:a"))
608608 break;
609− id = btf__add_struct(btf, "bar", 16);
609+ id = btf__add_struct(btf, "bar", 24);
610610 if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))
611611 break;
612612 err = btf__add_field(btf, "a", LIST_NODE, 0, 0);
@@ -623,19 +623,19 @@ static void test_btf(void) · 10 unmodified lines
623623 btf = init_btf();
624624 if (!ASSERT_OK_PTR(btf, "init_btf"))
625625 break;
626− id = btf__add_struct(btf, "foo", 20);
626+ id = btf__add_struct(btf, "foo", 28);
627627 if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
628628 break;
629629 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
630630 if (!ASSERT_OK(err, "btf__add_field foo::a"))
631631 break;
632− err = btf__add_field(btf, "b", SPIN_LOCK, 128, 0);
632+ err = btf__add_field(btf, "b", SPIN_LOCK, 192, 0);
633633 if (!ASSERT_OK(err, "btf__add_field foo::b"))
634634 break;
635635 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0);
636636 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b"))
637637 break;
638− id = btf__add_struct(btf, "bar", 36);
638+ id = btf__add_struct(btf, "bar", 44);
639639 if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))
640640 break;
641641 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
@@ -644,13 +644,13 @@ static void test_btf(void) · 2 unmodified lines
644644 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
645645 if (!ASSERT_OK(err, "btf__add_field bar::b"))
646646 break;
647− err = btf__add_field(btf, "c", SPIN_LOCK, 256, 0);
647+ err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
648648 if (!ASSERT_OK(err, "btf__add_field bar::c"))
649649 break;
650650 id = btf__add_decl_tag(btf, "contains:baz:a", 7, 0);
651651 if (!ASSERT_EQ(id, 8, "btf__add_decl_tag contains:baz:a"))
652652 break;
653− id = btf__add_struct(btf, "baz", 16);
653+ id = btf__add_struct(btf, "baz", 24);
654654 if (!ASSERT_EQ(id, 9, "btf__add_struct baz"))
655655 break;
656656 err = btf__add_field(btf, "a", LIST_NODE, 0, 0);
@@ -667,7 +667,7 @@ static void test_btf(void) · 10 unmodified lines
667667 btf = init_btf();
668668 if (!ASSERT_OK_PTR(btf, "init_btf"))
669669 break;
670− id = btf__add_struct(btf, "foo", 36);
670+ id = btf__add_struct(btf, "foo", 44);
671671 if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
672672 break;
673673 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
@@ -676,13 +676,13 @@ static void test_btf(void) · 2 unmodified lines
676676 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
677677 if (!ASSERT_OK(err, "btf__add_field foo::b"))
678678 break;
679− err = btf__add_field(btf, "c", SPIN_LOCK, 256, 0);
679+ err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
680680 if (!ASSERT_OK(err, "btf__add_field foo::c"))
681681 break;
682682 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0);
683683 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b"))
684684 break;
685− id = btf__add_struct(btf, "bar", 36);
685+ id = btf__add_struct(btf, "bar", 44);
686686 if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))
687687 break;
688688 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
@@ -691,13 +691,13 @@ static void test_btf(void) · 2 unmodified lines
691691 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
692692 if (!ASSERT_OK(err, "btf__add_field bar:b"))
693693 break;
694− err = btf__add_field(btf, "c", SPIN_LOCK, 256, 0);
694+ err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
695695 if (!ASSERT_OK(err, "btf__add_field bar:c"))
696696 break;
697697 id = btf__add_decl_tag(btf, "contains:baz:a", 7, 0);
698698 if (!ASSERT_EQ(id, 8, "btf__add_decl_tag contains:baz:a"))
699699 break;
700− id = btf__add_struct(btf, "baz", 16);
700+ id = btf__add_struct(btf, "baz", 24);
701701 if (!ASSERT_EQ(id, 9, "btf__add_struct baz"))
702702 break;
703703 err = btf__add_field(btf, "a", LIST_NODE, 0, 0);
@@ -726,7 +726,7 @@ static void test_btf(void) · 22 unmodified lines
726726 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0);
727727 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b"))
728728 break;
729− id = btf__add_struct(btf, "bar", 36);
729+ id = btf__add_struct(btf, "bar", 44);
730730 if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))
731731 break;
732732 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
@@ -735,13 +735,13 @@ static void test_btf(void) · 2 unmodified lines
735735 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
736736 if (!ASSERT_OK(err, "btf__add_field bar::b"))
737737 break;
738− err = btf__add_field(btf, "c", SPIN_LOCK, 256, 0);
738+ err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
739739 if (!ASSERT_OK(err, "btf__add_field bar::c"))
740740 break;
741741 id = btf__add_decl_tag(btf, "contains:baz:b", 7, 0);
742742 if (!ASSERT_EQ(id, 8, "btf__add_decl_tag"))
743743 break;
744− id = btf__add_struct(btf, "baz", 36);
744+ id = btf__add_struct(btf, "baz", 44);
745745 if (!ASSERT_EQ(id, 9, "btf__add_struct baz"))
746746 break;
747747 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
@@ -750,13 +750,13 @@ static void test_btf(void) · 2 unmodified lines
750750 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
751751 if (!ASSERT_OK(err, "btf__add_field bar::b"))
752752 break;
753− err = btf__add_field(btf, "c", SPIN_LOCK, 256, 0);
753+ err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
754754 if (!ASSERT_OK(err, "btf__add_field bar::c"))
755755 break;
756756 id = btf__add_decl_tag(btf, "contains:bam:a", 9, 0);
757757 if (!ASSERT_EQ(id, 10, "btf__add_decl_tag contains:bam:a"))
758758 break;
759− id = btf__add_struct(btf, "bam", 16);
759+ id = btf__add_struct(btf, "bam", 24);
760760 if (!ASSERT_EQ(id, 11, "btf__add_struct bam"))
761761 break;
762762 err = btf__add_field(btf, "a", LIST_NODE, 0, 0);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t