aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2012-06-20 00:02:10 -0400
committerDavid S. Miller <davem@davemloft.net>2012-06-20 17:38:55 -0400
commitda55737467c1c3bc02271039c088171d82e0796f (patch)
tree13598d84d783a3ca1b7789f17eda28f3554ef080 /net
parent6dab015cf8c9d2fabb13d0332998bc440e9c6555 (diff)
inetpeer: inetpeer_invalidate_tree() cleanup
No need to use cmpxchg() in inetpeer_invalidate_tree() since we hold base lock. Also use correct rcu annotations to remove sparse errors (CONFIG_SPARSE_RCU_POINTER=y) net/ipv4/inetpeer.c:144:19: error: incompatible types in comparison expression (different address spaces) net/ipv4/inetpeer.c:149:20: error: incompatible types in comparison expression (different address spaces) net/ipv4/inetpeer.c:595:10: error: incompatible types in comparison expression (different address spaces) Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Steffen Klassert <steffen.klassert@secunet.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/inetpeer.c34
1 files changed, 15 insertions, 19 deletions
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index cac02ad1425d..da90a8cab614 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -126,7 +126,7 @@ int inet_peer_maxttl __read_mostly = 10 * 60 * HZ; /* usual time to live: 10 min
126 126
127static void inetpeer_gc_worker(struct work_struct *work) 127static void inetpeer_gc_worker(struct work_struct *work)
128{ 128{
129 struct inet_peer *p, *n; 129 struct inet_peer *p, *n, *c;
130 LIST_HEAD(list); 130 LIST_HEAD(list);
131 131
132 spin_lock_bh(&gc_lock); 132 spin_lock_bh(&gc_lock);
@@ -138,17 +138,19 @@ static void inetpeer_gc_worker(struct work_struct *work)
138 138
139 list_for_each_entry_safe(p, n, &list, gc_list) { 139 list_for_each_entry_safe(p, n, &list, gc_list) {
140 140
141 if(need_resched()) 141 if (need_resched())
142 cond_resched(); 142 cond_resched();
143 143
144 if (p->avl_left != peer_avl_empty) { 144 c = rcu_dereference_protected(p->avl_left, 1);
145 list_add_tail(&p->avl_left->gc_list, &list); 145 if (c != peer_avl_empty) {
146 p->avl_left = peer_avl_empty; 146 list_add_tail(&c->gc_list, &list);
147 p->avl_left = peer_avl_empty_rcu;
147 } 148 }
148 149
149 if (p->avl_right != peer_avl_empty) { 150 c = rcu_dereference_protected(p->avl_right, 1);
150 list_add_tail(&p->avl_right->gc_list, &list); 151 if (c != peer_avl_empty) {
151 p->avl_right = peer_avl_empty; 152 list_add_tail(&c->gc_list, &list);
153 p->avl_right = peer_avl_empty_rcu;
152 } 154 }
153 155
154 n = list_entry(p->gc_list.next, struct inet_peer, gc_list); 156 n = list_entry(p->gc_list.next, struct inet_peer, gc_list);
@@ -587,23 +589,17 @@ static void inetpeer_inval_rcu(struct rcu_head *head)
587 589
588void inetpeer_invalidate_tree(struct inet_peer_base *base) 590void inetpeer_invalidate_tree(struct inet_peer_base *base)
589{ 591{
590 struct inet_peer *old, *new, *prev; 592 struct inet_peer *root;
591 593
592 write_seqlock_bh(&base->lock); 594 write_seqlock_bh(&base->lock);
593 595
594 old = base->root; 596 root = rcu_deref_locked(base->root, base);
595 if (old == peer_avl_empty_rcu) 597 if (root != peer_avl_empty) {
596 goto out; 598 base->root = peer_avl_empty_rcu;
597
598 new = peer_avl_empty_rcu;
599
600 prev = cmpxchg(&base->root, old, new);
601 if (prev == old) {
602 base->total = 0; 599 base->total = 0;
603 call_rcu(&prev->gc_rcu, inetpeer_inval_rcu); 600 call_rcu(&root->gc_rcu, inetpeer_inval_rcu);
604 } 601 }
605 602
606out:
607 write_sequnlock_bh(&base->lock); 603 write_sequnlock_bh(&base->lock);
608} 604}
609EXPORT_SYMBOL(inetpeer_invalidate_tree); 605EXPORT_SYMBOL(inetpeer_invalidate_tree);