dev_dbg(dev, "Problem restarting traffic for LAG node move\n");
 }
 
+/**
+ * ice_lag_build_netdev_list - populate the lag struct's netdev list
+ * @lag: local lag struct
+ * @ndlist: pointer to netdev list to populate
+ */
+static void ice_lag_build_netdev_list(struct ice_lag *lag,
+                                     struct ice_lag_netdev_list *ndlist)
+{
+       struct ice_lag_netdev_list *nl;
+       struct net_device *tmp_nd;
+
+       INIT_LIST_HEAD(&ndlist->node);
+       rcu_read_lock();
+       for_each_netdev_in_bond_rcu(lag->upper_netdev, tmp_nd) {
+               nl = kzalloc(sizeof(*nl), GFP_ATOMIC);
+               if (!nl)
+                       break;
+
+               nl->netdev = tmp_nd;
+               list_add(&nl->node, &ndlist->node);
+       }
+       rcu_read_unlock();
+       lag->netdev_head = &ndlist->node;
+}
+
+/**
+ * ice_lag_destroy_netdev_list - free lag struct's netdev list
+ * @lag: pointer to local lag struct
+ * @ndlist: pointer to lag struct netdev list
+ */
+static void ice_lag_destroy_netdev_list(struct ice_lag *lag,
+                                       struct ice_lag_netdev_list *ndlist)
+{
+       struct ice_lag_netdev_list *entry, *n;
+
+       rcu_read_lock();
+       list_for_each_entry_safe(entry, n, &ndlist->node, node) {
+               list_del(&entry->node);
+               kfree(entry);
+       }
+       rcu_read_unlock();
+       lag->netdev_head = NULL;
+}
+
 /**
  * ice_lag_move_single_vf_nodes - Move Tx scheduling nodes for single VF
  * @lag: primary interface LAG struct
 void ice_lag_move_new_vf_nodes(struct ice_vf *vf)
 {
        struct ice_lag_netdev_list ndlist;
-       struct list_head *tmp, *n;
        u8 pri_port, act_port;
        struct ice_lag *lag;
        struct ice_vsi *vsi;
        pri_port = pf->hw.port_info->lport;
        act_port = lag->active_port;
 
-       if (lag->upper_netdev) {
-               struct ice_lag_netdev_list *nl;
-               struct net_device *tmp_nd;
-
-               INIT_LIST_HEAD(&ndlist.node);
-               rcu_read_lock();
-               for_each_netdev_in_bond_rcu(lag->upper_netdev, tmp_nd) {
-                       nl = kzalloc(sizeof(*nl), GFP_ATOMIC);
-                       if (!nl)
-                               break;
-
-                       nl->netdev = tmp_nd;
-                       list_add(&nl->node, &ndlist.node);
-               }
-               rcu_read_unlock();
-       }
-
-       lag->netdev_head = &ndlist.node;
+       if (lag->upper_netdev)
+               ice_lag_build_netdev_list(lag, &ndlist);
 
        if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG) &&
            lag->bonded && lag->primary && pri_port != act_port &&
            !list_empty(lag->netdev_head))
                ice_lag_move_single_vf_nodes(lag, pri_port, act_port, vsi->idx);
 
-       list_for_each_safe(tmp, n, &ndlist.node) {
-               struct ice_lag_netdev_list *entry;
-
-               entry = list_entry(tmp, struct ice_lag_netdev_list, node);
-               list_del(&entry->node);
-               kfree(entry);
-       }
-       lag->netdev_head = NULL;
+       ice_lag_destroy_netdev_list(lag, &ndlist);
 
 new_vf_unlock:
        mutex_unlock(&pf->lag_mutex);
                        ice_lag_move_single_vf_nodes(lag, oldport, newport, i);
 }
 
+/**
+ * ice_lag_move_vf_nodes_cfg - move vf nodes outside LAG netdev event context
+ * @lag: local lag struct
+ * @src_prt: lport value for source port
+ * @dst_prt: lport value for destination port
+ *
+ * This function is used to move nodes during an out-of-netdev-event situation,
+ * primarily when the driver needs to reconfigure or recreate resources.
+ *
+ * Must be called while holding the lag_mutex to avoid lag events from
+ * processing while out-of-sync moves are happening.  Also, paired moves,
+ * such as used in a reset flow, should both be called under the same mutex
+ * lock to avoid changes between start of reset and end of reset.
+ */
+void ice_lag_move_vf_nodes_cfg(struct ice_lag *lag, u8 src_prt, u8 dst_prt)
+{
+       struct ice_lag_netdev_list ndlist;
+
+       ice_lag_build_netdev_list(lag, &ndlist);
+       ice_lag_move_vf_nodes(lag, src_prt, dst_prt);
+       ice_lag_destroy_netdev_list(lag, &ndlist);
+}
+
 #define ICE_LAG_SRIOV_CP_RECIPE                10
 #define ICE_LAG_SRIOV_TRAIN_PKT_LEN    16
 
 {
        struct ice_lag_netdev_list ndlist;
        struct ice_lag *lag, *prim_lag;
-       struct list_head *tmp, *n;
        u8 act_port, loc_port;
 
        if (!pf->lag || !pf->lag->bonded)
        if (lag->primary) {
                prim_lag = lag;
        } else {
-               struct ice_lag_netdev_list *nl;
-               struct net_device *tmp_nd;
-
-               INIT_LIST_HEAD(&ndlist.node);
-               rcu_read_lock();
-               for_each_netdev_in_bond_rcu(lag->upper_netdev, tmp_nd) {
-                       nl = kzalloc(sizeof(*nl), GFP_ATOMIC);
-                       if (!nl)
-                               break;
-
-                       nl->netdev = tmp_nd;
-                       list_add(&nl->node, &ndlist.node);
-               }
-               rcu_read_unlock();
-               lag->netdev_head = &ndlist.node;
+               ice_lag_build_netdev_list(lag, &ndlist);
                prim_lag = ice_lag_find_primary(lag);
        }
 
 
        ice_clear_rdma_cap(pf);
 lag_rebuild_out:
-       list_for_each_safe(tmp, n, &ndlist.node) {
-               struct ice_lag_netdev_list *entry;
-
-               entry = list_entry(tmp, struct ice_lag_netdev_list, node);
-               list_del(&entry->node);
-               kfree(entry);
-       }
+       ice_lag_destroy_netdev_list(lag, &ndlist);
        mutex_unlock(&pf->lag_mutex);
 }
 
 
            (struct virtchnl_vsi_queue_config_info *)msg;
        struct virtchnl_queue_pair_info *qpi;
        struct ice_pf *pf = vf->pf;
