Author: erj Date: Thu May 14 19:56:54 2020 New Revision: 361053 URL: https://svnweb.freebsd.org/changeset/base/361053
Log: MFC r360398 and r360902 These commits introduce a new iflib device-dependent method and implements that method in the Intel ethernet network drivers; this method tells iflib if the network interface needs to be restarted when certain events happen. This fixes several issues that occur when VLANs are registered or unregistered with the network interface. PR: 240818, 241785 Sponsored by: Intel Corporation Modified: stable/12/sys/dev/e1000/if_em.c stable/12/sys/dev/ixgbe/if_ix.c stable/12/sys/dev/ixgbe/if_ixv.c stable/12/sys/dev/ixl/if_iavf.c stable/12/sys/dev/ixl/if_ixl.c stable/12/sys/net/ifdi_if.m stable/12/sys/net/iflib.c stable/12/sys/net/iflib.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/dev/e1000/if_em.c ============================================================================== --- stable/12/sys/dev/e1000/if_em.c Thu May 14 19:56:16 2020 (r361052) +++ stable/12/sys/dev/e1000/if_em.c Thu May 14 19:56:54 2020 (r361053) @@ -251,6 +251,7 @@ static void em_if_timer(if_ctx_t ctx, uint16_t qid); static void em_if_vlan_register(if_ctx_t ctx, u16 vtag); static void em_if_vlan_unregister(if_ctx_t ctx, u16 vtag); static void em_if_watchdog_reset(if_ctx_t ctx); +static bool em_if_needs_restart(if_ctx_t ctx, enum iflib_restart_event event); static void em_identify_hardware(if_ctx_t ctx); static int em_allocate_pci_resources(if_ctx_t ctx); @@ -400,6 +401,7 @@ static device_method_t em_if_methods[] = { DEVMETHOD(ifdi_rx_queue_intr_enable, em_if_rx_queue_intr_enable), DEVMETHOD(ifdi_tx_queue_intr_enable, em_if_tx_queue_intr_enable), DEVMETHOD(ifdi_debug, em_if_debug), + DEVMETHOD(ifdi_needs_restart, em_if_needs_restart), DEVMETHOD_END }; @@ -437,6 +439,7 @@ static device_method_t igb_if_methods[] = { DEVMETHOD(ifdi_rx_queue_intr_enable, igb_if_rx_queue_intr_enable), DEVMETHOD(ifdi_tx_queue_intr_enable, igb_if_tx_queue_intr_enable), DEVMETHOD(ifdi_debug, em_if_debug), + DEVMETHOD(ifdi_needs_restart, em_if_needs_restart), DEVMETHOD_END }; @@ -4018,6 +4021,25 @@ em_if_get_counter(if_ctx_t ctx, ift_counter cnt) adapter->watchdog_events); default: return (if_get_counter_default(ifp, cnt)); + } +} + +/* em_if_needs_restart - Tell iflib when the driver needs to be reinitialized + * @ctx: iflib context + * @event: event code to check + * + * Defaults to returning true for unknown events. + * + * @returns true if iflib needs to reinit the interface + */ +static bool +em_if_needs_restart(if_ctx_t ctx __unused, enum iflib_restart_event event) +{ + switch (event) { + case IFLIB_RESTART_VLAN_CONFIG: + return (false); + default: + return (true); } } Modified: stable/12/sys/dev/ixgbe/if_ix.c ============================================================================== --- stable/12/sys/dev/ixgbe/if_ix.c Thu May 14 19:56:16 2020 (r361052) +++ stable/12/sys/dev/ixgbe/if_ix.c Thu May 14 19:56:54 2020 (r361053) @@ -139,6 +139,7 @@ static void ixgbe_if_update_admin_status(if_ctx_t ctx) static void ixgbe_if_vlan_register(if_ctx_t ctx, u16 vtag); static void ixgbe_if_vlan_unregister(if_ctx_t ctx, u16 vtag); static int ixgbe_if_i2c_req(if_ctx_t ctx, struct ifi2creq *req); +static bool ixgbe_if_needs_restart(if_ctx_t ctx, enum iflib_restart_event event); int ixgbe_intr(void *arg); /************************************************************************ @@ -273,6 +274,7 @@ static device_method_t ixgbe_if_methods[] = { DEVMETHOD(ifdi_vlan_unregister, ixgbe_if_vlan_unregister), DEVMETHOD(ifdi_get_counter, ixgbe_if_get_counter), DEVMETHOD(ifdi_i2c_req, ixgbe_if_i2c_req), + DEVMETHOD(ifdi_needs_restart, ixgbe_if_needs_restart), #ifdef PCI_IOV DEVMETHOD(ifdi_iov_init, ixgbe_if_iov_init), DEVMETHOD(ifdi_iov_uninit, ixgbe_if_iov_uninit), @@ -1232,6 +1234,25 @@ ixgbe_if_i2c_req(if_ctx_t ctx, struct ifi2creq *req) req->dev_addr, &req->data[i]); return (0); } /* ixgbe_if_i2c_req */ + +/* ixgbe_if_needs_restart - Tell iflib when the driver needs to be reinitialized + * @ctx: iflib context + * @event: event code to check + * + * Defaults to returning true for unknown events. + * + * @returns true if iflib needs to reinit the interface + */ +static bool +ixgbe_if_needs_restart(if_ctx_t ctx __unused, enum iflib_restart_event event) +{ + switch (event) { + case IFLIB_RESTART_VLAN_CONFIG: + return (false); + default: + return (true); + } +} /************************************************************************ * ixgbe_add_media_types Modified: stable/12/sys/dev/ixgbe/if_ixv.c ============================================================================== --- stable/12/sys/dev/ixgbe/if_ixv.c Thu May 14 19:56:16 2020 (r361052) +++ stable/12/sys/dev/ixgbe/if_ixv.c Thu May 14 19:56:54 2020 (r361053) @@ -110,6 +110,7 @@ static void ixv_if_register_vlan(if_ctx_t, u16); static void ixv_if_unregister_vlan(if_ctx_t, u16); static uint64_t ixv_if_get_counter(if_ctx_t, ift_counter); +static bool ixv_if_needs_restart(if_ctx_t, enum iflib_restart_event); static void ixv_save_stats(struct adapter *); static void ixv_init_stats(struct adapter *); @@ -172,6 +173,7 @@ static device_method_t ixv_if_methods[] = { DEVMETHOD(ifdi_vlan_register, ixv_if_register_vlan), DEVMETHOD(ifdi_vlan_unregister, ixv_if_unregister_vlan), DEVMETHOD(ifdi_get_counter, ixv_if_get_counter), + DEVMETHOD(ifdi_needs_restart, ixv_if_needs_restart), DEVMETHOD_END }; @@ -1189,6 +1191,25 @@ ixv_if_get_counter(if_ctx_t ctx, ift_counter cnt) return (if_get_counter_default(ifp, cnt)); } } /* ixv_if_get_counter */ + +/* ixv_if_needs_restart - Tell iflib when the driver needs to be reinitialized + * @ctx: iflib context + * @event: event code to check + * + * Defaults to returning true for every event. + * + * @returns true if iflib needs to reinit the interface + */ +static bool +ixv_if_needs_restart(if_ctx_t ctx __unused, enum iflib_restart_event event) +{ + switch (event) { + case IFLIB_RESTART_VLAN_CONFIG: + /* XXX: This may not need to return true */ + default: + return (true); + } +} /************************************************************************ * ixv_initialize_transmit_units - Enable transmit unit. Modified: stable/12/sys/dev/ixl/if_iavf.c ============================================================================== --- stable/12/sys/dev/ixl/if_iavf.c Thu May 14 19:56:16 2020 (r361052) +++ stable/12/sys/dev/ixl/if_iavf.c Thu May 14 19:56:54 2020 (r361053) @@ -92,6 +92,7 @@ static void iavf_if_vlan_register(if_ctx_t ctx, u16 v static void iavf_if_vlan_unregister(if_ctx_t ctx, u16 vtag); static uint64_t iavf_if_get_counter(if_ctx_t ctx, ift_counter cnt); static void iavf_if_stop(if_ctx_t ctx); +static bool iavf_if_needs_restart(if_ctx_t ctx, enum iflib_restart_event event); static int iavf_allocate_pci_resources(struct iavf_sc *); static int iavf_reset_complete(struct i40e_hw *); @@ -190,6 +191,7 @@ static device_method_t iavf_if_methods[] = { DEVMETHOD(ifdi_vlan_register, iavf_if_vlan_register), DEVMETHOD(ifdi_vlan_unregister, iavf_if_vlan_unregister), DEVMETHOD(ifdi_get_counter, iavf_if_get_counter), + DEVMETHOD(ifdi_needs_restart, iavf_if_needs_restart), DEVMETHOD_END }; @@ -1474,7 +1476,27 @@ iavf_if_get_counter(if_ctx_t ctx, ift_counter cnt) } } - +/* iavf_if_needs_restart - Tell iflib when the driver needs to be reinitialized + * @ctx: iflib context + * @event: event code to check + * + * Defaults to returning true for every event. + * + * @returns true if iflib needs to reinit the interface + */ +static bool +iavf_if_needs_restart(if_ctx_t ctx __unused, enum iflib_restart_event event) +{ + switch (event) { + case IFLIB_RESTART_VLAN_CONFIG: + /* This case must return true if VLAN anti-spoof checks are + * enabled by the PF driver for the VF. + */ + default: + return (true); + } +} + static void iavf_free_pci_resources(struct iavf_sc *sc) { Modified: stable/12/sys/dev/ixl/if_ixl.c ============================================================================== --- stable/12/sys/dev/ixl/if_ixl.c Thu May 14 19:56:16 2020 (r361052) +++ stable/12/sys/dev/ixl/if_ixl.c Thu May 14 19:56:54 2020 (r361053) @@ -117,6 +117,7 @@ static void ixl_if_vlan_unregister(if_ctx_t ctx, u16 static uint64_t ixl_if_get_counter(if_ctx_t ctx, ift_counter cnt); static int ixl_if_i2c_req(if_ctx_t ctx, struct ifi2creq *req); static int ixl_if_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data); +static bool ixl_if_needs_restart(if_ctx_t ctx, enum iflib_restart_event event); #ifdef PCI_IOV static void ixl_if_vflr_handle(if_ctx_t ctx); #endif @@ -187,6 +188,7 @@ static device_method_t ixl_if_methods[] = { DEVMETHOD(ifdi_get_counter, ixl_if_get_counter), DEVMETHOD(ifdi_i2c_req, ixl_if_i2c_req), DEVMETHOD(ifdi_priv_ioctl, ixl_if_priv_ioctl), + DEVMETHOD(ifdi_needs_restart, ixl_if_needs_restart), #ifdef PCI_IOV DEVMETHOD(ifdi_iov_init, ixl_if_iov_init), DEVMETHOD(ifdi_iov_uninit, ixl_if_iov_uninit), @@ -1650,6 +1652,24 @@ ixl_if_priv_ioctl(if_ctx_t ctx, u_long command, caddr_ } return (error); +} + +/* ixl_if_needs_restart - Tell iflib when the driver needs to be reinitialized + * @ctx: iflib context + * @event: event code to check + * + * Defaults to returning false for every event. + * + * @returns true if iflib needs to reinit the interface, false otherwise + */ +static bool +ixl_if_needs_restart(if_ctx_t ctx __unused, enum iflib_restart_event event) +{ + switch (event) { + case IFLIB_RESTART_VLAN_CONFIG: + default: + return (false); + } } static int Modified: stable/12/sys/net/ifdi_if.m ============================================================================== --- stable/12/sys/net/ifdi_if.m Thu May 14 19:56:16 2020 (r361052) +++ stable/12/sys/net/ifdi_if.m Thu May 14 19:56:54 2020 (r361053) @@ -169,6 +169,12 @@ CODE { } return (0); } + + static bool + null_needs_restart(if_ctx_t _ctx __unused, enum iflib_restart_event _event __unused) + { + return (true); + } }; # @@ -456,3 +462,8 @@ METHOD int sysctl_int_delay { METHOD void debug { if_ctx_t _ctx; } DEFAULT null_void_op; + +METHOD bool needs_restart { + if_ctx_t _ctx; + enum iflib_restart_event _event; +} DEFAULT null_needs_restart; Modified: stable/12/sys/net/iflib.c ============================================================================== --- stable/12/sys/net/iflib.c Thu May 14 19:56:16 2020 (r361052) +++ stable/12/sys/net/iflib.c Thu May 14 19:56:54 2020 (r361053) @@ -4297,10 +4297,13 @@ iflib_vlan_register(void *arg, if_t ifp, uint16_t vtag return; CTX_LOCK(ctx); + /* Driver may need all untagged packets to be flushed */ + if (IFDI_NEEDS_RESTART(ctx, IFLIB_RESTART_VLAN_CONFIG)) + iflib_stop(ctx); IFDI_VLAN_REGISTER(ctx, vtag); - /* Re-init to load the changes */ - if (if_getcapenable(ifp) & IFCAP_VLAN_HWFILTER) - iflib_if_init_locked(ctx); + /* Re-init to load the changes, if required */ + if (IFDI_NEEDS_RESTART(ctx, IFLIB_RESTART_VLAN_CONFIG)) + iflib_init_locked(ctx); CTX_UNLOCK(ctx); } @@ -4316,10 +4319,13 @@ iflib_vlan_unregister(void *arg, if_t ifp, uint16_t vt return; CTX_LOCK(ctx); + /* Driver may need all tagged packets to be flushed */ + if (IFDI_NEEDS_RESTART(ctx, IFLIB_RESTART_VLAN_CONFIG)) + iflib_stop(ctx); IFDI_VLAN_UNREGISTER(ctx, vtag); - /* Re-init to load the changes */ - if (if_getcapenable(ifp) & IFCAP_VLAN_HWFILTER) - iflib_if_init_locked(ctx); + /* Re-init to load the changes, if required */ + if (IFDI_NEEDS_RESTART(ctx, IFLIB_RESTART_VLAN_CONFIG)) + iflib_init_locked(ctx); CTX_UNLOCK(ctx); } Modified: stable/12/sys/net/iflib.h ============================================================================== --- stable/12/sys/net/iflib.h Thu May 14 19:56:16 2020 (r361052) +++ stable/12/sys/net/iflib.h Thu May 14 19:56:54 2020 (r361053) @@ -369,6 +369,15 @@ typedef enum { /* + * These enum values are used in iflib_needs_restart to indicate to iflib + * functions whether or not the interface needs restarting when certain events + * happen. + */ +enum iflib_restart_event { + IFLIB_RESTART_VLAN_CONFIG, +}; + +/* * field accessors */ void *iflib_get_softc(if_ctx_t ctx); _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"