*/
 static void ice_display_lag_info(struct ice_lag *lag)
 {
-       const char *name, *peer, *upper, *role, *bonded, *primary;
+       const char *name, *upper, *role, *bonded, *primary;
        struct device *dev = &lag->pf->pdev->dev;
 
        name = lag->netdev ? netdev_name(lag->netdev) : "unset";
-       peer = lag->peer_netdev ? netdev_name(lag->peer_netdev) : "unset";
        upper = lag->upper_netdev ? netdev_name(lag->upper_netdev) : "unset";
        primary = lag->primary ? "TRUE" : "FALSE";
        bonded = lag->bonded ? "BONDED" : "UNBONDED";
                role = "ERROR";
        }
 
-       dev_dbg(dev, "%s %s, peer:%s, upper:%s, role:%s, primary:%s\n", name,
-               bonded, peer, upper, role, primary);
+       dev_dbg(dev, "%s %s, upper:%s, role:%s, primary:%s\n", name, bonded,
+               upper, role, primary);
 }
 
 /**
                lag->upper_netdev = NULL;
        }
 
-       lag->peer_netdev = NULL;
        ice_set_rdma_cap(pf);
        lag->bonded = false;
        lag->role = ICE_LAG_NONE;
        ice_display_lag_info(lag);
 }
 
+/**
+ * ice_lag_process_event - process a task assigned to the lag_wq
+ * @work: pointer to work_struct
+ */
+static void ice_lag_process_event(struct work_struct *work)
+{
+       struct netdev_notifier_changeupper_info *info;
+       struct ice_lag_work *lag_work;
+       struct net_device *netdev;
+       struct list_head *tmp, *n;
+       struct ice_pf *pf;
+
+       lag_work = container_of(work, struct ice_lag_work, lag_task);
+       pf = lag_work->lag->pf;
+
+       mutex_lock(&pf->lag_mutex);
+       lag_work->lag->netdev_head = &lag_work->netdev_list.node;
+
+       switch (lag_work->event) {
+       case NETDEV_CHANGEUPPER:
+               info = &lag_work->info.changeupper_info;
+               ice_lag_changeupper_event(lag_work->lag, info);
+               break;
+       case NETDEV_BONDING_INFO:
+               ice_lag_info_event(lag_work->lag, &lag_work->info.bonding_info);
+               break;
+       case NETDEV_UNREGISTER:
+               if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG)) {
+                       netdev = lag_work->info.bonding_info.info.dev;
+                       if ((netdev == lag_work->lag->netdev ||
+                            lag_work->lag->primary) && lag_work->lag->bonded)
+                               ice_lag_unregister(lag_work->lag, netdev);
+               }
+               break;
+       default:
+               break;
+       }
+
+       /* cleanup resources allocated for this work item */
+       list_for_each_safe(tmp, n, &lag_work->netdev_list.node) {
+               struct ice_lag_netdev_list *entry;
+
+               entry = list_entry(tmp, struct ice_lag_netdev_list, node);
+               list_del(&entry->node);
+               kfree(entry);
+       }
+       lag_work->lag->netdev_head = NULL;
+
+       mutex_unlock(&pf->lag_mutex);
+
+       kfree(lag_work);
+}
+
 /**
  * ice_lag_event_handler - handle LAG events from netdev
  * @notif_blk: notifier block registered by this netdev
                      void *ptr)
 {
        struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
+       struct net_device *upper_netdev;
+       struct ice_lag_work *lag_work;
        struct ice_lag *lag;
 
-       lag = container_of(notif_blk, struct ice_lag, notif_block);
+       if (!netif_is_ice(netdev))
+               return NOTIFY_DONE;
+
+       if (event != NETDEV_CHANGEUPPER && event != NETDEV_BONDING_INFO &&
+           event != NETDEV_UNREGISTER)
+               return NOTIFY_DONE;
 
+       if (!(netdev->priv_flags & IFF_BONDING))
+               return NOTIFY_DONE;
+
+       lag = container_of(notif_blk, struct ice_lag, notif_block);
        if (!lag->netdev)
                return NOTIFY_DONE;
 
-       /* Check that the netdev is in the working namespace */
        if (!net_eq(dev_net(netdev), &init_net))
                return NOTIFY_DONE;
 
+       /* This memory will be freed at the end of ice_lag_process_event */
+       lag_work = kzalloc(sizeof(*lag_work), GFP_KERNEL);
+       if (!lag_work)
+               return -ENOMEM;
+
+       lag_work->event_netdev = netdev;
+       lag_work->lag = lag;
+       lag_work->event = event;
+       if (event == NETDEV_CHANGEUPPER) {
+               struct netdev_notifier_changeupper_info *info;
+
+               info = ptr;
+               upper_netdev = info->upper_dev;
+       } else {
+               upper_netdev = netdev_master_upper_dev_get(netdev);
+       }
+
+       INIT_LIST_HEAD(&lag_work->netdev_list.node);
+       if (upper_netdev) {
+               struct ice_lag_netdev_list *nd_list;
+               struct net_device *tmp_nd;
+
+               rcu_read_lock();
+               for_each_netdev_in_bond_rcu(upper_netdev, tmp_nd) {
+                       nd_list = kzalloc(sizeof(*nd_list), GFP_KERNEL);
+                       if (!nd_list)
+                               break;
+
+                       nd_list->netdev = tmp_nd;
+                       list_add(&nd_list->node, &lag_work->netdev_list.node);
+               }
+               rcu_read_unlock();
+       }
+
        switch (event) {
        case NETDEV_CHANGEUPPER:
-               ice_lag_changeupper_event(lag, ptr);
+               lag_work->info.changeupper_info =
+                       *((struct netdev_notifier_changeupper_info *)ptr);
                break;
        case NETDEV_BONDING_INFO:
-               ice_lag_info_event(lag, ptr);
-               break;
-       case NETDEV_UNREGISTER:
-               ice_lag_unregister(lag, netdev);
+               lag_work->info.bonding_info =
+                       *((struct netdev_notifier_bonding_info *)ptr);
                break;
        default:
+               lag_work->info.notifier_info =
+                       *((struct netdev_notifier_info *)ptr);
                break;
        }
 
+       INIT_WORK(&lag_work->lag_task, ice_lag_process_event);
+       queue_work(ice_lag_wq, &lag_work->lag_task);
+
        return NOTIFY_DONE;
 }
 
        lag->netdev = vsi->netdev;
        lag->role = ICE_LAG_NONE;
        lag->bonded = false;
-       lag->peer_netdev = NULL;
        lag->upper_netdev = NULL;
        lag->notif_block.notifier_call = NULL;