From: Eric Dumazet <eric.dumazet@gmail.com>
To: Ben Greear <greearb@candelatech.com>
Cc: NetDev <netdev@vger.kernel.org>
Subject: Re: /proc/net/dev is funky in 3.3.0
Date: Tue, 03 Apr 2012 09:06:29 +0200 [thread overview]
Message-ID: <1333436789.18626.43.camel@edumazet-glaptop> (raw)
In-Reply-To: <1333434995.18626.39.camel@edumazet-glaptop>
On Tue, 2012-04-03 at 08:36 +0200, Eric Dumazet wrote:
> Hmm, I think I understand, commit f04565ddf52 added a regression here, I
> will send a fix.
>
If you want to try following patch, please do so, I cant try it right
now...
I'll provide a proper changelog/attributions in a couple of hours, and
make tests myself of course.
Thanks
net/core/dev.c | 46 ++++++++++++----------------------------------
1 file changed, 12 insertions(+), 34 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 6c7dc9d..f7e7de3 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4028,54 +4028,45 @@ static int dev_ifconf(struct net *net, char __user *arg)
#ifdef CONFIG_PROC_FS
-#define BUCKET_SPACE (32 - NETDEV_HASHBITS)
+#define BUCKET_SPACE (32 - NETDEV_HASHBITS - 1)
struct dev_iter_state {
struct seq_net_private p;
- unsigned int pos; /* bucket << BUCKET_SPACE + offset */
};
#define get_bucket(x) ((x) >> BUCKET_SPACE)
#define get_offset(x) ((x) & ((1 << BUCKET_SPACE) - 1))
#define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o))
-static inline struct net_device *dev_from_same_bucket(struct seq_file *seq)
+static inline struct net_device *dev_from_same_bucket(struct seq_file *seq, loff_t *pos)
{
- struct dev_iter_state *state = seq->private;
struct net *net = seq_file_net(seq);
struct net_device *dev;
struct hlist_node *p;
struct hlist_head *h;
- unsigned int count, bucket, offset;
+ unsigned int count = 0, offset = get_offset(*pos);
- bucket = get_bucket(state->pos);
- offset = get_offset(state->pos);
- h = &net->dev_name_head[bucket];
- count = 0;
+ h = &net->dev_name_head[get_bucket(*pos)];
hlist_for_each_entry_rcu(dev, p, h, name_hlist) {
- if (count++ == offset) {
- state->pos = set_bucket_offset(bucket, count);
+ if (++count == offset)
return dev;
- }
}
return NULL;
}
-static inline struct net_device *dev_from_new_bucket(struct seq_file *seq)
+static inline struct net_device *dev_from_bucket(struct seq_file *seq, loff_t *pos)
{
- struct dev_iter_state *state = seq->private;
struct net_device *dev;
unsigned int bucket;
- bucket = get_bucket(state->pos);
do {
- dev = dev_from_same_bucket(seq);
+ dev = dev_from_same_bucket(seq, pos);
if (dev)
return dev;
- bucket++;
- state->pos = set_bucket_offset(bucket, 0);
+ bucket = get_bucket(*pos);
+ *pos = set_bucket_offset(bucket + 1, 1);
} while (bucket < NETDEV_HASHENTRIES);
return NULL;
@@ -4088,33 +4079,20 @@ static inline struct net_device *dev_from_new_bucket(struct seq_file *seq)
void *dev_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(RCU)
{
- struct dev_iter_state *state = seq->private;
-
rcu_read_lock();
if (!*pos)
return SEQ_START_TOKEN;
- /* check for end of the hash */
- if (state->pos == 0 && *pos > 1)
+ if (get_bucket(*pos) >= NETDEV_HASHENTRIES)
return NULL;
- return dev_from_new_bucket(seq);
+ return dev_from_bucket(seq, pos);
}
void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
- struct net_device *dev;
-
++*pos;
-
- if (v == SEQ_START_TOKEN)
- return dev_from_new_bucket(seq);
-
- dev = dev_from_same_bucket(seq);
- if (dev)
- return dev;
-
- return dev_from_new_bucket(seq);
+ return dev_from_bucket(seq, pos);
}
void dev_seq_stop(struct seq_file *seq, void *v)
next prev parent reply other threads:[~2012-04-03 7:06 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-04-03 4:29 /proc/net/dev is funky in 3.3.0 Ben Greear
2012-04-03 5:43 ` Eric Dumazet
2012-04-03 5:53 ` Ben Greear
2012-04-03 6:36 ` Eric Dumazet
2012-04-03 7:06 ` Eric Dumazet [this message]
2012-04-03 7:17 ` Mihai Maruseac
2012-04-03 8:33 ` [PATCH net: fix /proc/net/dev regression Eric Dumazet
2012-04-03 15:36 ` Ben Greear
2012-04-03 15:59 ` Eric Dumazet
2012-04-03 21:25 ` David Miller
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=1333436789.18626.43.camel@edumazet-glaptop \
--to=eric.dumazet@gmail.com \
--cc=greearb@candelatech.com \
--cc=netdev@vger.kernel.org \
/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