Re: [BUG] Linux-2.6.17-rt3 on arm ixdp465

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On Thu, 29 Jun 2006, Esben Nielsen wrote:

>
> On Thu, 29 Jun 2006, Milan Svoboda wrote:
>
>
> It seems that dma_unmap_single() on arm contains
>  	local_irq_save(flags);
>
>  	unmap_single(dev, dma_addr, size, dir);
>
>  	local_irq_restore(flags);
>

Yeah I saw this too.

> I don't know the dma code on arm. It doesn't look like a per-cpu code but it
> seems to me that it is not SMP safe and therefore not preempt-realtime
> safe, either.
>
> The hard thing is to figure out which datastructures exactly is protected
> by those irq-disable and put in a spinlock..
>
> I added Deepak Saxena on CC as he seems to be the last one who touched the
> file.
>

Well, the following patch may not be the best but I don't see it being any
worse than what is already there.  I don't have any arm platforms or even
an arm compiler, so I haven't even tested this patch with a compile.  But
it should be at least a temporary fix.

-- Steve

Signed-off-by: Steven Rostedt <[email protected]>

Index: linux-2.6.17-rt4/arch/arm/common/dmabounce.c
===================================================================
--- linux-2.6.17-rt4.orig/arch/arm/common/dmabounce.c	2006-06-29 07:56:54.000000000 -0400
+++ linux-2.6.17-rt4/arch/arm/common/dmabounce.c	2006-06-29 08:04:42.000000000 -0400
@@ -386,6 +386,8 @@ sync_single(struct device *dev, dma_addr

 /* ************************************************** */

+static DEFINE_SPINLOCK(dma_lock);
+
 /*
  * see if a buffer address is in an 'unsafe' range.  if it is
  * allocate a 'safe' buffer and copy the unsafe buffer into it.
@@ -404,11 +406,11 @@ dma_map_single(struct device *dev, void

 	BUG_ON(dir == DMA_NONE);

-	local_irq_save(flags);
+	spin_lock_irqsave(&dma_lock, flags);

 	dma_addr = map_single(dev, ptr, size, dir);

-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&dma_lock, flags);

 	return dma_addr;
 }
@@ -431,11 +433,11 @@ dma_unmap_single(struct device *dev, dma

 	BUG_ON(dir == DMA_NONE);

-	local_irq_save(flags);
+	spin_lock_irqsave(&dma_lock, flags);

 	unmap_single(dev, dma_addr, size, dir);

-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&dma_lock, flags);
 }

 int
@@ -450,7 +452,7 @@ dma_map_sg(struct device *dev, struct sc

 	BUG_ON(dir == DMA_NONE);

-	local_irq_save(flags);
+	spin_lock_irqsave(&dma_lock, flags);

 	for (i = 0; i < nents; i++, sg++) {
 		struct page *page = sg->page;
@@ -462,7 +464,7 @@ dma_map_sg(struct device *dev, struct sc
 			map_single(dev, ptr, length, dir);
 	}

-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&dma_lock, flags);

 	return nents;
 }
@@ -479,7 +481,7 @@ dma_unmap_sg(struct device *dev, struct

 	BUG_ON(dir == DMA_NONE);

-	local_irq_save(flags);
+	spin_lock_irqsave(&dma_lock, flags);

 	for (i = 0; i < nents; i++, sg++) {
 		dma_addr_t dma_addr = sg->dma_address;
@@ -488,7 +490,7 @@ dma_unmap_sg(struct device *dev, struct
 		unmap_single(dev, dma_addr, length, dir);
 	}

-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&dma_lock, flags);
 }

 void
@@ -500,11 +502,11 @@ dma_sync_single_for_cpu(struct device *d
 	dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
 		__func__, (void *) dma_addr, size, dir);

-	local_irq_save(flags);
+	spin_lock_irqsave(&dma_lock, flags);

 	sync_single(dev, dma_addr, size, dir);

-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&dma_lock, flags);
 }

 void
@@ -516,11 +518,11 @@ dma_sync_single_for_device(struct device
 	dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
 		__func__, (void *) dma_addr, size, dir);

-	local_irq_save(flags);
+	spin_lock_irqsave(&dma_lock, flags);

 	sync_single(dev, dma_addr, size, dir);

-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&dma_lock, flags);
 }

 void
@@ -535,7 +537,7 @@ dma_sync_sg_for_cpu(struct device *dev,

 	BUG_ON(dir == DMA_NONE);

-	local_irq_save(flags);
+	spin_lock_irqsave(&dma_lock, flags);

 	for (i = 0; i < nents; i++, sg++) {
 		dma_addr_t dma_addr = sg->dma_address;
@@ -544,7 +546,7 @@ dma_sync_sg_for_cpu(struct device *dev,
 		sync_single(dev, dma_addr, length, dir);
 	}

-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&dma_lock, flags);
 }

 void
@@ -559,7 +561,7 @@ dma_sync_sg_for_device(struct device *de

 	BUG_ON(dir == DMA_NONE);

-	local_irq_save(flags);
+	spin_lock_irqsave(&dma_lock, flags);

 	for (i = 0; i < nents; i++, sg++) {
 		dma_addr_t dma_addr = sg->dma_address;
@@ -568,7 +570,7 @@ dma_sync_sg_for_device(struct device *de
 		sync_single(dev, dma_addr, length, dir);
 	}

-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&dma_lock, flags);
 }

 static int
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux