ixgbe: Fix limitations on macvlan so we can support up to 63 offloaded devices
authorAlexander Duyck <alexander.h.duyck@intel.com>
Wed, 22 Nov 2017 18:56:40 +0000 (10:56 -0800)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Tue, 9 Jan 2018 16:49:04 +0000 (08:49 -0800)
This change is a fix of the macvlan offload so that we correctly handle
macvlan offloaded devices. Specifically we were configuring our limits based
on the assumption that we were going to max out the RSS indices for every
mode. As a result when we went to 15 or more macvlan interfaces we were
forced into the 2 queue RSS mode on VFs even though they could have still
supported 4.

This change splits the logic up so that we limit either the total number of
macvlan instances if DCB is enabled, or limit the number of RSS queues used
per macvlan (instead of per pool) if SR-IOV is enabled. By doing this we
can make best use of the part.

In addition I have increased the maximum number of supported interfaces to
63 with one queue per offloaded interface as this more closely reflects the
actual values supported by the interface.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/ixgbe/ixgbe.h
drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c

index 08fb589399d28e4f36c27c0b948ae42483ea75cc..f656f2bdc570857203a2ddb70ab686637ba74e78 100644 (file)
@@ -397,8 +397,7 @@ enum ixgbe_ring_f_enum {
 #define MAX_XDP_QUEUES                 (IXGBE_MAX_FDIR_INDICES + 1)
 #define IXGBE_MAX_L2A_QUEUES           4
 #define IXGBE_BAD_L2A_QUEUE            3
-#define IXGBE_MAX_MACVLANS             31
-#define IXGBE_MAX_DCBMACVLANS          8
+#define IXGBE_MAX_MACVLANS             63
 
 struct ixgbe_ring_feature {
        u16 limit;      /* upper limit on feature indices */
@@ -767,7 +766,8 @@ struct ixgbe_adapter {
 #endif /*CONFIG_DEBUG_FS*/
 
        u8 default_up;
-       unsigned long fwd_bitmask; /* Bitmask indicating in use pools */
+       /* Bitmask indicating in use pools */
+       DECLARE_BITMAP(fwd_bitmask, IXGBE_MAX_MACVLANS + 1);
 
 #define IXGBE_MAX_LINK_HANDLE 10
        struct ixgbe_jump_table *jump_tables[IXGBE_MAX_LINK_HANDLE];
index 56622adc76dc3b74ed1f9642b3d62a774b8d28e5..cceafbc3f1db48c1632ab1058e8ea1952a8a2eb4 100644 (file)
@@ -350,6 +350,9 @@ static bool ixgbe_set_dcb_sriov_queues(struct ixgbe_adapter *adapter)
        if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
                return false;
 
+       /* limit VMDq instances on the PF by number of Tx queues */
+       vmdq_i = min_t(u16, vmdq_i, MAX_TX_QUEUES / tcs);
+
        /* Add starting offset to total pool count */
        vmdq_i += adapter->ring_feature[RING_F_VMDQ].offset;
 
@@ -512,12 +515,14 @@ static bool ixgbe_set_sriov_queues(struct ixgbe_adapter *adapter)
 #ifdef IXGBE_FCOE
        u16 fcoe_i = 0;
 #endif
-       bool pools = (find_first_zero_bit(&adapter->fwd_bitmask, 32) > 1);
 
        /* only proceed if SR-IOV is enabled */
        if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
                return false;
 
+       /* limit l2fwd RSS based on total Tx queue limit */
+       rss_i = min_t(u16, rss_i, MAX_TX_QUEUES / vmdq_i);
+
        /* Add starting offset to total pool count */
        vmdq_i += adapter->ring_feature[RING_F_VMDQ].offset;
 
@@ -525,7 +530,7 @@ static bool ixgbe_set_sriov_queues(struct ixgbe_adapter *adapter)
        vmdq_i = min_t(u16, IXGBE_MAX_VMDQ_INDICES, vmdq_i);
 
        /* 64 pool mode with 2 queues per pool */
-       if ((vmdq_i > 32) || (vmdq_i > 16 && pools)) {
+       if (vmdq_i > 32) {
                vmdq_m = IXGBE_82599_VMDQ_2Q_MASK;
                rss_m = IXGBE_RSS_2Q_MASK;
                rss_i = min_t(u16, rss_i, 2);
index 4efb2b078f20b6071967e54ff659276c41cfce8d..144674c6c2939b08f4451223ee027e9dbb197165 100644 (file)
@@ -5379,14 +5379,13 @@ static int ixgbe_fwd_ring_up(struct net_device *vdev,
        unsigned int rxbase, txbase, queues;
        int i, baseq, err = 0;
 
-       if (!test_bit(accel->pool, &adapter->fwd_bitmask))
+       if (!test_bit(accel->pool, adapter->fwd_bitmask))
                return 0;
 
        baseq = accel->pool * adapter->num_rx_queues_per_pool;
-       netdev_dbg(vdev, "pool %i:%i queues %i:%i VSI bitmask %lx\n",
+       netdev_dbg(vdev, "pool %i:%i queues %i:%i\n",
                   accel->pool, adapter->num_rx_pools,
-                  baseq, baseq + adapter->num_rx_queues_per_pool,
-                  adapter->fwd_bitmask);
+                  baseq, baseq + adapter->num_rx_queues_per_pool);
 
        accel->netdev = vdev;
        accel->rx_base_queue = rxbase = baseq;
@@ -6284,7 +6283,7 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter,
        }
 
        /* PF holds first pool slot */
-       set_bit(0, &adapter->fwd_bitmask);
+       set_bit(0, adapter->fwd_bitmask);
        set_bit(__IXGBE_DOWN, &adapter->state);
 
        return 0;
@@ -8856,7 +8855,6 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
 {
        struct ixgbe_adapter *adapter = netdev_priv(dev);
        struct ixgbe_hw *hw = &adapter->hw;
-       bool pools;
 
        /* Hardware supports up to 8 traffic classes */
        if (tc > adapter->dcb_cfg.num_tcs.pg_tcs)
@@ -8865,10 +8863,6 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
        if (hw->mac.type == ixgbe_mac_82598EB && tc && tc < MAX_TRAFFIC_CLASS)
                return -EINVAL;
 
-       pools = (find_first_zero_bit(&adapter->fwd_bitmask, 32) > 1);
-       if (tc && pools && adapter->num_rx_pools > IXGBE_MAX_DCBMACVLANS)
-               return -EBUSY;
-
        /* Hardware has to reinitialize queues and interrupts to
         * match packet buffer alignment. Unfortunately, the
         * hardware is not flexible enough to do this dynamically.
@@ -9807,6 +9801,7 @@ static void *ixgbe_fwd_add(struct net_device *pdev, struct net_device *vdev)
        struct ixgbe_fwd_adapter *fwd_adapter = NULL;
        struct ixgbe_adapter *adapter = netdev_priv(pdev);
        int used_pools = adapter->num_vfs + adapter->num_rx_pools;
+       int tcs = netdev_get_num_tc(pdev) ? : 1;
        unsigned int limit;
        int pool, err;
 
@@ -9834,7 +9829,7 @@ static void *ixgbe_fwd_add(struct net_device *pdev, struct net_device *vdev)
        }
 
        if (((adapter->flags & IXGBE_FLAG_DCB_ENABLED) &&
-             adapter->num_rx_pools > IXGBE_MAX_DCBMACVLANS - 1) ||
+             adapter->num_rx_pools >= (MAX_TX_QUEUES / tcs)) ||
            (adapter->num_rx_pools > IXGBE_MAX_MACVLANS))
                return ERR_PTR(-EBUSY);
 
@@ -9842,9 +9837,9 @@ static void *ixgbe_fwd_add(struct net_device *pdev, struct net_device *vdev)
        if (!fwd_adapter)
                return ERR_PTR(-ENOMEM);
 
-       pool = find_first_zero_bit(&adapter->fwd_bitmask, 32);
-       set_bit(pool, &adapter->fwd_bitmask);
-       limit = find_last_bit(&adapter->fwd_bitmask, 32);
+       pool = find_first_zero_bit(adapter->fwd_bitmask, adapter->num_rx_pools);
+       set_bit(pool, adapter->fwd_bitmask);
+       limit = find_last_bit(adapter->fwd_bitmask, adapter->num_rx_pools + 1);
 
        /* Enable VMDq flag so device will be set in VM mode */
        adapter->flags |= IXGBE_FLAG_VMDQ_ENABLED | IXGBE_FLAG_SRIOV_ENABLED;
@@ -9870,7 +9865,7 @@ fwd_add_err:
        /* unwind counter and free adapter struct */
        netdev_info(pdev,
                    "%s: dfwd hardware acceleration failed\n", vdev->name);
-       clear_bit(pool, &adapter->fwd_bitmask);
+       clear_bit(pool, adapter->fwd_bitmask);
        kfree(fwd_adapter);
        return ERR_PTR(err);
 }
@@ -9881,9 +9876,9 @@ static void ixgbe_fwd_del(struct net_device *pdev, void *priv)
        struct ixgbe_adapter *adapter = fwd_adapter->real_adapter;
        unsigned int limit;
 
-       clear_bit(fwd_adapter->pool, &adapter->fwd_bitmask);
+       clear_bit(fwd_adapter->pool, adapter->fwd_bitmask);
 
-       limit = find_last_bit(&adapter->fwd_bitmask, 32);
+       limit = find_last_bit(adapter->fwd_bitmask, adapter->num_rx_pools);
        adapter->ring_feature[RING_F_VMDQ].limit = limit + 1;
        ixgbe_fwd_ring_down(fwd_adapter->netdev, fwd_adapter);
 
@@ -9898,11 +9893,11 @@ static void ixgbe_fwd_del(struct net_device *pdev, void *priv)
        }
 
        ixgbe_setup_tc(pdev, netdev_get_num_tc(pdev));
-       netdev_dbg(pdev, "pool %i:%i queues %i:%i VSI bitmask %lx\n",
+       netdev_dbg(pdev, "pool %i:%i queues %i:%i\n",
                   fwd_adapter->pool, adapter->num_rx_pools,
                   fwd_adapter->rx_base_queue,
-                  fwd_adapter->rx_base_queue + adapter->num_rx_queues_per_pool,
-                  adapter->fwd_bitmask);
+                  fwd_adapter->rx_base_queue +
+                  adapter->num_rx_queues_per_pool);
        kfree(fwd_adapter);
 }
 
index 15d89258fbc34689bfa70fae0f87a12f16f024c3..0085f4632966d94ea1c592bed689cc9b8f6fa564 100644 (file)
@@ -290,10 +290,9 @@ static int ixgbe_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
 {
 #ifdef CONFIG_PCI_IOV
        struct ixgbe_adapter *adapter = pci_get_drvdata(dev);
-       int err = 0;
-       u8 num_tc;
-       int i;
        int pre_existing_vfs = pci_num_vf(dev);
+       int err = 0, num_rx_pools, i, limit;
+       u8 num_tc;
 
        if (pre_existing_vfs && pre_existing_vfs != num_vfs)
                err = ixgbe_disable_sriov(adapter);
@@ -316,22 +315,14 @@ static int ixgbe_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
         * other values out of range.
         */
        num_tc = netdev_get_num_tc(adapter->netdev);
+       num_rx_pools = adapter->num_rx_pools;
+       limit = (num_tc > 4) ? IXGBE_MAX_VFS_8TC :
+               (num_tc > 1) ? IXGBE_MAX_VFS_4TC : IXGBE_MAX_VFS_1TC;
 
-       if (num_tc > 4) {
-               if ((num_vfs + adapter->num_rx_pools) > IXGBE_MAX_VFS_8TC) {
-                       e_dev_err("Currently the device is configured with %d TCs, Creating more than %d VFs is not allowed\n", num_tc, IXGBE_MAX_VFS_8TC);
-                       return -EPERM;
-               }
-       } else if ((num_tc > 1) && (num_tc <= 4)) {
-               if ((num_vfs + adapter->num_rx_pools) > IXGBE_MAX_VFS_4TC) {
-                       e_dev_err("Currently the device is configured with %d TCs, Creating more than %d VFs is not allowed\n", num_tc, IXGBE_MAX_VFS_4TC);
-                       return -EPERM;
-               }
-       } else {
-               if ((num_vfs + adapter->num_rx_pools) > IXGBE_MAX_VFS_1TC) {
-                       e_dev_err("Currently the device is configured with %d TCs, Creating more than %d VFs is not allowed\n", num_tc, IXGBE_MAX_VFS_1TC);
-                       return -EPERM;
-               }
+       if (num_vfs > (limit - num_rx_pools)) {
+               e_dev_err("Currently configured with %d TCs, and %d offloaded macvlans. Creating more than %d VFs is not allowed\n",
+                         num_tc, num_rx_pools - 1, limit - num_rx_pools);
+               return -EPERM;
        }
 
        err = __ixgbe_enable_sriov(adapter, num_vfs);