diff options
author | Edward Cree | 2020-07-02 17:29:58 +0100 |
---|---|---|
committer | David S. Miller | 2020-07-02 14:47:40 -0700 |
commit | a81dcd85a7c1bc548ce8fb635623970fdee5887d (patch) | |
tree | 832617d7896bd2e5fcd88aa1c740c5367e8dfbee /drivers/net/ethernet/sfc/efx_channels.c | |
parent | 69a704962e8cab43bd62301e104c222e7d23e361 (diff) |
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/efx_channels.c')
-rw-r--r-- | drivers/net/ethernet/sfc/efx_channels.c | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/drivers/net/ethernet/sfc/efx_channels.c b/drivers/net/ethernet/sfc/efx_channels.c index 30358f3f48ca..dd4f30ea48a8 100644 --- a/drivers/net/ethernet/sfc/efx_channels.c +++ b/drivers/net/ethernet/sfc/efx_channels.c @@ -524,7 +524,8 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel) for (j = 0; j < EFX_TXQ_TYPES; j++) { tx_queue = &channel->tx_queue[j]; tx_queue->efx = efx; - tx_queue->queue = i * EFX_TXQ_TYPES + j; + tx_queue->queue = -1; + tx_queue->label = j; tx_queue->channel = channel; } @@ -853,8 +854,9 @@ rollback: int efx_set_channels(struct efx_nic *efx) { - struct efx_channel *channel; struct efx_tx_queue *tx_queue; + struct efx_channel *channel; + unsigned int next_queue = 0; int xdp_queue_number; int rc; @@ -884,14 +886,30 @@ int efx_set_channels(struct efx_nic *efx) else channel->rx_queue.core_index = -1; - efx_for_each_channel_tx_queue(tx_queue, channel) { - tx_queue->queue -= (efx->tx_channel_offset * - EFX_TXQ_TYPES); - - if (efx_channel_is_xdp_tx(channel) && - xdp_queue_number < efx->xdp_tx_queue_count) { - efx->xdp_tx_queues[xdp_queue_number] = tx_queue; - xdp_queue_number++; + if (channel->channel >= efx->tx_channel_offset) { + if (efx_channel_is_xdp_tx(channel)) { + efx_for_each_channel_tx_queue(tx_queue, channel) { + tx_queue->queue = next_queue++; + netif_dbg(efx, drv, efx->net_dev, "Channel %u TXQ %u is XDP %u, HW %u\n", + channel->channel, tx_queue->label, + xdp_queue_number, tx_queue->queue); + /* We may have a few left-over XDP TX + * queues owing to xdp_tx_queue_count + * not dividing evenly by EFX_TXQ_TYPES. + * We still allocate and probe those + * TXQs, but never use them. + */ + if (xdp_queue_number < efx->xdp_tx_queue_count) + efx->xdp_tx_queues[xdp_queue_number] = tx_queue; + xdp_queue_number++; + } + } else { + efx_for_each_channel_tx_queue(tx_queue, channel) { + tx_queue->queue = next_queue++; + netif_dbg(efx, drv, efx->net_dev, "Channel %u TXQ %u is HW %u\n", + channel->channel, tx_queue->label, + tx_queue->queue); + } } } } |