diff options
Diffstat (limited to 'include/linux/list.h')
| -rw-r--r-- | include/linux/list.h | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/include/linux/list.h b/include/linux/list.h index aab2db21b013..e6ec59682274 100644 --- a/include/linux/list.h +++ b/include/linux/list.h | |||
| @@ -419,6 +419,20 @@ static inline void list_splice_init(struct list_head *list, | |||
| 419 | pos = n, n = list_entry(n->member.next, typeof(*n), member)) | 419 | pos = n, n = list_entry(n->member.next, typeof(*n), member)) |
| 420 | 420 | ||
| 421 | /** | 421 | /** |
| 422 | * list_for_each_entry_safe_continue - iterate over list of given type | ||
| 423 | * continuing after existing point safe against removal of list entry | ||
| 424 | * @pos: the type * to use as a loop counter. | ||
| 425 | * @n: another type * to use as temporary storage | ||
| 426 | * @head: the head for your list. | ||
| 427 | * @member: the name of the list_struct within the struct. | ||
| 428 | */ | ||
| 429 | #define list_for_each_entry_safe_continue(pos, n, head, member) \ | ||
| 430 | for (pos = list_entry(pos->member.next, typeof(*pos), member), \ | ||
| 431 | n = list_entry(pos->member.next, typeof(*pos), member); \ | ||
| 432 | &pos->member != (head); \ | ||
| 433 | pos = n, n = list_entry(n->member.next, typeof(*n), member)) | ||
| 434 | |||
| 435 | /** | ||
| 422 | * list_for_each_rcu - iterate over an rcu-protected list | 436 | * list_for_each_rcu - iterate over an rcu-protected list |
| 423 | * @pos: the &struct list_head to use as a loop counter. | 437 | * @pos: the &struct list_head to use as a loop counter. |
| 424 | * @head: the head for your list. | 438 | * @head: the head for your list. |
| @@ -620,6 +634,57 @@ static inline void hlist_add_after(struct hlist_node *n, | |||
| 620 | next->next->pprev = &next->next; | 634 | next->next->pprev = &next->next; |
| 621 | } | 635 | } |
| 622 | 636 | ||
| 637 | /** | ||
| 638 | * hlist_add_before_rcu - adds the specified element to the specified hlist | ||
| 639 | * before the specified node while permitting racing traversals. | ||
| 640 | * @n: the new element to add to the hash list. | ||
| 641 | * @next: the existing element to add the new element before. | ||
| 642 | * | ||
| 643 | * The caller must take whatever precautions are necessary | ||
| 644 | * (such as holding appropriate locks) to avoid racing | ||
| 645 | * with another list-mutation primitive, such as hlist_add_head_rcu() | ||
| 646 | * or hlist_del_rcu(), running on this same list. | ||
| 647 | * However, it is perfectly legal to run concurrently with | ||
| 648 | * the _rcu list-traversal primitives, such as | ||
| 649 | * hlist_for_each_rcu(), used to prevent memory-consistency | ||
| 650 | * problems on Alpha CPUs. | ||
| 651 | */ | ||
| 652 | static inline void hlist_add_before_rcu(struct hlist_node *n, | ||
| 653 | struct hlist_node *next) | ||
| 654 | { | ||
| 655 | n->pprev = next->pprev; | ||
| 656 | n->next = next; | ||
| 657 | smp_wmb(); | ||
| 658 | next->pprev = &n->next; | ||
| 659 | *(n->pprev) = n; | ||
| 660 | } | ||
| 661 | |||
| 662 | /** | ||
| 663 | * hlist_add_after_rcu - adds the specified element to the specified hlist | ||
| 664 | * after the specified node while permitting racing traversals. | ||
| 665 | * @prev: the existing element to add the new element after. | ||
| 666 | * @n: the new element to add to the hash list. | ||
| 667 | * | ||
| 668 | * The caller must take whatever precautions are necessary | ||
| 669 | * (such as holding appropriate locks) to avoid racing | ||
| 670 | * with another list-mutation primitive, such as hlist_add_head_rcu() | ||
| 671 | * or hlist_del_rcu(), running on this same list. | ||
| 672 | * However, it is perfectly legal to run concurrently with | ||
| 673 | * the _rcu list-traversal primitives, such as | ||
| 674 | * hlist_for_each_rcu(), used to prevent memory-consistency | ||
| 675 | * problems on Alpha CPUs. | ||
| 676 | */ | ||
| 677 | static inline void hlist_add_after_rcu(struct hlist_node *prev, | ||
| 678 | struct hlist_node *n) | ||
| 679 | { | ||
| 680 | n->next = prev->next; | ||
| 681 | n->pprev = &prev->next; | ||
| 682 | smp_wmb(); | ||
| 683 | prev->next = n; | ||
| 684 | if (n->next) | ||
| 685 | n->next->pprev = &n->next; | ||
| 686 | } | ||
| 687 | |||
| 623 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member) | 688 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member) |
| 624 | 689 | ||
| 625 | #define hlist_for_each(pos, head) \ | 690 | #define hlist_for_each(pos, head) \ |
