diff options
author | David S. Miller <davem@davemloft.net> | 2022-05-22 22:18:05 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2022-05-22 22:18:05 +0100 |
commit | 7e4d1c23759257ea62c418c8fb25ddbde1059547 (patch) | |
tree | 3bcd6b0cd1e136697e4adf991ad5d9ff80805366 | |
parent | 15d221d0c345b76947911a3ac91897ffe2f1cc4e (diff) | |
parent | 0a09c5b8cb8f75344da7d90c771b84f7cdeaea04 (diff) | |
download | linux-stable-7e4d1c23759257ea62c418c8fb25ddbde1059547.tar.gz linux-stable-7e4d1c23759257ea62c418c8fb25ddbde1059547.tar.bz2 linux-stable-7e4d1c23759257ea62c418c8fb25ddbde1059547.zip |
Merge branch 'dpaa2-swtso-fixes'
Ioana Ciornei says:
====================
dpaa2-eth: software TSO fixes
This patch fixes the software TSO feature in dpaa2-eth.
There are multiple errors that I made in the initial submission of the
code, which I didn't caught since I was always running with passthough
IOMMU.
The bug report came in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=215886
The bugs are in the Tx confirmation path, where I was trying to retrieve
a virtual address after DMA unmapping the area. Besides that, another
dma_unmap call was made with the wrong size.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c index 4b047255d928..cd9ec80522e7 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c @@ -1097,6 +1097,7 @@ static void dpaa2_eth_free_tx_fd(struct dpaa2_eth_priv *priv, u32 fd_len = dpaa2_fd_get_len(fd); struct dpaa2_sg_entry *sgt; int should_free_skb = 1; + void *tso_hdr; int i; fd_addr = dpaa2_fd_get_addr(fd); @@ -1135,20 +1136,21 @@ static void dpaa2_eth_free_tx_fd(struct dpaa2_eth_priv *priv, sgt = (struct dpaa2_sg_entry *)(buffer_start + priv->tx_data_offset); + /* Unmap the SGT buffer */ + dma_unmap_single(dev, fd_addr, swa->tso.sgt_size, + DMA_BIDIRECTIONAL); + /* Unmap and free the header */ + tso_hdr = dpaa2_iova_to_virt(priv->iommu_domain, dpaa2_sg_get_addr(sgt)); dma_unmap_single(dev, dpaa2_sg_get_addr(sgt), TSO_HEADER_SIZE, DMA_TO_DEVICE); - kfree(dpaa2_iova_to_virt(priv->iommu_domain, dpaa2_sg_get_addr(sgt))); + kfree(tso_hdr); /* Unmap the other SG entries for the data */ for (i = 1; i < swa->tso.num_sg; i++) dma_unmap_single(dev, dpaa2_sg_get_addr(&sgt[i]), dpaa2_sg_get_len(&sgt[i]), DMA_TO_DEVICE); - /* Unmap the SGT buffer */ - dma_unmap_single(dev, fd_addr, swa->sg.sgt_size, - DMA_BIDIRECTIONAL); - if (!swa->tso.is_last_fd) should_free_skb = 0; } else { |