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"

Reply via email to