1 /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
2 /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */
4 #include "bpf_arena_common.h"
6 struct arena_list_node
;
8 typedef struct arena_list_node __arena arena_list_node_t
;
10 struct arena_list_node
{
11 arena_list_node_t
*next
;
12 arena_list_node_t
* __arena
*pprev
;
15 struct arena_list_head
{
16 struct arena_list_node __arena
*first
;
18 typedef struct arena_list_head __arena arena_list_head_t
;
20 #define list_entry(ptr, type, member) arena_container_of(ptr, type, member)
22 #define list_entry_safe(ptr, type, member) \
23 ({ typeof(*ptr) * ___ptr = (ptr); \
24 ___ptr ? ({ cast_kern(___ptr); list_entry(___ptr, type, member); }) : NULL; \
28 static inline void *bpf_iter_num_new(struct bpf_iter_num
*it
, int i
, int j
) { return NULL
; }
29 static inline void bpf_iter_num_destroy(struct bpf_iter_num
*it
) {}
30 static inline bool bpf_iter_num_next(struct bpf_iter_num
*it
) { return true; }
31 #define cond_break ({})
35 /* Safely walk link list elements. Deletion of elements is allowed. */
36 #define list_for_each_entry(pos, head, member) \
37 for (void * ___tmp = (pos = list_entry_safe((head)->first, \
38 typeof(*(pos)), member), \
40 pos && ({ ___tmp = (void *)pos->member.next; 1; }) && can_loop; \
41 pos = list_entry_safe((void __arena *)___tmp, typeof(*(pos)), member))
43 static inline void list_add_head(arena_list_node_t
*n
, arena_list_head_t
*h
)
45 arena_list_node_t
*first
= h
->first
, * __arena
*tmp
;
49 WRITE_ONCE(n
->next
, first
);
54 WRITE_ONCE(first
->pprev
, tmp
);
57 WRITE_ONCE(h
->first
, n
);
62 WRITE_ONCE(n
->pprev
, tmp
);
65 static inline void __list_del(arena_list_node_t
*n
)
67 arena_list_node_t
*next
= n
->next
, *tmp
;
68 arena_list_node_t
* __arena
*pprev
= n
->pprev
;
74 WRITE_ONCE(tmp
, next
);
78 WRITE_ONCE(next
->pprev
, pprev
);
82 #define POISON_POINTER_DELTA 0
84 #define LIST_POISON1 ((void __arena *) 0x100 + POISON_POINTER_DELTA)
85 #define LIST_POISON2 ((void __arena *) 0x122 + POISON_POINTER_DELTA)
87 static inline void list_del(arena_list_node_t
*n
)
90 n
->next
= LIST_POISON1
;
91 n
->pprev
= LIST_POISON2
;