Date: Fri, 07 Aug 2026 08:14:45 +0000 From: Kevin Bowling <kbowling@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 703c756a2d29 - main - ixgbe: Validate SR-IOV before restarting the PF Message-ID: <6a7593f5.44de9.3ab4256f@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=703c756a2d298e5841471eb7d4d40f95a0dafe50 commit 703c756a2d298e5841471eb7d4d40f95a0dafe50 Author: Kevin Bowling <kbowling@FreeBSD.org> AuthorDate: 2026-08-06 11:05:32 +0000 Commit: Kevin Bowling <kbowling@FreeBSD.org> CommitDate: 2026-08-07 08:05:26 +0000 ixgbe: Validate SR-IOV before restarting the PF A deterministic IOV configuration error currently reaches the driver only after iflib has stopped the PF. The required cleanup restart then causes an avoidable carrier flap. Follow the igb pattern and validate the request in the PCI IOV method before entering the restart transaction. Reject queue layouts wider than the selected virtualization pool before they can alias unrelated 82599 registers. MFC after: 2 weeks --- sys/dev/ixgbe/if_ix.c | 23 +++++++++++++++- sys/dev/ixgbe/if_sriov.c | 67 +++++++++++++++++++++++++++++++++------------ sys/dev/ixgbe/ixgbe_sriov.h | 1 + 3 files changed, 73 insertions(+), 18 deletions(-) diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c index 38029e3ec895..f800be109fc3 100644 --- a/sys/dev/ixgbe/if_ix.c +++ b/sys/dev/ixgbe/if_ix.c @@ -169,6 +169,9 @@ static int ixgbe_if_detach(if_ctx_t); static int ixgbe_if_shutdown(if_ctx_t); static int ixgbe_if_suspend(if_ctx_t); static int ixgbe_if_resume(if_ctx_t); +#ifdef PCI_IOV +static int ixgbe_device_iov_init(device_t, uint16_t, const nvlist_t *); +#endif static void ixgbe_if_stop(if_ctx_t); void ixgbe_if_enable_intr(if_ctx_t); @@ -297,7 +300,7 @@ static device_method_t ix_methods[] = { DEVMETHOD(device_suspend, iflib_device_suspend), DEVMETHOD(device_resume, iflib_device_resume), #ifdef PCI_IOV - DEVMETHOD(pci_iov_init, iflib_device_iov_init_restart), + DEVMETHOD(pci_iov_init, ixgbe_device_iov_init), DEVMETHOD(pci_iov_uninit, iflib_device_iov_uninit_restart), DEVMETHOD(pci_iov_add_vf, iflib_device_iov_add_vf), #endif /* PCI_IOV */ @@ -320,6 +323,24 @@ MODULE_DEPEND(ix, ether, 1, 1, 1); MODULE_DEPEND(ix, iflib, 1, 1, 1); MODULE_DEPEND(ix, mdio, 1, 1, 1); +#ifdef PCI_IOV +static int +ixgbe_device_iov_init(device_t dev, uint16_t num_vfs, + const nvlist_t *params) +{ + struct ixgbe_softc *sc; + if_ctx_t ctx; + int error; + + ctx = device_get_softc(dev); + sc = iflib_get_softc(ctx); + error = ixgbe_iov_validate(sc, num_vfs); + if (error != 0) + return (error); + return (iflib_device_iov_init_restart(dev, num_vfs, params)); +} +#endif + static device_method_t ixgbe_if_methods[] = { DEVMETHOD(ifdi_attach_pre, ixgbe_if_attach_pre), DEVMETHOD(ifdi_attach_post, ixgbe_if_attach_post), diff --git a/sys/dev/ixgbe/if_sriov.c b/sys/dev/ixgbe/if_sriov.c index c05b82533081..b2325046d5e8 100644 --- a/sys/dev/ixgbe/if_sriov.c +++ b/sys/dev/ixgbe/if_sriov.c @@ -1028,18 +1028,20 @@ ixgbe_handle_mbx(void *context) } /* ixgbe_handle_mbx */ int -ixgbe_if_iov_init(if_ctx_t ctx, u16 num_vfs, const nvlist_t *config) +ixgbe_iov_validate(struct ixgbe_softc *sc, u16 num_vfs) { - struct ixgbe_softc *sc; - int i, num_filters, retval = 0; - - sc = iflib_get_softc(ctx); - sc->iov_mode = IXGBE_NO_VM; + int mode, pool, queue_count; - if (num_vfs == 0) { - /* Would we ever get num_vfs = 0? */ - retval = EINVAL; - goto err_init_iov; + if (!(sc->feat_cap & IXGBE_FEATURE_SRIOV)) + return (ENXIO); + if (num_vfs == 0) + return (EINVAL); + if (sc->vfs != NULL || sc->vf_mac_filters != NULL || + (sc->feat_en & IXGBE_FEATURE_SRIOV)) + return (EBUSY); + if (sc->intr_type != IFLIB_INTR_MSIX) { + device_printf(sc->dev, "SR-IOV requires MSI-X\n"); + return (ENOTSUP); } /* @@ -1049,17 +1051,43 @@ ixgbe_if_iov_init(if_ctx_t ctx, u16 num_vfs, const nvlist_t *config) * With 32 VFs, you can have up to four queues per VF. */ if (num_vfs >= IXGBE_32_VM) - sc->iov_mode = IXGBE_64_VM; + mode = IXGBE_64_VM; else - sc->iov_mode = IXGBE_32_VM; + mode = IXGBE_32_VM; + queue_count = ixgbe_vf_queues(mode); + if (sc->num_rx_queues > queue_count || + sc->num_tx_queues > queue_count) { + device_printf(sc->dev, + "SR-IOV mode supports %d PF queues, but %d RX and %d TX " + "queues are allocated\n", queue_count, sc->num_rx_queues, + sc->num_tx_queues); + return (ENOSPC); + } /* Again, reserving 1 VM's worth of queues for the PF */ - sc->pool = sc->iov_mode - 1; + pool = mode - 1; + if (num_vfs > pool || num_vfs >= IXGBE_64_VM) + return (ENOSPC); + return (0); +} - if ((num_vfs > sc->pool) || (num_vfs >= IXGBE_64_VM)) { - retval = ENOSPC; - goto err_init_iov; - } +int +ixgbe_if_iov_init(if_ctx_t ctx, u16 num_vfs, const nvlist_t *config) +{ + struct ixgbe_softc *sc; + int i, num_filters, retval; + + (void)config; + sc = iflib_get_softc(ctx); + retval = ixgbe_iov_validate(sc, num_vfs); + if (retval != 0) + return (retval); + + if (num_vfs >= IXGBE_32_VM) + sc->iov_mode = IXGBE_64_VM; + else + sc->iov_mode = IXGBE_32_VM; + sc->pool = sc->iov_mode - 1; sc->vfs = malloc(sizeof(*sc->vfs) * num_vfs, M_IXGBE_SRIOV, M_NOWAIT | M_ZERO); @@ -1093,6 +1121,11 @@ ixgbe_if_iov_init(if_ctx_t ctx, u16 num_vfs, const nvlist_t *config) return (retval); err_init_iov: + free(sc->vf_mac_filters, M_IXGBE_SRIOV); + sc->vf_mac_filters = NULL; + sc->num_vf_mac_filters = 0; + free(sc->vfs, M_IXGBE_SRIOV); + sc->vfs = NULL; sc->num_vfs = 0; sc->pool = 0; sc->iov_mode = IXGBE_NO_VM; diff --git a/sys/dev/ixgbe/ixgbe_sriov.h b/sys/dev/ixgbe/ixgbe_sriov.h index c38f4075b97a..443bf78e9a1d 100644 --- a/sys/dev/ixgbe/ixgbe_sriov.h +++ b/sys/dev/ixgbe/ixgbe_sriov.h @@ -74,6 +74,7 @@ int ixgbe_if_iov_vf_add(if_ctx_t, u16, const nvlist_t *); int ixgbe_if_iov_init(if_ctx_t, u16, const nvlist_t *); +int ixgbe_iov_validate(struct ixgbe_softc *, u16); void ixgbe_if_iov_uninit(if_ctx_t); void ixgbe_initialize_iov(struct ixgbe_softc *); void ixgbe_recalculate_max_frame(struct ixgbe_softc *);home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a7593f5.44de9.3ab4256f>
