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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).