23
23
#define LIST_HEAD (name ) \
24
24
struct list_head name = LIST_HEAD_INIT(name)
25
25
26
+ /**
27
+ * INIT_LIST_HEAD - Initialize a list_head structure
28
+ * @list: list_head structure to be initialized.
29
+ *
30
+ * Initializes the list_head to point to itself. If it is a list header,
31
+ * the result is an empty list.
32
+ */
26
33
static inline void INIT_LIST_HEAD (struct list_head * list )
27
34
{
28
35
WRITE_ONCE (list -> next , list );
@@ -120,12 +127,6 @@ static inline void __list_del_clearprev(struct list_head *entry)
120
127
entry -> prev = NULL ;
121
128
}
122
129
123
- /**
124
- * list_del - deletes entry from list.
125
- * @entry: the element to delete from the list.
126
- * Note: list_empty() on entry does not return true after this, the entry is
127
- * in an undefined state.
128
- */
129
130
static inline void __list_del_entry (struct list_head * entry )
130
131
{
131
132
if (!__list_del_entry_valid (entry ))
@@ -134,6 +135,12 @@ static inline void __list_del_entry(struct list_head *entry)
134
135
__list_del (entry -> prev , entry -> next );
135
136
}
136
137
138
+ /**
139
+ * list_del - deletes entry from list.
140
+ * @entry: the element to delete from the list.
141
+ * Note: list_empty() on entry does not return true after this, the entry is
142
+ * in an undefined state.
143
+ */
137
144
static inline void list_del (struct list_head * entry )
138
145
{
139
146
__list_del_entry (entry );
@@ -157,8 +164,15 @@ static inline void list_replace(struct list_head *old,
157
164
new -> prev -> next = new ;
158
165
}
159
166
167
+ /**
168
+ * list_replace_init - replace old entry by new one and initialize the old one
169
+ * @old : the element to be replaced
170
+ * @new : the new element to insert
171
+ *
172
+ * If @old was empty, it will be overwritten.
173
+ */
160
174
static inline void list_replace_init (struct list_head * old ,
161
- struct list_head * new )
175
+ struct list_head * new )
162
176
{
163
177
list_replace (old , new );
164
178
INIT_LIST_HEAD (old );
@@ -744,11 +758,36 @@ static inline void INIT_HLIST_NODE(struct hlist_node *h)
744
758
h -> pprev = NULL ;
745
759
}
746
760
761
+ /**
762
+ * hlist_unhashed - Has node been removed from list and reinitialized?
763
+ * @h: Node to be checked
764
+ *
765
+ * Not that not all removal functions will leave a node in unhashed
766
+ * state. For example, hlist_nulls_del_init_rcu() does leave the
767
+ * node in unhashed state, but hlist_nulls_del() does not.
768
+ */
747
769
static inline int hlist_unhashed (const struct hlist_node * h )
748
770
{
749
771
return !h -> pprev ;
750
772
}
751
773
774
+ /**
775
+ * hlist_unhashed_lockless - Version of hlist_unhashed for lockless use
776
+ * @h: Node to be checked
777
+ *
778
+ * This variant of hlist_unhashed() must be used in lockless contexts
779
+ * to avoid potential load-tearing. The READ_ONCE() is paired with the
780
+ * various WRITE_ONCE() in hlist helpers that are defined below.
781
+ */
782
+ static inline int hlist_unhashed_lockless (const struct hlist_node * h )
783
+ {
784
+ return !READ_ONCE (h -> pprev );
785
+ }
786
+
787
+ /**
788
+ * hlist_empty - Is the specified hlist_head structure an empty hlist?
789
+ * @h: Structure to check.
790
+ */
752
791
static inline int hlist_empty (const struct hlist_head * h )
753
792
{
754
793
return !READ_ONCE (h -> first );
@@ -761,16 +800,29 @@ static inline void __hlist_del(struct hlist_node *n)
761
800
762
801
WRITE_ONCE (* pprev , next );
763
802
if (next )
764
- next -> pprev = pprev ;
803
+ WRITE_ONCE ( next -> pprev , pprev ) ;
765
804
}
766
805
806
+ /**
807
+ * hlist_del - Delete the specified hlist_node from its list
808
+ * @n: Node to delete.
809
+ *
810
+ * Note that this function leaves the node in hashed state. Use
811
+ * hlist_del_init() or similar instead to unhash @n.
812
+ */
767
813
static inline void hlist_del (struct hlist_node * n )
768
814
{
769
815
__hlist_del (n );
770
816
n -> next = LIST_POISON1 ;
771
817
n -> pprev = LIST_POISON2 ;
772
818
}
773
819
820
+ /**
821
+ * hlist_del_init - Delete the specified hlist_node from its list and initialize
822
+ * @n: Node to delete.
823
+ *
824
+ * Note that this function leaves the node in unhashed state.
825
+ */
774
826
static inline void hlist_del_init (struct hlist_node * n )
775
827
{
776
828
if (!hlist_unhashed (n )) {
@@ -779,59 +831,95 @@ static inline void hlist_del_init(struct hlist_node *n)
779
831
}
780
832
}
781
833
834
+ /**
835
+ * hlist_add_head - add a new entry at the beginning of the hlist
836
+ * @n: new entry to be added
837
+ * @h: hlist head to add it after
838
+ *
839
+ * Insert a new entry after the specified head.
840
+ * This is good for implementing stacks.
841
+ */
782
842
static inline void hlist_add_head (struct hlist_node * n , struct hlist_head * h )
783
843
{
784
844
struct hlist_node * first = h -> first ;
785
- n -> next = first ;
845
+ WRITE_ONCE ( n -> next , first ) ;
786
846
if (first )
787
- first -> pprev = & n -> next ;
847
+ WRITE_ONCE ( first -> pprev , & n -> next ) ;
788
848
WRITE_ONCE (h -> first , n );
789
- n -> pprev = & h -> first ;
849
+ WRITE_ONCE ( n -> pprev , & h -> first ) ;
790
850
}
791
851
792
- /* next must be != NULL */
852
+ /**
853
+ * hlist_add_before - add a new entry before the one specified
854
+ * @n: new entry to be added
855
+ * @next: hlist node to add it before, which must be non-NULL
856
+ */
793
857
static inline void hlist_add_before (struct hlist_node * n ,
794
- struct hlist_node * next )
858
+ struct hlist_node * next )
795
859
{
796
- n -> pprev = next -> pprev ;
797
- n -> next = next ;
798
- next -> pprev = & n -> next ;
860
+ WRITE_ONCE ( n -> pprev , next -> pprev ) ;
861
+ WRITE_ONCE ( n -> next , next ) ;
862
+ WRITE_ONCE ( next -> pprev , & n -> next ) ;
799
863
WRITE_ONCE (* (n -> pprev ), n );
800
864
}
801
865
866
+ /**
867
+ * hlist_add_behing - add a new entry after the one specified
868
+ * @n: new entry to be added
869
+ * @prev: hlist node to add it after, which must be non-NULL
870
+ */
802
871
static inline void hlist_add_behind (struct hlist_node * n ,
803
872
struct hlist_node * prev )
804
873
{
805
- n -> next = prev -> next ;
806
- prev -> next = n ;
807
- n -> pprev = & prev -> next ;
874
+ WRITE_ONCE ( n -> next , prev -> next ) ;
875
+ WRITE_ONCE ( prev -> next , n ) ;
876
+ WRITE_ONCE ( n -> pprev , & prev -> next ) ;
808
877
809
878
if (n -> next )
810
- n -> next -> pprev = & n -> next ;
879
+ WRITE_ONCE ( n -> next -> pprev , & n -> next ) ;
811
880
}
812
881
813
- /* after that we'll appear to be on some hlist and hlist_del will work */
882
+ /**
883
+ * hlist_add_fake - create a fake hlist consisting of a single headless node
884
+ * @n: Node to make a fake list out of
885
+ *
886
+ * This makes @n appear to be its own predecessor on a headless hlist.
887
+ * The point of this is to allow things like hlist_del() to work correctly
888
+ * in cases where there is no list.
889
+ */
814
890
static inline void hlist_add_fake (struct hlist_node * n )
815
891
{
816
892
n -> pprev = & n -> next ;
817
893
}
818
894
895
+ /**
896
+ * hlist_fake: Is this node a fake hlist?
897
+ * @h: Node to check for being a self-referential fake hlist.
898
+ */
819
899
static inline bool hlist_fake (struct hlist_node * h )
820
900
{
821
901
return h -> pprev == & h -> next ;
822
902
}
823
903
824
- /*
904
+ /**
905
+ * hlist_is_singular_node - is node the only element of the specified hlist?
906
+ * @n: Node to check for singularity.
907
+ * @h: Header for potentially singular list.
908
+ *
825
909
* Check whether the node is the only node of the head without
826
- * accessing head:
910
+ * accessing head, thus avoiding unnecessary cache misses.
827
911
*/
828
912
static inline bool
829
913
hlist_is_singular_node (struct hlist_node * n , struct hlist_head * h )
830
914
{
831
915
return !n -> next && n -> pprev == & h -> first ;
832
916
}
833
917
834
- /*
918
+ /**
919
+ * hlist_move_list - Move an hlist
920
+ * @old: hlist_head for old list.
921
+ * @new: hlist_head for new list.
922
+ *
835
923
* Move a list from one list head to another. Fixup the pprev
836
924
* reference of the first entry if it exists.
837
925
*/
0 commit comments