net/cxgbe: improve Rx congestion control
Chelsio T6 NIC can support up to 8 priority channels to manage congestion. So, increase to 8 congestion channels for T6. Also, add Rxq state to avoid unnecessarily ringing doorbell and polling the hardware for more traffic when the Rxq is stopped. Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
This commit is contained in:
parent
7b3d52989a
commit
e30e5407fd
@ -162,6 +162,7 @@ struct sge_eth_rx_stats { /* Ethernet rx queue statistics */
|
||||
};
|
||||
|
||||
struct sge_eth_rxq { /* a SW Ethernet Rx queue */
|
||||
unsigned int flags; /* flags for state of the queue */
|
||||
struct sge_rspq rspq;
|
||||
struct sge_fl fl;
|
||||
struct sge_eth_rx_stats stats;
|
||||
@ -199,10 +200,14 @@ struct tx_sw_desc { /* SW state per Tx descriptor */
|
||||
struct tx_eth_coal_desc coalesce;
|
||||
};
|
||||
|
||||
enum {
|
||||
enum cxgbe_txq_state {
|
||||
EQ_STOPPED = (1 << 0),
|
||||
};
|
||||
|
||||
enum cxgbe_rxq_state {
|
||||
IQ_STOPPED = (1 << 0),
|
||||
};
|
||||
|
||||
struct eth_coalesce {
|
||||
unsigned char *ptr;
|
||||
unsigned char type;
|
||||
@ -821,8 +826,8 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *rspq, bool fwevtq,
|
||||
int t4_sge_eth_txq_start(struct sge_eth_txq *txq);
|
||||
int t4_sge_eth_txq_stop(struct sge_eth_txq *txq);
|
||||
void t4_sge_eth_txq_release(struct adapter *adap, struct sge_eth_txq *txq);
|
||||
int t4_sge_eth_rxq_start(struct adapter *adap, struct sge_rspq *rq);
|
||||
int t4_sge_eth_rxq_stop(struct adapter *adap, struct sge_rspq *rq);
|
||||
int t4_sge_eth_rxq_start(struct adapter *adap, struct sge_eth_rxq *rxq);
|
||||
int t4_sge_eth_rxq_stop(struct adapter *adap, struct sge_eth_rxq *rxq);
|
||||
void t4_sge_eth_rxq_release(struct adapter *adap, struct sge_eth_rxq *rxq);
|
||||
void t4_sge_eth_clear_queues(struct port_info *pi);
|
||||
void t4_sge_eth_release_queues(struct port_info *pi);
|
||||
|
@ -187,6 +187,7 @@ struct devlog_params {
|
||||
|
||||
struct arch_specific_params {
|
||||
u8 nchan;
|
||||
u8 cng_ch_bits_log; /* congestion channel map bits width */
|
||||
u16 mps_rplc_size;
|
||||
u16 vfcount;
|
||||
u32 sge_fl_db;
|
||||
|
@ -5044,6 +5044,10 @@ int t4_prep_adapter(struct adapter *adapter)
|
||||
adapter->params.arch.mps_rplc_size = 128;
|
||||
adapter->params.arch.nchan = NCHAN;
|
||||
adapter->params.arch.vfcount = 128;
|
||||
/* Congestion map is for 4 channels so that
|
||||
* MPS can have 4 priority per port.
|
||||
*/
|
||||
adapter->params.arch.cng_ch_bits_log = 2;
|
||||
break;
|
||||
case CHELSIO_T6:
|
||||
adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T6, pl_rev);
|
||||
@ -5053,6 +5057,10 @@ int t4_prep_adapter(struct adapter *adapter)
|
||||
adapter->params.arch.mps_rplc_size = 256;
|
||||
adapter->params.arch.nchan = 2;
|
||||
adapter->params.arch.vfcount = 256;
|
||||
/* Congestion map is for 2 channels so that
|
||||
* MPS can have 8 priority per port.
|
||||
*/
|
||||
adapter->params.arch.cng_ch_bits_log = 3;
|
||||
break;
|
||||
default:
|
||||
dev_err(adapter, "%s: Device %d is not supported\n",
|
||||
|
@ -562,17 +562,16 @@ void cxgbe_dev_tx_queue_release(void *q)
|
||||
|
||||
int cxgbe_dev_rx_queue_start(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
|
||||
{
|
||||
int ret;
|
||||
struct port_info *pi = eth_dev->data->dev_private;
|
||||
struct adapter *adap = pi->adapter;
|
||||
struct sge_rspq *q;
|
||||
struct sge_eth_rxq *rxq;
|
||||
int ret;
|
||||
|
||||
dev_debug(adapter, "%s: pi->port_id = %d; rx_queue_id = %d\n",
|
||||
__func__, pi->port_id, rx_queue_id);
|
||||
|
||||
q = eth_dev->data->rx_queues[rx_queue_id];
|
||||
|
||||
ret = t4_sge_eth_rxq_start(adap, q);
|
||||
rxq = eth_dev->data->rx_queues[rx_queue_id];
|
||||
ret = t4_sge_eth_rxq_start(adap, rxq);
|
||||
if (ret == 0)
|
||||
eth_dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
|
||||
|
||||
@ -581,16 +580,16 @@ int cxgbe_dev_rx_queue_start(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
|
||||
|
||||
int cxgbe_dev_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
|
||||
{
|
||||
int ret;
|
||||
struct port_info *pi = eth_dev->data->dev_private;
|
||||
struct adapter *adap = pi->adapter;
|
||||
struct sge_rspq *q;
|
||||
struct sge_eth_rxq *rxq;
|
||||
int ret;
|
||||
|
||||
dev_debug(adapter, "%s: pi->port_id = %d; rx_queue_id = %d\n",
|
||||
__func__, pi->port_id, rx_queue_id);
|
||||
|
||||
q = eth_dev->data->rx_queues[rx_queue_id];
|
||||
ret = t4_sge_eth_rxq_stop(adap, q);
|
||||
rxq = eth_dev->data->rx_queues[rx_queue_id];
|
||||
ret = t4_sge_eth_rxq_stop(adap, rxq);
|
||||
if (ret == 0)
|
||||
eth_dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
|
||||
|
||||
|
@ -1694,6 +1694,11 @@ int cxgbe_poll(struct sge_rspq *q, struct rte_mbuf **rx_pkts,
|
||||
unsigned int params;
|
||||
u32 val;
|
||||
|
||||
if (unlikely(rxq->flags & IQ_STOPPED)) {
|
||||
*work_done = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*work_done = process_responses(q, budget, rx_pkts);
|
||||
|
||||
if (*work_done) {
|
||||
@ -1754,22 +1759,22 @@ static void __iomem *bar2_address(struct adapter *adapter, unsigned int qid,
|
||||
return adapter->bar2 + bar2_qoffset;
|
||||
}
|
||||
|
||||
int t4_sge_eth_rxq_start(struct adapter *adap, struct sge_rspq *rq)
|
||||
int t4_sge_eth_rxq_start(struct adapter *adap, struct sge_eth_rxq *rxq)
|
||||
{
|
||||
struct sge_eth_rxq *rxq = container_of(rq, struct sge_eth_rxq, rspq);
|
||||
unsigned int fl_id = rxq->fl.size ? rxq->fl.cntxt_id : 0xffff;
|
||||
|
||||
rxq->flags &= ~IQ_STOPPED;
|
||||
return t4_iq_start_stop(adap, adap->mbox, true, adap->pf, 0,
|
||||
rq->cntxt_id, fl_id, 0xffff);
|
||||
rxq->rspq.cntxt_id, fl_id, 0xffff);
|
||||
}
|
||||
|
||||
int t4_sge_eth_rxq_stop(struct adapter *adap, struct sge_rspq *rq)
|
||||
int t4_sge_eth_rxq_stop(struct adapter *adap, struct sge_eth_rxq *rxq)
|
||||
{
|
||||
struct sge_eth_rxq *rxq = container_of(rq, struct sge_eth_rxq, rspq);
|
||||
unsigned int fl_id = rxq->fl.size ? rxq->fl.cntxt_id : 0xffff;
|
||||
|
||||
rxq->flags |= IQ_STOPPED;
|
||||
return t4_iq_start_stop(adap, adap->mbox, false, adap->pf, 0,
|
||||
rq->cntxt_id, fl_id, 0xffff);
|
||||
rxq->rspq.cntxt_id, fl_id, 0xffff);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1949,7 +1954,8 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
|
||||
* simple (and hopefully less wrong).
|
||||
*/
|
||||
if (is_pf4(adap) && !is_t4(adap->params.chip) && cong >= 0) {
|
||||
u32 param, val;
|
||||
u8 cng_ch_bits_log = adap->params.arch.cng_ch_bits_log;
|
||||
u32 param, val, ch_map = 0;
|
||||
int i;
|
||||
|
||||
param = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) |
|
||||
@ -1962,9 +1968,9 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
|
||||
X_CONMCTXT_CNGTPMODE_CHANNEL);
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (cong & (1 << i))
|
||||
val |= V_CONMCTXT_CNGCHMAP(1 <<
|
||||
(i << 2));
|
||||
ch_map |= 1 << (i << cng_ch_bits_log);
|
||||
}
|
||||
val |= V_CONMCTXT_CNGCHMAP(ch_map);
|
||||
}
|
||||
ret = t4_set_params(adap, adap->mbox, adap->pf, 0, 1,
|
||||
¶m, &val);
|
||||
@ -2201,7 +2207,7 @@ void t4_sge_eth_clear_queues(struct port_info *pi)
|
||||
rxq = &adap->sge.ethrxq[pi->first_rxqset];
|
||||
for (i = 0; i < pi->n_rx_qsets; i++, rxq++) {
|
||||
if (rxq->rspq.desc)
|
||||
t4_sge_eth_rxq_stop(adap, &rxq->rspq);
|
||||
t4_sge_eth_rxq_stop(adap, rxq);
|
||||
}
|
||||
|
||||
txq = &adap->sge.ethtxq[pi->first_txqset];
|
||||
@ -2220,7 +2226,7 @@ void t4_sge_eth_clear_queues(struct port_info *pi)
|
||||
void t4_sge_eth_rxq_release(struct adapter *adap, struct sge_eth_rxq *rxq)
|
||||
{
|
||||
if (rxq->rspq.desc) {
|
||||
t4_sge_eth_rxq_stop(adap, &rxq->rspq);
|
||||
t4_sge_eth_rxq_stop(adap, rxq);
|
||||
free_rspq_fl(adap, &rxq->rspq, rxq->fl.size ? &rxq->fl : NULL);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user