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

selftests/bpf: Validate multiple ref release_on_unlock logic

Modify list_push_pop_multiple to alloc and insert nodes 2-at-a-time.
Without the previous patch's fix, this block of code:

bpf_spin_lock(lock);
bpf_list_push_front(head, &f[i]->node);
bpf_list_push_front(head, &f[i + 1]->node);
bpf_spin_unlock(lock);

would fail check_reference_leak check as release_on_unlock logic would miss
a ref that should've been released.

Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com>
cc: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Acked-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/r/20221201183406.1203621-2-davemarchevsky@fb.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Dave Marchevsky and committed by
Alexei Starovoitov
78b037bd 1f82dffc

+16 -1
+16 -1
tools/testing/selftests/bpf/progs/linked_list.c
··· 99 99 struct foo *f[8], *pf; 100 100 int i; 101 101 102 - for (i = 0; i < ARRAY_SIZE(f); i++) { 102 + /* Loop following this check adds nodes 2-at-a-time in order to 103 + * validate multiple release_on_unlock release logic 104 + */ 105 + if (ARRAY_SIZE(f) % 2) 106 + return 10; 107 + 108 + for (i = 0; i < ARRAY_SIZE(f); i += 2) { 103 109 f[i] = bpf_obj_new(typeof(**f)); 104 110 if (!f[i]) 105 111 return 2; 106 112 f[i]->data = i; 113 + 114 + f[i + 1] = bpf_obj_new(typeof(**f)); 115 + if (!f[i + 1]) { 116 + bpf_obj_drop(f[i]); 117 + return 9; 118 + } 119 + f[i + 1]->data = i + 1; 120 + 107 121 bpf_spin_lock(lock); 108 122 bpf_list_push_front(head, &f[i]->node); 123 + bpf_list_push_front(head, &f[i + 1]->node); 109 124 bpf_spin_unlock(lock); 110 125 } 111 126