ll_temac: fix DMA resources leak
Subsystems (2)
PATCH v2 1/1 ll_temac: fix DMA resources leak
V2: Check pointers before releasing resources.
Fix DMA resources leak.
---
1 files changed, 32 insertions(+), 0 deletions(-)
drivers/net/ll_temac_main.c +32 -0
@@ -193,6 +193,35 @@ static int temac_dcr_setup(struct temac_local *lp, struct of_device *op,#endif /** +* * temac_dma_bd_release - Release buffer descriptor rings +*/ +static void temac_dma_bd_release (struct net_device *ndev) +{ +struct temac_local *lp =netdev_priv (ndev); +int i; + +for (i =0 ; i <RX_BD_NUM ; i++) { +if (!lp->rx_skb[i]) +break ; +else { +dma_unmap_single (ndev->dev.parent, lp->rx_bd_v[i].phys, +XTE_MAX_JUMBO_FRAME_SIZE ,DMA_FROM_DEVICE ); +dev_kfree_skb (lp->rx_skb[i]); + } + } +if (lp->rx_bd_v) +dma_free_coherent (ndev->dev.parent, +sizeof (*lp->rx_bd_v) *RX_BD_NUM , + lp->rx_bd_v, lp->rx_bd_p); +if (lp->tx_bd_v) +dma_free_coherent (ndev->dev.parent, +sizeof (*lp->tx_bd_v) *TX_BD_NUM , + lp->tx_bd_v, lp->tx_bd_p); +if (lp->rx_skb) +kfree (lp->rx_skb); +} + +/** * temac_dma_bd_init - Setup buffer descriptor rings */ static int temac_dma_bd_init (struct net_device *ndev)
@@ -275,6 +304,7 @@ static int temac_dma_bd_init(struct net_device *ndev)return 0 ; out: +temac_dma_bd_release (ndev);return -ENOMEM ; }
@@ -858,6 +888,8 @@ static int temac_stop(struct net_device *ndev)phy_disconnect (lp->phy_dev); lp->phy_dev =NULL ; +temac_dma_bd_release (ndev); +return 0 ; }
Quoted 22 lines · Denis Kirjanov
V2: Check pointers before releasing resources.
Fix DMA resources leak.
Signed-off-by Denis Kirjanov <[email protected]>Signed-off-by Kulikov Vasiliy <[email protected]>---
1 files changed, 32 insertions(+), 0 deletions(-)drivers/net/ll_temac_main.c +6
-0@@ -193,6 +193,35 @@ static int temac_dcr_setup(struct temac_local *lp, struct of_device *op,#endif /** +* * temac_dma_bd_release - Release buffer descriptor rings +*/ +static void temac_dma_bd_release (struct net_device *ndev) +{ +struct temac_local *lp =netdev_priv (ndev); +int i;
drivers/net/ll_temac_main.c static int temac_dcr_setup(struct temac_local *lp, struct of_device *op, · line 211
Quoted 10 lines
drivers/net/ll_temac_main.c +10
-0+ +for (i =0 ; i <RX_BD_NUM ; i++) { +if (!lp->rx_skb[i]) +break ; +else { +dma_unmap_single (ndev->dev.parent, lp->rx_bd_v[i].phys, +XTE_MAX_JUMBO_FRAME_SIZE ,DMA_FROM_DEVICE ); +dev_kfree_skb (lp->rx_skb[i]); + } + }
This cycle is needed only if (lp->rx_skb != NULL).
drivers/net/ll_temac_main.c static int temac_dcr_setup(struct temac_local *lp, struct of_device *op, · line 219
Quoted 8 lines
drivers/net/ll_temac_main.c +8
-0+if (lp->rx_bd_v) +dma_free_coherent (ndev->dev.parent, +sizeof (*lp->rx_bd_v) *RX_BD_NUM , + lp->rx_bd_v, lp->rx_bd_p); +if (lp->tx_bd_v) +dma_free_coherent (ndev->dev.parent, +sizeof (*lp->tx_bd_v) *TX_BD_NUM , + lp->tx_bd_v, lp->tx_bd_p);
After temac_dma_bd_release() lp->rx_bd_v and lp->rx_bd_p are freed but are nonzero. If lp->rx_skb allocation fails second time then these DMA's would be freed second time.lp->tx_bd_v = lp->rx_bd_v = NULL here fixes this.
Quoted 25 lines
drivers/net/ll_temac_main.c +8
-0+if (lp->rx_skb) +kfree (lp->rx_skb); +} + +/** * temac_dma_bd_init - Setup buffer descriptor rings */ static int temac_dma_bd_init (struct net_device *ndev)@@ -275,6 +304,7 @@ static int temac_dma_bd_init(struct net_device *ndev)return 0 ; out: +temac_dma_bd_release (ndev);return -ENOMEM ; }@@ -858,6 +888,8 @@ static int temac_stop(struct net_device *ndev)phy_disconnect (lp->phy_dev); lp->phy_dev =NULL ; +temac_dma_bd_release (ndev); +return 0 ; }
Quoted 68 lines · Kulikov Vasiliy
Quoted 22 lines · Denis Kirjanov
V2: Check pointers before releasing resources.
Fix DMA resources leak.
Signed-off-by Denis Kirjanov <[email protected]>Signed-off-by Kulikov Vasiliy <[email protected]>---
1 files changed, 32 insertions(+), 0 deletions(-)drivers/net/ll_temac_main.c +6
-0@@ -193,6 +193,35 @@ static int temac_dcr_setup(struct temac_local *lp, struct of_device *op,#endif /** +* * temac_dma_bd_release - Release buffer descriptor rings +*/ +static void temac_dma_bd_release (struct net_device *ndev) +{ +struct temac_local *lp =netdev_priv (ndev); +int i;drivers/net/ll_temac_main.c static int temac_dcr_setup(struct temac_local *lp, struct of_device *op, · line 211
Quoted 10 lines
drivers/net/ll_temac_main.c +10
-0+ +for (i =0 ; i <RX_BD_NUM ; i++) { +if (!lp->rx_skb[i]) +break ; +else { +dma_unmap_single (ndev->dev.parent, lp->rx_bd_v[i].phys, +XTE_MAX_JUMBO_FRAME_SIZE ,DMA_FROM_DEVICE ); +dev_kfree_skb (lp->rx_skb[i]); + } + }This cycle is needed only if (
lp->rx_skb!= NULL).drivers/net/ll_temac_main.c static int temac_dcr_setup(struct temac_local *lp, struct of_device *op, · line 219
Quoted 8 lines
drivers/net/ll_temac_main.c +8
-0+if (lp->rx_bd_v) +dma_free_coherent (ndev->dev.parent, +sizeof (*lp->rx_bd_v) *RX_BD_NUM , + lp->rx_bd_v, lp->rx_bd_p); +if (lp->tx_bd_v) +dma_free_coherent (ndev->dev.parent, +sizeof (*lp->tx_bd_v) *TX_BD_NUM , + lp->tx_bd_v, lp->tx_bd_p);After
temac_dma_bd_release()lp->rx_bd_vandlp->rx_bd_pare freed but are nonzero. Iflp->rx_skballocation fails second time then these DMA's would be freed second time.lp->tx_bd_v=lp->rx_bd_v= NULL here fixes this.Quoted 20 lines
drivers/net/ll_temac_main.c +6
-0+if (lp->rx_skb) +kfree (lp->rx_skb); +} + +/** * temac_dma_bd_init - Setup buffer descriptor rings */ static int temac_dma_bd_init (struct net_device *ndev)@@ -275,6 +304,7 @@ static int temac_dma_bd_init(struct net_device *ndev)return 0 ; out: +temac_dma_bd_release (ndev);return -ENOMEM ; }@@ -858,6 +888,8 @@ static int temac_stop(struct net_device *ndev)phy_disconnect (lp->phy_dev); lp->phy_dev =NULL ;
Quoted 5 lines
drivers/net/ll_temac_main.c static int temac_stop(struct net_device *ndev) · line 895
Quoted 5 lines
drivers/net/ll_temac_main.c +2
-0+temac_dma_bd_release (ndev); +return 0 ; }
I've fixed it in PATCH v3.
Quoted 69 lines · Kulikov Vasiliy
Quoted 68 lines · Kulikov Vasiliy
Quoted 22 lines · Denis Kirjanov
V2: Check pointers before releasing resources.
Fix DMA resources leak.
Signed-off-by Denis Kirjanov <[email protected]>Signed-off-by Kulikov Vasiliy <[email protected]>---
1 files changed, 32 insertions(+), 0 deletions(-)drivers/net/ll_temac_main.c +6
-0@@ -193,6 +193,35 @@ static int temac_dcr_setup(struct temac_local *lp, struct of_device *op,#endif /** +* * temac_dma_bd_release - Release buffer descriptor rings +*/ +static void temac_dma_bd_release (struct net_device *ndev) +{ +struct temac_local *lp =netdev_priv (ndev); +int i;drivers/net/ll_temac_main.c static int temac_dcr_setup(struct temac_local *lp, struct of_device *op, · line 211
Quoted 10 lines
drivers/net/ll_temac_main.c +10
-0+ +for (i =0 ; i <RX_BD_NUM ; i++) { +if (!lp->rx_skb[i]) +break ; +else { +dma_unmap_single (ndev->dev.parent, lp->rx_bd_v[i].phys, +XTE_MAX_JUMBO_FRAME_SIZE ,DMA_FROM_DEVICE ); +dev_kfree_skb (lp->rx_skb[i]); + } + }This cycle is needed only if (
lp->rx_skb!= NULL).drivers/net/ll_temac_main.c static int temac_dcr_setup(struct temac_local *lp, struct of_device *op, · line 219
Quoted 8 lines
drivers/net/ll_temac_main.c +8
-0+if (lp->rx_bd_v) +dma_free_coherent (ndev->dev.parent, +sizeof (*lp->rx_bd_v) *RX_BD_NUM , + lp->rx_bd_v, lp->rx_bd_p); +if (lp->tx_bd_v) +dma_free_coherent (ndev->dev.parent, +sizeof (*lp->tx_bd_v) *TX_BD_NUM , + lp->tx_bd_v, lp->tx_bd_p);After
temac_dma_bd_release()lp->rx_bd_vandlp->rx_bd_pare freed but are nonzero. Iflp->rx_skballocation fails second time then these DMA's would be freed second time.lp->tx_bd_v=lp->rx_bd_v= NULL here fixes this.Quoted 20 lines
drivers/net/ll_temac_main.c +6
-0+if (lp->rx_skb) +kfree (lp->rx_skb); +} + +/** * temac_dma_bd_init - Setup buffer descriptor rings */ static int temac_dma_bd_init (struct net_device *ndev)@@ -275,6 +304,7 @@ static int temac_dma_bd_init(struct net_device *ndev)return 0 ; out: +temac_dma_bd_release (ndev);return -ENOMEM ; }@@ -858,6 +888,8 @@ static int temac_stop(struct net_device *ndev)phy_disconnect (lp->phy_dev); lp->phy_dev =NULL ;
Quoted 6 lines
Quoted 5 lines
drivers/net/ll_temac_main.c static int temac_stop(struct net_device *ndev) · line 895
Quoted 5 lines
drivers/net/ll_temac_main.c +2
-0+temac_dma_bd_release (ndev); +return 0 ; }I've fixed it in PATCH v3.
Could you please fix this on the top on the previous one. Thanks.