aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Olsson <Robert.Olsson@data.slu.se>2005-08-25 16:01:03 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-08-29 19:08:31 -0400
commite5b4376074e02b783e56a8f7c42d544e18112c4e (patch)
tree7269e327d5132da92cd5c7238c03266b7c9f391b
parent3625796806419d97641d90e0f197eab9b952212e (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.h21
-rw-r--r--net/ipv4/fib_lookup.h1
-rw-r--r--net/ipv4/fib_semantics.c3
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
637static 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
647static 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
8struct fib_alias { 8struct 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. */
857int fib_semantic_match(struct list_head *head, const struct flowi *flp, 858int 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 &&