![]() |
|
|||
0001 /* SPDX-License-Identifier: GPL-2.0 */ 0002 #ifndef _LINUX_RCULIST_BL_H 0003 #define _LINUX_RCULIST_BL_H 0004 0005 /* 0006 * RCU-protected bl list version. See include/linux/list_bl.h. 0007 */ 0008 #include <linux/list_bl.h> 0009 #include <linux/rcupdate.h> 0010 0011 static inline void hlist_bl_set_first_rcu(struct hlist_bl_head *h, 0012 struct hlist_bl_node *n) 0013 { 0014 LIST_BL_BUG_ON((unsigned long)n & LIST_BL_LOCKMASK); 0015 LIST_BL_BUG_ON(((unsigned long)h->first & LIST_BL_LOCKMASK) != 0016 LIST_BL_LOCKMASK); 0017 rcu_assign_pointer(h->first, 0018 (struct hlist_bl_node *)((unsigned long)n | LIST_BL_LOCKMASK)); 0019 } 0020 0021 static inline struct hlist_bl_node *hlist_bl_first_rcu(struct hlist_bl_head *h) 0022 { 0023 return (struct hlist_bl_node *) 0024 ((unsigned long)rcu_dereference_check(h->first, hlist_bl_is_locked(h)) & ~LIST_BL_LOCKMASK); 0025 } 0026 0027 /** 0028 * hlist_bl_del_rcu - deletes entry from hash list without re-initialization 0029 * @n: the element to delete from the hash list. 0030 * 0031 * Note: hlist_bl_unhashed() on entry does not return true after this, 0032 * the entry is in an undefined state. It is useful for RCU based 0033 * lockfree traversal. 0034 * 0035 * In particular, it means that we can not poison the forward 0036 * pointers that may still be used for walking the hash list. 0037 * 0038 * The caller must take whatever precautions are necessary 0039 * (such as holding appropriate locks) to avoid racing 0040 * with another list-mutation primitive, such as hlist_bl_add_head_rcu() 0041 * or hlist_bl_del_rcu(), running on this same list. 0042 * However, it is perfectly legal to run concurrently with 0043 * the _rcu list-traversal primitives, such as 0044 * hlist_bl_for_each_entry(). 0045 */ 0046 static inline void hlist_bl_del_rcu(struct hlist_bl_node *n) 0047 { 0048 __hlist_bl_del(n); 0049 n->pprev = LIST_POISON2; 0050 } 0051 0052 /** 0053 * hlist_bl_add_head_rcu 0054 * @n: the element to add to the hash list. 0055 * @h: the list to add to. 0056 * 0057 * Description: 0058 * Adds the specified element to the specified hlist_bl, 0059 * while permitting racing traversals. 0060 * 0061 * The caller must take whatever precautions are necessary 0062 * (such as holding appropriate locks) to avoid racing 0063 * with another list-mutation primitive, such as hlist_bl_add_head_rcu() 0064 * or hlist_bl_del_rcu(), running on this same list. 0065 * However, it is perfectly legal to run concurrently with 0066 * the _rcu list-traversal primitives, such as 0067 * hlist_bl_for_each_entry_rcu(), used to prevent memory-consistency 0068 * problems on Alpha CPUs. Regardless of the type of CPU, the 0069 * list-traversal primitive must be guarded by rcu_read_lock(). 0070 */ 0071 static inline void hlist_bl_add_head_rcu(struct hlist_bl_node *n, 0072 struct hlist_bl_head *h) 0073 { 0074 struct hlist_bl_node *first; 0075 0076 /* don't need hlist_bl_first_rcu because we're under lock */ 0077 first = hlist_bl_first(h); 0078 0079 n->next = first; 0080 if (first) 0081 first->pprev = &n->next; 0082 n->pprev = &h->first; 0083 0084 /* need _rcu because we can have concurrent lock free readers */ 0085 hlist_bl_set_first_rcu(h, n); 0086 } 0087 /** 0088 * hlist_bl_for_each_entry_rcu - iterate over rcu list of given type 0089 * @tpos: the type * to use as a loop cursor. 0090 * @pos: the &struct hlist_bl_node to use as a loop cursor. 0091 * @head: the head for your list. 0092 * @member: the name of the hlist_bl_node within the struct. 0093 * 0094 */ 0095 #define hlist_bl_for_each_entry_rcu(tpos, pos, head, member) \ 0096 for (pos = hlist_bl_first_rcu(head); \ 0097 pos && \ 0098 ({ tpos = hlist_bl_entry(pos, typeof(*tpos), member); 1; }); \ 0099 pos = rcu_dereference_raw(pos->next)) 0100 0101 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |