Skip to content

Commit 7b4ec51

Browse files
emuslnkuba-moo
authored andcommitted
ionic: use per-queue xdp_prog
We originally were using a per-interface xdp_prog variable to track a loaded XDP program since we knew there would never be support for a per-queue XDP program. With that, we only built the per queue rxq_info struct when an XDP program was loaded and removed it on XDP program unload, and used the pointer as an indicator in the Rx hotpath to know to how build the buffers. However, that's really not the model generally used, and makes a conversion to page_pool Rx buffer cacheing a little problematic. This patch converts the driver to use the more common approach of using a per-queue xdp_prog pointer to work out buffer allocations and need for bpf_prog_run_xdp(). We jostle a couple of fields in the queue struct in order to keep the new xdp_prog pointer in a warm cacheline. Signed-off-by: Shannon Nelson <[email protected]> Signed-off-by: Brett Creeley <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 7639a6e commit 7b4ec51

File tree

3 files changed

+34
-31
lines changed

3 files changed

+34
-31
lines changed

drivers/net/ethernet/pensando/ionic/ionic_dev.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,8 @@ struct ionic_queue {
238238
unsigned int index;
239239
unsigned int num_descs;
240240
unsigned int max_sg_elems;
241+
241242
u64 features;
242-
unsigned int type;
243-
unsigned int hw_index;
244243
unsigned int hw_type;
245244
bool xdp_flush;
246245
union {
@@ -261,7 +260,11 @@ struct ionic_queue {
261260
struct ionic_rxq_sg_desc *rxq_sgl;
262261
};
263262
struct xdp_rxq_info *xdp_rxq_info;
263+
struct bpf_prog *xdp_prog;
264264
struct ionic_queue *partner;
265+
266+
unsigned int type;
267+
unsigned int hw_index;
265268
dma_addr_t base_pa;
266269
dma_addr_t cmb_base_pa;
267270
dma_addr_t sg_base_pa;

drivers/net/ethernet/pensando/ionic/ionic_lif.c

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static int ionic_start_queues(struct ionic_lif *lif);
4646
static void ionic_stop_queues(struct ionic_lif *lif);
4747
static void ionic_lif_queue_identify(struct ionic_lif *lif);
4848

49-
static int ionic_xdp_queues_config(struct ionic_lif *lif);
49+
static int ionic_xdp_rxqs_update(struct ionic_lif *lif);
5050
static void ionic_xdp_unregister_rxq_info(struct ionic_queue *q);
5151

5252
static void ionic_dim_work(struct work_struct *work)
@@ -2143,7 +2143,7 @@ static int ionic_txrx_enable(struct ionic_lif *lif)
21432143
int derr = 0;
21442144
int i, err;
21452145

2146-
err = ionic_xdp_queues_config(lif);
2146+
err = ionic_xdp_rxqs_update(lif);
21472147
if (err)
21482148
return err;
21492149

@@ -2192,7 +2192,7 @@ static int ionic_txrx_enable(struct ionic_lif *lif)
21922192
derr = ionic_qcq_disable(lif, lif->rxqcqs[i], derr);
21932193
}
21942194

2195-
ionic_xdp_queues_config(lif);
2195+
ionic_xdp_rxqs_update(lif);
21962196

21972197
return err;
21982198
}
@@ -2698,35 +2698,35 @@ static int ionic_xdp_register_rxq_info(struct ionic_queue *q, unsigned int napi_
26982698
return err;
26992699
}
27002700

