lkml.org 
[lkml]   [2006]   [Jun]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: [BUG] Linux-2.6.17-rt3 on arm ixdp465


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 <rostedt@goodmis.org>

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 majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2006-06-29 14:12    [W:0.072 / U:0.136 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site