mirror of
https://github.com/torvalds/linux.git
synced 2026-10-23 23:51:02 +02:00
ibmveth: fix TX LTB and filter unwind on open-fail
out_free_buffer_pools reuses open()'s loop index for the TX LTB
walk. After the pool unwind i is -1, so the TX buffers allocated
earlier are leaked. request_irq() failure has the same leak.
The TX-fail goto on that walk also skips dma_unmap of the filter
list (pre-existing since the LTB was added). Rewrite the TX walk
to real_num_tx_queues with a pointer check, and unmap the filter
list before those frees.
Fixes: d926793c1d ("ibmveth: Implement multi queue on xmit")
Cc: stable@vger.kernel.org
Signed-off-by: Mingming Cao <mmc@linux.ibm.com>
Reviewed-by: Dave Marquardt <davemarq@linux.ibm.com>
Link: https://patch.msgid.link/d14314c2b10f125f5e578782484ba3cc50564d53.1790357373.git.mmc@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
af0524bf4c
commit
84bec0bf03
|
|
@ -553,10 +553,15 @@ static int ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter,
|
|||
|
||||
static void ibmveth_free_tx_ltb(struct ibmveth_adapter *adapter, int idx)
|
||||
{
|
||||
void *ptr = adapter->tx_ltb_ptr[idx];
|
||||
|
||||
if (!ptr)
|
||||
return;
|
||||
|
||||
adapter->tx_ltb_ptr[idx] = NULL;
|
||||
dma_unmap_single(&adapter->vdev->dev, adapter->tx_ltb_dma[idx],
|
||||
adapter->tx_ltb_size, DMA_TO_DEVICE);
|
||||
kfree(adapter->tx_ltb_ptr[idx]);
|
||||
adapter->tx_ltb_ptr[idx] = NULL;
|
||||
kfree(ptr);
|
||||
}
|
||||
|
||||
static int ibmveth_allocate_tx_ltb(struct ibmveth_adapter *adapter, int idx)
|
||||
|
|
@ -667,7 +672,7 @@ static int ibmveth_open(struct net_device *netdev)
|
|||
|
||||
for (i = 0; i < netdev->real_num_tx_queues; i++) {
|
||||
if (ibmveth_allocate_tx_ltb(adapter, i))
|
||||
goto out_free_tx_ltb;
|
||||
goto out_unmap_filter_list;
|
||||
}
|
||||
|
||||
adapter->rx_queue.index = 0;
|
||||
|
|
@ -745,10 +750,8 @@ static int ibmveth_open(struct net_device *netdev)
|
|||
dma_unmap_single(dev, adapter->filter_list_dma, 4096,
|
||||
DMA_BIDIRECTIONAL);
|
||||
|
||||
out_free_tx_ltb:
|
||||
while (--i >= 0) {
|
||||
for (i = netdev->real_num_tx_queues - 1; i >= 0; i--)
|
||||
ibmveth_free_tx_ltb(adapter, i);
|
||||
}
|
||||
|
||||
out_unmap_buffer_list:
|
||||
dma_unmap_single(dev, adapter->buffer_list_dma, 4096,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user