Patchwork [v2] fix dmaengine_unmap failure

login
register
mail settings
Submitter xuelin.shi@freescale.com
Date March 20, 2014, 6:33 a.m.
Message ID <1395297230-8195-1-git-send-email-xuelin.shi@freescale.com>
Download mbox | patch
Permalink /patch/332007/
State Not Applicable
Headers show

Comments

xuelin.shi@freescale.com - March 20, 2014, 6:33 a.m.
From: Xuelin Shi <xuelin.shi@freescale.com>

The count which is used to get_unmap_data maybe not the same as the
count computed in dmaengine_unmap which causes to free data in a
wrong pool.

This patch fixes this issue by keeping the map count with unmap_data
structure and use this count to get the pool.

Signed-off-by: Xuelin Shi <xuelin.shi@freescale.com>
---
change history:
	v1: keep mempool pointer with unmap struct
	v2: keep u8 map_cnt instead of mempool pointer to save mem.

 drivers/dma/dmaengine.c   | 2 ++
 include/linux/dmaengine.h | 1 +
 2 files changed, 3 insertions(+)
Dan Williams - April 10, 2014, 4:03 a.m.
On Wed, Mar 19, 2014 at 11:33 PM,  <xuelin.shi@freescale.com> wrote:
> From: Xuelin Shi <xuelin.shi@freescale.com>
>
> The count which is used to get_unmap_data maybe not the same as the
> count computed in dmaengine_unmap which causes to free data in a
> wrong pool.
>
> This patch fixes this issue by keeping the map count with unmap_data
> structure and use this count to get the pool.
>
> Signed-off-by: Xuelin Shi <xuelin.shi@freescale.com>
> ---
> change history:
>         v1: keep mempool pointer with unmap struct
>         v2: keep u8 map_cnt instead of mempool pointer to save mem.
>

Looks good, but please next time remember to prefix your subject line.  I.e.

"dmaengine: fix dmaengine_unmap failure"

I'll fix this up.

--
Dan

Patch

diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index ed610b4..a4068e2 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -1014,6 +1014,7 @@  static void dmaengine_unmap(struct kref *kref)
 		dma_unmap_page(dev, unmap->addr[i], unmap->len,
 			       DMA_BIDIRECTIONAL);
 	}
+	cnt = unmap->map_cnt;
 	mempool_free(unmap, __get_unmap_pool(cnt)->pool);
 }
 
@@ -1079,6 +1080,7 @@  dmaengine_get_unmap_data(struct device *dev, int nr, gfp_t flags)
 	memset(unmap, 0, sizeof(*unmap));
 	kref_init(&unmap->kref);
 	unmap->dev = dev;
+	unmap->map_cnt = nr;
 
 	return unmap;
 }
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index c5c92d5..0a5f552 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -433,6 +433,7 @@  typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param);
 typedef void (*dma_async_tx_callback)(void *dma_async_param);
 
 struct dmaengine_unmap_data {
+	u8 map_cnt;
 	u8 to_cnt;
 	u8 from_cnt;
 	u8 bidi_cnt;