aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/dma-mapping.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-07-25 03:57:02 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-07-27 05:43:48 -0400
commit5bc23d32d86a132b5636a48dca0fa2528ef69ff9 (patch)
treeb23c8c9ad3693e39e42b2fb389aab037b14ed9a0 /arch/arm/mm/dma-mapping.c
parentd746196361c9c635128249bb6cf13e709ae6abe1 (diff)
ARM: DMA coherent allocator: align remapped addresses
The DMA coherent remap area is used to provide an uncached mapping of memory for coherency with DMA engines. Currently, we look for any free hole which our allocation will fit in with page alignment. However, this can lead to fragmentation of the area, and allows small allocations to cross L1 entry boundaries. This is undesirable as we want to move towards allocating sections of memory. Align allocations according to the size, limiting the alignment between the page and section sizes. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm/dma-mapping.c')
-rw-r--r--arch/arm/mm/dma-mapping.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 9e7742f0a102..c704eed63c5d 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -183,6 +183,8 @@ static void *
183__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot) 183__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
184{ 184{
185 struct arm_vmregion *c; 185 struct arm_vmregion *c;
186 size_t align;
187 int bit;
186 188
187 if (!consistent_pte[0]) { 189 if (!consistent_pte[0]) {
188 printk(KERN_ERR "%s: not initialised\n", __func__); 190 printk(KERN_ERR "%s: not initialised\n", __func__);
@@ -191,9 +193,20 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
191 } 193 }
192 194
193 /* 195 /*
196 * Align the virtual region allocation - maximum alignment is
197 * a section size, minimum is a page size. This helps reduce
198 * fragmentation of the DMA space, and also prevents allocations
199 * smaller than a section from crossing a section boundary.
200 */
201 bit = fls(size - 1) + 1;
202 if (bit > SECTION_SHIFT)
203 bit = SECTION_SHIFT;
204 align = 1 << bit;
205
206 /*
194 * Allocate a virtual address in the consistent mapping region. 207 * Allocate a virtual address in the consistent mapping region.
195 */ 208 */
196 c = arm_vmregion_alloc(&consistent_head, size, 209 c = arm_vmregion_alloc(&consistent_head, align, size,
197 gfp & ~(__GFP_DMA | __GFP_HIGHMEM)); 210 gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
198 if (c) { 211 if (c) {
199 pte_t *pte; 212 pte_t *pte;