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:
parent
14f534be40
commit
e7222f947e
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user