Skip to content

Commit

Permalink
net: use batched device unregister in veth and macvlan
Browse files Browse the repository at this point in the history
veth devices dont use the batched device unregisters yet.

Since veth are a pair of devices, it makes sense to use a batch of two
unregisters, this roughly divides dismantle time by two.

Fix this by changing dellink() callers to always provide a non NULL
head. (Idea from Michał Mirosław)

This patch also handles macvlan case : We now dismantle all macvlans on
top of a lower dev at once.

Reported-by: Alex Bligh <alex@alex.org.uk>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Michał Mirosław <mirqus@gmail.com>
Cc: Jesse Gross <jesse@nicira.com>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Ben Greear <greearb@candelatech.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Eric Dumazet authored and David S. Miller committed May 9, 2011
1 parent 7ef73bc commit 226bd34
Showing 2 changed files with 8 additions and 2 deletions.
5 changes: 4 additions & 1 deletion drivers/net/macvlan.c
Original file line number Diff line number Diff line change
@@ -785,6 +785,7 @@ static int macvlan_device_event(struct notifier_block *unused,
struct net_device *dev = ptr;
struct macvlan_dev *vlan, *next;
struct macvlan_port *port;
LIST_HEAD(list_kill);

if (!macvlan_port_exists(dev))
return NOTIFY_DONE;
@@ -810,7 +811,9 @@ static int macvlan_device_event(struct notifier_block *unused,
break;

list_for_each_entry_safe(vlan, next, &port->vlans, list)
vlan->dev->rtnl_link_ops->dellink(vlan->dev, NULL);
vlan->dev->rtnl_link_ops->dellink(vlan->dev, &list_kill);
unregister_netdevice_many(&list_kill);
list_del(&list_kill);
break;
case NETDEV_PRE_TYPE_CHANGE:
/* Forbid underlaying device to change its type. */
5 changes: 4 additions & 1 deletion net/core/rtnetlink.c
Original file line number Diff line number Diff line change
@@ -1501,6 +1501,7 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
char ifname[IFNAMSIZ];
struct nlattr *tb[IFLA_MAX+1];
int err;
LIST_HEAD(list_kill);

err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
if (err < 0)
@@ -1524,7 +1525,9 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
if (!ops)
return -EOPNOTSUPP;

ops->dellink(dev, NULL);
ops->dellink(dev, &list_kill);
unregister_netdevice_many(&list_kill);
list_del(&list_kill);
return 0;
}

0 comments on commit 226bd34

Please sign in to comment.