File Index
Files and directories
Sign in
FILE

linked_list_peek.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/progs/linked_list_peek.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */
  3
  4#include <vmlinux.h>
  5#include <bpf/bpf_helpers.h>
  6#include "bpf_misc.h"
  7#include "bpf_experimental.h"
  8
  9struct node_data {
 10	struct bpf_list_node l;
 11	int key;
 12};
 13
 14#define private(name) SEC(".data." #name) __hidden __attribute__((aligned(8)))
 15private(A) struct bpf_spin_lock glock;
 16private(A) struct bpf_list_head ghead __contains(node_data, l);
 17
 18#define list_entry(ptr, type, member) container_of(ptr, type, member)
 19#define NR_NODES 16
 20
 21int zero = 0;
 22
 23SEC("syscall")
 24__retval(0)
 25long list_peek(void *ctx)
 26{
 27	struct bpf_list_node *l_n;
 28	struct node_data *n;
 29	int i, err = 0;
 30
 31	bpf_spin_lock(&glock);
 32	l_n = bpf_list_front(&ghead);
 33	bpf_spin_unlock(&glock);
 34	if (l_n)
 35		return __LINE__;
 36
 37	bpf_spin_lock(&glock);
 38	l_n = bpf_list_back(&ghead);
 39	bpf_spin_unlock(&glock);
 40	if (l_n)
 41		return __LINE__;
 42
 43	for (i = zero; i < NR_NODES && can_loop; i++) {
 44		n = bpf_obj_new(typeof(*n));
 45		if (!n)
 46			return __LINE__;
 47		n->key = i;
 48		bpf_spin_lock(&glock);
 49		bpf_list_push_back(&ghead, &n->l);
 50		bpf_spin_unlock(&glock);
 51	}
 52
 53	bpf_spin_lock(&glock);
 54
 55	l_n = bpf_list_front(&ghead);
 56	if (!l_n) {
 57		err = __LINE__;
 58		goto done;
 59	}
 60
 61	n = list_entry(l_n, struct node_data, l);
 62	if (n->key != 0) {
 63		err = __LINE__;
 64		goto done;
 65	}
 66
 67	l_n = bpf_list_back(&ghead);
 68	if (!l_n) {
 69		err = __LINE__;
 70		goto done;
 71	}
 72
 73	n = list_entry(l_n, struct node_data, l);
 74	if (n->key != NR_NODES - 1) {
 75		err = __LINE__;
 76		goto done;
 77	}
 78
 79done:
 80	bpf_spin_unlock(&glock);
 81	return err;
 82}
 83
 84#define TEST_FB(op, dolock)					\
 85SEC("syscall")							\
 86__failure __msg(MSG)						\
 87long test_##op##_spinlock_##dolock(void *ctx)			\
 88{								\
 89	struct bpf_list_node *l_n;				\
 90	__u64 jiffies = 0;					\
 91								\
 92	if (dolock)						\
 93		bpf_spin_lock(&glock);				\
 94	l_n = bpf_list_##op(&ghead);				\
 95	if (l_n)						\
 96		jiffies = bpf_jiffies64();			\
 97	if (dolock)						\
 98		bpf_spin_unlock(&glock);			\
 99								\
100	return !!jiffies;					\
101}
102
103#define MSG "call bpf_list_{{(front|back).+}}; R0{{(_w)?}}=ptr_or_null_node_data(id={{[0-9]+}},non_own_ref"
104TEST_FB(front, true)
105TEST_FB(back, true)
106#undef MSG
107
108#define MSG "bpf_spin_lock at off=0 must be held for bpf_list_head"
109TEST_FB(front, false)
110TEST_FB(back, false)
111#undef MSG
112
113char _license[] SEC("license") = "GPL";
~/ Read-only file preview.