diff options
author | Edward Cree <ecree@solarflare.com> | 2020-07-02 19:29:58 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-07-03 00:47:40 +0300 |
commit | a81dcd85a7c1bc548ce8fb635623970fdee5887d (patch) | |
tree | 832617d7896bd2e5fcd88aa1c740c5367e8dfbee /drivers/net/ethernet/sfc/tx.c | |
parent | 69a704962e8cab43bd62301e104c222e7d23e361 (diff) | |
download | linux-a81dcd85a7c1bc548ce8fb635623970fdee5887d.tar.xz |
sfc: assign TXQs without gaps
Since we only allocate VIs for the number of TXQs we actually need, we
cannot naively use "channel * TXQ_TYPES + txq" for the TXQ number, as
this has gaps (when efx->tx_queues_per_channel < EFX_TXQ_TYPES) and
thus overruns the driver's VI allocations, causing the firmware to
reject the MC_CMD_INIT_TXQ based on INSTANCE.
Thus, we distinguish INSTANCE (stored in tx_queue->queue) from LABEL
(tx_queue->label); the former is allocated starting from 0 in
efx_set_channels(), while the latter is simply the txq type (index in
channel->tx_queue array).
To simplify things, rather than changing tx_queues_per_channel after
setting up TXQs, make Siena always probe its HIGHPRI queues at start
of day, rather than deferring it until tc mqprio enables them.
Signed-off-by: Edward Cree <ecree@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/sfc/tx.c')
-rw-r--r-- | drivers/net/ethernet/sfc/tx.c | 46 |
1 files changed, 6 insertions, 40 deletions
diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c index 76ff394f5b58..1bcf50ab95d9 100644 --- a/drivers/net/ethernet/sfc/tx.c +++ b/drivers/net/ethernet/sfc/tx.c @@ -551,8 +551,8 @@ void efx_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue) /* Must be inverse of queue lookup in efx_hard_start_xmit() */ tx_queue->core_txq = netdev_get_tx_queue(efx->net_dev, - tx_queue->queue / EFX_TXQ_TYPES + - ((tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI) ? + tx_queue->channel->channel + + ((tx_queue->label & EFX_TXQ_TYPE_HIGHPRI) ? efx->n_tx_channels : 0)); } @@ -561,10 +561,7 @@ int efx_setup_tc(struct net_device *net_dev, enum tc_setup_type type, { struct efx_nic *efx = netdev_priv(net_dev); struct tc_mqprio_qopt *mqprio = type_data; - struct efx_channel *channel; - struct efx_tx_queue *tx_queue; unsigned tc, num_tc; - int rc; if (type != TC_SETUP_QDISC_MQPRIO) return -EOPNOTSUPP; @@ -588,40 +585,9 @@ int efx_setup_tc(struct net_device *net_dev, enum tc_setup_type type, net_dev->tc_to_txq[tc].count = efx->n_tx_channels; } - if (num_tc > net_dev->num_tc) { - efx->tx_queues_per_channel = 4; - /* Initialise high-priority queues as necessary */ - efx_for_each_channel(channel, efx) { - efx_for_each_channel_tx_queue(tx_queue, channel) { - if (!(tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI)) - continue; - if (!tx_queue->buffer) { - rc = efx_probe_tx_queue(tx_queue); - if (rc) - return rc; - } - if (!tx_queue->initialised) - efx_init_tx_queue(tx_queue); - efx_init_tx_queue_core_txq(tx_queue); - } - } - } else { - /* Reduce number of classes before number of queues */ - net_dev->num_tc = num_tc; - } - - rc = netif_set_real_num_tx_queues(net_dev, - max_t(int, num_tc, 1) * - efx->n_tx_channels); - if (rc) - return rc; - - /* Do not destroy high-priority queues when they become - * unused. We would have to flush them first, and it is - * fairly difficult to flush a subset of TX queues. Leave - * it to efx_fini_channels(). - */ - net_dev->num_tc = num_tc; - return 0; + + return netif_set_real_num_tx_queues(net_dev, + max_t(int, num_tc, 1) * + efx->n_tx_channels); } |