diff options
author | Hannes Frederic Sowa <hannes@stressinduktion.org> | 2014-10-06 13:58:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-10-07 00:02:30 -0400 |
commit | 42b18706469a02c1f84375ac0ee2f30f28d85d4c (patch) | |
tree | b7018c4417ba63dd8470bd8314c37fcea929b116 /net/ipv6 | |
parent | 94b2cfe02bfe3f1918d91bd6f498e308c5605cbc (diff) |
ipv6: make rt_sernum atomic and serial number fields ordinary ints
Cc: YOSHIFUJI Hideaki <hideaki@yoshifuji.org>
Cc: Martin Lau <kafai@fb.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/ip6_fib.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index e8d7465b1597..332f1e0ff8e2 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -74,7 +74,7 @@ static int fib6_walk_continue(struct fib6_walker *w); | |||
74 | * result of redirects, path MTU changes, etc. | 74 | * result of redirects, path MTU changes, etc. |
75 | */ | 75 | */ |
76 | 76 | ||
77 | static __u32 rt_sernum; | 77 | static atomic_t rt_sernum = ATOMIC_INIT(1); |
78 | 78 | ||
79 | static void fib6_gc_timer_cb(unsigned long arg); | 79 | static void fib6_gc_timer_cb(unsigned long arg); |
80 | 80 | ||
@@ -95,12 +95,15 @@ static void fib6_walker_unlink(struct fib6_walker *w) | |||
95 | write_unlock_bh(&fib6_walker_lock); | 95 | write_unlock_bh(&fib6_walker_lock); |
96 | } | 96 | } |
97 | 97 | ||
98 | static u32 fib6_new_sernum(void) | 98 | static int fib6_new_sernum(void) |
99 | { | 99 | { |
100 | u32 n = ++rt_sernum; | 100 | int new, old; |
101 | if ((__s32)n <= 0) | 101 | |
102 | rt_sernum = n = 1; | 102 | do { |
103 | return n; | 103 | old = atomic_read(&rt_sernum); |
104 | new = old < INT_MAX ? old + 1 : 1; | ||
105 | } while (atomic_cmpxchg(&rt_sernum, old, new) != old); | ||
106 | return new; | ||
104 | } | 107 | } |
105 | 108 | ||
106 | /* | 109 | /* |
@@ -421,7 +424,7 @@ static struct fib6_node *fib6_add_1(struct fib6_node *root, | |||
421 | struct rt6key *key; | 424 | struct rt6key *key; |
422 | int bit; | 425 | int bit; |
423 | __be32 dir = 0; | 426 | __be32 dir = 0; |
424 | __u32 sernum = fib6_new_sernum(); | 427 | int sernum = fib6_new_sernum(); |
425 | 428 | ||
426 | RT6_TRACE("fib6_add_1\n"); | 429 | RT6_TRACE("fib6_add_1\n"); |
427 | 430 | ||
@@ -1598,7 +1601,7 @@ static void fib6_prune_clones(struct net *net, struct fib6_node *fn) | |||
1598 | 1601 | ||
1599 | static int fib6_update_sernum(struct rt6_info *rt, void *arg) | 1602 | static int fib6_update_sernum(struct rt6_info *rt, void *arg) |
1600 | { | 1603 | { |
1601 | __u32 sernum = *(__u32 *)arg; | 1604 | int sernum = *(int *)arg; |
1602 | 1605 | ||
1603 | if (rt->rt6i_node && | 1606 | if (rt->rt6i_node && |
1604 | rt->rt6i_node->fn_sernum != sernum) | 1607 | rt->rt6i_node->fn_sernum != sernum) |
@@ -1609,7 +1612,7 @@ static int fib6_update_sernum(struct rt6_info *rt, void *arg) | |||
1609 | 1612 | ||
1610 | static void fib6_flush_trees(struct net *net) | 1613 | static void fib6_flush_trees(struct net *net) |
1611 | { | 1614 | { |
1612 | __u32 new_sernum = fib6_new_sernum(); | 1615 | int new_sernum = fib6_new_sernum(); |
1613 | 1616 | ||
1614 | fib6_clean_all(net, fib6_update_sernum, &new_sernum); | 1617 | fib6_clean_all(net, fib6_update_sernum, &new_sernum); |
1615 | } | 1618 | } |
@@ -1822,7 +1825,7 @@ struct ipv6_route_iter { | |||
1822 | struct fib6_walker w; | 1825 | struct fib6_walker w; |
1823 | loff_t skip; | 1826 | loff_t skip; |
1824 | struct fib6_table *tbl; | 1827 | struct fib6_table *tbl; |
1825 | __u32 sernum; | 1828 | int sernum; |
1826 | }; | 1829 | }; |
1827 | 1830 | ||
1828 | static int ipv6_route_seq_show(struct seq_file *seq, void *v) | 1831 | static int ipv6_route_seq_show(struct seq_file *seq, void *v) |