@@ -1222,52 +1222,90 @@ int dev_open(struct net_device *dev)
1222
1222
}
1223
1223
EXPORT_SYMBOL (dev_open );
1224
1224
1225
- static int __dev_close (struct net_device * dev )
1225
+ static int __dev_close_many (struct list_head * head )
1226
1226
{
1227
- const struct net_device_ops * ops = dev -> netdev_ops ;
1227
+ struct net_device * dev ;
1228
1228
1229
1229
ASSERT_RTNL ();
1230
1230
might_sleep ();
1231
1231
1232
- /*
1233
- * Tell people we are going down, so that they can
1234
- * prepare to death, when device is still operating.
1235
- */
1236
- call_netdevice_notifiers (NETDEV_GOING_DOWN , dev );
1232
+ list_for_each_entry (dev , head , unreg_list ) {
1233
+ /*
1234
+ * Tell people we are going down, so that they can
1235
+ * prepare to death, when device is still operating.
1236
+ */
1237
+ call_netdevice_notifiers (NETDEV_GOING_DOWN , dev );
1237
1238
1238
- clear_bit (__LINK_STATE_START , & dev -> state );
1239
+ clear_bit (__LINK_STATE_START , & dev -> state );
1239
1240
1240
- /* Synchronize to scheduled poll. We cannot touch poll list,
1241
- * it can be even on different cpu. So just clear netif_running().
1242
- *
1243
- * dev->stop() will invoke napi_disable() on all of it's
1244
- * napi_struct instances on this device.
1245
- */
1246
- smp_mb__after_clear_bit (); /* Commit netif_running(). */
1241
+ /* Synchronize to scheduled poll. We cannot touch poll list, it
1242
+ * can be even on different cpu. So just clear netif_running().
1243
+ *
1244
+ * dev->stop() will invoke napi_disable() on all of it's
1245
+ * napi_struct instances on this device.
1246
+ */
1247
+ smp_mb__after_clear_bit (); /* Commit netif_running(). */
1248
+ }
1247
1249
1248
- dev_deactivate ( dev );
1250
+ dev_deactivate_many ( head );
1249
1251
1250
- /*
1251
- * Call the device specific close. This cannot fail.
1252
- * Only if device is UP
1253
- *
1254
- * We allow it to be called even after a DETACH hot-plug
1255
- * event.
1256
- */
1257
- if (ops -> ndo_stop )
1258
- ops -> ndo_stop (dev );
1252
+ list_for_each_entry (dev , head , unreg_list ) {
1253
+ const struct net_device_ops * ops = dev -> netdev_ops ;
1259
1254
1260
- /*
1261
- * Device is now down.
1262
- */
1255
+ /*
1256
+ * Call the device specific close. This cannot fail.
1257
+ * Only if device is UP
1258
+ *
1259
+ * We allow it to be called even after a DETACH hot-plug
1260
+ * event.
1261
+ */
1262
+ if (ops -> ndo_stop )
1263
+ ops -> ndo_stop (dev );
1264
+
1265
+ /*
1266
+ * Device is now down.
1267
+ */
1268
+
1269
+ dev -> flags &= ~IFF_UP ;
1270
+
1271
+ /*
1272
+ * Shutdown NET_DMA
1273
+ */
1274
+ net_dmaengine_put ();
1275
+ }
1263
1276
1264
- dev -> flags &= ~IFF_UP ;
1277
+ return 0 ;
1278
+ }
1279
+
1280
+ static int __dev_close (struct net_device * dev )
1281
+ {
1282
+ LIST_HEAD (single );
1283
+
1284
+ list_add (& dev -> unreg_list , & single );
1285
+ return __dev_close_many (& single );
1286
+ }
1287
+
1288
+ int dev_close_many (struct list_head * head )
1289
+ {
1290
+ struct net_device * dev , * tmp ;
1291
+ LIST_HEAD (tmp_list );
1292
+
1293
+ list_for_each_entry_safe (dev , tmp , head , unreg_list )
1294
+ if (!(dev -> flags & IFF_UP ))
1295
+ list_move (& dev -> unreg_list , & tmp_list );
1296
+
1297
+ __dev_close_many (head );
1265
1298
1266
1299
/*
1267
- * Shutdown NET_DMA
1300
+ * Tell people we are down
1268
1301
*/
1269
- net_dmaengine_put ();
1302
+ list_for_each_entry (dev , head , unreg_list ) {
1303
+ rtmsg_ifinfo (RTM_NEWLINK , dev , IFF_UP |IFF_RUNNING );
1304
+ call_netdevice_notifiers (NETDEV_DOWN , dev );
1305
+ }
1270
1306
1307
+ /* rollback_registered_many needs the complete original list */
1308
+ list_splice (& tmp_list , head );
1271
1309
return 0 ;
1272
1310
}
1273
1311
@@ -1282,16 +1320,10 @@ static int __dev_close(struct net_device *dev)
1282
1320
*/
1283
1321
int dev_close (struct net_device * dev )
1284
1322
{
1285
- if (!(dev -> flags & IFF_UP ))
1286
- return 0 ;
1287
-
1288
- __dev_close (dev );
1323
+ LIST_HEAD (single );
1289
1324
1290
- /*
1291
- * Tell people we are down
1292
- */
1293
- rtmsg_ifinfo (RTM_NEWLINK , dev , IFF_UP |IFF_RUNNING );
1294
- call_netdevice_notifiers (NETDEV_DOWN , dev );
1325
+ list_add (& dev -> unreg_list , & single );
1326
+ dev_close_many (& single );
1295
1327
1296
1328
return 0 ;
1297
1329
}
@@ -4963,10 +4995,12 @@ static void rollback_registered_many(struct list_head *head)
4963
4995
}
4964
4996
4965
4997
BUG_ON (dev -> reg_state != NETREG_REGISTERED );
4998
+ }
4966
4999
4967
- /* If device is running, close it first. */
4968
- dev_close ( dev );
5000
+ /* If device is running, close it first. */
5001
+ dev_close_many ( head );
4969
5002
5003
+ list_for_each_entry (dev , head , unreg_list ) {
4970
5004
/* And unlink it from device chain. */
4971
5005
unlist_netdevice (dev );
4972
5006
0 commit comments