0083-net-next-mediatek-fix-missing-free-of-scratch-memory.patch 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. From b48745c534ced06005d2ba57198b54a6a160b39d Mon Sep 17 00:00:00 2001
  2. From: John Crispin <john@phrozen.org>
  3. Date: Sat, 23 Apr 2016 09:18:28 +0200
  4. Subject: [PATCH 083/102] net-next: mediatek: fix missing free of scratch
  5. memory
  6. Scratch memory gets allocated in mtk_init_fq_dma() but the corresponding
  7. code to free it is missing inside mtk_dma_free() causing a memory leak.
  8. With this patch applied, we can run ifconfig/up/down several thousand
  9. times without any problems.
  10. Signed-off-by: John Crispin <john@phrozen.org>
  11. ---
  12. drivers/net/ethernet/mediatek/mtk_eth_soc.c | 18 +++++++++++++-----
  13. drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++
  14. 2 files changed, 15 insertions(+), 5 deletions(-)
  15. --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
  16. +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
  17. @@ -484,14 +484,14 @@ static inline void mtk_rx_get_desc(struc
  18. /* the qdma core needs scratch memory to be setup */
  19. static int mtk_init_fq_dma(struct mtk_eth *eth)
  20. {
  21. - dma_addr_t phy_ring_head, phy_ring_tail;
  22. + dma_addr_t phy_ring_tail;
  23. int cnt = MTK_DMA_SIZE;
  24. dma_addr_t dma_addr;
  25. int i;
  26. eth->scratch_ring = dma_alloc_coherent(eth->dev,
  27. cnt * sizeof(struct mtk_tx_dma),
  28. - &phy_ring_head,
  29. + &eth->phy_scratch_ring,
  30. GFP_ATOMIC | __GFP_ZERO);
  31. if (unlikely(!eth->scratch_ring))
  32. return -ENOMEM;
  33. @@ -508,19 +508,19 @@ static int mtk_init_fq_dma(struct mtk_et
  34. return -ENOMEM;
  35. memset(eth->scratch_ring, 0x0, sizeof(struct mtk_tx_dma) * cnt);
  36. - phy_ring_tail = phy_ring_head +
  37. + phy_ring_tail = eth->phy_scratch_ring +
  38. (sizeof(struct mtk_tx_dma) * (cnt - 1));
  39. for (i = 0; i < cnt; i++) {
  40. eth->scratch_ring[i].txd1 =
  41. (dma_addr + (i * MTK_QDMA_PAGE_SIZE));
  42. if (i < cnt - 1)
  43. - eth->scratch_ring[i].txd2 = (phy_ring_head +
  44. + eth->scratch_ring[i].txd2 = (eth->phy_scratch_ring +
  45. ((i + 1) * sizeof(struct mtk_tx_dma)));
  46. eth->scratch_ring[i].txd3 = TX_DMA_SDL(MTK_QDMA_PAGE_SIZE);
  47. }
  48. - mtk_w32(eth, phy_ring_head, MTK_QDMA_FQ_HEAD);
  49. + mtk_w32(eth, eth->phy_scratch_ring, MTK_QDMA_FQ_HEAD);
  50. mtk_w32(eth, phy_ring_tail, MTK_QDMA_FQ_TAIL);
  51. mtk_w32(eth, (cnt << 16) | cnt, MTK_QDMA_FQ_CNT);
  52. mtk_w32(eth, MTK_QDMA_PAGE_SIZE << 16, MTK_QDMA_FQ_BLEN);
  53. @@ -1220,6 +1220,14 @@ static void mtk_dma_free(struct mtk_eth
  54. for (i = 0; i < MTK_MAC_COUNT; i++)
  55. if (eth->netdev[i])
  56. netdev_reset_queue(eth->netdev[i]);
  57. + if (eth->scratch_ring) {
  58. + dma_free_coherent(eth->dev,
  59. + MTK_DMA_SIZE * sizeof(struct mtk_tx_dma),
  60. + eth->scratch_ring,
  61. + eth->phy_scratch_ring);
  62. + eth->scratch_ring = NULL;
  63. + eth->phy_scratch_ring = 0;
  64. + }
  65. mtk_tx_clean(eth);
  66. mtk_rx_clean(eth);
  67. kfree(eth->scratch_head);
  68. --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
  69. +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
  70. @@ -357,6 +357,7 @@ struct mtk_rx_ring {
  71. * @rx_ring: Pointer to the memore holding info about the RX ring
  72. * @rx_napi: The NAPI struct
  73. * @scratch_ring: Newer SoCs need memory for a second HW managed TX ring
  74. + * @phy_scratch_ring: physical address of scratch_ring
  75. * @scratch_head: The scratch memory that scratch_ring points to.
  76. * @clk_ethif: The ethif clock
  77. * @clk_esw: The switch clock
  78. @@ -384,6 +385,7 @@ struct mtk_eth {
  79. struct mtk_rx_ring rx_ring;
  80. struct napi_struct rx_napi;
  81. struct mtk_tx_dma *scratch_ring;
  82. + dma_addr_t phy_scratch_ring;
  83. void *scratch_head;
  84. struct clk *clk_ethif;
  85. struct clk *clk_esw;