summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRussell King <rmk@flint.arm.linux.org.uk>2003-01-10 21:41:11 +0000
committerRussell King <rmk@flint.arm.linux.org.uk>2003-01-10 21:41:11 +0000
commit9804476ca07d30f7771dfc51fe3e2bd22d910817 (patch)
tree0fe12038c525b5f6241ba278c4b71d60c701cea2 /include
parent28faab9908dcfabe654f07035f8c23cb0c1386d6 (diff)
[ARM] Fix consistent_alloc()
The old consistent memory allocator, which sat behind dma_coherent_alloc() and pci_consistent_alloc() was completely unable to handle allocations from interrupt context because we traditionally used ioremap, which in turn: - allocates memory using GFP_KERNEL for the vm_struct and the page tables themselves. - calls get_vm_area, which uses write_lock, and therefore is unsafe to call from interrupt context. In order to address this issue, a new consistent_alloc() which avoids the above issues has been implemented. Essentially, we set aside a section of the kernel VM space, and pre-allocate page tables to cover this area. We allocate "consistent" memory within this region. The handling of the allocation is designed to be generic; it should be possible to replace the vmalloc(), ioremap() and module_alloc() without too much hastle, but that would clearly be a 2.7 thing at this stage.
Diffstat (limited to 'include')
-rw-r--r--include/asm-arm/dma-mapping.h6
-rw-r--r--include/asm-arm/pci.h4
2 files changed, 5 insertions, 5 deletions
diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h
index dd85f46611e7..e3d1dbb7bebf 100644
--- a/include/asm-arm/dma-mapping.h
+++ b/include/asm-arm/dma-mapping.h
@@ -14,7 +14,7 @@
* devices. This is the "generic" version. The PCI specific version
* is in pci.h
*/
-extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle);
+extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle, unsigned long flags);
extern void consistent_free(void *vaddr, size_t size, dma_addr_t handle);
extern void consistent_sync(void *kaddr, size_t size, int rw);
@@ -84,12 +84,12 @@ static inline int dma_is_consistent(dma_addr_t handle)
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle)
{
- int gfp = GFP_KERNEL;
+ int gfp = GFP_ATOMIC;
if (dev == NULL || dmadev_is_sa1111(dev) || *dev->dma_mask != 0xffffffff)
gfp |= GFP_DMA;
- return consistent_alloc(gfp, size, handle);
+ return consistent_alloc(gfp, size, handle, 0);
}
/**
diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h
index 7760592d853f..7c690a057a20 100644
--- a/include/asm-arm/pci.h
+++ b/include/asm-arm/pci.h
@@ -40,13 +40,13 @@ static inline void pcibios_penalize_isa_irq(int irq)
static inline void *
pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *handle)
{
- int gfp = GFP_KERNEL;
+ int gfp = GFP_ATOMIC;
if (hwdev == NULL || pcidev_is_sa1111(hwdev) ||
hwdev->dma_mask != 0xffffffff)
gfp |= GFP_DMA;
- return consistent_alloc(gfp, size, handle);
+ return consistent_alloc(gfp, size, handle, 0);
}
static inline void