diff options
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_dev.h | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_lif.c | 37 | ||||
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 21 |
3 files changed, 34 insertions, 31 deletions
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h index f2f07bf88545..3ae6b34cc85f 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h @@ -238,9 +238,8 @@ struct ionic_queue { unsigned int index; unsigned int num_descs; unsigned int max_sg_elems; + u64 features; - unsigned int type; - unsigned int hw_index; unsigned int hw_type; bool xdp_flush; union { @@ -261,7 +260,11 @@ struct ionic_queue { struct ionic_rxq_sg_desc *rxq_sgl; }; struct xdp_rxq_info *xdp_rxq_info; + struct bpf_prog *xdp_prog; struct ionic_queue *partner; + + unsigned int type; + unsigned int hw_index; dma_addr_t base_pa; dma_addr_t cmb_base_pa; dma_addr_t sg_base_pa; diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index 86774d9922d8..68b540d26702 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -46,7 +46,7 @@ static int ionic_start_queues(struct ionic_lif *lif); static void ionic_stop_queues(struct ionic_lif *lif); static void ionic_lif_queue_identify(struct ionic_lif *lif); -static int ionic_xdp_queues_config(struct ionic_lif *lif); +static int ionic_xdp_rxqs_update(struct ionic_lif *lif); static void ionic_xdp_unregister_rxq_info(struct ionic_queue *q); static void ionic_dim_work(struct work_struct *work) @@ -2143,7 +2143,7 @@ static int ionic_txrx_enable(struct ionic_lif *lif) int derr = 0; int i, err; - err = ionic_xdp_queues_config(lif); + err = ionic_xdp_rxqs_update(lif); if (err) return err; @@ -2192,7 +2192,7 @@ err_out: derr = ionic_qcq_disable(lif, lif->rxqcqs[i], derr); } - ionic_xdp_queues_config(lif); + ionic_xdp_rxqs_update(lif); return err; } @@ -2698,35 +2698,35 @@ err_out: return err; } -static int ionic_xdp_queues_config(struct ionic_lif *lif) +static int ionic_xdp_rxqs_update(struct ionic_lif *lif) { + struct bpf_prog *xdp_prog; unsigned int i; int err; if (!lif->rxqcqs) return 0; - /* There's no need to rework memory if not going to/from NULL program. - * If there is no lif->xdp_prog, there should also be no q.xdp_rxq_info - * This way we don't need to keep an *xdp_prog in every queue struct. - */ - if (!lif->xdp_prog == !lif->rxqcqs[0]->q.xdp_rxq_info) - return 0; - + xdp_prog = READ_ONCE(lif->xdp_prog); for (i = 0; i < lif->ionic->nrxqs_per_lif && lif->rxqcqs[i]; i++) { struct ionic_queue *q = &lif->rxqcqs[i]->q; - if (q->xdp_rxq_info) { + if (q->xdp_prog) { ionic_xdp_unregister_rxq_info(q); - continue; + q->xdp_prog = NULL; } - err = ionic_xdp_register_rxq_info(q, lif->rxqcqs[i]->napi.napi_id); - if (err) { - dev_err(lif->ionic->dev, "failed to register RX queue %d info for XDP, err %d\n", - i, err); - goto err_out; + if (xdp_prog) { + unsigned int napi_id = lif->rxqcqs[i]->napi.napi_id; + + err = ionic_xdp_register_rxq_info(q, napi_id); + if (err) { + dev_err(lif->ionic->dev, "failed to register RX queue %d info for XDP, err %d\n", + i, err); + goto err_out; + } } + q->xdp_prog = xdp_prog; } return 0; @@ -2878,6 +2878,7 @@ static void ionic_swap_queues(struct ionic_qcq *a, struct ionic_qcq *b) swap(a->q.base, b->q.base); swap(a->q.base_pa, b->q.base_pa); swap(a->q.info, b->q.info); + swap(a->q.xdp_prog, b->q.xdp_prog); swap(a->q.xdp_rxq_info, b->q.xdp_rxq_info); swap(a->q.partner, b->q.partner); swap(a->q_base, b->q_base); diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c index d62b2b60b133..858ab4fd9218 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c @@ -190,7 +190,7 @@ static bool ionic_rx_buf_recycle(struct ionic_queue *q, if (page_to_nid(buf_info->page) != numa_mem_id()) return false; - size = ALIGN(len, q->xdp_rxq_info ? IONIC_PAGE_SIZE : IONIC_PAGE_SPLIT_SZ); + size = ALIGN(len, q->xdp_prog ? IONIC_PAGE_SIZE : IONIC_PAGE_SPLIT_SZ); buf_info->page_offset += size; if (buf_info->page_offset >= IONIC_PAGE_SIZE) return false; @@ -639,8 +639,7 @@ static void ionic_rx_clean(struct ionic_queue *q, struct net_device *netdev = q->lif->netdev; struct ionic_qcq *qcq = q_to_qcq(q); struct ionic_rx_stats *stats; - struct bpf_prog *xdp_prog; - unsigned int headroom; + unsigned int headroom = 0; struct sk_buff *skb; bool synced = false; bool use_copybreak; @@ -664,14 +663,13 @@ static void ionic_rx_clean(struct ionic_queue *q, stats->pkts++; stats->bytes += len; - xdp_prog = READ_ONCE(q->lif->xdp_prog); - if (xdp_prog) { - if (ionic_run_xdp(stats, netdev, xdp_prog, q, desc_info->bufs, len)) + if (q->xdp_prog) { + if (ionic_run_xdp(stats, netdev, q->xdp_prog, q, desc_info->bufs, len)) return; synced = true; + headroom = XDP_PACKET_HEADROOM; } - headroom = q->xdp_rxq_info ? XDP_PACKET_HEADROOM : 0; use_copybreak = len <= q->lif->rx_copybreak; if (use_copybreak) skb = ionic_rx_copybreak(netdev, q, desc_info, @@ -814,7 +812,7 @@ void ionic_rx_fill(struct ionic_queue *q) len = netdev->mtu + VLAN_ETH_HLEN; for (i = n_fill; i; i--) { - unsigned int headroom; + unsigned int headroom = 0; unsigned int buf_len; nfrags = 0; @@ -835,11 +833,12 @@ void ionic_rx_fill(struct ionic_queue *q) * XDP uses space in the first buffer, so account for * head room, tail room, and ip header in the first frag size. */ - headroom = q->xdp_rxq_info ? XDP_PACKET_HEADROOM : 0; - if (q->xdp_rxq_info) + if (q->xdp_prog) { buf_len = IONIC_XDP_MAX_LINEAR_MTU + VLAN_ETH_HLEN; - else + headroom = XDP_PACKET_HEADROOM; + } else { buf_len = ionic_rx_buf_size(buf_info); + } frag_len = min_t(u16, len, buf_len); desc->addr = cpu_to_le64(ionic_rx_buf_pa(buf_info) + headroom); |