diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-05-03 06:50:14 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-05-03 18:53:54 -0400 |
commit | 4f70ecca9c57731b4acbe5043eb22e4416bd2368 (patch) | |
tree | 3b725168959ffd2b65152e27dbe3479f6e110dd3 /include/linux/rculist.h | |
parent | 52a60ed2da716105de5f906a3630c475264b87d5 (diff) |
net: rcu fixes
Add hlist_for_each_entry_rcu_bh() and
hlist_for_each_entry_continue_rcu_bh() macros, and use them in
ipv6_get_ifaddr(), if6_get_first() and if6_get_next() to fix lockdeps
warnings.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Reviewed-by: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/rculist.h')
-rw-r--r-- | include/linux/rculist.h | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/include/linux/rculist.h b/include/linux/rculist.h index 004908b104d5..4ec3b38ce9c5 100644 --- a/include/linux/rculist.h +++ b/include/linux/rculist.h | |||
@@ -429,6 +429,23 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev, | |||
429 | pos = rcu_dereference_raw(pos->next)) | 429 | pos = rcu_dereference_raw(pos->next)) |
430 | 430 | ||
431 | /** | 431 | /** |
432 | * hlist_for_each_entry_rcu_bh - iterate over rcu list of given type | ||
433 | * @tpos: the type * to use as a loop cursor. | ||
434 | * @pos: the &struct hlist_node to use as a loop cursor. | ||
435 | * @head: the head for your list. | ||
436 | * @member: the name of the hlist_node within the struct. | ||
437 | * | ||
438 | * This list-traversal primitive may safely run concurrently with | ||
439 | * the _rcu list-mutation primitives such as hlist_add_head_rcu() | ||
440 | * as long as the traversal is guarded by rcu_read_lock(). | ||
441 | */ | ||
442 | #define hlist_for_each_entry_rcu_bh(tpos, pos, head, member) \ | ||
443 | for (pos = rcu_dereference_bh((head)->first); \ | ||
444 | pos && ({ prefetch(pos->next); 1; }) && \ | ||
445 | ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ | ||
446 | pos = rcu_dereference_bh(pos->next)) | ||
447 | |||
448 | /** | ||
432 | * hlist_for_each_entry_continue_rcu - iterate over a hlist continuing after current point | 449 | * hlist_for_each_entry_continue_rcu - iterate over a hlist continuing after current point |
433 | * @tpos: the type * to use as a loop cursor. | 450 | * @tpos: the type * to use as a loop cursor. |
434 | * @pos: the &struct hlist_node to use as a loop cursor. | 451 | * @pos: the &struct hlist_node to use as a loop cursor. |
@@ -440,6 +457,18 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev, | |||
440 | ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ | 457 | ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ |
441 | pos = rcu_dereference(pos->next)) | 458 | pos = rcu_dereference(pos->next)) |
442 | 459 | ||
460 | /** | ||
461 | * hlist_for_each_entry_continue_rcu_bh - iterate over a hlist continuing after current point | ||
462 | * @tpos: the type * to use as a loop cursor. | ||
463 | * @pos: the &struct hlist_node to use as a loop cursor. | ||
464 | * @member: the name of the hlist_node within the struct. | ||
465 | */ | ||
466 | #define hlist_for_each_entry_continue_rcu_bh(tpos, pos, member) \ | ||
467 | for (pos = rcu_dereference_bh((pos)->next); \ | ||
468 | pos && ({ prefetch(pos->next); 1; }) && \ | ||
469 | ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ | ||
470 | pos = rcu_dereference_bh(pos->next)) | ||
471 | |||
443 | 472 | ||
444 | #endif /* __KERNEL__ */ | 473 | #endif /* __KERNEL__ */ |
445 | #endif | 474 | #endif |