2701-
static int ionic_xdp_queues_config(struct ionic_lif *lif)
2701+
static int ionic_xdp_rxqs_update(struct ionic_lif *lif)
27022702
{
2703+
struct bpf_prog *xdp_prog;
27032704
unsigned int i;
27042705
int err;
27052706

27062707
if (!lif->rxqcqs)
27072708
return 0;
27082709

2709-
/* There's no need to rework memory if not going to/from NULL program.
2710-
* If there is no lif->xdp_prog, there should also be no q.xdp_rxq_info
2711-
* This way we don't need to keep an *xdp_prog in every queue struct.
2712-
*/
2713-
if (!lif->xdp_prog == !lif->rxqcqs[0]->q.xdp_rxq_info)
2714-
return 0;
2715-
2710+
xdp_prog = READ_ONCE(lif->xdp_prog);
27162711
for (i = 0; i < lif->ionic->nrxqs_per_lif && lif->rxqcqs[i]; i++) {
27172712
struct ionic_queue *q = &lif->rxqcqs[i]->q;
27182713

2719-
if (q->xdp_rxq_info) {
2714+
if (q->xdp_prog) {
27202715
ionic_xdp_unregister_rxq_info(q);
2721-
continue;
2716+
q->xdp_prog = NULL;
27222717
}
27232718

2724-
err = ionic_xdp_register_rxq_info(q, lif->rxqcqs[i]->napi.napi_id);
2725-
if (err) {
2726-
dev_err(lif->ionic->dev, "failed to register RX queue %d info for XDP, err %d\n",
2727-
i, err);
2728-
goto err_out;
2719+
if (xdp_prog) {
2720+
unsigned int napi_id = lif->rxqcqs[i]->napi.napi_id;
2721+
2722+
err = ionic_xdp_register_rxq_info(q, napi_id);
2723+
if (err) {
2724+
dev_err(lif->ionic->dev, "failed to register RX queue %d info for XDP, err %d\n",
2725+
i, err);
2726+
goto err_out;
2727+
}
27292728
}
2729+
q->xdp_prog = xdp_prog;
27302730
}
27312731

27322732
return 0;
@@ -2878,6 +2878,7 @@ static void ionic_swap_queues(struct ionic_qcq *a, struct ionic_qcq *b)
28782878
swap(a->q.base, b->q.base);
28792879
swap(a->q.base_pa, b->q.base_pa);
28802880
swap(a->q.info, b->q.info);
2881+
swap(a->q.xdp_prog, b->q.xdp_prog);
28812882
swap(a->q.xdp_rxq_info, b->q.xdp_rxq_info);
28822883
swap(a->q.partner, b->q.partner);
28832884
swap(a->q_base, b->q_base);

drivers/net/ethernet/pensando/ionic/ionic_txrx.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ static bool ionic_rx_buf_recycle(struct ionic_queue *q,
190190
if (page_to_nid(buf_info->page) != numa_mem_id())
191191
return false;
192192

193-
size = ALIGN(len, q->xdp_rxq_info ? IONIC_PAGE_SIZE : IONIC_PAGE_SPLIT_SZ);
193+
size = ALIGN(len, q->xdp_prog ? IONIC_PAGE_SIZE : IONIC_PAGE_SPLIT_SZ);
194194
buf_info->page_offset += size;
195195
if (buf_info->page_offset >= IONIC_PAGE_SIZE)
196196
return false;
@@ -639,8 +639,7 @@ static void ionic_rx_clean(struct ionic_queue *q,
639639
struct net_device *netdev = q->lif->netdev;
640640
struct ionic_qcq *qcq = q_to_qcq(q);
641641
struct ionic_rx_stats *stats;
642-
struct bpf_prog *xdp_prog;
643-
unsigned int headroom;
642+
unsigned int headroom = 0;
644643
struct sk_buff *skb;
645644
bool synced = false;
646645
bool use_copybreak;
@@ -664,14 +663,13 @@ static void ionic_rx_clean(struct ionic_queue *q,
664663
stats->pkts++;
665664
stats->bytes += len;
666665

667-
xdp_prog = READ_ONCE(q->lif->xdp_prog);
668-
if (xdp_prog) {
669-
if (ionic_run_xdp(stats, netdev, xdp_prog, q, desc_info->bufs, len))
666+
if (q->xdp_prog) {
667+
if (ionic_run_xdp(stats, netdev, q->xdp_prog, q, desc_info->bufs, len))
670668
return;
671669
synced = true;
670+
headroom = XDP_PACKET_HEADROOM;
672671
}
673672

674-
headroom = q->xdp_rxq_info ? XDP_PACKET_HEADROOM : 0;
675673
use_copybreak = len <= q->lif->rx_copybreak;
676674
if (use_copybreak)
677675
skb = ionic_rx_copybreak(netdev, q, desc_info,
@@ -814,7 +812,7 @@ void ionic_rx_fill(struct ionic_queue *q)
814812
len = netdev->mtu + VLAN_ETH_HLEN;
815813

816814
for (i = n_fill; i; i--) {
817-
unsigned int headroom;
815+
unsigned int headroom = 0;
818816
unsigned int buf_len;
819817

820818
nfrags = 0;
@@ -835,11 +833,12 @@ void ionic_rx_fill(struct ionic_queue *q)
835833
* XDP uses space in the first buffer, so account for
836834
* head room, tail room, and ip header in the first frag size.
837835
*/
838-
headroom = q->xdp_rxq_info ? XDP_PACKET_HEADROOM : 0;
839-
if (q->xdp_rxq_info)
836+
if (q->xdp_prog) {
840837
buf_len = IONIC_XDP_MAX_LINEAR_MTU + VLAN_ETH_HLEN;
841-
else
838+
headroom = XDP_PACKET_HEADROOM;
839+
} else {
842840
buf_len = ionic_rx_buf_size(buf_info);
841+
}
843842
frag_len = min_t(u16, len, buf_len);
844843

845844
desc->addr = cpu_to_le64(ionic_rx_buf_pa(buf_info) + headroom);

0 commit comments

Comments
 (0)