net/ionic: free all buffers during Rx queue stop

Free all of the mbufs in the receive queue when the queue is
stopped. This will allow them to be resized when the MTU is
changed.

Signed-off-by: Andrew Boyer <andrew.boyer@amd.com>
This commit is contained in:
Andrew Boyer 2022-10-18 12:41:11 -07:00 committed by Ferruh Yigit
parent 14f534be40
commit e7222f947e
5 changed files with 81 additions and 89 deletions

View File

@ -317,6 +317,15 @@ ionic_cq_init(struct ionic_cq *cq, uint16_t num_descs)
return 0;
}
void
ionic_cq_reset(struct ionic_cq *cq)
{
cq->tail_idx = 0;
cq->done_color = 1;
memset(cq->base, 0, sizeof(struct ionic_nop_comp) * cq->num_descs);
}
void
ionic_cq_map(struct ionic_cq *cq, void *base, rte_iova_t base_pa)
{
@ -379,3 +388,10 @@ ionic_q_sg_map(struct ionic_queue *q, void *base, rte_iova_t base_pa)
q->sg_base = base;
q->sg_base_pa = base_pa;
}
void
ionic_q_reset(struct ionic_queue *q)
{
q->head_idx = 0;
q->tail_idx = 0;
}

View File

@ -225,6 +225,7 @@ struct ionic_doorbell __iomem *ionic_db_map(struct ionic_lif *lif,
struct ionic_queue *q);
int ionic_cq_init(struct ionic_cq *cq, uint16_t num_descs);
void ionic_cq_reset(struct ionic_cq *cq);
void ionic_cq_map(struct ionic_cq *cq, void *base, rte_iova_t base_pa);
typedef bool (*ionic_cq_cb)(struct ionic_cq *cq, uint16_t cq_desc_index,
void *cb_arg);
@ -232,6 +233,7 @@ uint32_t ionic_cq_service(struct ionic_cq *cq, uint32_t work_to_do,
ionic_cq_cb cb, void *cb_arg);
int ionic_q_init(struct ionic_queue *q, uint32_t index, uint16_t num_descs);
void ionic_q_reset(struct ionic_queue *q);
void ionic_q_map(struct ionic_queue *q, void *base, rte_iova_t base_pa);
void ionic_q_sg_map(struct ionic_queue *q, void *base, rte_iova_t base_pa);

View File

