File Index
Files and directories
Sign in
FILE

rculist_bl.h

File preview with syntax highlighting.

linux-6.19.14/include/linux/rculist_bl.h C
  1/* SPDX-License-Identifier: GPL-2.0 */
  2#ifndef _LINUX_RCULIST_BL_H
  3#define _LINUX_RCULIST_BL_H
  4
  5/*
  6 * RCU-protected bl list version. See include/linux/list_bl.h.
  7 */
  8#include <linux/list_bl.h>
  9#include <linux/rcupdate.h>
 10
 11static inline void hlist_bl_set_first_rcu(struct hlist_bl_head *h,
 12					struct hlist_bl_node *n)
 13{
 14	LIST_BL_BUG_ON((unsigned long)n & LIST_BL_LOCKMASK);
 15	LIST_BL_BUG_ON(((unsigned long)h->first & LIST_BL_LOCKMASK) !=
 16							LIST_BL_LOCKMASK);
 17	rcu_assign_pointer(h->first,
 18		(struct hlist_bl_node *)((unsigned long)n | LIST_BL_LOCKMASK));
 19}
 20
 21static inline struct hlist_bl_node *hlist_bl_first_rcu(struct hlist_bl_head *h)
 22{
 23	return (struct hlist_bl_node *)
 24		((unsigned long)rcu_dereference_check(h->first, hlist_bl_is_locked(h)) & ~LIST_BL_LOCKMASK);
 25}
 26
 27/**
 28 * hlist_bl_del_rcu - deletes entry from hash list without re-initialization
 29 * @n: the element to delete from the hash list.
 30 *
 31 * Note: hlist_bl_unhashed() on entry does not return true after this,
 32 * the entry is in an undefined state. It is useful for RCU based
 33 * lockfree traversal.
 34 *
 35 * In particular, it means that we can not poison the forward
 36 * pointers that may still be used for walking the hash list.
 37 *
 38 * The caller must take whatever precautions are necessary
 39 * (such as holding appropriate locks) to avoid racing
 40 * with another list-mutation primitive, such as hlist_bl_add_head_rcu()
 41 * or hlist_bl_del_rcu(), running on this same list.
 42 * However, it is perfectly legal to run concurrently with
 43 * the _rcu list-traversal primitives, such as
 44 * hlist_bl_for_each_entry().
 45 */
 46static inline void hlist_bl_del_rcu(struct hlist_bl_node *n)
 47{
 48	__hlist_bl_del(n);
 49	n->pprev = LIST_POISON2;
 50}
 51
 52/**
 53 * hlist_bl_add_head_rcu
 54 * @n: the element to add to the hash list.
 55 * @h: the list to add to.
 56 *
 57 * Description:
 58 * Adds the specified element to the specified hlist_bl,
 59 * while permitting racing traversals.
 60 *
 61 * The caller must take whatever precautions are necessary
 62 * (such as holding appropriate locks) to avoid racing
 63 * with another list-mutation primitive, such as hlist_bl_add_head_rcu()
 64 * or hlist_bl_del_rcu(), running on this same list.
 65 * However, it is perfectly legal to run concurrently with
 66 * the _rcu list-traversal primitives, such as
 67 * hlist_bl_for_each_entry_rcu(), used to prevent memory-consistency
 68 * problems on Alpha CPUs.  Regardless of the type of CPU, the
 69 * list-traversal primitive must be guarded by rcu_read_lock().
 70 */
 71static inline void hlist_bl_add_head_rcu(struct hlist_bl_node *n,
 72					struct hlist_bl_head *h)
 73{
 74	struct hlist_bl_node *first;
 75
 76	/* don't need hlist_bl_first_rcu because we're under lock */
 77	first = hlist_bl_first(h);
 78
 79	n->next = first;
 80	if (first)
 81		first->pprev = &n->next;
 82	n->pprev = &h->first;
 83
 84	/* need _rcu because we can have concurrent lock free readers */
 85	hlist_bl_set_first_rcu(h, n);
 86}
 87/**
 88 * hlist_bl_for_each_entry_rcu - iterate over rcu list of given type
 89 * @tpos:	the type * to use as a loop cursor.
 90 * @pos:	the &struct hlist_bl_node to use as a loop cursor.
 91 * @head:	the head for your list.
 92 * @member:	the name of the hlist_bl_node within the struct.
 93 *
 94 */
 95#define hlist_bl_for_each_entry_rcu(tpos, pos, head, member)		\
 96	for (pos = hlist_bl_first_rcu(head);				\
 97		pos &&							\
 98		({ tpos = hlist_bl_entry(pos, typeof(*tpos), member); 1; }); \
 99		pos = rcu_dereference_raw(pos->next))
100
101#endif
~/ Read-only file preview.