Message ID | 1504299812.15310.26.camel@edumazet-glaptop3.roam.corp.google.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
Series | [net-next] inetpeer: fix RCU lookup() | expand |
From: Eric Dumazet <eric.dumazet@gmail.com> Date: Fri, 01 Sep 2017 14:03:32 -0700 > From: Eric Dumazet <edumazet@google.com> > > Excess of seafood or something happened while I cooked the commit > adding RB tree to inetpeer. > > Of course, RCU rules need to be respected or bad things can happen. > > In this particular loop, we need to read *pp once per iteration, not > twice. > > Fixes: b145425f269a ("inetpeer: remove AVL implementation in favor of RB tree") > Reported-by: John Sperbeck <jsperbeck@google.com> > Signed-off-by: Eric Dumazet <edumazet@google.com> Cheers for excess seafood :-) Applied.
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 337ad41bb80a5fcd3db7ac674292c5b5d462982e..e7eb590c86ce2b33654c17c61619de74ff07bfd1 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -102,15 +102,18 @@ static struct inet_peer *lookup(const struct inetpeer_addr *daddr, struct rb_node **parent_p, struct rb_node ***pp_p) { - struct rb_node **pp, *parent; + struct rb_node **pp, *parent, *next; struct inet_peer *p; pp = &base->rb_root.rb_node; parent = NULL; - while (*pp) { + while (1) { int cmp; - parent = rcu_dereference_raw(*pp); + next = rcu_dereference_raw(*pp); + if (!next) + break; + parent = next; p = rb_entry(parent, struct inet_peer, rb_node); cmp = inetpeer_addr_cmp(daddr, &p->daddr); if (cmp == 0) {