Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F174414148
D58739.id187024.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D58739.id187024.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 September 5, 2026
+.Dd September 17, 2026
.Dt ICE 4
.Os
.Sh NAME
@@ -1195,6 +1195,76 @@
An externally initiated VF function-level reset, PF reset, or SR-IOV
configuration recreation releases the VF.
.Pp
+For each VF in an active SR-IOV configuration,
+.Xr ifconfig 8
+with the
+.Fl v
+option displays cached PF state, including its MAC address, allocated transmit
+and receive queues, exact trunk VLAN-filter count and capacity, negotiated
+virtual-channel API, and configured MAC, VLAN, anti-spoof, and promiscuous-mode
+policy.
+The VF link-state policy is automatic: each VF follows the PF link state.
+The API version is present only after the VF completes its resource handshake
+following the last reset.
+The generic traffic-permission and fault-containment fields indicate whether
+PF policy currently permits the VF to issue traffic and whether MDD or
+software mailbox protection has isolated it.
+They do not indicate link state or observed traffic.
+.Pp
+Structured status consumers also receive mirroring, malicious-driver,
+mailbox, MAC-filter, and reset diagnostics in the version 1
+.Cm driver.ice
+namespace of the
+.Xr rtnetlink 4
+VF status response:
+.Bl -tag -width "mailbox-overflow-events"
+.It Cm version
+Namespace version number, currently 1.
+.It Cm mirror-configured
+Boolean indicating whether a mirror source VSI is configured.
+.It Cm mirror-source-vsi
+The source VSI number; omitted when no mirror is configured.
+.It Cm mirror-ingress-active
+Boolean indicating whether the ingress hardware mirror rule is installed.
+.It Cm mirror-egress-active
+Boolean indicating whether the egress hardware mirror rule is installed.
+.It Cm mdd-blocked
+Boolean indicating that malicious-driver detection has isolated the VF.
+.It Cm mdd-tx-events
+Cumulative number of transmit malicious-driver latches attributed to the VF.
+.It Cm mdd-rx-events
+Cumulative number of receive malicious-driver latches attributed to the VF.
+.It Cm mailbox-blocked
+Boolean indicating that software mailbox-overflow detection has isolated the
+VF.
+This field is omitted on E830 controllers, which enforce the mailbox limit in
+hardware without persistent software isolation.
+.It Cm mailbox-overflow-events
+Cumulative number of times software mailbox-overflow detection has isolated
+the VF.
+This field is omitted on E830 controllers.
+.It Cm mac-filter-count
+Number of VF-owned explicit MAC filters recorded by the PF, including unicast
+and multicast addresses.
+The administrator-assigned MAC and implicit broadcast filter do not count
+toward this quota.
+.It Cm mac-filter-limit
+Maximum number of VF-owned explicit MAC filters permitted by PF policy.
+This field is omitted until the PF has accepted the VF configuration.
+.It Cm reset-failed
+Boolean indicating that a VF reset or restoration of its PF-owned policy
+failed.
+The VF remains held until reset recovery succeeds.
+.It Cm rebuild-required
+Boolean indicating that the VF's PF-owned VSI state needs rebuilding.
+This includes a pending rebuild during PF or device reset as well as a failed
+rebuild; it does not by itself indicate failure.
+A VF reset cannot recover this state.
+.El
+.Pp
+The status query uses driver-cached state and does not issue AdminQ commands
+or read device registers.
+.Pp
An up to date list of parameters and their defaults can be found by using
.Xr iovctl 8
with the
@@ -1252,6 +1322,7 @@
.Sh SEE ALSO
.Xr iflib 4 ,
.Xr led 4 ,
+.Xr rtnetlink 4 ,
.Xr vlan 4 ,
.Xr ifconfig 8 ,
.Xr sysctl 8 ,
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
@@ -71,7 +71,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),
+ VF_FLAG_REBUILD_REQUIRED = BIT(6),
VF_FLAG_RESET_FAILED = BIT(7),
VF_FLAG_MDD_BLOCKED = BIT(8),
VF_FLAG_MBX_BLOCKED = BIT(9),
@@ -139,6 +139,8 @@
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);
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
@@ -40,6 +40,43 @@
#include "ice_iov.h"
#include "ice_fault.h"
+#include <net/if_vf_status.h>
+
+/* Version 1 driver.ice extension schema; documented in ice(4). */
+#define ICE_VF_STATUS_NAMESPACE "driver.ice"
+#define ICE_VF_STATUS_VERSION 1
+#define ICE_VF_STATUS_MIRROR_CONFIGURED "mirror-configured"
+#define ICE_VF_STATUS_MIRROR_SOURCE_VSI "mirror-source-vsi"
+#define ICE_VF_STATUS_MIRROR_INGRESS_ACTIVE "mirror-ingress-active"
+#define ICE_VF_STATUS_MIRROR_EGRESS_ACTIVE "mirror-egress-active"
+#define ICE_VF_STATUS_MDD_BLOCKED "mdd-blocked"
+#define ICE_VF_STATUS_MDD_TX_EVENTS "mdd-tx-events"
+#define ICE_VF_STATUS_MDD_RX_EVENTS "mdd-rx-events"
+#define ICE_VF_STATUS_MBX_BLOCKED "mailbox-blocked"
+#define ICE_VF_STATUS_MBX_OVERFLOW_EVENTS "mailbox-overflow-events"
+#define ICE_VF_STATUS_MAC_FILTER_COUNT "mac-filter-count"
+#define ICE_VF_STATUS_MAC_FILTER_LIMIT "mac-filter-limit"
+#define ICE_VF_STATUS_RESET_FAILED "reset-failed"
+#define ICE_VF_STATUS_REBUILD_REQUIRED "rebuild-required"
+
+/* Optional fields are compacted when absent; values define schema order. */
+enum ice_vf_status_field {
+ ICE_VF_STATUS_FIELD_MIRROR_CONFIGURED,
+ ICE_VF_STATUS_FIELD_MIRROR_SOURCE_VSI,
+ ICE_VF_STATUS_FIELD_MIRROR_INGRESS_ACTIVE,
+ ICE_VF_STATUS_FIELD_MIRROR_EGRESS_ACTIVE,
+ ICE_VF_STATUS_FIELD_MDD_BLOCKED,
+ ICE_VF_STATUS_FIELD_MDD_TX_EVENTS,
+ ICE_VF_STATUS_FIELD_MDD_RX_EVENTS,
+ ICE_VF_STATUS_FIELD_MBX_BLOCKED,
+ ICE_VF_STATUS_FIELD_MBX_OVERFLOW_EVENTS,
+ ICE_VF_STATUS_FIELD_MAC_FILTER_COUNT,
+ ICE_VF_STATUS_FIELD_MAC_FILTER_LIMIT,
+ ICE_VF_STATUS_FIELD_RESET_FAILED,
+ ICE_VF_STATUS_FIELD_REBUILD_REQUIRED,
+ ICE_VF_STATUS_NUM_FIELDS,
+};
+
#define ICE_VC_MAX_RX_BUFFER \
((16 * 1024) - BIT(ICE_RLAN_CTX_DBUF_S))
#define ICE_VIRTCHNL_QUEUE_MAP_SIZE 16
@@ -631,6 +668,144 @@
return (error);
}
+/**
+ * ice_iov_vf_status - report configured VF state
+ * @sc: device private structure
+ * @statusp: returned status snapshot
+ *
+ * The iflib context lock protects VF state and VSI lifetime while this
+ * method constructs the report.
+ */
+int
+ice_iov_vf_status(struct ice_softc *sc, struct if_vf_status **statusp)
+{
+ struct ice_vf *vf;
+ struct ice_vsi *vsi;
+ struct if_vf_extension *extension;
+ struct if_vf_info *info;
+ struct if_vf_status *status;
+ u32 vf_flags;
+ bool mirror_configured, software_mbx_limit;
+ uint32_t field, num_fields;
+ int i;
+
+ if (!ice_is_bit_set(sc->feat_en, ICE_FEATURE_SRIOV))
+ return (EOPNOTSUPP);
+ status = if_vf_status_alloc(sc->num_vfs);
+ if (status == NULL)
+ return (ENOMEM);
+ for (i = 0; i < sc->num_vfs; i++) {
+ vf = &sc->vfs[i];
+ vsi = vf->vsi;
+ vf_flags = atomic_load_acq_32(&vf->vf_flags);
+ info = &status->vfs[i];
+ info->fields = IFVF_F_CONFIGURED | IFVF_F_INITIALIZED |
+ IFVF_F_TRAFFIC_ALLOWED | IFVF_F_FAULT_BLOCKED |
+ IFVF_F_LINK_STATE_POLICY |
+ IFVF_F_VLAN_MODE | IFVF_F_VLAN_COUNT |
+ IFVF_F_ALLOW_SET_MAC | IFVF_F_ALLOW_SET_VLAN |
+ IFVF_F_MAC_ANTI_SPOOF | IFVF_F_ALLOW_PROMISC;
+ info->index = i;
+ info->configured =
+ (vf_flags & VF_FLAG_ENABLED) != 0 && vsi != NULL;
+ info->initialized = info->configured &&
+ (vf_flags & VF_FLAG_INITIALIZED) != 0;
+ info->traffic_allowed = info->configured &&
+ (vf_flags & (VF_FLAG_MDD_BLOCKED |
+ VF_FLAG_MBX_BLOCKED)) == 0;
+ info->fault_blocked = (vf_flags & (VF_FLAG_MDD_BLOCKED |
+ VF_FLAG_MBX_BLOCKED)) != 0;
+ info->link_state_policy = IFVF_LINK_AUTO;
+ if (info->initialized) {
+ snprintf(info->api_version, sizeof(info->api_version),
+ "%u.%u", vf->version.major, vf->version.minor);
+ info->fields |= IFVF_F_API_VERSION;
+ }
+ if (!ETHER_IS_ZERO(vf->mac)) {
+ memcpy(info->mac, vf->mac, sizeof(info->mac));
+ info->fields |= IFVF_F_MAC;
+ }
+ /* The ICE IOV schema exposes only VF-managed trunk membership. */
+ info->vlan_mode = IFVF_VLAN_TRUNK;
+ info->vlan_count = vf->vlan_cnt;
+ if (info->configured) {
+ info->vlan_limit = vf->vlan_limit;
+ info->fields |= IFVF_F_VLAN_LIMIT;
+ }
+ if (vsi != NULL) {
+ info->tx_queue_count = vsi->num_tx_queues;
+ info->rx_queue_count = vsi->num_rx_queues;
+ info->fields |= IFVF_F_NUM_TX_QUEUES |
+ IFVF_F_NUM_RX_QUEUES;
+ }
+
+ mirror_configured = vsi != NULL && vsi->mirror_src_vsi !=
+ ICE_INVALID_MIRROR_VSI;
+ software_mbx_limit = !ice_is_e830(&sc->hw);
+ num_fields = ICE_VF_STATUS_NUM_FIELDS -
+ (mirror_configured ? 0 : 1) -
+ (software_mbx_limit ? 0 : 2) -
+ (info->configured ? 0 : 1);
+ extension = if_vf_status_add_extension(info,
+ ICE_VF_STATUS_NAMESPACE, ICE_VF_STATUS_VERSION,
+ num_fields);
+ if (extension == NULL) {
+ if_vf_status_free(status);
+ return (ENOMEM);
+ }
+ field = ICE_VF_STATUS_FIELD_MIRROR_CONFIGURED;
+ if_vf_extension_set_bool(extension, field++,
+ ICE_VF_STATUS_MIRROR_CONFIGURED, mirror_configured);
+ if (mirror_configured)
+ if_vf_extension_set_number(extension, field++,
+ ICE_VF_STATUS_MIRROR_SOURCE_VSI,
+ vsi->mirror_src_vsi);
+ if_vf_extension_set_bool(extension, field++,
+ ICE_VF_STATUS_MIRROR_INGRESS_ACTIVE,
+ vsi != NULL &&
+ vsi->rule_mir_ingress != ICE_INVAL_MIRROR_RULE_ID);
+ if_vf_extension_set_bool(extension, field++,
+ ICE_VF_STATUS_MIRROR_EGRESS_ACTIVE,
+ vsi != NULL &&
+ vsi->rule_mir_egress != ICE_INVAL_MIRROR_RULE_ID);
+ if_vf_extension_set_bool(extension, field++,
+ ICE_VF_STATUS_MDD_BLOCKED,
+ (vf_flags & VF_FLAG_MDD_BLOCKED) != 0);
+ if_vf_extension_set_number(extension, field++,
+ ICE_VF_STATUS_MDD_TX_EVENTS, vf->mdd_tx_events);
+ if_vf_extension_set_number(extension, field++,
+ ICE_VF_STATUS_MDD_RX_EVENTS, vf->mdd_rx_events);
+ if (software_mbx_limit) {
+ if_vf_extension_set_bool(extension, field++,
+ ICE_VF_STATUS_MBX_BLOCKED,
+ (vf_flags & VF_FLAG_MBX_BLOCKED) != 0);
+ if_vf_extension_set_number(extension, field++,
+ ICE_VF_STATUS_MBX_OVERFLOW_EVENTS,
+ vf->mbx_overflow_events);
+ }
+ if_vf_extension_set_number(extension, field++,
+ ICE_VF_STATUS_MAC_FILTER_COUNT, vf->mac_filter_cnt);
+ if (info->configured)
+ if_vf_extension_set_number(extension, field++,
+ ICE_VF_STATUS_MAC_FILTER_LIMIT, vf->mac_filter_limit);
+ if_vf_extension_set_bool(extension, field++,
+ ICE_VF_STATUS_RESET_FAILED,
+ (vf_flags & VF_FLAG_RESET_FAILED) != 0);
+ if_vf_extension_set_bool(extension, field++,
+ ICE_VF_STATUS_REBUILD_REQUIRED,
+ (vf_flags & VF_FLAG_REBUILD_REQUIRED) != 0);
+ KASSERT(field == num_fields,
+ ("ICE VF status field count %u != %u", field, num_fields));
+ info->allow_set_mac = (vf_flags & VF_FLAG_SET_MAC_CAP) != 0;
+ info->allow_set_vlan = (vf_flags & VF_FLAG_VLAN_CAP) != 0;
+ info->mac_anti_spoof =
+ (vf_flags & VF_FLAG_MAC_ANTI_SPOOF) != 0;
+ info->allow_promisc = (vf_flags & VF_FLAG_PROMISC_CAP) != 0;
+ }
+ *statusp = status;
+ return (0);
+}
+
/**
* ice_iov_uninit - Called by the OS when VFs are destroyed
* @sc: device softc structure
@@ -722,7 +897,7 @@
continue;
vf_flags = atomic_load_acq_32(&vf->vf_flags);
if ((vf_flags & VF_FLAG_ENABLED) != 0 && vf->vsi != NULL) {
- if ((vf_flags & VF_FLAG_REBUILD_FAILED) != 0) {
+ if ((vf_flags & VF_FLAG_REBUILD_REQUIRED) != 0) {
/* Consume the event but leave the invalid VF held. */
wr32(hw, GLGEN_VFLRSTAT(reg_idx), BIT(bit_idx));
ice_flush(hw);
@@ -996,7 +1171,7 @@
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);
+ atomic_set_32(&vf->vf_flags, VF_FLAG_REBUILD_REQUIRED);
ice_iov_clear_vf_queue_state(vf);
ICE_IOV_FAIL_POINT(sc, vf->vf_num, rebuild_before_initialize, error,
fail);
@@ -1025,7 +1200,7 @@
}
atomic_clear_32(&vf->vf_flags,
- VF_FLAG_REBUILD_FAILED | VF_FLAG_RESET_FAILED);
+ VF_FLAG_REBUILD_REQUIRED | VF_FLAG_RESET_FAILED);
ice_iov_ready_vf(sc, vf);
return (0);
@@ -1064,7 +1239,7 @@
/* A VFR cannot recover PF-owned VSI state lost during PF rebuild. */
if (release_vf && (atomic_load_acq_32(&vf->vf_flags) &
- VF_FLAG_REBUILD_FAILED) != 0)
+ VF_FLAG_REBUILD_REQUIRED) != 0)
return (EIO);
global_vf_num = vf->vf_num + hw->func_caps.vf_base_id;
@@ -1234,7 +1409,7 @@
/* Block mailbox reconfiguration before asserting reset. */
atomic_clear_32(&vf->vf_flags, VF_FLAG_INITIALIZED);
- atomic_set_32(&vf->vf_flags, VF_FLAG_REBUILD_FAILED);
+ atomic_set_32(&vf->vf_flags, VF_FLAG_REBUILD_REQUIRED);
reg = rd32(hw, VPGEN_VFRTRIG(vf->vf_num));
reg |= VPGEN_VFRTRIG_VFSWR_M;
wr32(hw, VPGEN_VFRTRIG(vf->vf_num), reg);
@@ -2889,9 +3064,9 @@
/*
* Permit only reset negotiation while VF hardware state is unsafe.
- * A VFR can retry RESET_FAILED; REBUILD_FAILED requires a PF rebuild.
+ * A VFR can retry RESET_FAILED; REBUILD_REQUIRED needs a PF rebuild.
*/
- if ((vf_flags & (VF_FLAG_REBUILD_FAILED | VF_FLAG_RESET_FAILED)) != 0 &&
+ if ((vf_flags & (VF_FLAG_REBUILD_REQUIRED | 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,
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
@@ -93,6 +93,7 @@
static int ice_if_iov_init(if_ctx_t ctx, uint16_t num_vfs, const nvlist_t *params);
static void ice_if_iov_uninit(if_ctx_t ctx);
static int ice_if_iov_vf_add(if_ctx_t ctx, uint16_t vfnum, const nvlist_t *params);
+static int ice_if_vf_status(if_ctx_t ctx, struct if_vf_status **statusp);
static void ice_if_vflr_handle(if_ctx_t ctx);
#endif
static int ice_setup_mirror_vsi(struct ice_mirr_if *mif);
@@ -220,6 +221,7 @@
DEVMETHOD(ifdi_iov_vf_add, ice_if_iov_vf_add),
DEVMETHOD(ifdi_iov_init, ice_if_iov_init),
DEVMETHOD(ifdi_iov_uninit, ice_if_iov_uninit),
+ DEVMETHOD(ifdi_vf_status, ice_if_vf_status),
DEVMETHOD(ifdi_vflr_handle, ice_if_vflr_handle),
#endif
DEVMETHOD_END
@@ -2613,6 +2615,21 @@
if (error != 0)
device_printf(sc->dev,
"Failed to quiesce one or more VFs: %d\n", error);
+ } else {
+ /*
+ * Hardware has already gated the VFs. Invalidate their cached
+ * handshake before dropping CTX_LOCK to wait for reset, even if
+ * rebuilding later fails before reaching the VF VSIs.
+ */
+ for (int i = 0; i < sc->num_vfs; i++) {
+ struct ice_vf *vf = &sc->vfs[i];
+
+ if ((atomic_load_acq_32(&vf->vf_flags) &
+ VF_FLAG_ENABLED) == 0 || vf->vsi == NULL)
+ continue;
+ atomic_clear_32(&vf->vf_flags, VF_FLAG_INITIALIZED);
+ atomic_set_32(&vf->vf_flags, VF_FLAG_REBUILD_REQUIRED);
+ }
}
#endif
@@ -3635,6 +3652,19 @@
return ice_iov_add_vf(sc, vfnum, params);
}
+/**
+ * ice_if_vf_status - report configured VF state
+ * @ctx: iflib context pointer
+ * @statusp: returned VF status snapshot
+ */
+static int
+ice_if_vf_status(if_ctx_t ctx, struct if_vf_status **statusp)
+{
+ struct ice_softc *sc = (struct ice_softc *)iflib_get_softc(ctx);
+
+ return (ice_iov_vf_status(sc, statusp));
+}
+
/**
* ice_if_vflr_handle - iov VFLR handler
* @ctx: iflib context pointer
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Oct 4, 12:48 AM (7 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40157993
Default Alt Text
D58739.id187024.diff (15 KB)
Attached To
Mode
D58739: ice: Report SR-IOV VF status
Attached
Detach File
Event Timeline
Log In to Comment