Rev 6082 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6082 | Rev 6936 | ||
---|---|---|---|
Line 177... | Line 177... | ||
177 | new->next->prev = new; |
177 | new->next->prev = new; |
178 | old->prev = LIST_POISON2; |
178 | old->prev = LIST_POISON2; |
179 | } |
179 | } |
Line 180... | Line 180... | ||
180 | 180 | ||
181 | /** |
181 | /** |
182 | * list_splice_init_rcu - splice an RCU-protected list into an existing list. |
182 | * __list_splice_init_rcu - join an RCU-protected list into an existing list. |
- | 183 | * @list: the RCU-protected list to splice |
|
183 | * @list: the RCU-protected list to splice |
184 | * @prev: points to the last element of the existing list |
184 | * @head: the place in the list to splice the first list into |
185 | * @next: points to the first element of the existing list |
185 | * @sync: function to sync: synchronize_rcu(), synchronize_sched(), ... |
186 | * @sync: function to sync: synchronize_rcu(), synchronize_sched(), ... |
- | 187 | * |
|
186 | * |
188 | * The list pointed to by @prev and @next can be RCU-read traversed |
187 | * @head can be RCU-read traversed concurrently with this function. |
189 | * concurrently with this function. |
188 | * |
190 | * |
189 | * Note that this function blocks. |
191 | * Note that this function blocks. |
190 | * |
192 | * |
191 | * Important note: the caller must take whatever action is necessary to |
193 | * Important note: the caller must take whatever action is necessary to prevent |
192 | * prevent any other updates to @head. In principle, it is possible |
194 | * any other updates to the existing list. In principle, it is possible to |
193 | * to modify the list as soon as sync() begins execution. |
195 | * modify the list as soon as sync() begins execution. If this sort of thing |
194 | * If this sort of thing becomes necessary, an alternative version |
196 | * becomes necessary, an alternative version based on call_rcu() could be |
195 | * based on call_rcu() could be created. But only if -really- |
197 | * created. But only if -really- needed -- there is no shortage of RCU API |
196 | * needed -- there is no shortage of RCU API members. |
198 | * members. |
197 | */ |
199 | */ |
- | 200 | static inline void __list_splice_init_rcu(struct list_head *list, |
|
198 | static inline void list_splice_init_rcu(struct list_head *list, |
201 | struct list_head *prev, |
199 | struct list_head *head, |
202 | struct list_head *next, |
200 | void (*sync)(void)) |
203 | void (*sync)(void)) |
201 | { |
204 | { |
202 | struct list_head *first = list->next; |
205 | struct list_head *first = list->next; |
203 | struct list_head *last = list->prev; |
- | |
204 | struct list_head *at = head->next; |
- | |
205 | - | ||
206 | if (list_empty(list)) |
- | |
Line 207... | Line 206... | ||
207 | return; |
206 | struct list_head *last = list->prev; |
208 | 207 | ||
209 | /* |
208 | /* |
210 | * "first" and "last" tracking list, so initialize it. RCU readers |
209 | * "first" and "last" tracking list, so initialize it. RCU readers |
Line 229... | Line 228... | ||
229 | * to concurrent RCU readers. Note that RCU readers are not |
228 | * to concurrent RCU readers. Note that RCU readers are not |
230 | * permitted to traverse the prev pointers without excluding |
229 | * permitted to traverse the prev pointers without excluding |
231 | * this function. |
230 | * this function. |
232 | */ |
231 | */ |
Line 233... | Line 232... | ||
233 | 232 | ||
234 | last->next = at; |
233 | last->next = next; |
235 | rcu_assign_pointer(list_next_rcu(head), first); |
234 | rcu_assign_pointer(list_next_rcu(prev), first); |
236 | first->prev = head; |
235 | first->prev = prev; |
- | 236 | next->prev = last; |
|
- | 237 | } |
|
- | 238 | ||
- | 239 | /** |
|
- | 240 | * list_splice_init_rcu - splice an RCU-protected list into an existing list, |
|
- | 241 | * designed for stacks. |
|
- | 242 | * @list: the RCU-protected list to splice |
|
- | 243 | * @head: the place in the existing list to splice the first list into |
|
- | 244 | * @sync: function to sync: synchronize_rcu(), synchronize_sched(), ... |
|
- | 245 | */ |
|
- | 246 | static inline void list_splice_init_rcu(struct list_head *list, |
|
- | 247 | struct list_head *head, |
|
- | 248 | void (*sync)(void)) |
|
- | 249 | { |
|
- | 250 | if (!list_empty(list)) |
|
- | 251 | __list_splice_init_rcu(list, head, head->next, sync); |
|
- | 252 | } |
|
- | 253 | ||
- | 254 | /** |
|
- | 255 | * list_splice_tail_init_rcu - splice an RCU-protected list into an existing |
|
- | 256 | * list, designed for queues. |
|
- | 257 | * @list: the RCU-protected list to splice |
|
- | 258 | * @head: the place in the existing list to splice the first list into |
|
- | 259 | * @sync: function to sync: synchronize_rcu(), synchronize_sched(), ... |
|
- | 260 | */ |
|
- | 261 | static inline void list_splice_tail_init_rcu(struct list_head *list, |
|
- | 262 | struct list_head *head, |
|
- | 263 | void (*sync)(void)) |
|
- | 264 | { |
|
- | 265 | if (!list_empty(list)) |
|
237 | at->prev = last; |
266 | __list_splice_init_rcu(list, head->prev, head, sync); |
Line 238... | Line 267... | ||
238 | } |
267 | } |
239 | 268 | ||
240 | /** |
269 | /** |
Line 303... | Line 332... | ||
303 | for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \ |
332 | for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \ |
304 | &pos->member != (head); \ |
333 | &pos->member != (head); \ |
305 | pos = list_entry_rcu(pos->member.next, typeof(*pos), member)) |
334 | pos = list_entry_rcu(pos->member.next, typeof(*pos), member)) |
Line 306... | Line 335... | ||
306 | 335 | ||
- | 336 | /** |
|
- | 337 | * list_entry_lockless - get the struct for this entry |
|
- | 338 | * @ptr: the &struct list_head pointer. |
|
- | 339 | * @type: the type of the struct this is embedded in. |
|
- | 340 | * @member: the name of the list_head within the struct. |
|
- | 341 | * |
|
- | 342 | * This primitive may safely run concurrently with the _rcu list-mutation |
|
- | 343 | * primitives such as list_add_rcu(), but requires some implicit RCU |
|
- | 344 | * read-side guarding. One example is running within a special |
|
- | 345 | * exception-time environment where preemption is disabled and where |
|
- | 346 | * lockdep cannot be invoked (in which case updaters must use RCU-sched, |
|
- | 347 | * as in synchronize_sched(), call_rcu_sched(), and friends). Another |
|
- | 348 | * example is when items are added to the list, but never deleted. |
|
- | 349 | */ |
|
- | 350 | #define list_entry_lockless(ptr, type, member) \ |
|
- | 351 | container_of((typeof(ptr))lockless_dereference(ptr), type, member) |
|
- | 352 | ||
- | 353 | /** |
|
- | 354 | * list_for_each_entry_lockless - iterate over rcu list of given type |
|
- | 355 | * @pos: the type * to use as a loop cursor. |
|
- | 356 | * @head: the head for your list. |
|
- | 357 | * @member: the name of the list_struct within the struct. |
|
- | 358 | * |
|
- | 359 | * This primitive may safely run concurrently with the _rcu list-mutation |
|
- | 360 | * primitives such as list_add_rcu(), but requires some implicit RCU |
|
- | 361 | * read-side guarding. One example is running within a special |
|
- | 362 | * exception-time environment where preemption is disabled and where |
|
- | 363 | * lockdep cannot be invoked (in which case updaters must use RCU-sched, |
|
- | 364 | * as in synchronize_sched(), call_rcu_sched(), and friends). Another |
|
- | 365 | * example is when items are added to the list, but never deleted. |
|
- | 366 | */ |
|
- | 367 | #define list_for_each_entry_lockless(pos, head, member) \ |
|
- | 368 | for (pos = list_entry_lockless((head)->next, typeof(*pos), member); \ |
|
- | 369 | &pos->member != (head); \ |
|
- | 370 | pos = list_entry_lockless(pos->member.next, typeof(*pos), member)) |
|
- | 371 | ||
307 | /** |
372 | /** |
308 | * list_for_each_entry_continue_rcu - continue iteration over list of given type |
373 | * list_for_each_entry_continue_rcu - continue iteration over list of given type |
309 | * @pos: the type * to use as a loop cursor. |
374 | * @pos: the type * to use as a loop cursor. |
310 | * @head: the head for your list. |
375 | * @head: the head for your list. |
311 | * @member: the name of the list_head within the struct. |
376 | * @member: the name of the list_head within the struct. |