Skip to contentSkip to conversation

XDP support for ixgbe

PATCH Superseded John Fastabend 5 participants 13 messages Mar 24, 2017 – Apr 11, 2017

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

v7 cover XDP support for ixgbe

This version fixes a couple issues with q_vector allocation and query on XDP program.

---

John Fastabend (2):
ixgbe: add XDP support for pass and drop actions
ixgbe: add support for XDP_TX action

 drivers/net/ethernet/intel/ixgbe/ixgbe.h         |   23 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |   29 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c     |   78 +++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  434 +++++++++++++++++++---
 4 files changed, 490 insertions(+), 74 deletions(-)

--
Signature

#1 lore raw

PATCH v7 1/2 ixgbe: add XDP support for pass and drop actions

Basic XDP drop support for ixgbe. Uses READ_ONCE/xchg semantics on XDP programs instead of rcu primitives as suggested by Daniel Borkmann and Alex Duyck.

---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h         |    4 -
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |    4 -
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  163 +++++++++++++++++++---
 3 files changed, 144 insertions(+), 27 deletions(-)
drivers/net/ethernet/intel/ixgbe/ixgbe.h +3 -1
index 656ca8f..cb14813 100644
@@ -318,6 +318,7 @@ struct ixgbe_ring {
 	struct ixgbe_ring *next;	/* pointer to next ring in q_vector */
 	struct ixgbe_q_vector *q_vector; /* backpointer to host q_vector */
 	struct net_device *netdev;	/* netdev ring belongs to */
+	struct bpf_prog *xdp_prog;
 	struct device *dev;		/* device for DMA mapping */
 	struct ixgbe_fwd_adapter *l2_accel_priv;
 	void *desc;			/* descriptor ring memory */
@@ -555,6 +556,7 @@ struct ixgbe_adapter {
 	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
 	/* OS defined structs */
 	struct net_device *netdev;
+	struct bpf_prog *xdp_prog;
 	struct pci_dev *pdev;
 
 	unsigned long state;
@@ -835,7 +837,7 @@ enum ixgbe_boards {
 void ixgbe_reinit_locked(struct ixgbe_adapter *adapter);
 void ixgbe_reset(struct ixgbe_adapter *adapter);
 void ixgbe_set_ethtool_ops(struct net_device *netdev);
-int ixgbe_setup_rx_resources(struct ixgbe_ring *);
+int ixgbe_setup_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
 int ixgbe_setup_tx_resources(struct ixgbe_ring *);
 void ixgbe_free_rx_resources(struct ixgbe_ring *);
 void ixgbe_free_tx_resources(struct ixgbe_ring *);
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +2 -2
index 59730ed..79a126d 100644
@@ -1128,7 +1128,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
 			       sizeof(struct ixgbe_ring));
 
 			temp_ring[i].count = new_rx_count;
-			err = ixgbe_setup_rx_resources(&temp_ring[i]);
+			err = ixgbe_setup_rx_resources(adapter, &temp_ring[i]);
 			if (err) {
 				while (i) {
 					i--;
@@ -1761,7 +1761,7 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
 	rx_ring->netdev = adapter->netdev;
 	rx_ring->reg_idx = adapter->rx_ring[0]->reg_idx;
 
-	err = ixgbe_setup_rx_resources(rx_ring);
+	err = ixgbe_setup_rx_resources(adapter, rx_ring);
 	if (err) {
 		ret_val = 4;
 		goto err_nomem;
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +139 -24

290 lines not on this page · raw message

#2 lore raw

PATCH v7 1/2 ixgbe: add XDP support for pass and drop actions

Quoted 6 lines · John Fastabend

Basic XDP drop support for ixgbe. Uses READ_ONCE/xchg semantics on XDP
programs instead of rcu primitives as suggested by Daniel Borkmann and
Alex Duyck.

Quoted 8 lines

---

?drivers/net/ethernet/intel/ixgbe/ixgbe.h???????? |??? 4 -
?drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |??? 4 -
?drivers/net/ethernet/intel/ixgbe/ixgbe_main.c??? |? 163

+++++++++++++++++++---
?3 files changed, 144 insertions(+), 27 deletions(-)

Does not apply cleanly to my dev-queue branch, what tree did you base
these changes on?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part
URL: <http://lists.osuosl.org/pipermail/intel-wired-lan/attachments/20170324/5adc8802/attachment.asc>

#3 lore raw

PATCH v7 1/2 ixgbe: add XDP support for pass and drop actions

Quoted 16 lines · Jeff Kirsher
Quoted 6 lines · John Fastabend

Basic XDP drop support for ixgbe. Uses READ_ONCE/xchg semantics on XDP
programs instead of rcu primitives as suggested by Daniel Borkmann and
Alex Duyck.

Quoted 8 lines
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h         |    4 -
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |    4 -
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  163
+++++++++++++++++++---
 3 files changed, 144 insertions(+), 27 deletions(-)
Quoted 3 lines

Does not apply cleanly to my dev-queue branch, what tree did you base these changes on?

Did you pop off the v6 series? I see its still in your tree :/ Or do you just want fixes to the initial series?

Thanks,
John

#4 lore raw

PATCH v7 1/2 ixgbe: add XDP support for pass and drop actions

Quoted 19 lines · John Fastabend
Quoted 18 lines · Jeff Kirsher
Quoted 16 lines · John Fastabend

Basic XDP drop support for ixgbe. Uses READ_ONCE/xchg semantics on
XDP
programs instead of rcu primitives as suggested by Daniel Borkmann
and
Alex Duyck.

---

? drivers/net/ethernet/intel/ixgbe/ixgbe.h???????? |??? 4 -
? drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |??? 4 -
? drivers/net/ethernet/intel/ixgbe/ixgbe_main.c??? |? 163

+++++++++++++++++++---
? 3 files changed, 144 insertions(+), 27 deletions(-)

Quoted 8 lines
Quoted 4 lines

Does not apply cleanly to my dev-queue branch, what tree did you base
these changes on?

Did you pop off the v6 series? I see its still in your tree :/ Or do you
just want fixes to the initial series?

Crap, you are right. Let me try this again without v6 applied...
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part
URL: <http://lists.osuosl.org/pipermail/intel-wired-lan/attachments/20170325/de2bf7a0/attachment.asc>

#5 lore raw

PATCH v7 1/2 ixgbe: add XDP support for pass and drop actions

In reply to John Fastabend
Quoted 13 lines

-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at lists.osuosl.org] On Behalf Of John Fastabend
Sent: Thursday, March 23, 2017 9:31 PM
To: john.fastabend at gmail.com; alexander.duyck at gmail.com
Cc: intel-wired-lan at lists.osuosl.org; u9012063 at gmail.com
Subject: [Intel-wired-lan] [PATCH v7 1/2] ixgbe: add XDP support for pass and drop actions

Basic XDP drop support for ixgbe. Uses READ_ONCE/xchg semantics on XDP programs instead of rcu primitives as suggested by Daniel Borkmann and Alex Duyck.

Quoted 8 lines
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h         |    4 -
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |    4 -
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  163
+++++++++++++++++++---
 3 files changed, 144 insertions(+), 27 deletions(-)
#6 lore raw

PATCH v7 1/2 ixgbe: add XDP support for pass and drop actions

In reply to John Fastabend
Quoted 4 lines

-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at lists.osuosl.org] On Behalf Of John Fastabend
Sent: Thursday, March 23, 2017 9:31 PM

To: [email protected]; alexander.duyck at gmail.com

Quoted 183 lines

Cc: intel-wired-lan at lists.osuosl.org; u9012063 at gmail.com
Subject: [Intel-wired-lan] [PATCH v7 1/2] ixgbe: add XDP support for pass and drop actions

Basic XDP drop support for ixgbe. Uses READ_ONCE/xchg semantics on XDP programs instead of rcu primitives as suggested by Daniel Borkmann and Alex Duyck.

---

drivers/net/ethernet/intel/ixgbe/ixgbe.h         |    4 -
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |    4 -
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  163
+++++++++++++++++++---
3 files changed, 144 insertions(+), 27 deletions(-)
drivers/net/ethernet/intel/ixgbe/ixgbe.h +3 -1
index 656ca8f..cb14813 100644
@@ -318,6 +318,7 @@ struct ixgbe_ring {
 	struct ixgbe_ring *next;	/* pointer to next ring in q_vector */
 	struct ixgbe_q_vector *q_vector; /* backpointer to host q_vector */
 	struct net_device *netdev;	/* netdev ring belongs to */
+	struct bpf_prog *xdp_prog;
 	struct device *dev;		/* device for DMA mapping */
 	struct ixgbe_fwd_adapter *l2_accel_priv;
 	void *desc;			/* descriptor ring memory */
@@ -555,6 +556,7 @@ struct ixgbe_adapter {
 	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
 	/* OS defined structs */
 	struct net_device *netdev;
+	struct bpf_prog *xdp_prog;
 	struct pci_dev *pdev;
 
 	unsigned long state;
@@ -835,7 +837,7 @@ enum ixgbe_boards {
 void ixgbe_reinit_locked(struct ixgbe_adapter *adapter);
 void ixgbe_reset(struct ixgbe_adapter *adapter);
 void ixgbe_set_ethtool_ops(struct net_device *netdev);
-int ixgbe_setup_rx_resources(struct ixgbe_ring *);
+int ixgbe_setup_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
 int ixgbe_setup_tx_resources(struct ixgbe_ring *);
 void ixgbe_free_rx_resources(struct ixgbe_ring *);
 void ixgbe_free_tx_resources(struct ixgbe_ring *);
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +1 -1
index 59730ed..79a126d 100644
@@ -1128,7 +1128,7 @@ static int ixgbe_set_ringparam(struct net_device
 *netdev,
 			       sizeof(struct ixgbe_ring));
 
 			temp_ring[i].count = new_rx_count;
-			err = ixgbe_setup_rx_resources(&temp_ring[i]);
+			err = ixgbe_setup_rx_resources(adapter, &temp_ring[i]);
 			if (err) {
 				while (i) {
					i--;
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +1 -1
@@ -1761,7 +1761,7 @@ static int ixgbe_setup_desc_rings(struct
 ixgbe_adapter *adapter)
 	rx_ring->netdev = adapter->netdev;
 	rx_ring->reg_idx = adapter->rx_ring[0]->reg_idx;
 
-	err = ixgbe_setup_rx_resources(rx_ring);
+	err = ixgbe_setup_rx_resources(adapter, rx_ring);
 	if (err) {
 		ret_val = 4;
		goto err_nomem;
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +7 -0
index 91c1cda..ddb75ba 100644
@@ -49,6 +49,9 @@
 #include <linux/if_macvlan.h>
 #include <linux/if_bridge.h>
 #include <linux/prefetch.h>
+#include <linux/bpf.h>
+#include <linux/bpf_trace.h>
+#include <linux/atomic.h>
 #include <scsi/fc/fc_fcoe.h>
 #include <net/udp_tunnel.h>
 #include <net/pkt_cls.h>
@@ -1858,6 +1861,10 @@ static void ixgbe_dma_sync_frag(struct ixgbe_ring
 *rx_ring,
 * @rx_desc: pointer to the EOP Rx descriptor
 * @skb: pointer to current skb being fixed
 *
+ * Check if the skb is valid in the XDP case it will be an error pointer.
+ * Return true in this case to abort processing and advance to next
+ * descriptor.
+ *
 * Check for corrupted packet headers caused by senders on the local L2
 * embedded NIC switch not setting up their Tx Descriptors right.  These

* should be very rare.

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +4 -0
@@ -1876,6 +1883,10 @@ static bool ixgbe_cleanup_headers(struct ixgbe_ring
 *rx_ring,
 {
 	struct net_device *netdev = rx_ring->netdev;
 
+	/* XDP packets use error pointer so abort at this point */
+	if (IS_ERR(skb))
+		return true;
+
 	/* verify that the packet does not have any known errors */
 	if (unlikely(ixgbe_test_staterr(rx_desc,
					IXGBE_RXDADV_ERR_FRAME_ERR_MASK) &&
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +1 -1
@@ -2051,7 +2062,7 @@ static void ixgbe_put_rx_buffer(struct ixgbe_ring
 *rx_ring,
 		/* hand second half of page back to the ring */
 		ixgbe_reuse_rx_page(rx_ring, rx_buffer);
 	} else {
-		if (IXGBE_CB(skb)->dma == rx_buffer->dma) {
+		if (!IS_ERR(skb) && IXGBE_CB(skb)->dma == rx_buffer->dma) {
 			/* the page has been released from the ring */
 			IXGBE_CB(skb)->page_released = true;
		} else {
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +3 -3
@@ -2072,10 +2083,10 @@ static void ixgbe_put_rx_buffer(struct ixgbe_ring
 *rx_ring,
 
 static struct sk_buff *ixgbe_construct_skb(struct ixgbe_ring *rx_ring,
 					   struct ixgbe_rx_buffer *rx_buffer,
-					   union ixgbe_adv_rx_desc *rx_desc,
-					   unsigned int size)
+					   struct xdp_buff *xdp,
+					   union ixgbe_adv_rx_desc *rx_desc)
 {
-	void *va = page_address(rx_buffer->page) + rx_buffer->page_offset;
+	unsigned int size = xdp->data_end - xdp->data;
 #if (PAGE_SIZE < 8192)
 	unsigned int truesize = ixgbe_rx_pg_size(rx_ring) / 2;

#else

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +2 -2
@@ -2084,9 +2095,9 @@ static struct sk_buff *ixgbe_construct_skb(struct
 ixgbe_ring *rx_ring,
 	struct sk_buff *skb;
 
 	/* prefetch first cache line of first page */
-	prefetch(va);
+	prefetch(xdp->data);
 #if L1_CACHE_BYTES < 128
-	prefetch(va + L1_CACHE_BYTES);
+	prefetch(xdp->data + L1_CACHE_BYTES);
 #endif
 
	/* allocate a skb to store the frags */
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +1 -1
@@ -2099,7 +2110,7 @@ static struct sk_buff *ixgbe_construct_skb(struct
 ixgbe_ring *rx_ring,
 			IXGBE_CB(skb)->dma = rx_buffer->dma;
 
 		skb_add_rx_frag(skb, 0, rx_buffer->page,
-				rx_buffer->page_offset,
+				xdp->data - page_address(rx_buffer->page),
 				size, truesize);
 #if (PAGE_SIZE < 8192)
		rx_buffer->page_offset ^= truesize;
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +4 -4
@@ -2107,7 +2118,8 @@ static struct sk_buff *ixgbe_construct_skb(struct
 ixgbe_ring *rx_ring,
 		rx_buffer->page_offset += truesize;
 #endif
 	} else {
-		memcpy(__skb_put(skb, size), va, ALIGN(size, sizeof(long)));
+		memcpy(__skb_put(skb, size),
+		       xdp->data, ALIGN(size, sizeof(long)));
 		rx_buffer->pagecnt_bias++;
 	}
@@ -2116,10 +2128,9 @@ static struct sk_buff *ixgbe_construct_skb(struct
 ixgbe_ring *rx_ring,
 
 static struct sk_buff *ixgbe_build_skb(struct ixgbe_ring *rx_ring,
 				       struct ixgbe_rx_buffer *rx_buffer,
-				       union ixgbe_adv_rx_desc *rx_desc,
-				       unsigned int size)
+				       struct xdp_buff *xdp,
+				       union ixgbe_adv_rx_desc *rx_desc)
 {
-	void *va = page_address(rx_buffer->page) + rx_buffer->page_offset;
 #if (PAGE_SIZE < 8192)
 	unsigned int truesize = ixgbe_rx_pg_size(rx_ring) / 2;
Quoted 1 line

#else

This patch introduces a build error in the case where PAGE_SIZE >= 8192 because the "size" parameter was removed from the function parameters, but it is still being used to calculate truesize for that case.

Thanks,
Emil

#7 lore raw

PATCH v7 2/2 ixgbe: add support for XDP_TX action

In reply to John Fastabend

Add support for XDP_TX action.

A couple design choices were made here. First I use a new ring pointer structure xdp_ring[] in the adapter struct instead of pushing the newly allocated xdp TX rings into the tx_ring[] structure. This means we have to duplicate loops around rings in places we want to initialize both TX rings and XDP rings. But by making it explicit it is obvious when we are using XDP rings and when we are using TX rings. Further we don't have to do ring arithmatic which is error prone. As a proof point for doing this my first patches used only a single ring structure and introduced bugs in FCoE code and macvlan code paths.

Second I am aware this is not the most optimized version of this code possible. I want to get baseline support in using the most readable format possible and then once this series is included I will optimize the TX path in another series of patches.

---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h         |   19 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |   25 ++
 drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c     |   78 +++++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  279 +++++++++++++++++++---
 4 files changed, 350 insertions(+), 51 deletions(-)
drivers/net/ethernet/intel/ixgbe/ixgbe.h +18 -1
index cb14813..e8cd449 100644
@@ -235,7 +235,11 @@ struct vf_macvlans {
 struct ixgbe_tx_buffer {
 	union ixgbe_adv_tx_desc *next_to_watch;
 	unsigned long time_stamp;
-	struct sk_buff *skb;
+	union {
+		struct sk_buff *skb;
+		/* XDP uses address ptr on irq_clean */
+		void *data;
+	};
 	unsigned int bytecount;
 	unsigned short gso_segs;
 	__be16 protocol;
@@ -288,6 +292,7 @@ enum ixgbe_ring_state_t {
 	__IXGBE_TX_XPS_INIT_DONE,
 	__IXGBE_TX_DETECT_HANG,
 	__IXGBE_HANG_CHECK_ARMED,
+	__IXGBE_TX_XDP_RING,
 };
 
 #define ring_uses_build_skb(ring) \
@@ -314,6 +319,12 @@ struct ixgbe_fwd_adapter {
 	set_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state)
 #define clear_ring_rsc_enabled(ring) \
 	clear_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state)
+#define ring_is_xdp(ring) \
+	test_bit(__IXGBE_TX_XDP_RING, &(ring)->state)
+#define set_ring_xdp(ring) \
+	set_bit(__IXGBE_TX_XDP_RING, &(ring)->state)
+#define clear_ring_xdp(ring) \
+	clear_bit(__IXGBE_TX_XDP_RING, &(ring)->state)
 struct ixgbe_ring {
 	struct ixgbe_ring *next;	/* pointer to next ring in q_vector */
 	struct ixgbe_q_vector *q_vector; /* backpointer to host q_vector */
@@ -380,6 +391,7 @@ enum ixgbe_ring_f_enum {
 #define IXGBE_MAX_FCOE_INDICES		8
 #define MAX_RX_QUEUES			(IXGBE_MAX_FDIR_INDICES + 1)
 #define MAX_TX_QUEUES			(IXGBE_MAX_FDIR_INDICES + 1)
+#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
@@ -623,6 +635,10 @@ struct ixgbe_adapter {
 	__be16 vxlan_port;
 	__be16 geneve_port;
 
+	/* XDP */
+	int num_xdp_queues;
+	struct ixgbe_ring *xdp_ring[MAX_XDP_QUEUES];
+
 	/* TX */
 	struct ixgbe_ring *tx_ring[MAX_TX_QUEUES] ____cacheline_aligned_in_smp;
 
@@ -669,6 +685,7 @@ struct ixgbe_adapter {
 
 	u64 tx_busy;
 	unsigned int tx_ring_count;
+	unsigned int xdp_ring_count;
 	unsigned int rx_ring_count;
 
 	u32 link_speed;
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +25 -0
index 79a126d..b0fd2f5 100644
@@ -1071,15 +1071,19 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
 	if (!netif_running(adapter->netdev)) {
 		for (i = 0; i < adapter->num_tx_queues; i++)
 			adapter->tx_ring[i]->count = new_tx_count;
+		for (i = 0; i < adapter->num_xdp_queues; i++)
+			adapter->xdp_ring[i]->count = new_tx_count;
 		for (i = 0; i < adapter->num_rx_queues; i++)
 			adapter->rx_ring[i]->count = new_rx_count;
 		adapter->tx_ring_count = new_tx_count;
+		adapter->xdp_ring_count = new_tx_count;
 		adapter->rx_ring_count = new_rx_count;
 		goto clear_reset;
 	}
 
 	/* allocate temporary buffer to store rings in */
 	i = max_t(int, adapter->num_tx_queues, adapter->num_rx_queues);
+	i = max_t(int, i, adapter->num_xdp_queues);
 	temp_ring = vmalloc(i * sizeof(struct ixgbe_ring));
 
 	if (!temp_ring) {
@@ -1111,12 +1115,33 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
 			}
 		}
 
+		for (i = 0; i < adapter->num_xdp_queues; i++) {
+			memcpy(&temp_ring[i], adapter->xdp_ring[i],
+			       sizeof(struct ixgbe_ring));
+
+			temp_ring[i].count = new_tx_count;
+			err = ixgbe_setup_tx_resources(&temp_ring[i]);
+			if (err) {
+				while (i) {
+					i--;
+					ixgbe_free_tx_resources(&temp_ring[i]);
+				}
+				goto err_setup;
+			}
+		}
+
 		for (i = 0; i < adapter->num_tx_queues; i++) {
 			ixgbe_free_tx_resources(adapter->tx_ring[i]);
 
 			memcpy(adapter->tx_ring[i], &temp_ring[i],
 			       sizeof(struct ixgbe_ring));
 		}
+		for (i = 0; i < adapter->num_xdp_queues; i++) {
+			ixgbe_free_tx_resources(adapter->xdp_ring[i]);
+
+			memcpy(adapter->xdp_ring[i], &temp_ring[i],
+			       sizeof(struct ixgbe_ring));
+		}
 
 		adapter->tx_ring_count = new_tx_count;
 	}
drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +68 -10

209 lines not on this page · raw message

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +239 -40

505 lines not on this page · raw message

#8 lore raw

PATCH v7 2/2 ixgbe: add support for XDP_TX action

Quoted 26 lines

-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at lists.osuosl.org] On Behalf Of John Fastabend
Sent: Thursday, March 23, 2017 9:32 PM
To: john.fastabend at gmail.com; alexander.duyck at gmail.com
Cc: intel-wired-lan at lists.osuosl.org; u9012063 at gmail.com
Subject: [Intel-wired-lan] [PATCH v7 2/2] ixgbe: add support for XDP_TX action

Add support for XDP_TX action.

A couple design choices were made here. First I use a new ring pointer structure xdp_ring[] in the adapter struct instead of pushing the newly allocated xdp TX rings into the tx_ring[] structure. This means we have to duplicate loops around rings in places we want to initialize both TX rings and XDP rings.
But by making it explicit it is obvious when we are using XDP rings and when we are using TX rings. Further we don't have to do ring arithmatic which is error prone. As a proof point for doing this my first patches used only a single ring structure and introduced bugs in FCoE code and macvlan code paths.

Second I am aware this is not the most optimized version of this code possible. I want to get baseline support in using the most readable format possible and then once this series is included I will optimize the TX path in another series of patches.

Quoted 8 lines
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h         |   19 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |   25 ++
 drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c     |   78 +++++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  279
+++++++++++++++++++---
 4 files changed, 350 insertions(+), 51 deletions(-)
#9 lore raw

PATCH v7 2/2 ixgbe: add support for XDP_TX action

In reply to John Fastabend
Quoted 19 lines · On Thu, 23 Mar 2017 21:31:45 -0700 John Fastabend <[email protected]>…

Add support for XDP_TX action.

A couple design choices were made here. First I use a new ring pointer structure xdp_ring[] in the adapter struct instead of pushing the newly allocated xdp TX rings into the tx_ring[] structure. This means we have to duplicate loops around rings in places we want to initialize both TX rings and XDP rings. But by making it explicit it is obvious when we are using XDP rings and when we are using TX rings. Further we don't have to do ring arithmatic which is error prone. As a proof point for doing this my first patches used only a single ring structure and introduced bugs in FCoE code and macvlan code paths.

Second I am aware this is not the most optimized version of this code possible. I want to get baseline support in using the most readable format possible and then once this series is included I will optimize the TX path in another series of patches.

Quoted 7 lines
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h         |   19 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |   25 ++
 drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c     |   78 +++++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  279 +++++++++++++++++++---
 4 files changed, 350 insertions(+), 51 deletions(-)

Hi there.

I've been testing&backporting these patches (good job btw) for DDoS mitigation solutions and got one question/issue about XDP queues setup:

Briefly, what is being done:
N_cpus queues are allocated

drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter) · line 318

Quoted 1 line
drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +1 -0
+	return adapter->xdp_prog ? nr_cpu_ids : 0;

and ixgbe_xmit_xdp_ring chooses one of them, based on the cpu it is running on

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, · line 8203

Quoted 1 line
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +1 -0
+	struct ixgbe_ring *ring = adapter->xdp_ring[smp_processor_id()];

It's pretty good on ~default setups with one rx queue per each cpu and uniformly spread irqs: queue#0 on cpu#0, queue#i on cpu#i etc. It is even ok to reduce the number of queues (however then there's going to be some unused xdp-only q_vectors/irqs). The real problem arises when one wants to move irqs to different cpus: for instance, to handle packets only on cpus #8-15,24-27 (say, 2x8 NUMA server with HT and NIC bound to 2nd processor). XDP rings are going to be shuffled really hard in this scenario: ixgbe_xmit_xdp_ring would choose xdp_ring of some other q_vector, and irq of this q_vector would be handled on some other cpu (hence memory pages would walk across cpus etc).

And I'm curious, why not to hard-pair xdp rings with rx rings (placing each pair in the same q_vector ofc)? It would save some irqs when n_queues < n_cpus and make irq manipulation a lot easier. I couldn't get any real cons against this pairing (except it might be a bit harder to implement), and couldn't find any discussion about it. Did I miss something?

Also, regarding this patch, you might want to initialize q_vector->itr to IXGBE_12K_ITR for xdp-only q_vectors.
Currently,

	if (txr_count && !rxr_count) {
doesn't hit in ixgbe_alloc_q_vectors, and the 'else' branch
    /* rx or rx/tx vector */
    if (adapter->rx_itr_setting == 1)
        q_vector->itr = IXGBE_20K_ITR;

sets it to IXGBE_20K_ITR.

#10 lore raw

v7 cover XDP support for ixgbe

In reply to John Fastabend
Quoted 10 lines · John Fastabend

This version fixes a couple issues with q_vector allocation and query on XDP program.

---

John Fastabend (2):
ixgbe: add XDP support for pass and drop actions
ixgbe: add support for XDP_TX action

Quoted 8 lines
 drivers/net/ethernet/intel/ixgbe/ixgbe.h         |   23 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |   29 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c     |   78 +++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  434 +++++++++++++++++++---
 4 files changed, 490 insertions(+), 74 deletions(-)

--
Signature

Thanks. I tested using samples/bpf/xdp1 and xdp2 using ping and dpdk pktgen. Both work OK.

When enabling xdp, dmesg shows:

[12270.610462] pps pps0: new PPS source ptp6
[12270.610465] ixgbe 0000:05:00.0: registered PHC device on enp5s0f0
[12271.619018] ixgbe 0000:05:00.0: removed PHC on enp5s0f0
[12271.943334] ixgbe 0000:05:00.0: Multiqueue Enabled: Rx Queue count
= 16, Tx Queue count = 16 XDP Queue count = 0
[12272.011324] pps pps0: new PPS source ptp6
[12272.011326] ixgbe 0000:05:00.0: registered PHC device on enp5s0f0
[12276.477066] ixgbe 0000:05:00.0 enp5s0f0: NIC Link is Up 10 Gbps,

Flow Control: None

I'm not sure it's important or not.
Regards,
William

#11 lore raw

v7 cover XDP support for ixgbe

Quoted 33 lines · William Tu
Quoted 10 lines · John Fastabend

This version fixes a couple issues with q_vector allocation and query on XDP program.

---

John Fastabend (2):
ixgbe: add XDP support for pass and drop actions
ixgbe: add support for XDP_TX action

Quoted 8 lines
 drivers/net/ethernet/intel/ixgbe/ixgbe.h         |   23 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |   29 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c     |   78 +++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  434 +++++++++++++++++++---
 4 files changed, 490 insertions(+), 74 deletions(-)

--
Signature

Thanks. I tested using samples/bpf/xdp1 and xdp2 using ping and dpdk pktgen. Both work OK.

When enabling xdp, dmesg shows:

[12270.610462] pps pps0: new PPS source ptp6
[12270.610465] ixgbe 0000:05:00.0: registered PHC device on enp5s0f0
[12271.619018] ixgbe 0000:05:00.0: removed PHC on enp5s0f0
[12271.943334] ixgbe 0000:05:00.0: Multiqueue Enabled: Rx Queue count
= 16, Tx Queue count = 16 XDP Queue count = 0
[12272.011324] pps pps0: new PPS source ptp6
[12272.011326] ixgbe 0000:05:00.0: registered PHC device on enp5s0f0
[12276.477066] ixgbe 0000:05:00.0 enp5s0f0: NIC Link is Up 10 Gbps,
Quoted 6 lines

Flow Control: None

I'm not sure it's important or not.
Regards,
William

Well that is a bit odd. When you load the XDP program we should see a "XDP Queue count" equal to the cpu count from /proc/cpuinfo. But if this is from either after unloading a XDP program or from initial loading the module before an XDP program is loaded than zero is expected. The queues are only added after the XDP program is loaded.

Thanks,
John

#12 lore raw

v7 cover XDP support for ixgbe

Quoted 41 lines · John Fastabend
Quoted 33 lines · William Tu
Quoted 10 lines · John Fastabend

This version fixes a couple issues with q_vector allocation and query on XDP program.

---

John Fastabend (2):
ixgbe: add XDP support for pass and drop actions
ixgbe: add support for XDP_TX action

Quoted 8 lines
 drivers/net/ethernet/intel/ixgbe/ixgbe.h         |   23 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |   29 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c     |   78 +++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  434 +++++++++++++++++++---
 4 files changed, 490 insertions(+), 74 deletions(-)

--
Signature

Thanks. I tested using samples/bpf/xdp1 and xdp2 using ping and dpdk pktgen. Both work OK.

When enabling xdp, dmesg shows:

[12270.610462] pps pps0: new PPS source ptp6
[12270.610465] ixgbe 0000:05:00.0: registered PHC device on enp5s0f0
[12271.619018] ixgbe 0000:05:00.0: removed PHC on enp5s0f0
[12271.943334] ixgbe 0000:05:00.0: Multiqueue Enabled: Rx Queue count
= 16, Tx Queue count = 16 XDP Queue count = 0
[12272.011324] pps pps0: new PPS source ptp6
[12272.011326] ixgbe 0000:05:00.0: registered PHC device on enp5s0f0
[12276.477066] ixgbe 0000:05:00.0 enp5s0f0: NIC Link is Up 10 Gbps,
Quoted 6 lines

Flow Control: None

I'm not sure it's important or not.
Regards,
William

Quoted 9 lines

Well that is a bit odd. When you load the XDP program we should see a "XDP Queue count" equal to the cpu count from /proc/cpuinfo. But if this is from either after unloading a XDP program or from initial loading the module before an XDP program is loaded than zero is expected. The queues are only added after the XDP program is loaded.

Thanks,
John

in my case I have 16 cpus. But I saw XDP queues either 0 or 48.

[86079.450650] ixgbe 0000:05:00.1 enp5s0f1: NIC Link is Up 10 Gbps,
Flow Control: None
[86940.730799] ixgbe 0000:05:00.0: removed PHC on enp5s0f0
[86941.052806] ixgbe 0000:05:00.0: Multiqueue Enabled: Rx Queue count
= 16, Tx Queue count = 16 XDP Queue count = 48
[86941.216825] pps pps0: new PPS source ptp6
[86941.216827] ixgbe 0000:05:00.0: registered PHC device on enp5s0f0
[86945.371094] ixgbe 0000:05:00.0 enp5s0f0: NIC Link is Up 10 Gbps,
Flow Control: None
[86954.498885] ixgbe 0000:05:00.1: removed PHC on enp5s0f1
[86954.824992] ixgbe 0000:05:00.1: Multiqueue Enabled: Rx Queue count
= 16, Tx Queue count = 16 XDP Queue count = 0
[86954.893054] pps pps1: new PPS source ptp7
[86954.893055] ixgbe 0000:05:00.1: registered PHC device on enp5s0f1
[86959.094568] ixgbe 0000:05:00.1 enp5s0f1: NIC Link is Up 10 Gbps,
Flow Control: None
[86991.730721] ixgbe 0000:05:00.1: removed PHC on enp5s0f1
[86992.052007] ixgbe 0000:05:00.1: Multiqueue Enabled: Rx Queue count
= 16, Tx Queue count = 16 XDP Queue count = 48
[86992.216915] pps pps1: new PPS source ptp7
[86992.216916] ixgbe 0000:05:00.1: registered PHC device on enp5s0f1
[86992.338119] ixgbe 0000:05:00.1 enp5s0f1: initiating reset to clear

Tx work after link loss

Thanks,
William