@@ -6124,8 +6124,6 @@ void netif_receive_skb_list(struct list_head *head)
6124
6124
}
6125
6125
EXPORT_SYMBOL (netif_receive_skb_list );
6126
6126
6127
- static DEFINE_PER_CPU (struct work_struct , flush_works ) ;
6128
-
6129
6127
/* Network device is going away, flush any packets still pending */
6130
6128
static void flush_backlog (struct work_struct * work )
6131
6129
{
@@ -6182,36 +6180,54 @@ static bool flush_required(int cpu)
6182
6180
return true;
6183
6181
}
6184
6182
6183
+ struct flush_backlogs {
6184
+ cpumask_t flush_cpus ;
6185
+ struct work_struct w [];
6186
+ };
6187
+
6188
+ static struct flush_backlogs * flush_backlogs_alloc (void )
6189
+ {
6190
+ return kmalloc (struct_size_t (struct flush_backlogs , w , nr_cpu_ids ),
6191
+ GFP_KERNEL );
6192
+ }
6193
+
6194
+ static struct flush_backlogs * flush_backlogs_fallback ;
6195
+ static DEFINE_MUTEX (flush_backlogs_mutex );
6196
+
6185
6197
static void flush_all_backlogs (void )
6186
6198
{
6187
- static cpumask_t flush_cpus ;
6199
+ struct flush_backlogs * ptr = flush_backlogs_alloc () ;
6188
6200
unsigned int cpu ;
6189
6201
6190
- /* since we are under rtnl lock protection we can use static data
6191
- * for the cpumask and avoid allocating on stack the possibly
6192
- * large mask
6193
- */
6194
- ASSERT_RTNL ( );
6202
+ if (! ptr ) {
6203
+ mutex_lock ( & flush_backlogs_mutex );
6204
+ ptr = flush_backlogs_fallback ;
6205
+ }
6206
+ cpumask_clear ( & ptr -> flush_cpus );
6195
6207
6196
6208
cpus_read_lock ();
6197
6209
6198
- cpumask_clear (& flush_cpus );
6199
6210
for_each_online_cpu (cpu ) {
6200
6211
if (flush_required (cpu )) {
6201
- queue_work_on ( cpu , system_highpri_wq ,
6202
- per_cpu_ptr ( & flush_works , cpu ) );
6203
- cpumask_set_cpu (cpu , & flush_cpus );
6212
+ INIT_WORK ( & ptr -> w [ cpu ], flush_backlog );
6213
+ queue_work_on ( cpu , system_highpri_wq , & ptr -> w [ cpu ] );
6214
+ __cpumask_set_cpu (cpu , & ptr -> flush_cpus );
6204
6215
}
6205
6216
}
6206
6217
6207
6218
/* we can have in flight packet[s] on the cpus we are not flushing,
6208
6219
* synchronize_net() in unregister_netdevice_many() will take care of
6209
- * them
6220
+ * them.
6210
6221
*/
6211
- for_each_cpu (cpu , & flush_cpus )
6212
- flush_work (per_cpu_ptr ( & flush_works , cpu ) );
6222
+ for_each_cpu (cpu , & ptr -> flush_cpus )
6223
+ flush_work (& ptr -> w [ cpu ] );
6213
6224
6214
6225
cpus_read_unlock ();
6226
+
6227
+ if (ptr != flush_backlogs_fallback )
6228
+ kfree (ptr );
6229
+ else
6230
+ mutex_unlock (& flush_backlogs_mutex );
6215
6231
}
6216
6232
6217
6233
static void net_rps_send_ipi (struct softnet_data * remsd )
@@ -10244,14 +10260,46 @@ static void dev_index_release(struct net *net, int ifindex)
10244
10260
WARN_ON (xa_erase (& net -> dev_by_index , ifindex ));
10245
10261
}
10246
10262
10263
+ static bool from_cleanup_net (void )
10264
+ {
10265
+ #ifdef CONFIG_NET_NS
10266
+ return current == cleanup_net_task ;
10267
+ #else
10268
+ return false;
10269
+ #endif
10270
+ }
10271
+
10272
+ static void rtnl_drop_if_cleanup_net (void )
10273
+ {
10274
+ if (from_cleanup_net ())
10275
+ __rtnl_unlock ();
10276
+ }
10277
+
10278
+ static void rtnl_acquire_if_cleanup_net (void )
10279
+ {
10280
+ if (from_cleanup_net ())
10281
+ rtnl_lock ();
10282
+ }
10283
+
10247
10284
/* Delayed registration/unregisteration */
10248
10285
LIST_HEAD (net_todo_list );
10286
+ static LIST_HEAD (net_todo_list_for_cleanup_net );
10287
+
10288
+ /* TODO: net_todo_list/net_todo_list_for_cleanup_net should probably
10289
+ * be provided by callers, instead of being static, rtnl protected.
10290
+ */
10291
+ static struct list_head * todo_list (void )
10292
+ {
10293
+ return from_cleanup_net () ? & net_todo_list_for_cleanup_net :
10294
+ & net_todo_list ;
10295
+ }
10296
+
10249
10297
DECLARE_WAIT_QUEUE_HEAD (netdev_unregistering_wq );
10250
10298
atomic_t dev_unreg_count = ATOMIC_INIT (0 );
10251
10299
10252
10300
static void net_set_todo (struct net_device * dev )
10253
10301
{
10254
- list_add_tail (& dev -> todo_list , & net_todo_list );
10302
+ list_add_tail (& dev -> todo_list , todo_list () );
10255
10303
}
10256
10304
10257
10305
static netdev_features_t netdev_sync_upper_features (struct net_device * lower ,
@@ -11101,7 +11149,7 @@ void netdev_run_todo(void)
11101
11149
#endif
11102
11150
11103
11151
/* Snapshot list, allow later requests */
11104
- list_replace_init (& net_todo_list , & list );
11152
+ list_replace_init (todo_list () , & list );
11105
11153
11106
11154
__rtnl_unlock ();
11107
11155
@@ -11623,7 +11671,7 @@ EXPORT_SYMBOL_GPL(alloc_netdev_dummy);
11623
11671
void synchronize_net (void )
11624
11672
{
11625
11673
might_sleep ();
11626
- if (rtnl_is_locked ())
11674
+ if (from_cleanup_net () || rtnl_is_locked ())
11627
11675
synchronize_rcu_expedited ();
11628
11676
else
11629
11677
synchronize_rcu ();
@@ -11728,9 +11776,11 @@ void unregister_netdevice_many_notify(struct list_head *head,
11728
11776
WRITE_ONCE (dev -> reg_state , NETREG_UNREGISTERING );
11729
11777
netdev_unlock (dev );
11730
11778
}
11731
- flush_all_backlogs ();
11732
11779
11780
+ rtnl_drop_if_cleanup_net ();
11781
+ flush_all_backlogs ();
11733
11782
synchronize_net ();
11783
+ rtnl_acquire_if_cleanup_net ();
11734
11784
11735
11785
list_for_each_entry (dev , head , unreg_list ) {
11736
11786
struct sk_buff * skb = NULL ;
@@ -11790,7 +11840,9 @@ void unregister_netdevice_many_notify(struct list_head *head,
11790
11840
#endif
11791
11841
}
11792
11842
11843
+ rtnl_drop_if_cleanup_net ();
11793
11844
synchronize_net ();
11845
+ rtnl_acquire_if_cleanup_net ();
11794
11846
11795
11847
list_for_each_entry (dev , head , unreg_list ) {
11796
11848
netdev_put (dev , & dev -> dev_registered_tracker );
@@ -12455,12 +12507,13 @@ static int __init net_dev_init(void)
12455
12507
* Initialise the packet receive queues.
12456
12508
*/
12457
12509
12510
+ flush_backlogs_fallback = flush_backlogs_alloc ();
12511
+ if (!flush_backlogs_fallback )
12512
+ goto out ;
12513
+
12458
12514
for_each_possible_cpu (i ) {
12459
- struct work_struct * flush = per_cpu_ptr (& flush_works , i );
12460
12515
struct softnet_data * sd = & per_cpu (softnet_data , i );
12461
12516
12462
- INIT_WORK (flush , flush_backlog );
12463
-
12464
12517
skb_queue_head_init (& sd -> input_pkt_queue );
12465
12518
skb_queue_head_init (& sd -> process_queue );
12466
12519
#ifdef CONFIG_XFRM_OFFLOAD
0 commit comments