@ -30,25 +30,7 @@ static const uint8_t ionic_qtype_vers[IONIC_QTYPE_MAX] = {
static int ionic_lif_addr_add(struct ionic_lif *lif, const uint8_t *addr);
static int ionic_lif_addr_del(struct ionic_lif *lif, const uint8_t *addr);
int
ionic_qcq_enable(struct ionic_qcq *qcq)
{
struct ionic_queue *q = &qcq->q;
struct ionic_lif *lif = qcq->lif;
struct ionic_admin_ctx ctx = {
.pending_work = true,
.cmd.q_control = {
.opcode = IONIC_CMD_Q_CONTROL,
.type = q->type,
.index = rte_cpu_to_le_32(q->index),
.oper = IONIC_Q_ENABLE,
},
};
return ionic_adminq_post_wait(lif, &ctx);
}
int
static int
ionic_qcq_disable(struct ionic_qcq *qcq)
{
struct ionic_queue *q = &qcq->q;
@ -133,7 +115,6 @@ ionic_lif_get_abs_stats(const struct ionic_lif *lif, struct rte_eth_stats *stats
for (i = 0; i < lif->nrxqcqs; i++) {
struct ionic_rx_stats *rx_stats = &lif->rxqcqs[i]->stats;
stats->ierrors +=
rx_stats->no_cb_arg +
rx_stats->bad_cq_status +
rx_stats->no_room +
rx_stats->bad_len;
@ -154,7 +135,6 @@ ionic_lif_get_abs_stats(const struct ionic_lif *lif, struct rte_eth_stats *stats
stats->q_ipackets[i] = rx_stats->packets;
stats->q_ibytes[i] = rx_stats->bytes;
stats->q_errors[i] =
rx_stats->no_cb_arg +
rx_stats->bad_cq_status +
rx_stats->no_room +
rx_stats->bad_len;
@ -1146,12 +1126,16 @@ ionic_lif_rss_teardown(struct ionic_lif *lif)
void
ionic_lif_txq_deinit(struct ionic_tx_qcq *txq)
{
ionic_qcq_disable(&txq->qcq);
txq->flags &= ~IONIC_QCQ_F_INITED;
}
void
ionic_lif_rxq_deinit(struct ionic_rx_qcq *rxq)
{
ionic_qcq_disable(&rxq->qcq);
rxq->flags &= ~IONIC_QCQ_F_INITED;
}
@ -1488,6 +1472,9 @@ ionic_lif_txq_init(struct ionic_tx_qcq *txq)
ctx.cmd.q_init.ring_size);
IONIC_PRINT(DEBUG, "txq_init.ver %u", ctx.cmd.q_init.ver);
ionic_q_reset(q);
ionic_cq_reset(cq);
err = ionic_adminq_post_wait(lif, &ctx);
if (err)
return err;
@ -1536,6 +1523,9 @@ ionic_lif_rxq_init(struct ionic_rx_qcq *rxq)
ctx.cmd.q_init.ring_size);
IONIC_PRINT(DEBUG, "rxq_init.ver %u", ctx.cmd.q_init.ver);
ionic_q_reset(q);
ionic_cq_reset(cq);
err = ionic_adminq_post_wait(lif, &ctx);
if (err)
return err;

View File

@ -39,7 +39,6 @@ struct ionic_tx_stats {
struct ionic_rx_stats {
uint64_t packets;
uint64_t bytes;
uint64_t no_cb_arg;
uint64_t bad_cq_status;
uint64_t no_room;
uint64_t bad_len;
@ -207,9 +206,6 @@ int ionic_tx_qcq_alloc(struct ionic_lif *lif, uint32_t socket_id,
struct ionic_tx_qcq **qcq_out);
void ionic_qcq_free(struct ionic_qcq *qcq);
int ionic_qcq_enable(struct ionic_qcq *qcq);
int ionic_qcq_disable(struct ionic_qcq *qcq);
int ionic_lif_rxq_init(struct ionic_rx_qcq *rxq);
void ionic_lif_rxq_deinit(struct ionic_rx_qcq *rxq);

View File

@ -47,6 +47,34 @@
#include "ionic_lif.h"
#include "ionic_rxtx.h"
static void
ionic_empty_array(void **array, uint32_t cnt, uint16_t idx)
{
uint32_t i;
for (i = idx; i < cnt; i++)
if (array[i])
rte_pktmbuf_free_seg(array[i]);
memset(array, 0, sizeof(void *) * cnt);
}
static void __rte_cold
ionic_tx_empty(struct ionic_tx_qcq *txq)
{
struct ionic_queue *q = &txq->qcq.q;
ionic_empty_array(q->info, q->num_descs, 0);
}
static void __rte_cold
ionic_rx_empty(struct ionic_rx_qcq *rxq)
{
struct ionic_queue *q = &rxq->qcq.q;
ionic_empty_array(q->info, q->num_descs, 0);
}
/*********************************************************************
*
* TX functions
@ -121,21 +149,16 @@ void __rte_cold
ionic_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
{
struct ionic_tx_qcq *txq = dev->data->tx_queues[qid];
struct ionic_tx_stats *stats = &txq->stats;
IONIC_PRINT_CALL();
IONIC_PRINT(DEBUG, "TX queue %u pkts %ju tso %ju",
txq->qcq.q.index, stats->packets, stats->tso);
ionic_lif_txq_deinit(txq);
ionic_qcq_free(&txq->qcq);
}
int __rte_cold
ionic_dev_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
{
struct ionic_tx_stats *stats;
struct ionic_tx_qcq *txq;
IONIC_PRINT(DEBUG, "Stopping TX queue %u", tx_queue_id);
@ -150,9 +173,14 @@ ionic_dev_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
* before disabling Tx queue
*/
ionic_qcq_disable(&txq->qcq);
ionic_lif_txq_deinit(txq);
ionic_tx_flush(txq);
/* Free all buffers from descriptor ring */
ionic_tx_empty(txq);
stats = &txq->stats;
IONIC_PRINT(DEBUG, "TX queue %u pkts %ju tso %ju",
txq->qcq.q.index, stats->packets, stats->tso);
return 0;
}
@ -236,13 +264,9 @@ ionic_dev_tx_queue_start(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
IONIC_PRINT(DEBUG, "Starting TX queue %u, %u descs",
tx_queue_id, txq->qcq.q.num_descs);
if (!(txq->flags & IONIC_QCQ_F_INITED)) {
err = ionic_lif_txq_init(txq);
if (err)
return err;
} else {
ionic_qcq_enable(&txq->qcq);
}
err = ionic_lif_txq_init(txq);
if (err)
return err;
tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
@ -648,42 +672,16 @@ ionic_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
qinfo->conf.offloads = dev->data->dev_conf.rxmode.offloads;
}
static void __rte_cold
ionic_rx_empty(struct ionic_rx_qcq *rxq)
{
struct ionic_queue *q = &rxq->qcq.q;
struct rte_mbuf *mbuf;
void **info;
while (q->tail_idx != q->head_idx) {
info = IONIC_INFO_PTR(q, q->tail_idx);
mbuf = info[0];
rte_mempool_put(rxq->mb_pool, mbuf);
q->tail_idx = Q_NEXT_TO_SRVC(q, 1);
}
}
void __rte_cold
ionic_dev_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
{
struct ionic_rx_qcq *rxq = dev->data->rx_queues[qid];
struct ionic_rx_stats *stats;
if (!rxq)
return;
IONIC_PRINT_CALL();
stats = &rxq->stats;
IONIC_PRINT(DEBUG, "RX queue %u pkts %ju mtod %ju",
rxq->qcq.q.index, stats->packets, stats->mtods);
ionic_rx_empty(rxq);
ionic_lif_rxq_deinit(rxq);
ionic_qcq_free(&rxq->qcq);
}
@ -787,17 +785,6 @@ ionic_rx_clean(struct ionic_rx_qcq *rxq,
rxm = info[0];
if (!rx_svc) {
stats->no_cb_arg++;
/* Flush */
rte_pktmbuf_free(rxm);
/*
* Note: rte_mempool_put is faster with no segs
* rte_mempool_put(rxq->mb_pool, rxm);
*/
return;
}
if (cq_desc->status) {
stats->bad_cq_status++;
ionic_rx_recycle(q, q_desc_index, rxm);
@ -1028,13 +1015,9 @@ ionic_dev_rx_queue_start(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
IONIC_PRINT(DEBUG, "Starting RX queue %u, %u descs, size %u",
rx_queue_id, rxq->qcq.q.num_descs, rxq->frame_size);
if (!(rxq->flags & IONIC_QCQ_F_INITED)) {
err = ionic_lif_rxq_init(rxq);
if (err)
return err;
} else {
ionic_qcq_enable(&rxq->qcq);
}
err = ionic_lif_rxq_init(rxq);
if (err)
return err;
/* Allocate buffers for descriptor rings */
if (ionic_rx_fill(rxq) != 0) {
@ -1103,19 +1086,24 @@ ionic_rxq_service(struct ionic_rx_qcq *rxq, uint32_t work_to_do,
int __rte_cold
ionic_dev_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
{
uint8_t *rx_queue_state = eth_dev->data->rx_queue_state;
struct ionic_rx_stats *stats;
struct ionic_rx_qcq *rxq;
IONIC_PRINT(DEBUG, "Stopping RX queue %u", rx_queue_id);
rxq = eth_dev->data->rx_queues[rx_queue_id];
eth_dev->data->rx_queue_state[rx_queue_id] =
RTE_ETH_QUEUE_STATE_STOPPED;
rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
ionic_qcq_disable(&rxq->qcq);
ionic_lif_rxq_deinit(rxq);
/* Flush */
ionic_rxq_service(rxq, -1, NULL);
/* Free all buffers from descriptor ring */
ionic_rx_empty(rxq);
stats = &rxq->stats;
IONIC_PRINT(DEBUG, "RX queue %u pkts %ju mtod %ju",
rxq->qcq.q.index, stats->packets, stats->mtods);
return 0;
}