diff options
| author | Russell King <rmk@flint.arm.linux.org.uk> | 2003-01-10 21:41:11 +0000 |
|---|---|---|
| committer | Russell King <rmk@flint.arm.linux.org.uk> | 2003-01-10 21:41:11 +0000 |
| commit | 9804476ca07d30f7771dfc51fe3e2bd22d910817 (patch) | |
| tree | 0fe12038c525b5f6241ba278c4b71d60c701cea2 /include | |
| parent | 28faab9908dcfabe654f07035f8c23cb0c1386d6 (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.h | 6 | ||||
| -rw-r--r-- | include/asm-arm/pci.h | 4 |
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 |
