Skip to content

Commit be1222b

Browse files
Björn TöpelAlexei Starovoitov
authored andcommitted
i40e: Separate kernel allocated rx_bi rings from AF_XDP rings
Continuing the path to support MEM_TYPE_XSK_BUFF_POOL, the AF_XDP zero-copy/sk_buff rx_bi rings are now separate. Functions to properly allocate the different rings are added as well. v3->v4: Made i40e_fd_handle_status() static. (kbuild test robot) v4->v5: Fix kdoc for i40e_clean_programming_status(). (Jakub) Signed-off-by: Björn Töpel <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/bpf/[email protected]
1 parent e1675f9 commit be1222b

File tree

7 files changed

+142
-127
lines changed

7 files changed

+142
-127
lines changed

drivers/net/ethernet/intel/i40e/i40e_main.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3260,8 +3260,12 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
32603260
if (ring->vsi->type == I40E_VSI_MAIN)
32613261
xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq);
32623262

3263+
kfree(ring->rx_bi);
32633264
ring->xsk_umem = i40e_xsk_umem(ring);
32643265
if (ring->xsk_umem) {
3266+
ret = i40e_alloc_rx_bi_zc(ring);
3267+
if (ret)
3268+
return ret;
32653269
ring->rx_buf_len = ring->xsk_umem->chunk_size_nohr -
32663270
XDP_PACKET_HEADROOM;
32673271
/* For AF_XDP ZC, we disallow packets to span on
@@ -3280,6 +3284,9 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
32803284
ring->queue_index);
32813285

32823286
} else {
3287+
ret = i40e_alloc_rx_bi(ring);
3288+
if (ret)
3289+
return ret;
32833290
ring->rx_buf_len = vsi->rx_buf_len;
32843291
if (ring->vsi->type == I40E_VSI_MAIN) {
32853292
ret = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq,

drivers/net/ethernet/intel/i40e/i40e_txrx.c

Lines changed: 44 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -521,28 +521,29 @@ int i40e_add_del_fdir(struct i40e_vsi *vsi,
521521
/**
522522
* i40e_fd_handle_status - check the Programming Status for FD
523523
* @rx_ring: the Rx ring for this descriptor
524-
* @rx_desc: the Rx descriptor for programming Status, not a packet descriptor.
524+
* @qword0_raw: qword0
525+
* @qword1: qword1 after le_to_cpu
525526
* @prog_id: the id originally used for programming
526527
*
527528
* This is used to verify if the FD programming or invalidation
528529
* requested by SW to the HW is successful or not and take actions accordingly.
529530
**/
530-
void i40e_fd_handle_status(struct i40e_ring *rx_ring,
531-
union i40e_rx_desc *rx_desc, u8 prog_id)
531+
static void i40e_fd_handle_status(struct i40e_ring *rx_ring, u64 qword0_raw,
532+
u64 qword1, u8 prog_id)
532533
{
533534
struct i40e_pf *pf = rx_ring->vsi->back;
534535
struct pci_dev *pdev = pf->pdev;
536+
struct i40e_32b_rx_wb_qw0 *qw0;
535537
u32 fcnt_prog, fcnt_avail;
536538
u32 error;
537-
u64 qw;
538539

539-
qw = le64_to_cpu(rx_desc->wb.qword1.status_error_len);
540-
error = (qw & I40E_RX_PROG_STATUS_DESC_QW1_ERROR_MASK) >>
540+
qw0 = (struct i40e_32b_rx_wb_qw0 *)&qword0_raw;
541+
error = (qword1 & I40E_RX_PROG_STATUS_DESC_QW1_ERROR_MASK) >>
541542
I40E_RX_PROG_STATUS_DESC_QW1_ERROR_SHIFT;
542543

543544
if (error == BIT(I40E_RX_PROG_STATUS_DESC_FD_TBL_FULL_SHIFT)) {
544-
pf->fd_inv = le32_to_cpu(rx_desc->wb.qword0.hi_dword.fd_id);
545-
if ((rx_desc->wb.qword0.hi_dword.fd_id != 0) ||
545+
pf->fd_inv = le32_to_cpu(qw0->hi_dword.fd_id);
546+
if (qw0->hi_dword.fd_id != 0 ||
546547
(I40E_DEBUG_FD & pf->hw.debug_mask))
547548
dev_warn(&pdev->dev, "ntuple filter loc = %d, could not be added\n",
548549
pf->fd_inv);
@@ -560,7 +561,7 @@ void i40e_fd_handle_status(struct i40e_ring *rx_ring,
560561
/* store the current atr filter count */
561562
pf->fd_atr_cnt = i40e_get_current_atr_cnt(pf);
562563

563-
if ((rx_desc->wb.qword0.hi_dword.fd_id == 0) &&
564+
if (qw0->hi_dword.fd_id == 0 &&
564565
test_bit(__I40E_FD_SB_AUTO_DISABLED, pf->state)) {
565566
/* These set_bit() calls aren't atomic with the
566567
* test_bit() here, but worse case we potentially
@@ -589,7 +590,7 @@ void i40e_fd_handle_status(struct i40e_ring *rx_ring,
589590
} else if (error == BIT(I40E_RX_PROG_STATUS_DESC_NO_FD_ENTRY_SHIFT)) {
590591
if (I40E_DEBUG_FD & pf->hw.debug_mask)
591592
dev_info(&pdev->dev, "ntuple filter fd_id = %d, could not be removed\n",
592-
rx_desc->wb.qword0.hi_dword.fd_id);
593+
qw0->hi_dword.fd_id);
593594
}
594595
}
595596

@@ -1232,64 +1233,27 @@ static void i40e_reuse_rx_page(struct i40e_ring *rx_ring,
12321233
}
12331234

12341235
/**
1235-
* i40e_rx_is_programming_status - check for programming status descriptor
1236-
* @qw: qword representing status_error_len in CPU ordering
1237-
*
1238-
* The value of in the descriptor length field indicate if this
1239-
* is a programming status descriptor for flow director or FCoE
1240-
* by the value of I40E_RX_PROG_STATUS_DESC_LENGTH, otherwise
1241-
* it is a packet descriptor.
1242-
**/
1243-
static inline bool i40e_rx_is_programming_status(u64 qw)
1244-
{
1245-
/* The Rx filter programming status and SPH bit occupy the same
1246-
* spot in the descriptor. Since we don't support packet split we
1247-
* can just reuse the bit as an indication that this is a
1248-
* programming status descriptor.
1249-
*/
1250-
return qw & I40E_RXD_QW1_LENGTH_SPH_MASK;
1251-
}
1252-
1253-
/**
1254-
* i40e_clean_programming_status - try clean the programming status descriptor
1236+
* i40e_clean_programming_status - clean the programming status descriptor
12551237
* @rx_ring: the rx ring that has this descriptor
1256-
* @rx_desc: the rx descriptor written back by HW
1257-
* @qw: qword representing status_error_len in CPU ordering
1238+
* @qword0_raw: qword0
1239+
* @qword1: qword1 representing status_error_len in CPU ordering
12581240
*
12591241
* Flow director should handle FD_FILTER_STATUS to check its filter programming
12601242
* status being successful or not and take actions accordingly. FCoE should
12611243
* handle its context/filter programming/invalidation status and take actions.
12621244
*
12631245
* Returns an i40e_rx_buffer to reuse if the cleanup occurred, otherwise NULL.
12641246
**/
1265-
struct i40e_rx_buffer *i40e_clean_programming_status(
1266-
struct i40e_ring *rx_ring,
1267-
union i40e_rx_desc *rx_desc,
1268-
u64 qw)
1247+
void i40e_clean_programming_status(struct i40e_ring *rx_ring, u64 qword0_raw,
1248+
u64 qword1)
12691249
{
1270-
struct i40e_rx_buffer *rx_buffer;
1271-
u32 ntc;
12721250
u8 id;
12731251

1274-
if (!i40e_rx_is_programming_status(qw))
1275-
return NULL;
1276-
1277-
ntc = rx_ring->next_to_clean;
1278-
1279-
/* fetch, update, and store next to clean */
1280-
rx_buffer = i40e_rx_bi(rx_ring, ntc++);
1281-
ntc = (ntc < rx_ring->count) ? ntc : 0;
1282-
rx_ring->next_to_clean = ntc;
1283-
1284-
prefetch(I40E_RX_DESC(rx_ring, ntc));
1285-
1286-
id = (qw & I40E_RX_PROG_STATUS_DESC_QW1_PROGID_MASK) >>
1252+
id = (qword1 & I40E_RX_PROG_STATUS_DESC_QW1_PROGID_MASK) >>
12871253
I40E_RX_PROG_STATUS_DESC_QW1_PROGID_SHIFT;
12881254

12891255
if (id == I40E_RX_PROG_STATUS_DESC_FD_FILTER_STATUS)
1290-
i40e_fd_handle_status(rx_ring, rx_desc, id);
1291-
1292-
return rx_buffer;
1256+
i40e_fd_handle_status(rx_ring, qword0_raw, qword1, id);
12931257
}
12941258

12951259
/**
@@ -1341,13 +1305,25 @@ int i40e_setup_tx_descriptors(struct i40e_ring *tx_ring)
13411305
return -ENOMEM;
13421306
}
13431307

1308+
int i40e_alloc_rx_bi(struct i40e_ring *rx_ring)
1309+
{
1310+
unsigned long sz = sizeof(*rx_ring->rx_bi) * rx_ring->count;
1311+
1312+
rx_ring->rx_bi = kzalloc(sz, GFP_KERNEL);
1313+
return rx_ring->rx_bi ? 0 : -ENOMEM;
1314+
}
1315+
1316+
static void i40e_clear_rx_bi(struct i40e_ring *rx_ring)
1317+
{
1318+
memset(rx_ring->rx_bi, 0, sizeof(*rx_ring->rx_bi) * rx_ring->count);
1319+
}
1320+
13441321
/**
13451322
* i40e_clean_rx_ring - Free Rx buffers
13461323
* @rx_ring: ring to be cleaned
13471324
**/
13481325
void i40e_clean_rx_ring(struct i40e_ring *rx_ring)
13491326
{
1350-
unsigned long bi_size;
13511327
u16 i;
13521328

13531329
/* ring already cleared, nothing to do */
@@ -1393,8 +1369,10 @@ void i40e_clean_rx_ring(struct i40e_ring *rx_ring)
13931369
}
13941370

13951371
skip_free:
1396-
bi_size = sizeof(struct i40e_rx_buffer) * rx_ring->count;
1397-
memset(rx_ring->rx_bi, 0, bi_size);
1372+
if (rx_ring->xsk_umem)
1373+
i40e_clear_rx_bi_zc(rx_ring);
1374+
else
1375+
i40e_clear_rx_bi(rx_ring);
13981376

13991377
/* Zero out the descriptor ring */
14001378
memset(rx_ring->desc, 0, rx_ring->size);
@@ -1435,15 +1413,7 @@ void i40e_free_rx_resources(struct i40e_ring *rx_ring)
14351413
int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring)
14361414
{
14371415
struct device *dev = rx_ring->dev;
1438-
int err = -ENOMEM;
1439-
int bi_size;
1440-
1441-
/* warn if we are about to overwrite the pointer */
1442-
WARN_ON(rx_ring->rx_bi);
1443-
bi_size = sizeof(struct i40e_rx_buffer) * rx_ring->count;
1444-
rx_ring->rx_bi = kzalloc(bi_size, GFP_KERNEL);
1445-
if (!rx_ring->rx_bi)
1446-
goto err;
1416+
int err;
14471417

14481418
u64_stats_init(&rx_ring->syncp);
14491419

@@ -1456,7 +1426,7 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring)
14561426
if (!rx_ring->desc) {
14571427
dev_info(dev, "Unable to allocate memory for the Rx descriptor ring, size=%d\n",
14581428
rx_ring->size);
1459-
goto err;
1429+
return -ENOMEM;
14601430
}
14611431

14621432
rx_ring->next_to_alloc = 0;
@@ -1468,16 +1438,12 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring)
14681438
err = xdp_rxq_info_reg(&rx_ring->xdp_rxq, rx_ring->netdev,
14691439
rx_ring->queue_index);
14701440
if (err < 0)
1471-
goto err;
1441+
return err;
14721442
}
14731443

14741444
rx_ring->xdp_prog = rx_ring->vsi->xdp_prog;
14751445

14761446
return 0;
1477-
err:
1478-
kfree(rx_ring->rx_bi);
1479-
rx_ring->rx_bi = NULL;
1480-
return err;
14811447
}
14821448

14831449
/**
@@ -2387,9 +2353,12 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
23872353
*/
23882354
dma_rmb();
23892355

2390-
rx_buffer = i40e_clean_programming_status(rx_ring, rx_desc,
2391-
qword);
2392-
if (unlikely(rx_buffer)) {
2356+
if (i40e_rx_is_programming_status(qword)) {
2357+
i40e_clean_programming_status(rx_ring,
2358+
rx_desc->raw.qword[0],
2359+
qword);
2360+
rx_buffer = i40e_rx_bi(rx_ring, rx_ring->next_to_clean);
2361+
i40e_inc_ntc(rx_ring);
23932362
i40e_reuse_rx_page(rx_ring, rx_buffer);
23942363
cleaned_count++;
23952364
continue;

drivers/net/ethernet/intel/i40e/i40e_txrx.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -296,17 +296,15 @@ struct i40e_tx_buffer {
296296

297297
struct i40e_rx_buffer {
298298
dma_addr_t dma;
299-
union {
300-
struct {
301-
struct page *page;
302-
__u32 page_offset;
303-
__u16 pagecnt_bias;
304-
};
305-
struct {
306-
void *addr;
307-
u64 handle;
308-
};
309-
};
299+
struct page *page;
300+
__u32 page_offset;
301+
__u16 pagecnt_bias;
302+
};
303+
304+
struct i40e_rx_buffer_zc {
305+
dma_addr_t dma;
306+
void *addr;
307+
u64 handle;
310308
};
311309

312310
struct i40e_queue_stats {
@@ -358,6 +356,7 @@ struct i40e_ring {
358356
union {
359357
struct i40e_tx_buffer *tx_bi;
360358
struct i40e_rx_buffer *rx_bi;
359+
struct i40e_rx_buffer_zc *rx_bi_zc;
361360
};
362361
DECLARE_BITMAP(state, __I40E_RING_STATE_NBITS);
363362
u16 queue_index; /* Queue number of ring */
@@ -495,6 +494,7 @@ int __i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size);
495494
bool __i40e_chk_linearize(struct sk_buff *skb);
496495
int i40e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
497496
u32 flags);
497+
int i40e_alloc_rx_bi(struct i40e_ring *rx_ring);
498498

499499
/**
500500
* i40e_get_head - Retrieve head from head writeback

drivers/net/ethernet/intel/i40e/i40e_txrx_common.h

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,9 @@
44
#ifndef I40E_TXRX_COMMON_
55
#define I40E_TXRX_COMMON_
66

7-
void i40e_fd_handle_status(struct i40e_ring *rx_ring,
8-
union i40e_rx_desc *rx_desc, u8 prog_id);
97
int i40e_xmit_xdp_tx_ring(struct xdp_buff *xdp, struct i40e_ring *xdp_ring);
10-
struct i40e_rx_buffer *i40e_clean_programming_status(
11-
struct i40e_ring *rx_ring,
12-
union i40e_rx_desc *rx_desc,
13-
u64 qw);
8+
void i40e_clean_programming_status(struct i40e_ring *rx_ring, u64 qword0_raw,
9+
u64 qword1);
1410
void i40e_process_skb_fields(struct i40e_ring *rx_ring,
1511
union i40e_rx_desc *rx_desc, struct sk_buff *skb);
1612
void i40e_xdp_ring_update_tail(struct i40e_ring *xdp_ring);
@@ -84,6 +80,38 @@ static inline void i40e_arm_wb(struct i40e_ring *tx_ring,
8480
}
8581
}
8682

83+
/**
84+
* i40e_rx_is_programming_status - check for programming status descriptor
85+
* @qword1: qword1 representing status_error_len in CPU ordering
86+
*
87+
* The value of in the descriptor length field indicate if this
88+
* is a programming status descriptor for flow director or FCoE
89+
* by the value of I40E_RX_PROG_STATUS_DESC_LENGTH, otherwise
90+
* it is a packet descriptor.
91+
**/
92+
static inline bool i40e_rx_is_programming_status(u64 qword1)
93+
{
94+
/* The Rx filter programming status and SPH bit occupy the same
95+
* spot in the descriptor. Since we don't support packet split we
96+
* can just reuse the bit as an indication that this is a
97+
* programming status descriptor.
98+
*/
99+
return qword1 & I40E_RXD_QW1_LENGTH_SPH_MASK;
100+
}
101+
102+
/**
103+
* i40e_inc_ntc: Advance the next_to_clean index
104+
* @rx_ring: Rx ring
105+
**/
106+
static inline void i40e_inc_ntc(struct i40e_ring *rx_ring)
107+
{
108+
u32 ntc = rx_ring->next_to_clean + 1;
109+
110+
ntc = (ntc < rx_ring->count) ? ntc : 0;
111+
rx_ring->next_to_clean = ntc;
112+
prefetch(I40E_RX_DESC(rx_ring, ntc));
113+
}
114+
87115
void i40e_xsk_clean_rx_ring(struct i40e_ring *rx_ring);
88116
void i40e_xsk_clean_tx_ring(struct i40e_ring *tx_ring);
89117
bool i40e_xsk_any_rx_ring_enabled(struct i40e_vsi *vsi);

drivers/net/ethernet/intel/i40e/i40e_type.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,7 @@ union i40e_32byte_rx_desc {
689689
__le64 rsvd2;
690690
} read;
691691
struct {
692-
struct {
692+
struct i40e_32b_rx_wb_qw0 {
693693
struct {
694694
union {
695695
__le16 mirroring_status;
@@ -727,6 +727,9 @@ union i40e_32byte_rx_desc {
727727
} hi_dword;
728728
} qword3;
729729
} wb; /* writeback */
730+
struct {
731+
u64 qword[4];
732+
} raw;
730733
};
731734

732735
enum i40e_rx_desc_status_bits {

0 commit comments

Comments
 (0)