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
231/* Non-opaque version of bpf_rb_node in uapi/linux/bpf.h */231/* Non-opaque version of bpf_rb_node in uapi/linux/bpf.h */
232struct bpf_rb_node_kern {232struct bpf_rb_node_kern {
233 struct rb_node rb_node;233 struct rb_node rb_node;
234 void *owner;
234} __attribute__((aligned(8)));235} __attribute__((aligned(8)));
235 236
236/* Non-opaque version of bpf_list_node in uapi/linux/bpf.h */237/* Non-opaque version of bpf_list_node in uapi/linux/bpf.h */
237struct bpf_list_node_kern {238struct bpf_list_node_kern {
238 struct list_head list_head;239 struct list_head list_head;
240 void *owner;
239} __attribute__((aligned(8)));241} __attribute__((aligned(8)));
240 242
241struct bpf_map {243struct bpf_map {
include/uapi/linux/bpf.h+2−0
@@ -7052,6 +7052,7 @@ struct bpf_list_head { · 7051 unmodified lines
7052struct bpf_list_node {7052struct bpf_list_node {
7053 __u64 :64;7053 __u64 :64;
7054 __u64 :64;7054 __u64 :64;
7055 __u64 :64;
7055} __attribute__((aligned(8)));7056} __attribute__((aligned(8)));
7056 7057
7057struct bpf_rb_root {7058struct bpf_rb_root {
@@ -7063,6 +7064,7 @@ struct bpf_rb_node { · 5 unmodified lines
7063 __u64 :64;7064 __u64 :64;
7064 __u64 :64;7065 __u64 :64;
7065 __u64 :64;7066 __u64 :64;
7067 __u64 :64;
7066} __attribute__((aligned(8)));7068} __attribute__((aligned(8)));
7067 7069
7068struct bpf_refcount {7070struct 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
1953 */1953 */
1954 if (unlikely(!h->next))1954 if (unlikely(!h->next))
1955 INIT_LIST_HEAD(h);1955 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)) {
1957 /* Only called from BPF prog, no need to migrate_disable */1961 /* Only called from BPF prog, no need to migrate_disable */
1958 __bpf_obj_drop_impl((void *)n - off, rec);1962 __bpf_obj_drop_impl((void *)n - off, rec);
1959 return -EINVAL;1963 return -EINVAL;
1960 }1964 }
1961 1965
1962 tail ? list_add_tail(n, h) : list_add(n, h);1966 tail ? list_add_tail(n, h) : list_add(n, h);
1967 WRITE_ONCE(node->owner, head);
1963 1968
1964 return 0;1969 return 0;
1965}1970}
@@ -1987,6 +1992,7 @@ __bpf_kfunc int bpf_list_push_back_impl(struct bpf_list_head *head, · 21 unmodified lines
1987static struct bpf_list_node *__bpf_list_del(struct bpf_list_head *head, bool tail)1992static struct bpf_list_node *__bpf_list_del(struct bpf_list_head *head, bool tail)
1988{1993{
1989 struct list_head *n, *h = (void *)head;1994 struct list_head *n, *h = (void *)head;
1995 struct bpf_list_node_kern *node;
1990 1996
1991 /* If list_head was 0-initialized by map, bpf_obj_init_field wasn't1997 /* If list_head was 0-initialized by map, bpf_obj_init_field wasn't
1992 * called on its fields, so init here1998 * 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
1995 INIT_LIST_HEAD(h);2001 INIT_LIST_HEAD(h);
1996 if (list_empty(h))2002 if (list_empty(h))
1997 return NULL;2003 return NULL;
2004
1998 n = tail ? h->prev : h->next;2005 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
1999 list_del_init(n);2010 list_del_init(n);
2011 WRITE_ONCE(node->owner, NULL);
2000 return (struct bpf_list_node *)n;2012 return (struct bpf_list_node *)n;
2001}2013}
2002 2014
@@ -2013,14 +2025,19 @@ __bpf_kfunc struct bpf_list_node *bpf_list_pop_back(struct bpf_list_head *head) · 10 unmodified lines
2013__bpf_kfunc struct bpf_rb_node *bpf_rbtree_remove(struct bpf_rb_root *root,2025__bpf_kfunc struct bpf_rb_node *bpf_rbtree_remove(struct bpf_rb_root *root,
2014 struct bpf_rb_node *node)2026 struct bpf_rb_node *node)
2015{2027{
2028 struct bpf_rb_node_kern *node_internal = (struct bpf_rb_node_kern *)node;
2016 struct rb_root_cached *r = (struct rb_root_cached *)root;2029 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;
2018 2031
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)
2020 return NULL;2036 return NULL;
2021 2037
2022 rb_erase_cached(n, r);2038 rb_erase_cached(n, r);
2023 RB_CLEAR_NODE(n);2039 RB_CLEAR_NODE(n);
2040 WRITE_ONCE(node_internal->owner, NULL);
2024 return (struct bpf_rb_node *)n;2041 return (struct bpf_rb_node *)n;
2025}2042}
2026 2043
@@ -2036,7 +2053,10 @@ static int __bpf_rbtree_add(struct bpf_rb_root *root, · 9 unmodified lines
2036 bpf_callback_t cb = (bpf_callback_t)less;2053 bpf_callback_t cb = (bpf_callback_t)less;
2037 bool leftmost = true;2054 bool leftmost = true;
2038 2055
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)) {
2040 /* Only called from BPF prog, no need to migrate_disable */2060 /* Only called from BPF prog, no need to migrate_disable */
2041 __bpf_obj_drop_impl((void *)n - off, rec);2061 __bpf_obj_drop_impl((void *)n - off, rec);
2042 return -EINVAL;2062 return -EINVAL;
@@ -2054,6 +2074,7 @@ static int __bpf_rbtree_add(struct bpf_rb_root *root, · 11 unmodified lines
2054 2074
2055 rb_link_node(n, parent, link);2075 rb_link_node(n, parent, link);
2056 rb_insert_color_cached(n, (struct rb_root_cached *)root, leftmost);2076 rb_insert_color_cached(n, (struct rb_root_cached *)root, leftmost);
2077 WRITE_ONCE(node->owner, root);
2057 return 0;2078 return 0;
2058}2079}
2059 2080
tools/testing/selftests/bpf/prog_tests/linked_list.c+39−39
@@ -23,7 +23,7 @@ static struct { · 22 unmodified lines
23 "bpf_spin_lock at off=" #off " must be held for bpf_list_head" }, \23 "bpf_spin_lock at off=" #off " must be held for bpf_list_head" }, \
24 { #test "_missing_lock_pop_back", \24 { #test "_missing_lock_pop_back", \
25 "bpf_spin_lock at off=" #off " must be held for bpf_list_head" },25 "bpf_spin_lock at off=" #off " must be held for bpf_list_head" },
26 TEST(kptr, 32)26 TEST(kptr, 40)
27 TEST(global, 16)27 TEST(global, 16)
28 TEST(map, 0)28 TEST(map, 0)
29 TEST(inner_map, 0)29 TEST(inner_map, 0)
@@ -31,7 +31,7 @@ static struct { · 1 unmodified line
31#define TEST(test, op) \31#define TEST(test, op) \
32 { #test "_kptr_incorrect_lock_" #op, \32 { #test "_kptr_incorrect_lock_" #op, \
33 "held lock and object are not in the same allocation\n" \33 "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" }, \
35 { #test "_global_incorrect_lock_" #op, \35 { #test "_global_incorrect_lock_" #op, \
36 "held lock and object are not in the same allocation\n" \36 "held lock and object are not in the same allocation\n" \
37 "bpf_spin_lock at off=16 must be held for bpf_list_head" }, \37 "bpf_spin_lock at off=16 must be held for bpf_list_head" }, \
@@ -84,23 +84,23 @@ static struct { · 46 unmodified lines
84 { "double_push_back", "arg#1 expected pointer to allocated object" },84 { "double_push_back", "arg#1 expected pointer to allocated object" },
85 { "no_node_value_type", "bpf_list_node not found at offset=0" },85 { "no_node_value_type", "bpf_list_node not found at offset=0" },
86 { "incorrect_value_type",86 { "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, "
88 "but arg is at offset=0 in struct bar" },88 "but arg is at offset=0 in struct bar" },
89 { "incorrect_node_var_off", "variable ptr_ access var_off=(0x0; 0xffffffff) disallowed" },89 { "incorrect_node_var_off", "variable ptr_ access var_off=(0x0; 0xffffffff) disallowed" },
90 { "incorrect_node_off1", "bpf_list_node not found at offset=41" },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=40 in struct foo" },91 { "incorrect_node_off2", "arg#1 offset=0, but expected bpf_list_node at offset=48 in struct foo" },
92 { "no_head_type", "bpf_list_head not found at offset=0" },92 { "no_head_type", "bpf_list_head not found at offset=0" },
93 { "incorrect_head_var_off1", "R1 doesn't have constant offset" },93 { "incorrect_head_var_off1", "R1 doesn't have constant offset" },
94 { "incorrect_head_var_off2", "variable ptr_ access var_off=(0x0; 0xffffffff) disallowed" },94 { "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" },
96 { "incorrect_head_off2", "bpf_list_head not found at offset=1" },96 { "incorrect_head_off2", "bpf_list_head not found at offset=1" },
97 { "pop_front_off",97 { "pop_front_off",
98 "15: (bf) r1 = r6 ; R1_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=40,imm=0) "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=40,imm=0) refs=2,4\n"99 "R6_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=48,imm=0) refs=2,4\n"
100 "16: (85) call bpf_this_cpu_ptr#154\nR1 type=ptr_or_null_ expected=percpu_ptr_" },100 "16: (85) call bpf_this_cpu_ptr#154\nR1 type=ptr_or_null_ expected=percpu_ptr_" },
101 { "pop_back_off",101 { "pop_back_off",
102 "15: (bf) r1 = r6 ; R1_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=40,imm=0) "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=40,imm=0) refs=2,4\n"103 "R6_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=48,imm=0) refs=2,4\n"
104 "16: (85) call bpf_this_cpu_ptr#154\nR1 type=ptr_or_null_ expected=percpu_ptr_" },104 "16: (85) call bpf_this_cpu_ptr#154\nR1 type=ptr_or_null_ expected=percpu_ptr_" },
105};105};
106 106
@@ -257,7 +257,7 @@ static struct btf *init_btf(void) · 150 unmodified lines
257 hid = btf__add_struct(btf, "bpf_list_head", 16);257 hid = btf__add_struct(btf, "bpf_list_head", 16);
258 if (!ASSERT_EQ(hid, LIST_HEAD, "btf__add_struct bpf_list_head"))258 if (!ASSERT_EQ(hid, LIST_HEAD, "btf__add_struct bpf_list_head"))
259 goto end;259 goto end;
260 nid = btf__add_struct(btf, "bpf_list_node", 16);260 nid = btf__add_struct(btf, "bpf_list_node", 24);
261 if (!ASSERT_EQ(nid, LIST_NODE, "btf__add_struct bpf_list_node"))261 if (!ASSERT_EQ(nid, LIST_NODE, "btf__add_struct bpf_list_node"))
262 goto end;262 goto end;
263 return btf;263 return btf;
@@ -276,7 +276,7 @@ static void list_and_rb_node_same_struct(bool refcount_field) · 12 unmodified lines
276 if (!ASSERT_OK_PTR(btf, "init_btf"))276 if (!ASSERT_OK_PTR(btf, "init_btf"))
277 return;277 return;
278 278
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);
280 if (!ASSERT_GT(bpf_rb_node_btf_id, 0, "btf__add_struct bpf_rb_node"))280 if (!ASSERT_GT(bpf_rb_node_btf_id, 0, "btf__add_struct bpf_rb_node"))
281 return;281 return;
282 282
@@ -286,17 +286,17 @@ static void list_and_rb_node_same_struct(bool refcount_field) · 3 unmodified lines
286 return;286 return;
287 }287 }
288 288
289 id = btf__add_struct(btf, "bar", refcount_field ? 44 : 40);289 id = btf__add_struct(btf, "bar", refcount_field ? 60 : 56);
290 if (!ASSERT_GT(id, 0, "btf__add_struct bar"))290 if (!ASSERT_GT(id, 0, "btf__add_struct bar"))
291 return;291 return;
292 err = btf__add_field(btf, "a", LIST_NODE, 0, 0);292 err = btf__add_field(btf, "a", LIST_NODE, 0, 0);
293 if (!ASSERT_OK(err, "btf__add_field bar::a"))293 if (!ASSERT_OK(err, "btf__add_field bar::a"))
294 return;294 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);
296 if (!ASSERT_OK(err, "btf__add_field bar::c"))296 if (!ASSERT_OK(err, "btf__add_field bar::c"))
297 return;297 return;
298 if (refcount_field) {298 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);
300 if (!ASSERT_OK(err, "btf__add_field bar::ref"))300 if (!ASSERT_OK(err, "btf__add_field bar::ref"))
301 return;301 return;
302 }302 }
@@ -527,7 +527,7 @@ static void test_btf(void) · 224 unmodified lines
527 btf = init_btf();527 btf = init_btf();
528 if (!ASSERT_OK_PTR(btf, "init_btf"))528 if (!ASSERT_OK_PTR(btf, "init_btf"))
529 break;529 break;
530 id = btf__add_struct(btf, "foo", 36);530 id = btf__add_struct(btf, "foo", 44);
531 if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))531 if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
532 break;532 break;
533 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);533 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
@@ -536,7 +536,7 @@ static void test_btf(void) · 2 unmodified lines
536 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);536 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
537 if (!ASSERT_OK(err, "btf__add_field foo::b"))537 if (!ASSERT_OK(err, "btf__add_field foo::b"))
538 break;538 break;
539 err = btf__add_field(btf, "c", SPIN_LOCK, 256, 0);539 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
540 if (!ASSERT_OK(err, "btf__add_field foo::c"))540 if (!ASSERT_OK(err, "btf__add_field foo::c"))
541 break;541 break;
542 id = btf__add_decl_tag(btf, "contains:foo:b", 5, 0);542 id = btf__add_decl_tag(btf, "contains:foo:b", 5, 0);
@@ -553,7 +553,7 @@ static void test_btf(void) · 10 unmodified lines
553 btf = init_btf();553 btf = init_btf();
554 if (!ASSERT_OK_PTR(btf, "init_btf"))554 if (!ASSERT_OK_PTR(btf, "init_btf"))
555 break;555 break;
556 id = btf__add_struct(btf, "foo", 36);556 id = btf__add_struct(btf, "foo", 44);
557 if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))557 if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
558 break;558 break;
559 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);559 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
@@ -562,13 +562,13 @@ static void test_btf(void) · 2 unmodified lines
562 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);562 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
563 if (!ASSERT_OK(err, "btf__add_field foo::b"))563 if (!ASSERT_OK(err, "btf__add_field foo::b"))
564 break;564 break;
565 err = btf__add_field(btf, "c", SPIN_LOCK, 256, 0);565 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
566 if (!ASSERT_OK(err, "btf__add_field foo::c"))566 if (!ASSERT_OK(err, "btf__add_field foo::c"))
567 break;567 break;
568 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0);568 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0);
569 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b"))569 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b"))
570 break;570 break;
571 id = btf__add_struct(btf, "bar", 36);571 id = btf__add_struct(btf, "bar", 44);
572 if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))572 if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))
573 break;573 break;
574 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);574 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
@@ -577,7 +577,7 @@ static void test_btf(void) · 2 unmodified lines
577 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);577 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
578 if (!ASSERT_OK(err, "btf__add_field bar::b"))578 if (!ASSERT_OK(err, "btf__add_field bar::b"))
579 break;579 break;
580 err = btf__add_field(btf, "c", SPIN_LOCK, 256, 0);580 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
581 if (!ASSERT_OK(err, "btf__add_field bar::c"))581 if (!ASSERT_OK(err, "btf__add_field bar::c"))
582 break;582 break;
583 id = btf__add_decl_tag(btf, "contains:foo:b", 7, 0);583 id = btf__add_decl_tag(btf, "contains:foo:b", 7, 0);
@@ -594,19 +594,19 @@ static void test_btf(void) · 10 unmodified lines
594 btf = init_btf();594 btf = init_btf();
595 if (!ASSERT_OK_PTR(btf, "init_btf"))595 if (!ASSERT_OK_PTR(btf, "init_btf"))
596 break;596 break;
597 id = btf__add_struct(btf, "foo", 20);597 id = btf__add_struct(btf, "foo", 28);
598 if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))598 if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
599 break;599 break;
600 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);600 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
601 if (!ASSERT_OK(err, "btf__add_field foo::a"))601 if (!ASSERT_OK(err, "btf__add_field foo::a"))
602 break;602 break;
603 err = btf__add_field(btf, "b", SPIN_LOCK, 128, 0);603 err = btf__add_field(btf, "b", SPIN_LOCK, 192, 0);
604 if (!ASSERT_OK(err, "btf__add_field foo::b"))604 if (!ASSERT_OK(err, "btf__add_field foo::b"))
605 break;605 break;
606 id = btf__add_decl_tag(btf, "contains:bar:a", 5, 0);606 id = btf__add_decl_tag(btf, "contains:bar:a", 5, 0);
607 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:a"))607 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:a"))
608 break;608 break;
609 id = btf__add_struct(btf, "bar", 16);609 id = btf__add_struct(btf, "bar", 24);
610 if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))610 if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))
611 break;611 break;
612 err = btf__add_field(btf, "a", LIST_NODE, 0, 0);612 err = btf__add_field(btf, "a", LIST_NODE, 0, 0);
@@ -623,19 +623,19 @@ static void test_btf(void) · 10 unmodified lines
623 btf = init_btf();623 btf = init_btf();
624 if (!ASSERT_OK_PTR(btf, "init_btf"))624 if (!ASSERT_OK_PTR(btf, "init_btf"))
625 break;625 break;
626 id = btf__add_struct(btf, "foo", 20);626 id = btf__add_struct(btf, "foo", 28);
627 if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))627 if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
628 break;628 break;
629 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);629 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
630 if (!ASSERT_OK(err, "btf__add_field foo::a"))630 if (!ASSERT_OK(err, "btf__add_field foo::a"))
631 break;631 break;
632 err = btf__add_field(btf, "b", SPIN_LOCK, 128, 0);632 err = btf__add_field(btf, "b", SPIN_LOCK, 192, 0);
633 if (!ASSERT_OK(err, "btf__add_field foo::b"))633 if (!ASSERT_OK(err, "btf__add_field foo::b"))
634 break;634 break;
635 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0);635 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0);
636 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b"))636 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b"))
637 break;637 break;
638 id = btf__add_struct(btf, "bar", 36);638 id = btf__add_struct(btf, "bar", 44);
639 if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))639 if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))
640 break;640 break;
641 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);641 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
@@ -644,13 +644,13 @@ static void test_btf(void) · 2 unmodified lines
644 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);644 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
645 if (!ASSERT_OK(err, "btf__add_field bar::b"))645 if (!ASSERT_OK(err, "btf__add_field bar::b"))
646 break;646 break;
647 err = btf__add_field(btf, "c", SPIN_LOCK, 256, 0);647 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
648 if (!ASSERT_OK(err, "btf__add_field bar::c"))648 if (!ASSERT_OK(err, "btf__add_field bar::c"))
649 break;649 break;
650 id = btf__add_decl_tag(btf, "contains:baz:a", 7, 0);650 id = btf__add_decl_tag(btf, "contains:baz:a", 7, 0);
651 if (!ASSERT_EQ(id, 8, "btf__add_decl_tag contains:baz:a"))651 if (!ASSERT_EQ(id, 8, "btf__add_decl_tag contains:baz:a"))
652 break;652 break;
653 id = btf__add_struct(btf, "baz", 16);653 id = btf__add_struct(btf, "baz", 24);
654 if (!ASSERT_EQ(id, 9, "btf__add_struct baz"))654 if (!ASSERT_EQ(id, 9, "btf__add_struct baz"))
655 break;655 break;
656 err = btf__add_field(btf, "a", LIST_NODE, 0, 0);656 err = btf__add_field(btf, "a", LIST_NODE, 0, 0);
@@ -667,7 +667,7 @@ static void test_btf(void) · 10 unmodified lines
667 btf = init_btf();667 btf = init_btf();
668 if (!ASSERT_OK_PTR(btf, "init_btf"))668 if (!ASSERT_OK_PTR(btf, "init_btf"))
669 break;669 break;
670 id = btf__add_struct(btf, "foo", 36);670 id = btf__add_struct(btf, "foo", 44);
671 if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))671 if (!ASSERT_EQ(id, 5, "btf__add_struct foo"))
672 break;672 break;
673 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);673 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
@@ -676,13 +676,13 @@ static void test_btf(void) · 2 unmodified lines
676 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);676 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
677 if (!ASSERT_OK(err, "btf__add_field foo::b"))677 if (!ASSERT_OK(err, "btf__add_field foo::b"))
678 break;678 break;
679 err = btf__add_field(btf, "c", SPIN_LOCK, 256, 0);679 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
680 if (!ASSERT_OK(err, "btf__add_field foo::c"))680 if (!ASSERT_OK(err, "btf__add_field foo::c"))
681 break;681 break;
682 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0);682 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0);
683 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b"))683 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b"))
684 break;684 break;
685 id = btf__add_struct(btf, "bar", 36);685 id = btf__add_struct(btf, "bar", 44);
686 if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))686 if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))
687 break;687 break;
688 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);688 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
@@ -691,13 +691,13 @@ static void test_btf(void) · 2 unmodified lines
691 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);691 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
692 if (!ASSERT_OK(err, "btf__add_field bar:b"))692 if (!ASSERT_OK(err, "btf__add_field bar:b"))
693 break;693 break;
694 err = btf__add_field(btf, "c", SPIN_LOCK, 256, 0);694 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
695 if (!ASSERT_OK(err, "btf__add_field bar:c"))695 if (!ASSERT_OK(err, "btf__add_field bar:c"))
696 break;696 break;
697 id = btf__add_decl_tag(btf, "contains:baz:a", 7, 0);697 id = btf__add_decl_tag(btf, "contains:baz:a", 7, 0);
698 if (!ASSERT_EQ(id, 8, "btf__add_decl_tag contains:baz:a"))698 if (!ASSERT_EQ(id, 8, "btf__add_decl_tag contains:baz:a"))
699 break;699 break;
700 id = btf__add_struct(btf, "baz", 16);700 id = btf__add_struct(btf, "baz", 24);
701 if (!ASSERT_EQ(id, 9, "btf__add_struct baz"))701 if (!ASSERT_EQ(id, 9, "btf__add_struct baz"))
702 break;702 break;
703 err = btf__add_field(btf, "a", LIST_NODE, 0, 0);703 err = btf__add_field(btf, "a", LIST_NODE, 0, 0);
@@ -726,7 +726,7 @@ static void test_btf(void) · 22 unmodified lines
726 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0);726 id = btf__add_decl_tag(btf, "contains:bar:b", 5, 0);
727 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b"))727 if (!ASSERT_EQ(id, 6, "btf__add_decl_tag contains:bar:b"))
728 break;728 break;
729 id = btf__add_struct(btf, "bar", 36);729 id = btf__add_struct(btf, "bar", 44);
730 if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))730 if (!ASSERT_EQ(id, 7, "btf__add_struct bar"))
731 break;731 break;
732 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);732 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
@@ -735,13 +735,13 @@ static void test_btf(void) · 2 unmodified lines
735 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);735 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
736 if (!ASSERT_OK(err, "btf__add_field bar::b"))736 if (!ASSERT_OK(err, "btf__add_field bar::b"))
737 break;737 break;
738 err = btf__add_field(btf, "c", SPIN_LOCK, 256, 0);738 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
739 if (!ASSERT_OK(err, "btf__add_field bar::c"))739 if (!ASSERT_OK(err, "btf__add_field bar::c"))
740 break;740 break;
741 id = btf__add_decl_tag(btf, "contains:baz:b", 7, 0);741 id = btf__add_decl_tag(btf, "contains:baz:b", 7, 0);
742 if (!ASSERT_EQ(id, 8, "btf__add_decl_tag"))742 if (!ASSERT_EQ(id, 8, "btf__add_decl_tag"))
743 break;743 break;
744 id = btf__add_struct(btf, "baz", 36);744 id = btf__add_struct(btf, "baz", 44);
745 if (!ASSERT_EQ(id, 9, "btf__add_struct baz"))745 if (!ASSERT_EQ(id, 9, "btf__add_struct baz"))
746 break;746 break;
747 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);747 err = btf__add_field(btf, "a", LIST_HEAD, 0, 0);
@@ -750,13 +750,13 @@ static void test_btf(void) · 2 unmodified lines
750 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);750 err = btf__add_field(btf, "b", LIST_NODE, 128, 0);
751 if (!ASSERT_OK(err, "btf__add_field bar::b"))751 if (!ASSERT_OK(err, "btf__add_field bar::b"))
752 break;752 break;
753 err = btf__add_field(btf, "c", SPIN_LOCK, 256, 0);753 err = btf__add_field(btf, "c", SPIN_LOCK, 320, 0);
754 if (!ASSERT_OK(err, "btf__add_field bar::c"))754 if (!ASSERT_OK(err, "btf__add_field bar::c"))
755 break;755 break;
756 id = btf__add_decl_tag(btf, "contains:bam:a", 9, 0);756 id = btf__add_decl_tag(btf, "contains:bam:a", 9, 0);
757 if (!ASSERT_EQ(id, 10, "btf__add_decl_tag contains:bam:a"))757 if (!ASSERT_EQ(id, 10, "btf__add_decl_tag contains:bam:a"))
758 break;758 break;
759 id = btf__add_struct(btf, "bam", 16);759 id = btf__add_struct(btf, "bam", 24);
760 if (!ASSERT_EQ(id, 11, "btf__add_struct bam"))760 if (!ASSERT_EQ(id, 11, "btf__add_struct bam"))
761 break;761 break;
762 err = btf__add_field(btf, "a", LIST_NODE, 0, 0);762 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