diff options
author | Robert Olsson <Robert.Olsson@data.slu.se> | 2005-08-25 16:01:03 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2005-08-29 19:08:31 -0400 |
commit | e5b4376074e02b783e56a8f7c42d544e18112c4e (patch) | |
tree | 7269e327d5132da92cd5c7238c03266b7c9f391b | |
parent | 3625796806419d97641d90e0f197eab9b952212e (diff) |
[IPV4]: Prepare FIB core for RCU.
* RCU versions of hlist_***_rcu
* fib_alias partial rcu port just whats needed now.
Signed-off-by: Robert Olsson <Robert.Olsson@data.slu.se>
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/list.h | 21 | ||||
-rw-r--r-- | net/ipv4/fib_lookup.h | 1 | ||||
-rw-r--r-- | net/ipv4/fib_semantics.c | 3 |
3 files changed, 24 insertions, 1 deletions
diff --git a/include/linux/list.h b/include/linux/list.h index 0f2435f92db3..9b9b0eec1e8a 100644 --- a/include/linux/list.h +++ b/include/linux/list.h | |||
@@ -634,6 +634,27 @@ static inline void hlist_add_after(struct hlist_node *n, | |||
634 | next->next->pprev = &next->next; | 634 | next->next->pprev = &next->next; |
635 | } | 635 | } |
636 | 636 | ||
637 | static inline void hlist_add_before_rcu(struct hlist_node *n, | ||
638 | struct hlist_node *next) | ||
639 | { | ||
640 | n->pprev = next->pprev; | ||
641 | n->next = next; | ||
642 | smp_wmb(); | ||
643 | next->pprev = &n->next; | ||
644 | *(n->pprev) = n; | ||
645 | } | ||
646 | |||
647 | static inline void hlist_add_after_rcu(struct hlist_node *prev, | ||
648 | struct hlist_node *n) | ||
649 | { | ||
650 | n->next = prev->next; | ||
651 | n->pprev = &prev->next; | ||
652 | smp_wmb(); | ||
653 | prev->next = n; | ||
654 | if (n->next) | ||
655 | n->next->pprev = &n->next; | ||
656 | } | ||
657 | |||
637 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member) | 658 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member) |
638 | 659 | ||
639 | #define hlist_for_each(pos, head) \ | 660 | #define hlist_for_each(pos, head) \ |
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h index b729d97cfa93..ef6609ea0eb7 100644 --- a/net/ipv4/fib_lookup.h +++ b/net/ipv4/fib_lookup.h | |||
@@ -7,6 +7,7 @@ | |||
7 | 7 | ||
8 | struct fib_alias { | 8 | struct fib_alias { |
9 | struct list_head fa_list; | 9 | struct list_head fa_list; |
10 | struct rcu_head rcu; | ||
10 | struct fib_info *fa_info; | 11 | struct fib_info *fa_info; |
11 | u8 fa_tos; | 12 | u8 fa_tos; |
12 | u8 fa_type; | 13 | u8 fa_type; |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 7e4651b3caa8..d41219e8037c 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -854,6 +854,7 @@ failure: | |||
854 | return NULL; | 854 | return NULL; |
855 | } | 855 | } |
856 | 856 | ||
857 | /* Note! fib_semantic_match intentionally uses RCU list functions. */ | ||
857 | int fib_semantic_match(struct list_head *head, const struct flowi *flp, | 858 | int fib_semantic_match(struct list_head *head, const struct flowi *flp, |
858 | struct fib_result *res, __u32 zone, __u32 mask, | 859 | struct fib_result *res, __u32 zone, __u32 mask, |
859 | int prefixlen) | 860 | int prefixlen) |
@@ -861,7 +862,7 @@ int fib_semantic_match(struct list_head *head, const struct flowi *flp, | |||
861 | struct fib_alias *fa; | 862 | struct fib_alias *fa; |
862 | int nh_sel = 0; | 863 | int nh_sel = 0; |
863 | 864 | ||
864 | list_for_each_entry(fa, head, fa_list) { | 865 | list_for_each_entry_rcu(fa, head, fa_list) { |
865 | int err; | 866 | int err; |
866 | 867 | ||
867 | if (fa->fa_tos && | 868 | if (fa->fa_tos && |