mmc: rk_sdmmc: fix SW-IOMMU memory leak
authorShawn Lin <shawn.lin@rock-chips.com>
Wed, 12 Aug 2015 08:25:27 +0000 (16:25 +0800)
committerShawn Lin <shawn.lin@rock-chips.com>
Thu, 20 Aug 2015 08:05:06 +0000 (16:05 +0800)
We could quickly reproduce this bug by decrease IO_TLB_DEFAULT_SIZE
and manually disable mmc DTO interrupt which can make driver fall into
post_tmo all the time.

So, some of these dump for swiotlb we can get here due to no enough
IO_TLB can be used to map page for kernel space:

DMA: Out of SW-IOMMU space for 128 bytes at device ff0f0000.rksdmmc
DMA: Out of SW-IOMMU space for 128 bytes at device ff0f0000.rksdmmc
...
DMA: Out of SW-IOMMU space for 128 bytes at device ff0f0000.rksdmmc
DMA: Out of SW-IOMMU space for 128 bytes at device ff0f0000.rksdmmc

Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Reported-and-tested-by: Jianhong Chen <chenjh@rock-chips.com>
Cc: Yao Xiao <xy@rock-chips.com>
drivers/mmc/host/rk_sdmmc.c

index 870c94cc1ec1df4086a4a9f3c8e4a1d7c13e526d..7c2b6fe855fe1548b860898be6e7015b56b50bb7 100755 (executable)
@@ -1969,20 +1969,21 @@ static void dw_mci_post_tmo(struct mmc_host *mmc)
 {
        struct dw_mci_slot *slot = mmc_priv(mmc);
        struct dw_mci *host = slot->host;
-       struct mmc_data *data;
        u32 i, regs, cmd_flags;
        u32 sdio_int;
        unsigned long timeout = 0;
        bool ret_timeout = true, is_retry = false;
        u32 opcode, offset;
 
+       if (host->cur_slot->mrq->data)
+               dw_mci_stop_dma(host);
+
        offset = host->cru_reset_offset;
        opcode = host->mrq->cmd->opcode;
        host->cur_slot->mrq = NULL;
        host->mrq = NULL;
        host->state = STATE_IDLE;
-
-       data = host->data;
+       host->data = NULL;
 
        if ((opcode == MMC_SEND_TUNING_BLOCK_HS200) ||
            (opcode == MMC_SEND_TUNING_BLOCK))