Page MenuHomeFreeBSD

D59023.diff
No OneTemporary

D59023.diff

Index: share/man/man4/ice.4
===================================================================
--- share/man/man4/ice.4
+++ share/man/man4/ice.4
@@ -1158,6 +1158,10 @@
while the PF and its sibling VFs continue recovering.
A VF function-level reset cannot recreate this PF-owned VSI state; another PF
or device reset, or SR-IOV configuration recreation, is required.
+If a mandatory stage of an individual VF reset fails, the driver likewise
+leaves that VF inactive instead of publishing incomplete hardware state.
+A later VF reset can retry this recovery; a PF or device reset, or SR-IOV
+configuration recreation, can also recover the VF.
.Pp
For each configured VF,
.Xr ifconfig 8
Index: sys/dev/ice/ice_iov.h
===================================================================
--- sys/dev/ice/ice_iov.h
+++ sys/dev/ice/ice_iov.h
@@ -72,6 +72,7 @@
VF_FLAG_MAC_ANTI_SPOOF = BIT(4),
VF_FLAG_INITIALIZED = BIT(5),
VF_FLAG_REBUILD_FAILED = BIT(6),
+ VF_FLAG_RESET_FAILED = BIT(7),
};
/**
Index: sys/dev/ice/ice_iov.c
===================================================================
--- sys/dev/ice/ice_iov.c
+++ sys/dev/ice/ice_iov.c
@@ -67,9 +67,12 @@
static struct ice_vf *ice_iov_get_vf(struct ice_softc *sc, int vf_num);
static int ice_iov_configure_mac_anti_spoof(struct ice_softc *sc,
struct ice_vf *vf);
+static int ice_iov_restore_vf_host_config(struct ice_softc *sc,
+ struct ice_vf *vf);
+static void ice_iov_clear_vf_queue_state(struct ice_vf *vf);
static void ice_iov_ready_vf(struct ice_softc *sc, struct ice_vf *vf);
-static void ice_reset_vf(struct ice_softc *sc, struct ice_vf *vf,
- bool trigger_vflr);
+static int ice_reset_vf(struct ice_softc *sc, struct ice_vf *vf,
+ bool trigger_vflr);
static void ice_iov_setup_intr_mapping(struct ice_softc *sc, struct ice_vf *vf);
static void ice_vc_version_msg(struct ice_softc *sc, struct ice_vf *vf,
@@ -92,6 +95,8 @@
static void ice_vc_notify_vf_link_state(struct ice_softc *sc, struct ice_vf *vf);
static void ice_vc_disable_queues_msg(struct ice_softc *sc, struct ice_vf *vf,
u8 *msg_buf);
+static int ice_vc_disable_queues(struct ice_softc *sc, struct ice_vf *vf,
+ u32 tx_queues, u32 rx_queues);
static void ice_vc_cfg_irq_map_msg(struct ice_softc *sc, struct ice_vf *vf,
u8 *msg_buf);
static void ice_vc_get_stats_msg(struct ice_softc *sc, struct ice_vf *vf,
@@ -260,8 +265,8 @@
* @sc: device softc structure
* @vf: VF whose VSI security policy should be configured
*
- * PF and device resets discard the hardware VSI context, so callers must
- * replay this policy after creating or rebuilding the VF's VSI.
+ * VF, PF, and device resets can discard hardware VSI policy, so callers must
+ * replay it before releasing a newly created or reset VF.
*/
static int
ice_iov_configure_mac_anti_spoof(struct ice_softc *sc, struct ice_vf *vf)
@@ -296,6 +301,43 @@
return (0);
}
+/**
+ * ice_iov_restore_vf_host_config - Restore PF-owned policy after a VF reset
+ * @sc: device softc structure
+ * @vf: VF whose host configuration should be restored
+ *
+ * A VF reset discards the guest's filter configuration. Remove the matching
+ * software switch state as well so that replayed guest requests reach
+ * firmware instead of being mistaken for filters which still exist. Restore
+ * the PF-owned source-MAC policy and base filters before releasing the VF.
+ */
+static int
+ice_iov_restore_vf_host_config(struct ice_softc *sc, struct ice_vf *vf)
+{
+ struct ice_vsi *vsi = vf->vsi;
+ int error;
+
+ ice_remove_vsi_fltr(&sc->hw, vsi->idx);
+ vf->mac_filter_cnt = 0;
+ vf->vlan_cnt = 0;
+ bzero(vf->vlans_map, sizeof(vf->vlans_map));
+
+ error = ice_iov_configure_mac_anti_spoof(sc, vf);
+ if (error != 0)
+ return (error);
+
+ error = ice_add_vsi_mac_filter(vsi, broadcastaddr);
+ if (error != 0)
+ return (error);
+ if (!ETHER_IS_ZERO(vf->mac)) {
+ error = ice_add_vsi_mac_filter(vsi, vf->mac);
+ if (error != 0)
+ return (error);
+ }
+
+ return (0);
+}
+
/**
* ice_iov_add_vf - Called by the OS for each VF to create
* @sc: device softc structure
@@ -749,6 +791,18 @@
}
}
+/**
+ * ice_iov_clear_vf_queue_state - Clear tracked VF queue state
+ * @vf: driver's VF structure for the VF to update
+ */
+static void
+ice_iov_clear_vf_queue_state(struct ice_vf *vf)
+{
+ vf->txq_configured = 0;
+ vf->rxq_configured = 0;
+ vf->rxq_enabled = 0;
+}
+
/**
* ice_iov_ready_vf - Setup VF interrupts and mark it as ready
* @sc: device softc structure
@@ -765,9 +819,7 @@
u32 reg;
/* A VF or PF reset discards all queue configuration and state. */
- vf->txq_configured = 0;
- vf->rxq_configured = 0;
- vf->rxq_enabled = 0;
+ ice_iov_clear_vf_queue_state(vf);
/* Clear the triggering bit */
reg = rd32(hw, VPGEN_VFRTRIG(vf->vf_num));
@@ -805,6 +857,7 @@
vf = ice_iov_get_vf(sc, vsi->vf_num);
atomic_clear_32(&vf->vf_flags, VF_FLAG_INITIALIZED);
atomic_set_32(&vf->vf_flags, VF_FLAG_REBUILD_FAILED);
+ ice_iov_clear_vf_queue_state(vf);
ICE_IOV_FAIL_POINT(sc, vf->vf_num, rebuild_before_initialize, error,
fail);
@@ -831,7 +884,8 @@
return (EIO);
}
- atomic_clear_32(&vf->vf_flags, VF_FLAG_REBUILD_FAILED);
+ atomic_clear_32(&vf->vf_flags,
+ VF_FLAG_REBUILD_FAILED | VF_FLAG_RESET_FAILED);
ice_iov_ready_vf(sc, vf);
return (0);
@@ -847,25 +901,26 @@
* @vf: driver's VF structure for VF to be reset
* @trigger_vflr: trigger a reset or only handle already executed reset
*
- * Performs a VFR for the given VF. This function busy waits until the
- * reset completes in the HW, notifies the VF that the reset is done
- * by setting a bit in a HW register, then returns.
+ * Performs a VFR for the given VF. This function busy waits until the reset
+ * completes in the HW and publishes VFACTIVE only after every mandatory
+ * reset stage succeeds.
*
* @remark This also sets up the PF<->VF interrupt mapping and allocations in
* the hardware after the hardware reset is finished, via
* ice_iov_setup_intr_mapping()
*/
-static void
+static int
ice_reset_vf(struct ice_softc *sc, struct ice_vf *vf, bool trigger_vflr)
{
u16 global_vf_num, reg_idx, bit_idx;
struct ice_hw *hw = &sc->hw;
- int status;
+ int error, status;
u32 reg;
int i;
global_vf_num = vf->vf_num + hw->func_caps.vf_base_id;
atomic_clear_32(&vf->vf_flags, VF_FLAG_INITIALIZED);
+ error = 0;
if (trigger_vflr) {
reg = rd32(hw, VPGEN_VFRTRIG(vf->vf_num));
@@ -890,18 +945,34 @@
DELAY(ICE_PCI_CIAD_WAIT_DELAY_US);
}
- if (i == ICE_PCI_CIAD_WAIT_COUNT)
+ if (i == ICE_PCI_CIAD_WAIT_COUNT) {
device_printf(sc->dev,
"VF-%d PCI transactions stuck\n", vf->vf_num);
+ error = ETIMEDOUT;
+ }
+
+ /*
+ * Remove the tracked queue leaves from the software scheduler before
+ * issuing the reset-only AQ command. That command drains hardware but
+ * does not update the shared scheduler database.
+ */
+ status = ice_vc_disable_queues(sc, vf, vf->txq_configured,
+ vf->rxq_enabled);
+ if (status != 0 && error == 0)
+ error = status;
+ ice_iov_clear_vf_queue_state(vf);
/* This zero-queue command is required to complete every VF reset. */
status = ice_dis_vsi_txq(hw->port_info, vf->vsi->idx, 0, 0,
NULL, NULL, NULL, ICE_VF_RESET, vf->vf_num, NULL);
- if (status)
+ if (status) {
device_printf(sc->dev,
"%s: Failed to disable LAN Tx queues: err %s aq_err %s\n",
__func__, ice_status_str(status),
ice_aq_str(hw->adminq.sq_last_status));
+ if (error == 0)
+ error = EIO;
+ }
/* Then check for the VF reset to finish in HW */
for (i = 0; i < ICE_VPGEN_VFRSTAT_WAIT_COUNT; i++) {
@@ -911,16 +982,33 @@
DELAY(ICE_VPGEN_VFRSTAT_WAIT_DELAY_US);
}
- if (i == ICE_VPGEN_VFRSTAT_WAIT_COUNT)
+ if (i == ICE_VPGEN_VFRSTAT_WAIT_COUNT) {
device_printf(sc->dev,
"VF-%d Reset is stuck\n", vf->vf_num);
+ if (error == 0)
+ error = ETIMEDOUT;
+ }
+
+ if (error != 0) {
+ atomic_set_32(&vf->vf_flags, VF_FLAG_RESET_FAILED);
+ return (error);
+ }
+
+ atomic_clear_32(&vf->vf_flags, VF_FLAG_RESET_FAILED);
/* A VFR cannot recover PF-owned VSI state lost during PF rebuild. */
if ((atomic_load_acq_32(&vf->vf_flags) &
VF_FLAG_REBUILD_FAILED) != 0)
- return;
+ return (EIO);
+
+ error = ice_iov_restore_vf_host_config(sc, vf);
+ if (error != 0) {
+ atomic_set_32(&vf->vf_flags, VF_FLAG_RESET_FAILED);
+ return (error);
+ }
ice_iov_ready_vf(sc, vf);
+ return (0);
}
/**
@@ -2408,7 +2496,7 @@
return;
/* Only a later PF rebuild can restore an invalid firmware VSI. */
- if ((vf_flags & VF_FLAG_REBUILD_FAILED) != 0 &&
+ if ((vf_flags & (VF_FLAG_REBUILD_FAILED | VF_FLAG_RESET_FAILED)) != 0 &&
v_opcode != VIRTCHNL_OP_VERSION &&
v_opcode != VIRTCHNL_OP_RESET_VF) {
ice_aq_send_msg_to_vf(hw, v_id, v_opcode,

File Metadata

Mime Type
text/plain
Expires
Fri, Aug 21, 12:52 PM (6 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37032169
Default Alt Text
D59023.diff (8 KB)

Event Timeline