Commit ac8813c0 authored by Shannon Nelson's avatar Shannon Nelson Committed by Jakub Kicinski

ionic: convert Rx queue buffers to use page_pool

Our home-grown buffer management needs to go away and we need
to be playing nicely with the page_pool infrastructure.  This
converts the Rx traffic queues to use page_pool.

Also, since ionic_rx_buf_size() was removed, redefine
IONIC_PAGE_SIZE to account for IONIC_MAX_BUF_LEN being the
largest allowed buffer to prevent overflowing u16 variables,
which could happen when PAGE_SIZE is defined as >= 64KB.

include/linux/minmax.h:93:37: warning: conversion from 'long unsigned int' to 'u16' {aka 'short unsigned int'} changes value from '65536' to '0' [-Woverflow]
Signed-off-by: default avatarShannon Nelson <shannon.nelson@amd.com>
Signed-off-by: default avatarBrett Creeley <brett.creeley@amd.com>
Link: https://patch.msgid.link/20240906232623.39651-7-brett.creeley@amd.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent a7f3f635
......@@ -23,6 +23,7 @@ config IONIC
depends on PTP_1588_CLOCK_OPTIONAL
select NET_DEVLINK
select DIMLIB
select PAGE_POOL
help
This enables the support for the Pensando family of Ethernet
adapters. More specific information on this driver can be
......
......@@ -181,10 +181,7 @@ struct ionic_queue;
struct ionic_qcq;
#define IONIC_MAX_BUF_LEN ((u16)-1)
#define IONIC_PAGE_SIZE PAGE_SIZE
#define IONIC_PAGE_SPLIT_SZ (PAGE_SIZE / 2)
#define IONIC_PAGE_GFP_MASK (GFP_ATOMIC | __GFP_NOWARN |\
__GFP_COMP | __GFP_MEMALLOC)
#define IONIC_PAGE_SIZE MIN(PAGE_SIZE, IONIC_MAX_BUF_LEN)
#define IONIC_XDP_MAX_LINEAR_MTU (IONIC_PAGE_SIZE - \
(VLAN_ETH_HLEN + \
......@@ -248,11 +245,6 @@ struct ionic_queue {
struct ionic_rxq_desc *rxq;
struct ionic_admin_cmd *adminq;
};
union {
void __iomem *cmb_base;
struct ionic_txq_desc __iomem *cmb_txq;
struct ionic_rxq_desc __iomem *cmb_rxq;
};
union {
void *sg_base;
struct ionic_txq_sg_desc *txq_sgl;
......@@ -261,8 +253,14 @@ struct ionic_queue {
};
struct xdp_rxq_info *xdp_rxq_info;
struct bpf_prog *xdp_prog;
struct page_pool *page_pool;
struct ionic_queue *partner;
union {
void __iomem *cmb_base;
struct ionic_txq_desc __iomem *cmb_txq;
struct ionic_rxq_desc __iomem *cmb_rxq;
};
unsigned int type;
unsigned int hw_index;
dma_addr_t base_pa;
......
......@@ -13,6 +13,7 @@
#include <linux/cpumask.h>
#include <linux/crash_dump.h>
#include <linux/vmalloc.h>
#include <net/page_pool/helpers.h>
#include "ionic.h"
#include "ionic_bus.h"
......@@ -439,6 +440,9 @@ static void ionic_qcq_free(struct ionic_lif *lif, struct ionic_qcq *qcq)
qcq->sg_base_pa = 0;
}
page_pool_destroy(qcq->q.page_pool);
qcq->q.page_pool = NULL;
ionic_qcq_intr_free(lif, qcq);
vfree(qcq->q.info);
qcq->q.info = NULL;
......@@ -553,7 +557,8 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,
unsigned int cq_desc_size,
unsigned int sg_desc_size,
unsigned int desc_info_size,
unsigned int pid, struct ionic_qcq **qcq)
unsigned int pid, struct bpf_prog *xdp_prog,
struct ionic_qcq **qcq)
{
struct ionic_dev *idev = &lif->ionic->idev;
struct device *dev = lif->ionic->dev;
......@@ -579,6 +584,31 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,
goto err_out_free_qcq;
}
if (type == IONIC_QTYPE_RXQ) {
struct page_pool_params pp_params = {
.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV,
.order = 0,
.pool_size = num_descs,
.nid = NUMA_NO_NODE,
.dev = lif->ionic->dev,
.napi = &new->napi,
.dma_dir = DMA_FROM_DEVICE,
.max_len = PAGE_SIZE,
.netdev = lif->netdev,
};
if (xdp_prog)
pp_params.dma_dir = DMA_BIDIRECTIONAL;
new->q.page_pool = page_pool_create(&pp_params);
if (IS_ERR(new->q.page_pool)) {
netdev_err(lif->netdev, "Cannot create page_pool\n");
err = PTR_ERR(new->q.page_pool);
new->q.page_pool = NULL;
goto err_out_free_q_info;
}
}
new->q.type = type;
new->q.max_sg_elems = lif->qtype_info[type].max_sg_elems;
......@@ -586,12 +616,12 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,
desc_size, sg_desc_size, pid);
if (err) {
netdev_err(lif->netdev, "Cannot initialize queue\n");
goto err_out_free_q_info;
goto err_out_free_page_pool;
}
err = ionic_alloc_qcq_interrupt(lif, new);
if (err)
goto err_out_free_q_info;
goto err_out_free_page_pool;
err = ionic_cq_init(lif, &new->cq, &new->intr, num_descs, cq_desc_size);
if (err) {
......@@ -712,6 +742,8 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,
devm_free_irq(dev, new->intr.vector, &new->napi);
ionic_intr_free(lif->ionic, new->intr.index);
}
err_out_free_page_pool:
page_pool_destroy(new->q.page_pool);
err_out_free_q_info:
vfree(new->q.info);
err_out_free_qcq:
......@@ -734,7 +766,7 @@ static int ionic_qcqs_alloc(struct ionic_lif *lif)
sizeof(struct ionic_admin_comp),
0,
sizeof(struct ionic_admin_desc_info),
lif->kern_pid, &lif->adminqcq);
lif->kern_pid, NULL, &lif->adminqcq);
if (err)
return err;
ionic_debugfs_add_qcq(lif, lif->adminqcq);
......@@ -747,7 +779,7 @@ static int ionic_qcqs_alloc(struct ionic_lif *lif)
sizeof(union ionic_notifyq_comp),
0,
sizeof(struct ionic_admin_desc_info),
lif->kern_pid, &lif->notifyqcq);
lif->kern_pid, NULL, &lif->notifyqcq);
if (err)
goto err_out;
ionic_debugfs_add_qcq(lif, lif->notifyqcq);
......@@ -965,7 +997,7 @@ int ionic_lif_create_hwstamp_txq(struct ionic_lif *lif)
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, txq_i, "hwstamp_tx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
sizeof(struct ionic_tx_desc_info),
lif->kern_pid, &txq);
lif->kern_pid, NULL, &txq);
if (err)
goto err_qcq_alloc;
......@@ -1025,7 +1057,7 @@ int ionic_lif_create_hwstamp_rxq(struct ionic_lif *lif)
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, rxq_i, "hwstamp_rx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
sizeof(struct ionic_rx_desc_info),
lif->kern_pid, &rxq);
lif->kern_pid, NULL, &rxq);
if (err)
goto err_qcq_alloc;
......@@ -2051,7 +2083,7 @@ static int ionic_txrx_alloc(struct ionic_lif *lif)
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
sizeof(struct ionic_tx_desc_info),
lif->kern_pid, &lif->txqcqs[i]);
lif->kern_pid, NULL, &lif->txqcqs[i]);
if (err)
goto err_out;
......@@ -2083,7 +2115,8 @@ static int ionic_txrx_alloc(struct ionic_lif *lif)
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
sizeof(struct ionic_rx_desc_info),
lif->kern_pid, &lif->rxqcqs[i]);
lif->kern_pid, lif->xdp_prog,
&lif->rxqcqs[i]);
if (err)
goto err_out;
......@@ -2679,15 +2712,15 @@ static int ionic_register_rxq_info(struct ionic_queue *q, unsigned int napi_id)
err = xdp_rxq_info_reg(rxq_info, q->lif->netdev, q->index, napi_id);
if (err) {
dev_err(q->dev, "Queue %d xdp_rxq_info_reg failed, err %d\n",
q->index, err);
netdev_err(q->lif->netdev, "q%d xdp_rxq_info_reg failed, err %d\n",
q->index, err);
goto err_out;
}
err = xdp_rxq_info_reg_mem_model(rxq_info, MEM_TYPE_PAGE_ORDER0, NULL);
err = xdp_rxq_info_reg_mem_model(rxq_info, MEM_TYPE_PAGE_POOL, q->page_pool);
if (err) {
dev_err(q->dev, "Queue %d xdp_rxq_info_reg_mem_model failed, err %d\n",
q->index, err);
netdev_err(q->lif->netdev, "q%d xdp_rxq_info_reg_mem_model failed, err %d\n",
q->index, err);
xdp_rxq_info_unreg(rxq_info);
goto err_out;
}
......@@ -2853,7 +2886,16 @@ static int ionic_cmb_reconfig(struct ionic_lif *lif,
static void ionic_swap_queues(struct ionic_qcq *a, struct ionic_qcq *b)
{
/* only swapping the queues, not the napi, flags, or other stuff */
/* only swapping the queues and napi, not flags or other stuff */
swap(a->napi, b->napi);
if (a->q.type == IONIC_QTYPE_RXQ) {
swap(a->q.page_pool, b->q.page_pool);
a->q.page_pool->p.napi = &a->napi;
if (b->q.page_pool) /* is NULL when increasing queue count */
b->q.page_pool->p.napi = &b->napi;
}
swap(a->q.features, b->q.features);
swap(a->q.num_descs, b->q.num_descs);
swap(a->q.desc_size, b->q.desc_size);
......@@ -2943,7 +2985,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags,
4, desc_sz, comp_sz, sg_desc_sz,
sizeof(struct ionic_tx_desc_info),
lif->kern_pid, &lif->txqcqs[i]);
lif->kern_pid, NULL, &lif->txqcqs[i]);
if (err)
goto err_out;
}
......@@ -2952,7 +2994,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
sizeof(struct ionic_tx_desc_info),
lif->kern_pid, &tx_qcqs[i]);
lif->kern_pid, NULL, &tx_qcqs[i]);
if (err)
goto err_out;
}
......@@ -2974,7 +3016,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags,
4, desc_sz, comp_sz, sg_desc_sz,
sizeof(struct ionic_rx_desc_info),
lif->kern_pid, &lif->rxqcqs[i]);
lif->kern_pid, NULL, &lif->rxqcqs[i]);
if (err)
goto err_out;
}
......@@ -2983,7 +3025,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
sizeof(struct ionic_rx_desc_info),
lif->kern_pid, &rx_qcqs[i]);
lif->kern_pid, qparam->xdp_prog, &rx_qcqs[i]);
if (err)
goto err_out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment