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]