Skip to content

Commit

Permalink
[NET]: Rework dev_base via list_head (v3)
Browse files Browse the repository at this point in the history
Cleanup of dev_base list use, with the aim to simplify making device
list per-namespace. In almost every occasion, use of dev_base variable
and dev->next pointer could be easily replaced by for_each_netdev
loop. A few most complicated places were converted to using
first_netdev()/next_netdev().

Signed-off-by: Pavel Emelianov <[email protected]>
Acked-by: Kirill Korotaev <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
xemul authored and davem330 committed May 3, 2007
1 parent 03fba04 commit 7562f87
Show file tree
Hide file tree
Showing 31 changed files with 249 additions and 194 deletions.
2 changes: 1 addition & 1 deletion arch/s390/appldata/appldata_net_sum.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ static void appldata_get_net_sum_data(void *data)
tx_dropped = 0;
collisions = 0;
read_lock(&dev_base_lock);
for (dev = dev_base; dev != NULL; dev = dev->next) {
for_each_netdev(dev) {
stats = dev->get_stats(dev);
rx_packets += stats->rx_packets;
tx_packets += stats->tx_packets;
Expand Down
3 changes: 2 additions & 1 deletion arch/sparc64/solaris/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,8 @@ static inline int solaris_i(unsigned int fd, unsigned int cmd, u32 arg)
int i = 0;

read_lock_bh(&dev_base_lock);
for (d = dev_base; d; d = d->next) i++;
for_each_netdev(d)
i++;
read_unlock_bh(&dev_base_lock);

if (put_user (i, (int __user *)A(arg)))
Expand Down
8 changes: 5 additions & 3 deletions drivers/block/aoe/aoecmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,15 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
sl = sl_tail = NULL;

read_lock(&dev_base_lock);
for (ifp = dev_base; ifp; dev_put(ifp), ifp = ifp->next) {
for_each_netdev(ifp) {
dev_hold(ifp);
if (!is_aoe_netif(ifp))
continue;
goto cont;

skb = new_skb(sizeof *h + sizeof *ch);
if (skb == NULL) {
printk(KERN_INFO "aoe: skb alloc failure\n");
continue;
goto cont;
}
skb_put(skb, sizeof *h + sizeof *ch);
skb->dev = ifp;
Expand All @@ -221,6 +221,8 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)

skb->next = sl;
sl = skb;
cont:
dev_put(ifp);
}
read_unlock(&dev_base_lock);

Expand Down
4 changes: 1 addition & 3 deletions drivers/net/wireless/strip.c
Original file line number Diff line number Diff line change
Expand Up @@ -1971,8 +1971,7 @@ static struct net_device *get_strip_dev(struct strip *strip_info)
sizeof(zero_address))) {
struct net_device *dev;
read_lock_bh(&dev_base_lock);
dev = dev_base;
while (dev) {
for_each_netdev(dev) {
if (dev->type == strip_info->dev->type &&
!memcmp(dev->dev_addr,
&strip_info->true_dev_addr,
Expand All @@ -1983,7 +1982,6 @@ static struct net_device *get_strip_dev(struct strip *strip_info)
read_unlock_bh(&dev_base_lock);
return (dev);
}
dev = dev->next;
}
read_unlock_bh(&dev_base_lock);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/parisc/led.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ static __inline__ int led_get_net_activity(void)
* for reading should be OK */
read_lock(&dev_base_lock);
rcu_read_lock();
for (dev = dev_base; dev; dev = dev->next) {
for_each_netdev(dev) {
struct net_device_stats *stats;
struct in_device *in_dev = __in_dev_get_rcu(dev);
if (!in_dev || !in_dev->ifa_list)
Expand Down
2 changes: 1 addition & 1 deletion fs/afs/netdevices.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs,
ASSERT(maxbufs > 0);

rtnl_lock();
for (dev = dev_base; dev; dev = dev->next) {
for_each_netdev(dev) {
if (dev->type == ARPHRD_LOOPBACK && !wantloopback)
continue;
idev = __in_dev_get_rtnl(dev);
Expand Down
26 changes: 24 additions & 2 deletions include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ struct net_device

unsigned long state;

struct net_device *next;
struct list_head dev_list;

/* The device initialization function. Called only once. */
int (*init)(struct net_device *dev);
Expand Down Expand Up @@ -575,9 +575,31 @@ struct packet_type {
#include <linux/notifier.h>

extern struct net_device loopback_dev; /* The loopback */
extern struct net_device *dev_base; /* All devices */
extern struct list_head dev_base_head; /* All devices */
extern rwlock_t dev_base_lock; /* Device list lock */

#define for_each_netdev(d) \
list_for_each_entry(d, &dev_base_head, dev_list)
#define for_each_netdev_safe(d, n) \
list_for_each_entry_safe(d, n, &dev_base_head, dev_list)
#define for_each_netdev_continue(d) \
list_for_each_entry_continue(d, &dev_base_head, dev_list)
#define net_device_entry(lh) list_entry(lh, struct net_device, dev_list)

static inline struct net_device *next_net_device(struct net_device *dev)
{
struct list_head *lh;

lh = dev->dev_list.next;
return lh == &dev_base_head ? NULL : net_device_entry(lh);
}

static inline struct net_device *first_net_device(void)
{
return list_empty(&dev_base_head) ? NULL :
net_device_entry(dev_base_head.next);
}

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(unsigned short type, char *hwaddr);
Expand Down
3 changes: 1 addition & 2 deletions net/8021q/vlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,7 @@ static void __exit vlan_cleanup_devices(void)
struct net_device *dev, *nxt;

rtnl_lock();
for (dev = dev_base; dev; dev = nxt) {
nxt = dev->next;
for_each_netdev_safe(dev, nxt) {
if (dev->priv_flags & IFF_802_1Q_VLAN) {
unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
VLAN_DEV_INFO(dev)->vlan_id);
Expand Down
36 changes: 24 additions & 12 deletions net/8021q/vlanproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,9 @@ int vlan_proc_rem_dev(struct net_device *vlandev)
* The following few functions build the content of /proc/net/vlan/config
*/

/* starting at dev, find a VLAN device */
static struct net_device *vlan_skip(struct net_device *dev)
static inline int is_vlan_dev(struct net_device *dev)
{
while (dev && !(dev->priv_flags & IFF_802_1Q_VLAN))
dev = dev->next;

return dev;
return dev->priv_flags & IFF_802_1Q_VLAN;
}

/* start read of /proc/net/vlan/config */
Expand All @@ -257,19 +253,35 @@ static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
if (*pos == 0)
return SEQ_START_TOKEN;

for (dev = vlan_skip(dev_base); dev && i < *pos;
dev = vlan_skip(dev->next), ++i);
for_each_netdev(dev) {
if (!is_vlan_dev(dev))
continue;

if (i++ == *pos)
return dev;
}

return (i == *pos) ? dev : NULL;
return NULL;
}

static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct net_device *dev;

++*pos;

return vlan_skip((v == SEQ_START_TOKEN)
? dev_base
: ((struct net_device *)v)->next);
dev = (struct net_device *)v;
if (v == SEQ_START_TOKEN)
dev = net_device_entry(&dev_base_head);

for_each_netdev_continue(dev) {
if (!is_vlan_dev(dev))
continue;

return dev;
}

return NULL;
}

static void vlan_seq_stop(struct seq_file *seq, void *v)
Expand Down
4 changes: 1 addition & 3 deletions net/bridge/br_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,11 +475,9 @@ void __exit br_cleanup_bridges(void)
struct net_device *dev, *nxt;

rtnl_lock();
for (dev = dev_base; dev; dev = nxt) {
nxt = dev->next;
for_each_netdev_safe(dev, nxt)
if (dev->priv_flags & IFF_EBRIDGE)
del_br(dev->priv);
}
rtnl_unlock();

}
4 changes: 3 additions & 1 deletion net/bridge/br_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ static int get_bridge_ifindices(int *indices, int num)
struct net_device *dev;
int i = 0;

for (dev = dev_base; dev && i < num; dev = dev->next) {
for_each_netdev(dev) {
if (i >= num)
break;
if (dev->priv_flags & IFF_EBRIDGE)
indices[i++] = dev->ifindex;
}
Expand Down
3 changes: 2 additions & 1 deletion net/bridge/br_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
struct net_device *dev;
int idx;

for (dev = dev_base, idx = 0; dev; dev = dev->next) {
idx = 0;
for_each_netdev(dev) {
/* not a bridge port */
if (dev->br_port == NULL || idx < cb->args[0])
goto skip;
Expand Down
Loading

0 comments on commit 7562f87

Please sign in to comment.