From: Mohammed Shafi Shajakhan Date: Fri, 23 Sep 2011 09:03:14 +0000 (+0530) Subject: ath9k: Fix a dma warning/memory leak X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=ba54238552625aad2d75f455a4d3db18ea7dec68;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git ath9k: Fix a dma warning/memory leak proper dma_unmapping and freeing of skb's has to be done in the rx cleanup for EDMA chipsets when the device is unloaded and this also seems to address the following warning which shows up occasionally when the device is unloaded Call Trace: [] warn_slowpath_common+0x72/0xa0 [] ? dma_debug_device_change+0x19c/0x200 [] ? dma_debug_device_change+0x19c/0x200 [] warn_slowpath_fmt+0x33/0x40 [] dma_debug_device_change+0x19c/0x200 [] notifier_call_chain+0x82/0xb0 [] __blocking_notifier_call_chain+0x60/0x90 [] blocking_notifier_call_chain+0x1f/0x30 [] __device_release_driver+0xa4/0xc0 [] driver_detach+0x97/0xa0 [] bus_remove_driver+0x6c/0xe0 [] ? sysfs_addrm_finish+0x4b/0x60 [] driver_unregister+0x49/0x80 [] ? sysfs_remove_file+0x14/0x20 [] pci_unregister_driver+0x32/0x80 [] ath_pci_exit+0x12/0x20 [ath9k] [] ath9k_exit+0x17/0x36 [ath9k] [] ? mutex_unlock+0xd/0x10 [] sys_delete_module+0x13f/0x200 [] ? sys_munmap+0x4b/0x60 [] ? restore_all+0xf/0xf [] ? spurious_fault+0xe0/0xe0 [] ? trace_hardirqs_on_caller+0xf4/0x180 [] sysenter_do_call+0x12/0x38 ---[ end trace 16e1c1521c06bcf9 ]--- Mapped at: [] debug_dma_map_page+0x48/0x120 [] ath_rx_init+0x3f8/0x4b0 [ath9k] [] ath9k_init_device+0x4c4/0x7b0 [ath9k] [] ath_pci_probe+0x263/0x330 [ath9k] Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 9a4850154fb2..4c21f8cbdeb5 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -205,14 +205,22 @@ static void ath_rx_remove_buffer(struct ath_softc *sc, static void ath_rx_edma_cleanup(struct ath_softc *sc) { + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); struct ath_buf *bf; ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP); ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP); list_for_each_entry(bf, &sc->rx.rxbuf, list) { - if (bf->bf_mpdu) + if (bf->bf_mpdu) { + dma_unmap_single(sc->dev, bf->bf_buf_addr, + common->rx_bufsize, + DMA_BIDIRECTIONAL); dev_kfree_skb_any(bf->bf_mpdu); + bf->bf_buf_addr = 0; + bf->bf_mpdu = NULL; + } } INIT_LIST_HEAD(&sc->rx.rxbuf);