From: Eric Dumazet <dada1@cosmosbay.com>
To: Herbert Xu <herbert@gondor.apana.org.au>,
"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: davem@davemloft.net, dipankar@in.ibm.com, netdev@vger.kernel.org
Subject: [NET] ROUTE: fix rcu_dereference() uses in /proc/net/rt_cache
Date: Wed, 09 Jan 2008 08:38:56 +0100 [thread overview]
Message-ID: <47847A10.1020508@cosmosbay.com> (raw)
In-Reply-To: <E1JCU1E-00076z-00@gondolin.me.apana.org.au>
[-- Attachment #1: Type: text/plain, Size: 2290 bytes --]
Herbert Xu a écrit :
> Eric Dumazet <dada1@cosmosbay.com> wrote:
>> Very good question, but honestly I really dont see why it was there at the
>> first place :
>
> It was there because someone went through this file and robotically
> replaced all conditional read barriers with rcu_dereference, even when
> it made zero sense.
>
> Basically you can add a conditional barrier either at the point where
> the pointer gets read, or where it gets derferenced. Previously we
> did the latter (except that the show function didn't have a barrier
> at all which is technically a bug though harmless in pratice). This
> patch moves it to the spot where it gets read which is also OK.
>
>> static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *r)
>> {
>> - struct rt_cache_iter_state *st = rcu_dereference(seq->private);
>> + struct rt_cache_iter_state *st = seq->private;
>>
>> - r = r->u.dst.rt_next;
>> + r = rcu_dereference(r->u.dst.rt_next);
>> while (!r) {
>> rcu_read_unlock_bh();
>> if (--st->bucket < 0)
>> break;
>> rcu_read_lock_bh();
>> - r = rt_hash_table[st->bucket].chain;
>> + r = rcu_dereference(rt_hash_table[st->bucket].chain);
>> }
>> return r;
>
> Slight optimisation: please move both barriers onto the return statement,
> i.e.,
>
> return rcu_dereference(r);
I am not sure this is valid, since it will do this :
r = rt_hash_table[st->bucket].chain;
if (r)
return rcu_dereference(r);
So compiler might be dumb enough do dereference
&rt_hash_table[st->bucket].chain two times.
It seems Dipankar is busy at this moment, so I will post again the patch and
ask a comment from Paul :)
Thank you
[NET] ROUTE: fix rcu_dereference() uses in /proc/net/rt_cache
In rt_cache_get_next(), no need to guard seq->private by a rcu_dereference()
since seq is private to the thread running this function. Reading seq.private
once (as guaranted bu rcu_dereference()) or several time if compiler really is
dumb enough wont change the result.
But we miss real spots where rcu_dereference() are needed, both in
rt_cache_get_first() and rt_cache_get_next()
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
[-- Attachment #2: route_rcu.patch --]
[-- Type: text/plain, Size: 1011 bytes --]
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index d337706..3b7562f 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -278,7 +278,7 @@ static struct rtable *rt_cache_get_first(struct seq_file *seq)
for (st->bucket = rt_hash_mask; st->bucket >= 0; --st->bucket) {
rcu_read_lock_bh();
- r = rt_hash_table[st->bucket].chain;
+ r = rcu_dereference(rt_hash_table[st->bucket].chain);
if (r)
break;
rcu_read_unlock_bh();
@@ -288,15 +288,15 @@ static struct rtable *rt_cache_get_first(struct seq_file *seq)
static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *r)
{
- struct rt_cache_iter_state *st = rcu_dereference(seq->private);
+ struct rt_cache_iter_state *st = seq->private;
- r = r->u.dst.rt_next;
+ r = rcu_dereference(r->u.dst.rt_next);
while (!r) {
rcu_read_unlock_bh();
if (--st->bucket < 0)
break;
rcu_read_lock_bh();
- r = rt_hash_table[st->bucket].chain;
+ r = rcu_dereference(rt_hash_table[st->bucket].chain);
}
return r;
}
next prev parent reply other threads:[~2008-01-09 7:40 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-07 18:30 [IPV4] ROUTE: ip_rt_dump() is unecessary slow Eric Dumazet
2008-01-08 5:52 ` David Miller
2008-01-08 6:11 ` Eric Dumazet
2008-01-08 6:15 ` David Miller
2008-01-08 6:37 ` Eric Dumazet
2008-01-09 6:02 ` Herbert Xu
2008-01-09 7:38 ` Eric Dumazet [this message]
2008-01-09 9:46 ` [NET] ROUTE: fix rcu_dereference() uses in /proc/net/rt_cache Herbert Xu
2008-01-09 10:37 ` Eric Dumazet
2008-01-09 14:22 ` Paul E. McKenney
2008-01-09 14:31 ` David Miller
2008-01-09 14:43 ` Paul E. McKenney
2008-01-09 17:36 ` Eric Dumazet
2008-01-10 11:56 ` David Miller
2008-01-10 14:06 ` [DECNET] ROUTE: fix rcu_dereference() uses in /proc/net/decnet_cache Eric Dumazet
2008-01-11 6:35 ` David Miller
2008-01-10 23:10 ` [NET] ROUTE: fix rcu_dereference() uses in /proc/net/rt_cache Jarek Poplawski
2008-01-10 23:51 ` Paul E. McKenney
2008-01-11 14:13 ` Jarek Poplawski
2008-01-11 0:00 ` Herbert Xu
2008-01-11 8:30 ` Jarek Poplawski
2008-01-11 9:11 ` Jarek Poplawski
2008-01-11 9:23 ` Jarek Poplawski
2008-01-11 10:38 ` Herbert Xu
2008-01-11 11:30 ` Jarek Poplawski
2008-01-11 10:37 ` Herbert Xu
2008-01-11 12:31 ` Jarek Poplawski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=47847A10.1020508@cosmosbay.com \
--to=dada1@cosmosbay.com \
--cc=davem@davemloft.net \
--cc=dipankar@in.ibm.com \
--cc=herbert@gondor.apana.org.au \
--cc=netdev@vger.kernel.org \
--cc=paulmck@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.