Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F167266734
D59023.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D59023.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D59023: ice: Fail closed when VF reset does not complete
Attached
Detach File
Event Timeline
Log In to Comment