Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F167297697
D58905.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D58905.diff
View Options
diff --git a/share/man/man4/ice.4 b/share/man/man4/ice.4
--- a/share/man/man4/ice.4
+++ b/share/man/man4/ice.4
@@ -32,7 +32,7 @@
.\"
.\" * Other names and brands may be claimed as the property of others.
.\"
-.Dd August 11, 2026
+.Dd August 19, 2026
.Dt ICE 4
.Os
.Sh NAME
@@ -1145,6 +1145,14 @@
By default, this is set to 64.
.El
.Pp
+PF and device resets discard the hardware state of every VF.
+The driver keeps each configured VF inactive while reconstructing its VSI and
+allows it to renegotiate resources only after reconstruction succeeds.
+If one VF cannot be reconstructed, it remains configured but uninitialized
+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.
+.Pp
For each configured VF,
.Xr ifconfig 8
with the
diff --git a/sys/dev/ice/ice_iov.h b/sys/dev/ice/ice_iov.h
--- a/sys/dev/ice/ice_iov.h
+++ b/sys/dev/ice/ice_iov.h
@@ -70,6 +70,7 @@
VF_FLAG_PROMISC_CAP = BIT(3),
VF_FLAG_MAC_ANTI_SPOOF = BIT(4),
VF_FLAG_INITIALIZED = BIT(5),
+ VF_FLAG_REBUILD_FAILED = BIT(6),
};
/**
@@ -115,11 +116,13 @@
int ice_iov_init(struct ice_softc *sc, uint16_t num_vfs, const nvlist_t *params);
int ice_iov_add_vf(struct ice_softc *sc, uint16_t vfnum, const nvlist_t *params);
+int ice_iov_rebuild_vf(struct ice_softc *sc, struct ice_vsi *vsi);
struct if_vf_status;
int ice_iov_vf_status(struct ice_softc *sc, struct if_vf_status **statusp);
void ice_iov_uninit(struct ice_softc *sc);
void ice_iov_handle_vflr(struct ice_softc *sc);
+void ice_iov_notify_vfs_reset(struct ice_softc *sc);
void ice_vc_handle_vf_msg(struct ice_softc *sc, struct ice_rq_event_info *event);
void ice_vc_notify_all_vfs_link_state(struct ice_softc *sc);
diff --git a/sys/dev/ice/ice_iov.c b/sys/dev/ice/ice_iov.c
--- a/sys/dev/ice/ice_iov.c
+++ b/sys/dev/ice/ice_iov.c
@@ -590,6 +590,36 @@
}
}
+/**
+ * ice_iov_notify_vfs_reset - Notify initialized VFs of an impending reset
+ * @sc: device softc structure
+ *
+ * Give VF drivers advance notice while the mailbox control queue is still
+ * alive. Ignore individual send failures so one VF cannot prevent the PF from
+ * notifying its siblings or proceeding with the reset.
+ */
+void
+ice_iov_notify_vfs_reset(struct ice_softc *sc)
+{
+ struct virtchnl_pf_event event = {};
+ struct ice_hw *hw = &sc->hw;
+ struct ice_vf *vf;
+
+ if (!ice_check_sq_alive(hw, &hw->mailboxq))
+ return;
+
+ event.event = VIRTCHNL_EVENT_RESET_IMPENDING;
+ event.severity = PF_EVENT_SEVERITY_CERTAIN_DOOM;
+ for (int i = 0; i < sc->num_vfs; i++) {
+ vf = &sc->vfs[i];
+ if ((atomic_load_acq_32(&vf->vf_flags) &
+ VF_FLAG_INITIALIZED) == 0)
+ continue;
+ (void)ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_EVENT,
+ VIRTCHNL_STATUS_SUCCESS, (u8 *)&event, sizeof(event), NULL);
+ }
+}
+
/**
* ice_iov_ready_vf - Setup VF interrupts and mark it as ready
* @sc: device softc structure
@@ -619,6 +649,54 @@
ice_flush(hw);
}
+/**
+ * ice_iov_rebuild_vf - Rebuild a VF VSI after a PF or device reset
+ * @sc: device softc structure
+ * @vsi: VF VSI to rebuild
+ *
+ * PF and device resets discard the hardware VSI and interrupt state for every
+ * VF. Re-add the VSI and replay its configuration before reporting the VF as
+ * active. A failed rebuild leaves the VF inactive while allowing the PF and
+ * other VFs to recover.
+ */
+int
+ice_iov_rebuild_vf(struct ice_softc *sc, struct ice_vsi *vsi)
+{
+ struct ice_eth_stats accumulated_stats;
+ struct ice_hw *hw = &sc->hw;
+ struct ice_vf *vf;
+ int error, status;
+
+ MPASS(vsi->type == ICE_VSI_VF);
+ 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);
+
+ /* A new hardware VSI starts a new raw statistics epoch. */
+ accumulated_stats = vsi->hw_stats.cur;
+ error = ice_initialize_vsi(vsi);
+ if (error != 0) {
+ device_printf(sc->dev,
+ "Unable to re-initialize VF %d VSI, err %s\n",
+ vf->vf_num, ice_err_str(error));
+ return (error);
+ }
+ vsi->hw_stats.cur = accumulated_stats;
+
+ status = ice_replay_vsi(hw, vsi->idx);
+ if (status != 0) {
+ device_printf(sc->dev,
+ "Failed to replay VF %d VSI, err %s aq_err %s\n",
+ vf->vf_num, ice_status_str(status),
+ ice_aq_str(hw->adminq.sq_last_status));
+ return (EIO);
+ }
+
+ atomic_clear_32(&vf->vf_flags, VF_FLAG_REBUILD_FAILED);
+ ice_iov_ready_vf(sc, vf);
+ return (0);
+}
+
/**
* ice_reset_vf - Perform a hardware reset (VFR) on a VF
* @sc: device softc structure
@@ -672,14 +750,14 @@
device_printf(sc->dev,
"VF-%d PCI transactions stuck\n", vf->vf_num);
- /* Disable TX queues, which is required during 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);
+ /* 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)
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));
+ "%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));
/* Then check for the VF reset to finish in HW */
for (i = 0; i < ICE_VPGEN_VFRSTAT_WAIT_COUNT; i++) {
@@ -693,6 +771,11 @@
device_printf(sc->dev,
"VF-%d Reset is stuck\n", vf->vf_num);
+ /* 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;
+
ice_iov_ready_vf(sc, vf);
}
@@ -1587,6 +1670,7 @@
__func__, vf->vf_num, vqs->vsi_id, vsi->idx);
ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_GET_STATS,
VIRTCHNL_STATUS_ERR_PARAM, NULL, 0, NULL);
+ return;
}
ice_update_vsi_hw_stats(vf->vsi);
@@ -1765,6 +1849,7 @@
device_t dev = sc->dev;
struct ice_vf *vf;
int err = 0;
+ u32 vf_flags;
u32 v_opcode = event->desc.cookie_high;
u16 v_id = event->desc.retval;
@@ -1788,6 +1873,19 @@
return;
}
+ vf_flags = atomic_load_acq_32(&vf->vf_flags);
+ if ((vf_flags & VF_FLAG_ENABLED) == 0 || vf->vsi == NULL)
+ return;
+
+ /* Only a later PF rebuild can restore an invalid firmware VSI. */
+ if ((vf_flags & VF_FLAG_REBUILD_FAILED) != 0 &&
+ v_opcode != VIRTCHNL_OP_VERSION &&
+ v_opcode != VIRTCHNL_OP_RESET_VF) {
+ ice_aq_send_msg_to_vf(hw, v_id, v_opcode,
+ VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR, NULL, 0, NULL);
+ return;
+ }
+
switch (v_opcode) {
case VIRTCHNL_OP_VERSION:
ice_vc_version_msg(sc, vf, msg);
diff --git a/sys/dev/ice/ice_lib.c b/sys/dev/ice/ice_lib.c
--- a/sys/dev/ice/ice_lib.c
+++ b/sys/dev/ice/ice_lib.c
@@ -6457,6 +6457,9 @@
* interrupt on all PFs. Initiate the reset now. Preparation and
* rebuild logic will be handled by the admin status task.
*/
+#ifdef PCI_IOV
+ ice_iov_notify_vfs_reset(sc);
+#endif
status = ice_reset(hw, reset_type);
/*
@@ -7855,6 +7858,17 @@
if (!vsi)
continue;
+#ifdef PCI_IOV
+ if (vsi->type == ICE_VSI_VF) {
+ status = ice_iov_rebuild_vf(sc, vsi);
+ if (status != 0)
+ device_printf(sc->dev,
+ "Failed to rebuild VF %d VSI; leaving VF disabled\n",
+ vsi->vf_num);
+ continue;
+ }
+#endif
+
status = ice_replay_vsi(hw, vsi->idx);
if (status) {
device_printf(sc->dev, "Failed to replay VSI %d, err %s aq_err %s\n",
diff --git a/sys/dev/ice/if_ice_iflib.c b/sys/dev/ice/if_ice_iflib.c
--- a/sys/dev/ice/if_ice_iflib.c
+++ b/sys/dev/ice/if_ice_iflib.c
@@ -2529,6 +2529,11 @@
if (ice_test_state(&sc->state, ICE_STATE_RECOVERY_MODE))
return;
+#ifdef PCI_IOV
+ /* Notify initialized VFs while the mailbox queue is still available. */
+ ice_iov_notify_vfs_reset(sc);
+#endif
+
/* Restore identification while the control queues are still usable. */
ice_led_restore(sc);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Aug 21, 6:30 PM (15 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37045603
Default Alt Text
D58905.diff (7 KB)
Attached To
Mode
D58905: ice: Rebuild VF VSIs after PF resets
Attached
Detach File
Event Timeline
Log In to Comment