]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
i40e: disallow changing the number of descriptors when AF_XDP is on
authorBjörn Töpel <bjorn.topel@intel.com>
Fri, 7 Sep 2018 08:18:48 +0000 (10:18 +0200)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Tue, 25 Sep 2018 20:16:19 +0000 (13:16 -0700)
When an AF_XDP UMEM is attached to any of the Rx rings, we disallow a
user to change the number of descriptors via e.g. "ethtool -G IFNAME".

Otherwise, the size of the stash/reuse queue can grow unbounded, which
would result in OOM or leaking userspace buffers.

Signed-off-by: Björn Töpel <bjorn.topel@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_ethtool.c
drivers/net/ethernet/intel/i40e/i40e_txrx_common.h
drivers/net/ethernet/intel/i40e/i40e_xsk.c

index 87fe2e60602fbb426aa96fa075f8e6a4bf3f6616..9f8464f8078341021bd8c012eac16e2213d39279 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "i40e.h"
 #include "i40e_diag.h"
+#include "i40e_txrx_common.h"
 
 /* ethtool statistics helpers */
 
@@ -1710,6 +1711,13 @@ static int i40e_set_ringparam(struct net_device *netdev,
            (new_rx_count == vsi->rx_rings[0]->count))
                return 0;
 
+       /* If there is a AF_XDP UMEM attached to any of Rx rings,
+        * disallow changing the number of descriptors -- regardless
+        * if the netdev is running or not.
+        */
+       if (i40e_xsk_any_rx_ring_enabled(vsi))
+               return -EBUSY;
+
        while (test_and_set_bit(__I40E_CONFIG_BUSY, pf->state)) {
                timeout--;
                if (!timeout)
index 8d46acff6f2e22ea1ea236d1558a0a0515c1603c..09809dffe39931a843b11204d3480c30e1f68554 100644 (file)
@@ -89,5 +89,6 @@ static inline void i40e_arm_wb(struct i40e_ring *tx_ring,
 
 void i40e_xsk_clean_rx_ring(struct i40e_ring *rx_ring);
 void i40e_xsk_clean_tx_ring(struct i40e_ring *tx_ring);
+bool i40e_xsk_any_rx_ring_enabled(struct i40e_vsi *vsi);
 
 #endif /* I40E_TXRX_COMMON_ */
index 3867038837133e53db8669703a843342953ea77b..add1e457886df5e40a11388738b7580bc3a2508c 100644 (file)
@@ -944,3 +944,24 @@ void i40e_xsk_clean_tx_ring(struct i40e_ring *tx_ring)
        if (xsk_frames)
                xsk_umem_complete_tx(umem, xsk_frames);
 }
+
+/**
+ * i40e_xsk_any_rx_ring_enabled - Checks if Rx rings have AF_XDP UMEM attached
+ * @vsi: vsi
+ *
+ * Returns true if any of the Rx rings has an AF_XDP UMEM attached
+ **/
+bool i40e_xsk_any_rx_ring_enabled(struct i40e_vsi *vsi)
+{
+       int i;
+
+       if (!vsi->xsk_umems)
+               return false;
+
+       for (i = 0; i < vsi->num_queue_pairs; i++) {
+               if (vsi->xsk_umems[i])
+                       return true;
+       }
+
+       return false;
+}