@@ -56,11 +56,10 @@ static void ice_lag_set_backup(struct ice_lag *lag)
56
56
*/
57
57
static void ice_display_lag_info (struct ice_lag * lag )
58
58
{
59
- const char * name , * peer , * upper , * role , * bonded , * primary ;
59
+ const char * name , * upper , * role , * bonded , * primary ;
60
60
struct device * dev = & lag -> pf -> pdev -> dev ;
61
61
62
62
name = lag -> netdev ? netdev_name (lag -> netdev ) : "unset" ;
63
- peer = lag -> peer_netdev ? netdev_name (lag -> peer_netdev ) : "unset" ;
64
63
upper = lag -> upper_netdev ? netdev_name (lag -> upper_netdev ) : "unset" ;
65
64
primary = lag -> primary ? "TRUE" : "FALSE" ;
66
65
bonded = lag -> bonded ? "BONDED" : "UNBONDED" ;
@@ -82,8 +81,8 @@ static void ice_display_lag_info(struct ice_lag *lag)
82
81
role = "ERROR" ;
83
82
}
84
83
85
- dev_dbg (dev , "%s %s, peer:%s, upper:%s, role:%s, primary:%s\n" , name ,
86
- bonded , peer , upper , role , primary );
84
+ dev_dbg (dev , "%s %s, upper:%s, role:%s, primary:%s\n" , name , bonded ,
85
+ upper , role , primary );
87
86
}
88
87
89
88
/**
@@ -198,7 +197,6 @@ ice_lag_unlink(struct ice_lag *lag,
198
197
lag -> upper_netdev = NULL ;
199
198
}
200
199
201
- lag -> peer_netdev = NULL ;
202
200
ice_set_rdma_cap (pf );
203
201
lag -> bonded = false;
204
202
lag -> role = ICE_LAG_NONE ;
@@ -288,6 +286,59 @@ static void ice_lag_changeupper_event(struct ice_lag *lag, void *ptr)
288
286
ice_display_lag_info (lag );
289
287
}
290
288
289
+ /**
290
+ * ice_lag_process_event - process a task assigned to the lag_wq
291
+ * @work: pointer to work_struct
292
+ */
293
+ static void ice_lag_process_event (struct work_struct * work )
294
+ {
295
+ struct netdev_notifier_changeupper_info * info ;
296
+ struct ice_lag_work * lag_work ;
297
+ struct net_device * netdev ;
298
+ struct list_head * tmp , * n ;
299
+ struct ice_pf * pf ;
300
+
301
+ lag_work = container_of (work , struct ice_lag_work , lag_task );
302
+ pf = lag_work -> lag -> pf ;
303
+
304
+ mutex_lock (& pf -> lag_mutex );
305
+ lag_work -> lag -> netdev_head = & lag_work -> netdev_list .node ;
306
+
307
+ switch (lag_work -> event ) {
308
+ case NETDEV_CHANGEUPPER :
309
+ info = & lag_work -> info .changeupper_info ;
310
+ ice_lag_changeupper_event (lag_work -> lag , info );
311
+ break ;
312
+ case NETDEV_BONDING_INFO :
313
+ ice_lag_info_event (lag_work -> lag , & lag_work -> info .bonding_info );
314
+ break ;
315
+ case NETDEV_UNREGISTER :
316
+ if (ice_is_feature_supported (pf , ICE_F_SRIOV_LAG )) {
317
+ netdev = lag_work -> info .bonding_info .info .dev ;
318
+ if ((netdev == lag_work -> lag -> netdev ||
319
+ lag_work -> lag -> primary ) && lag_work -> lag -> bonded )
320
+ ice_lag_unregister (lag_work -> lag , netdev );
321
+ }
322
+ break ;
323
+ default :
324
+ break ;
325
+ }
326
+
327
+ /* cleanup resources allocated for this work item */
328
+ list_for_each_safe (tmp , n , & lag_work -> netdev_list .node ) {
329
+ struct ice_lag_netdev_list * entry ;
330
+
331
+ entry = list_entry (tmp , struct ice_lag_netdev_list , node );
332
+ list_del (& entry -> node );
333
+ kfree (entry );
334
+ }
335
+ lag_work -> lag -> netdev_head = NULL ;
336
+
337
+ mutex_unlock (& pf -> lag_mutex );
338
+
339
+ kfree (lag_work );
340
+ }
341
+
291
342
/**
292
343
* ice_lag_event_handler - handle LAG events from netdev
293
344
* @notif_blk: notifier block registered by this netdev
@@ -299,31 +350,79 @@ ice_lag_event_handler(struct notifier_block *notif_blk, unsigned long event,
299
350
void * ptr )
300
351
{
301
352
struct net_device * netdev = netdev_notifier_info_to_dev (ptr );
353
+ struct net_device * upper_netdev ;
354
+ struct ice_lag_work * lag_work ;
302
355
struct ice_lag * lag ;
303
356
304
- lag = container_of (notif_blk , struct ice_lag , notif_block );
357
+ if (!netif_is_ice (netdev ))
358
+ return NOTIFY_DONE ;
359
+
360
+ if (event != NETDEV_CHANGEUPPER && event != NETDEV_BONDING_INFO &&
361
+ event != NETDEV_UNREGISTER )
362
+ return NOTIFY_DONE ;
305
363
364
+ if (!(netdev -> priv_flags & IFF_BONDING ))
365
+ return NOTIFY_DONE ;
366
+
367
+ lag = container_of (notif_blk , struct ice_lag , notif_block );
306
368
if (!lag -> netdev )
307
369
return NOTIFY_DONE ;
308
370
309
- /* Check that the netdev is in the working namespace */
310
371
if (!net_eq (dev_net (netdev ), & init_net ))
311
372
return NOTIFY_DONE ;
312
373
374
+ /* This memory will be freed at the end of ice_lag_process_event */
375
+ lag_work = kzalloc (sizeof (* lag_work ), GFP_KERNEL );
376
+ if (!lag_work )
377
+ return - ENOMEM ;
378
+
379
+ lag_work -> event_netdev = netdev ;
380
+ lag_work -> lag = lag ;
381
+ lag_work -> event = event ;
382
+ if (event == NETDEV_CHANGEUPPER ) {
383
+ struct netdev_notifier_changeupper_info * info ;
384
+
385
+ info = ptr ;
386
+ upper_netdev = info -> upper_dev ;
387
+ } else {
388
+ upper_netdev = netdev_master_upper_dev_get (netdev );
389
+ }
390
+
391
+ INIT_LIST_HEAD (& lag_work -> netdev_list .node );
392
+ if (upper_netdev ) {
393
+ struct ice_lag_netdev_list * nd_list ;
394
+ struct net_device * tmp_nd ;
395
+
396
+ rcu_read_lock ();
397
+ for_each_netdev_in_bond_rcu (upper_netdev , tmp_nd ) {
398
+ nd_list = kzalloc (sizeof (* nd_list ), GFP_KERNEL );
399
+ if (!nd_list )
400
+ break ;
401
+
402
+ nd_list -> netdev = tmp_nd ;
403
+ list_add (& nd_list -> node , & lag_work -> netdev_list .node );
404
+ }
405
+ rcu_read_unlock ();
406
+ }
407
+
313
408
switch (event ) {
314
409
case NETDEV_CHANGEUPPER :
315
- ice_lag_changeupper_event (lag , ptr );
410
+ lag_work -> info .changeupper_info =
411
+ * ((struct netdev_notifier_changeupper_info * )ptr );
316
412
break ;
317
413
case NETDEV_BONDING_INFO :
318
- ice_lag_info_event (lag , ptr );
319
- break ;
320
- case NETDEV_UNREGISTER :
321
- ice_lag_unregister (lag , netdev );
414
+ lag_work -> info .bonding_info =
415
+ * ((struct netdev_notifier_bonding_info * )ptr );
322
416
break ;
323
417
default :
418
+ lag_work -> info .notifier_info =
419
+ * ((struct netdev_notifier_info * )ptr );
324
420
break ;
325
421
}
326
422
423
+ INIT_WORK (& lag_work -> lag_task , ice_lag_process_event );
424
+ queue_work (ice_lag_wq , & lag_work -> lag_task );
425
+
327
426
return NOTIFY_DONE ;
328
427
}
329
428
@@ -398,7 +497,6 @@ int ice_init_lag(struct ice_pf *pf)
398
497
lag -> netdev = vsi -> netdev ;
399
498
lag -> role = ICE_LAG_NONE ;
400
499
lag -> bonded = false;
401
- lag -> peer_netdev = NULL ;
402
500
lag -> upper_netdev = NULL ;
403
501
lag -> notif_block .notifier_call = NULL ;
404
502
0 commit comments