|
@@ -1307,7 +1307,7 @@ static int __dev_close_many(struct list_head *head)
|
|
|
ASSERT_RTNL();
|
|
|
might_sleep();
|
|
|
|
|
|
- list_for_each_entry(dev, head, unreg_list) {
|
|
|
+ list_for_each_entry(dev, head, close_list) {
|
|
|
call_netdevice_notifiers(NETDEV_GOING_DOWN, dev);
|
|
|
|
|
|
clear_bit(__LINK_STATE_START, &dev->state);
|
|
@@ -1323,7 +1323,7 @@ static int __dev_close_many(struct list_head *head)
|
|
|
|
|
|
dev_deactivate_many(head);
|
|
|
|
|
|
- list_for_each_entry(dev, head, unreg_list) {
|
|
|
+ list_for_each_entry(dev, head, close_list) {
|
|
|
const struct net_device_ops *ops = dev->netdev_ops;
|
|
|
|
|
|
/*
|
|
@@ -1351,7 +1351,7 @@ static int __dev_close(struct net_device *dev)
|
|
|
/* Temporarily disable netpoll until the interface is down */
|
|
|
netpoll_rx_disable(dev);
|
|
|
|
|
|
- list_add(&dev->unreg_list, &single);
|
|
|
+ list_add(&dev->close_list, &single);
|
|
|
retval = __dev_close_many(&single);
|
|
|
list_del(&single);
|
|
|
|
|
@@ -1362,21 +1362,20 @@ static int __dev_close(struct net_device *dev)
|
|
|
static int dev_close_many(struct list_head *head)
|
|
|
{
|
|
|
struct net_device *dev, *tmp;
|
|
|
- LIST_HEAD(tmp_list);
|
|
|
|
|
|
- list_for_each_entry_safe(dev, tmp, head, unreg_list)
|
|
|
+ /* Remove the devices that don't need to be closed */
|
|
|
+ list_for_each_entry_safe(dev, tmp, head, close_list)
|
|
|
if (!(dev->flags & IFF_UP))
|
|
|
- list_move(&dev->unreg_list, &tmp_list);
|
|
|
+ list_del_init(&dev->close_list);
|
|
|
|
|
|
__dev_close_many(head);
|
|
|
|
|
|
- list_for_each_entry(dev, head, unreg_list) {
|
|
|
+ list_for_each_entry_safe(dev, tmp, head, close_list) {
|
|
|
rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING);
|
|
|
call_netdevice_notifiers(NETDEV_DOWN, dev);
|
|
|
+ list_del_init(&dev->close_list);
|
|
|
}
|
|
|
|
|
|
- /* rollback_registered_many needs the complete original list */
|
|
|
- list_splice(&tmp_list, head);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1397,7 +1396,7 @@ int dev_close(struct net_device *dev)
|
|
|
/* Block netpoll rx while the interface is going down */
|
|
|
netpoll_rx_disable(dev);
|
|
|
|
|
|
- list_add(&dev->unreg_list, &single);
|
|
|
+ list_add(&dev->close_list, &single);
|
|
|
dev_close_many(&single);
|
|
|
list_del(&single);
|
|
|
|
|
@@ -5439,6 +5438,7 @@ static void net_set_todo(struct net_device *dev)
|
|
|
static void rollback_registered_many(struct list_head *head)
|
|
|
{
|
|
|
struct net_device *dev, *tmp;
|
|
|
+ LIST_HEAD(close_head);
|
|
|
|
|
|
BUG_ON(dev_boot_phase);
|
|
|
ASSERT_RTNL();
|
|
@@ -5461,7 +5461,9 @@ static void rollback_registered_many(struct list_head *head)
|
|
|
}
|
|
|
|
|
|
/* If device is running, close it first. */
|
|
|
- dev_close_many(head);
|
|
|
+ list_for_each_entry(dev, head, unreg_list)
|
|
|
+ list_add_tail(&dev->close_list, &close_head);
|
|
|
+ dev_close_many(&close_head);
|
|
|
|
|
|
list_for_each_entry(dev, head, unreg_list) {
|
|
|
/* And unlink it from device chain. */
|
|
@@ -6257,6 +6259,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
|
|
|
|
|
|
INIT_LIST_HEAD(&dev->napi_list);
|
|
|
INIT_LIST_HEAD(&dev->unreg_list);
|
|
|
+ INIT_LIST_HEAD(&dev->close_list);
|
|
|
INIT_LIST_HEAD(&dev->link_watch_list);
|
|
|
INIT_LIST_HEAD(&dev->adj_list.upper);
|
|
|
INIT_LIST_HEAD(&dev->adj_list.lower);
|