~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/include/linux/rculist_bl.h

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 
 11 static 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 
 21 static 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  */
 46 static 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  */
 71 static 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
102 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php