Skip to content

Commit 21092e9

Browse files
anguy11Jeff Kirsher
authored andcommitted
ixgbevf: Add support for XDP_TX action
This implements the XDP_TX action which is modeled on the ixgbe implementation. However instead of using CPU id to determine which XDP queue to use, this uses the received RX queue index, which is similar to i40e. Doing this eliminates the restriction that number of CPUs not exceed number of XDP queues that ixgbe has. Also, based on the number of queues available, the number of TX queues may be reduced when an XDP program is loaded in order to accommodate the XDP queues. Based largely on commit 33fdc82 ("ixgbe: add support for XDP_TX action") Signed-off-by: Tony Nguyen <[email protected]> Acked-by: John Fastabend <[email protected]> Tested-by: Andrew Bowers <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent c7aec59 commit 21092e9

File tree

3 files changed

+294
-32
lines changed

3 files changed

+294
-32
lines changed

drivers/net/ethernet/intel/ixgbevf/ethtool.c

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ static int ixgbevf_set_ringparam(struct net_device *netdev,
269269
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
270270
struct ixgbevf_ring *tx_ring = NULL, *rx_ring = NULL;
271271
u32 new_rx_count, new_tx_count;
272-
int i, err = 0;
272+
int i, j, err = 0;
273273

274274
if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
275275
return -EINVAL;
@@ -293,15 +293,19 @@ static int ixgbevf_set_ringparam(struct net_device *netdev,
293293
if (!netif_running(adapter->netdev)) {
294294
for (i = 0; i < adapter->num_tx_queues; i++)
295295
adapter->tx_ring[i]->count = new_tx_count;
296+
for (i = 0; i < adapter->num_xdp_queues; i++)
297+
adapter->xdp_ring[i]->count = new_tx_count;
296298
for (i = 0; i < adapter->num_rx_queues; i++)
297299
adapter->rx_ring[i]->count = new_rx_count;
298300
adapter->tx_ring_count = new_tx_count;
301+
adapter->xdp_ring_count = new_tx_count;
299302
adapter->rx_ring_count = new_rx_count;
300303
goto clear_reset;
301304
}
302305

303306
if (new_tx_count != adapter->tx_ring_count) {
304-
tx_ring = vmalloc(adapter->num_tx_queues * sizeof(*tx_ring));
307+
tx_ring = vmalloc((adapter->num_tx_queues +
308+
adapter->num_xdp_queues) * sizeof(*tx_ring));
305309
if (!tx_ring) {
306310
err = -ENOMEM;
307311
goto clear_reset;
@@ -324,6 +328,24 @@ static int ixgbevf_set_ringparam(struct net_device *netdev,
324328
goto clear_reset;
325329
}
326330
}
331+
332+
for (j = 0; j < adapter->num_xdp_queues; i++, j++) {
333+
/* clone ring and setup updated count */
334+
tx_ring[i] = *adapter->xdp_ring[j];
335+
tx_ring[i].count = new_tx_count;
336+
err = ixgbevf_setup_tx_resources(&tx_ring[i]);
337+
if (err) {
338+
while (i) {
339+
i--;
340+
ixgbevf_free_tx_resources(&tx_ring[i]);
341+
}
342+
343+
vfree(tx_ring);
344+
tx_ring = NULL;
345+
346+
goto clear_reset;
347+
}
348+
}
327349
}
328350

329351
if (new_rx_count != adapter->rx_ring_count) {
@@ -368,6 +390,12 @@ static int ixgbevf_set_ringparam(struct net_device *netdev,
368390
}
369391
adapter->tx_ring_count = new_tx_count;
370392

393+
for (j = 0; j < adapter->num_xdp_queues; i++, j++) {
394+
ixgbevf_free_tx_resources(adapter->xdp_ring[j]);
395+
*adapter->xdp_ring[j] = tx_ring[i];
396+
}
397+
adapter->xdp_ring_count = new_tx_count;
398+
371399
vfree(tx_ring);
372400
tx_ring = NULL;
373401
}
@@ -390,7 +418,8 @@ static int ixgbevf_set_ringparam(struct net_device *netdev,
390418
clear_reset:
391419
/* free Tx resources if Rx error is encountered */
392420
if (tx_ring) {
393-
for (i = 0; i < adapter->num_tx_queues; i++)
421+
for (i = 0;
422+
i < adapter->num_tx_queues + adapter->num_xdp_queues; i++)
394423
ixgbevf_free_tx_resources(&tx_ring[i]);
395424
vfree(tx_ring);
396425
}

drivers/net/ethernet/intel/ixgbevf/ixgbevf.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@
5252
struct ixgbevf_tx_buffer {
5353
union ixgbe_adv_tx_desc *next_to_watch;
5454
unsigned long time_stamp;
55-
struct sk_buff *skb;
55+
union {
56+
struct sk_buff *skb;
57+
/* XDP uses address ptr on irq_clean */
58+
void *data;
59+
};
5660
unsigned int bytecount;
5761
unsigned short gso_segs;
5862
__be16 protocol;
@@ -95,8 +99,16 @@ enum ixgbevf_ring_state_t {
9599
__IXGBEVF_RX_BUILD_SKB_ENABLED,
96100
__IXGBEVF_TX_DETECT_HANG,
97101
__IXGBEVF_HANG_CHECK_ARMED,
102+
__IXGBEVF_TX_XDP_RING,
98103
};
99104

105+
#define ring_is_xdp(ring) \
106+
test_bit(__IXGBEVF_TX_XDP_RING, &(ring)->state)
107+
#define set_ring_xdp(ring) \
108+
set_bit(__IXGBEVF_TX_XDP_RING, &(ring)->state)
109+
#define clear_ring_xdp(ring) \
110+
clear_bit(__IXGBEVF_TX_XDP_RING, &(ring)->state)
111+
100112
struct ixgbevf_ring {
101113
struct ixgbevf_ring *next;
102114
struct ixgbevf_q_vector *q_vector; /* backpointer to q_vector */
@@ -139,6 +151,7 @@ struct ixgbevf_ring {
139151

140152
#define MAX_RX_QUEUES IXGBE_VF_MAX_RX_QUEUES
141153
#define MAX_TX_QUEUES IXGBE_VF_MAX_TX_QUEUES
154+
#define MAX_XDP_QUEUES IXGBE_VF_MAX_TX_QUEUES
142155
#define IXGBEVF_MAX_RSS_QUEUES 2
143156
#define IXGBEVF_82599_RETA_SIZE 128 /* 128 entries */
144157
#define IXGBEVF_X550_VFRETA_SIZE 64 /* 64 entries */
@@ -339,6 +352,10 @@ struct ixgbevf_adapter {
339352
u32 eims_enable_mask;
340353
u32 eims_other;
341354

355+
/* XDP */
356+
int num_xdp_queues;
357+
struct ixgbevf_ring *xdp_ring[MAX_XDP_QUEUES];
358+
342359
/* TX */
343360
int num_tx_queues;
344361
struct ixgbevf_ring *tx_ring[MAX_TX_QUEUES]; /* One per active queue */
@@ -373,6 +390,7 @@ struct ixgbevf_adapter {
373390
unsigned long state;
374391
u64 tx_busy;
375392
unsigned int tx_ring_count;
393+
unsigned int xdp_ring_count;
376394
unsigned int rx_ring_count;
377395

378396
u8 __iomem *io_addr; /* Mainly for iounmap use */

0 commit comments

Comments
 (0)