From e05f62d03c3863c74e4e9162a13d77697b18a5e3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 26 Jan 2011 18:08:02 +0000 Subject: [PATCH] --- yaml --- r: 236713 b: refs/heads/master c: ccf434380d1a67df2dcb9113206b77d0cb0a1cef h: refs/heads/master i: 236711: e36105c28091d9acb694fe6693099339802bd22c v: v3 --- [refs] | 2 +- trunk/include/linux/netdevice.h | 9 ++++++++- trunk/net/core/dev.c | 11 +++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index d49905bb8903..ae88aca23901 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 065825402c058f4a123ddc53dbbe864cc5caaf64 +refs/heads/master: ccf434380d1a67df2dcb9113206b77d0cb0a1cef diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 8858422c5c5d..c7d707452228 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -1447,7 +1447,7 @@ static inline struct net_device *next_net_device_rcu(struct net_device *dev) struct net *net; net = dev_net(dev); - lh = rcu_dereference(dev->dev_list.next); + lh = rcu_dereference(list_next_rcu(&dev->dev_list)); return lh == &net->dev_base_head ? NULL : net_device_entry(lh); } @@ -1457,6 +1457,13 @@ static inline struct net_device *first_net_device(struct net *net) net_device_entry(net->dev_base_head.next); } +static inline struct net_device *first_net_device_rcu(struct net *net) +{ + struct list_head *lh = rcu_dereference(list_next_rcu(&net->dev_base_head)); + + return lh == &net->dev_base_head ? NULL : net_device_entry(lh); +} + extern int netdev_boot_setup_check(struct net_device *dev); extern unsigned long netdev_boot_base(const char *prefix, int unit); extern struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type, diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 1b4c07fe295f..ddd5df2b61d4 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -4051,12 +4051,15 @@ void *dev_seq_start(struct seq_file *seq, loff_t *pos) void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) { - struct net_device *dev = (v == SEQ_START_TOKEN) ? - first_net_device(seq_file_net(seq)) : - next_net_device((struct net_device *)v); + struct net_device *dev = v; + + if (v == SEQ_START_TOKEN) + dev = first_net_device_rcu(seq_file_net(seq)); + else + dev = next_net_device_rcu(dev); ++*pos; - return rcu_dereference(dev); + return dev; } void dev_seq_stop(struct seq_file *seq, void *v)