+       struct ice_lag *lag;
        struct ice_vsi *vsi;
+       u8 act_prt, pri_prt;
        int i = -1, q_idx;
 
+       lag = pf->lag;
+       mutex_lock(&pf->lag_mutex);
+       act_prt = ICE_LAG_INVALID_PORT;
+       pri_prt = pf->hw.port_info->lport;
+       if (lag && lag->bonded && lag->primary) {
+               act_prt = lag->active_port;
+               if (act_prt != pri_prt && act_prt != ICE_LAG_INVALID_PORT &&
+                   lag->upper_netdev)
+                       ice_lag_move_vf_nodes_cfg(lag, act_prt, pri_prt);
+               else
+                       act_prt = ICE_LAG_INVALID_PORT;
+       }
+
        if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states))
                goto error_param;
 
                }
        }
 
+       if (lag && lag->bonded && lag->primary &&
+           act_prt != ICE_LAG_INVALID_PORT)
+               ice_lag_move_vf_nodes_cfg(lag, pri_prt, act_prt);
+       mutex_unlock(&pf->lag_mutex);
+
        /* send the response to the VF */
        return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES,
                                     VIRTCHNL_STATUS_SUCCESS, NULL, 0);
                                vf->vf_id, i);
        }
 
+       if (lag && lag->bonded && lag->primary &&
+           act_prt != ICE_LAG_INVALID_PORT)
+               ice_lag_move_vf_nodes_cfg(lag, pri_prt, act_prt);
+       mutex_unlock(&pf->lag_mutex);
+
        ice_lag_move_new_vf_nodes(vf);
 
        /* send the response to the VF */