Merge branch 'fixes-for-3.6' of git://git.linaro.org/people/mszyprowski/linux-dma-mapping

Pull DMA-mapping fixes from Marek Szyprowski:
"Another set of fixes for ARM dma-mapping subsystem.

Commit e9da6e9905e6 replaced custom consistent buffer remapping code
with generic vmalloc areas. It however introduced some regressions
caused by limited support for allocations in atomic context. This
series contains fixes for those regressions.

For some subplatforms the default, pre-allocated pool for atomic
allocations turned out to be too small, so a function for setting its
size has been added.

Another set of patches adds support for atomic allocations to
IOMMU-aware DMA-mapping implementation.

The last part of this pull request contains two fixes for Contiguous
Memory Allocator, which relax too strict requirements."

* 'fixes-for-3.6' of git://git.linaro.org/people/mszyprowski/linux-dma-mapping:
ARM: dma-mapping: IOMMU allocates pages from atomic_pool with GFP_ATOMIC
ARM: dma-mapping: Introduce __atomic_get_pages() for __iommu_get_pages()
ARM: dma-mapping: Refactor out to introduce __in_atomic_pool
ARM: dma-mapping: atomic_pool with struct page **pages
ARM: Kirkwood: increase atomic coherent pool size
ARM: DMA-Mapping: print warning when atomic coherent allocation fails
ARM: DMA-Mapping: add function for setting coherent pool size from platform code
ARM: relax conditions required for enabling Contiguous Memory Allocator
mm: cma: fix alignment requirements for contiguous regions

Changed files
+120 -12
arch
arm
include
mach-kirkwood
mm
drivers
+1 -1
arch/arm/Kconfig
··· 6 6 select HAVE_DMA_API_DEBUG 7 7 select HAVE_IDE if PCI || ISA || PCMCIA 8 8 select HAVE_DMA_ATTRS 9 - select HAVE_DMA_CONTIGUOUS if (CPU_V6 || CPU_V6K || CPU_V7) 9 + select HAVE_DMA_CONTIGUOUS if MMU 10 10 select HAVE_MEMBLOCK 11 11 select RTC_LIB 12 12 select SYS_SUPPORTS_APM_EMULATION
+7
arch/arm/include/asm/dma-mapping.h
··· 203 203 } 204 204 205 205 /* 206 + * This can be called during early boot to increase the size of the atomic 207 + * coherent DMA pool above the default value of 256KiB. It must be called 208 + * before postcore_initcall. 209 + */ 210 + extern void __init init_dma_coherent_pool_size(unsigned long size); 211 + 212 + /* 206 213 * This can be called during boot to increase the size of the consistent 207 214 * DMA region above it's default value of 2MB. It must be called before the 208 215 * memory allocator is initialised, i.e. before any core_initcall.
+7
arch/arm/mach-kirkwood/common.c
··· 517 517 void __init kirkwood_init_early(void) 518 518 { 519 519 orion_time_set_base(TIMER_VIRT_BASE); 520 + 521 + /* 522 + * Some Kirkwood devices allocate their coherent buffers from atomic 523 + * context. Increase size of atomic coherent pool to make sure such 524 + * the allocations won't fail. 525 + */ 526 + init_dma_coherent_pool_size(SZ_1M); 520 527 } 521 528 522 529 int kirkwood_tclk;
+104 -10
arch/arm/mm/dma-mapping.c
··· 267 267 vunmap(cpu_addr); 268 268 } 269 269 270 + #define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K 271 + 270 272 struct dma_pool { 271 273 size_t size; 272 274 spinlock_t lock; 273 275 unsigned long *bitmap; 274 276 unsigned long nr_pages; 275 277 void *vaddr; 276 - struct page *page; 278 + struct page **pages; 277 279 }; 278 280 279 281 static struct dma_pool atomic_pool = { 280 - .size = SZ_256K, 282 + .size = DEFAULT_DMA_COHERENT_POOL_SIZE, 281 283 }; 282 284 283 285 static int __init early_coherent_pool(char *p) ··· 288 286 return 0; 289 287 } 290 288 early_param("coherent_pool", early_coherent_pool); 289 + 290 + void __init init_dma_coherent_pool_size(unsigned long size) 291 + { 292 + /* 293 + * Catch any attempt to set the pool size too late. 294 + */ 295 + BUG_ON(atomic_pool.vaddr); 296 + 297 + /* 298 + * Set architecture specific coherent pool size only if 299 + * it has not been changed by kernel command line parameter. 300 + */ 301 + if (atomic_pool.size == DEFAULT_DMA_COHERENT_POOL_SIZE) 302 + atomic_pool.size = size; 303 + } 291 304 292 305 /* 293 306 * Initialise the coherent pool for atomic allocations. ··· 314 297 unsigned long nr_pages = pool->size >> PAGE_SHIFT; 315 298 unsigned long *bitmap; 316 299 struct page *page; 300 + struct page **pages; 317 301 void *ptr; 318 302 int bitmap_size = BITS_TO_LONGS(nr_pages) * sizeof(long); 319 303 ··· 322 304 if (!bitmap) 323 305 goto no_bitmap; 324 306 307 + pages = kzalloc(nr_pages * sizeof(struct page *), GFP_KERNEL); 308 + if (!pages) 309 + goto no_pages; 310 + 325 311 if (IS_ENABLED(CONFIG_CMA)) 326 312 ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page); 327 313 else 328 314 ptr = __alloc_remap_buffer(NULL, pool->size, GFP_KERNEL, prot, 329 315 &page, NULL); 330 316 if (ptr) { 317 + int i; 318 + 319 + for (i = 0; i < nr_pages; i++) 320 + pages[i] = page + i; 321 + 331 322 spin_lock_init(&pool->lock); 332 323 pool->vaddr = ptr; 333 - pool->page = page; 324 + pool->pages = pages; 334 325 pool->bitmap = bitmap; 335 326 pool->nr_pages = nr_pages; 336 327 pr_info("DMA: preallocated %u KiB pool for atomic coherent allocations\n", 337 328 (unsigned)pool->size / 1024); 338 329 return 0; 339 330 } 331 + no_pages: 340 332 kfree(bitmap); 341 333 no_bitmap: 342 334 pr_err("DMA: failed to allocate %u KiB pool for atomic coherent allocation\n", ··· 471 443 if (pageno < pool->nr_pages) { 472 444 bitmap_set(pool->bitmap, pageno, count); 473 445 ptr = pool->vaddr + PAGE_SIZE * pageno; 474 - *ret_page = pool->page + pageno; 446 + *ret_page = pool->pages[pageno]; 447 + } else { 448 + pr_err_once("ERROR: %u KiB atomic DMA coherent pool is too small!\n" 449 + "Please increase it with coherent_pool= kernel parameter!\n", 450 + (unsigned)pool->size / 1024); 475 451 } 476 452 spin_unlock_irqrestore(&pool->lock, flags); 477 453 478 454 return ptr; 455 + } 456 + 457 + static bool __in_atomic_pool(void *start, size_t size) 458 + { 459 + struct dma_pool *pool = &atomic_pool; 460 + void *end = start + size; 461 + void *pool_start = pool->vaddr; 462 + void *pool_end = pool->vaddr + pool->size; 463 + 464 + if (start < pool_start || start > pool_end) 465 + return false; 466 + 467 + if (end <= pool_end) 468 + return true; 469 + 470 + WARN(1, "Wrong coherent size(%p-%p) from atomic pool(%p-%p)\n", 471 + start, end - 1, pool_start, pool_end - 1); 472 + 473 + return false; 479 474 } 480 475 481 476 static int __free_from_pool(void *start, size_t size) ··· 507 456 unsigned long pageno, count; 508 457 unsigned long flags; 509 458 510 - if (start < pool->vaddr || start > pool->vaddr + pool->size) 459 + if (!__in_atomic_pool(start, size)) 511 460 return 0; 512 - 513 - if (start + size > pool->vaddr + pool->size) { 514 - WARN(1, "freeing wrong coherent size from pool\n"); 515 - return 0; 516 - } 517 461 518 462 pageno = (start - pool->vaddr) >> PAGE_SHIFT; 519 463 count = size >> PAGE_SHIFT; ··· 1136 1090 return 0; 1137 1091 } 1138 1092 1093 + static struct page **__atomic_get_pages(void *addr) 1094 + { 1095 + struct dma_pool *pool = &atomic_pool; 1096 + struct page **pages = pool->pages; 1097 + int offs = (addr - pool->vaddr) >> PAGE_SHIFT; 1098 + 1099 + return pages + offs; 1100 + } 1101 + 1139 1102 static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs) 1140 1103 { 1141 1104 struct vm_struct *area; 1105 + 1106 + if (__in_atomic_pool(cpu_addr, PAGE_SIZE)) 1107 + return __atomic_get_pages(cpu_addr); 1142 1108 1143 1109 if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) 1144 1110 return cpu_addr; ··· 1159 1101 if (area && (area->flags & VM_ARM_DMA_CONSISTENT)) 1160 1102 return area->pages; 1161 1103 return NULL; 1104 + } 1105 + 1106 + static void *__iommu_alloc_atomic(struct device *dev, size_t size, 1107 + dma_addr_t *handle) 1108 + { 1109 + struct page *page; 1110 + void *addr; 1111 + 1112 + addr = __alloc_from_pool(size, &page); 1113 + if (!addr) 1114 + return NULL; 1115 + 1116 + *handle = __iommu_create_mapping(dev, &page, size); 1117 + if (*handle == DMA_ERROR_CODE) 1118 + goto err_mapping; 1119 + 1120 + return addr; 1121 + 1122 + err_mapping: 1123 + __free_from_pool(addr, size); 1124 + return NULL; 1125 + } 1126 + 1127 + static void __iommu_free_atomic(struct device *dev, struct page **pages, 1128 + dma_addr_t handle, size_t size) 1129 + { 1130 + __iommu_remove_mapping(dev, handle, size); 1131 + __free_from_pool(page_address(pages[0]), size); 1162 1132 } 1163 1133 1164 1134 static void *arm_iommu_alloc_attrs(struct device *dev, size_t size, ··· 1198 1112 1199 1113 *handle = DMA_ERROR_CODE; 1200 1114 size = PAGE_ALIGN(size); 1115 + 1116 + if (gfp & GFP_ATOMIC) 1117 + return __iommu_alloc_atomic(dev, size, handle); 1201 1118 1202 1119 pages = __iommu_alloc_buffer(dev, size, gfp); 1203 1120 if (!pages) ··· 1265 1176 1266 1177 if (!pages) { 1267 1178 WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr); 1179 + return; 1180 + } 1181 + 1182 + if (__in_atomic_pool(cpu_addr, size)) { 1183 + __iommu_free_atomic(dev, pages, handle, size); 1268 1184 return; 1269 1185 } 1270 1186
+1 -1
drivers/base/dma-contiguous.c
··· 250 250 return -EINVAL; 251 251 252 252 /* Sanitise input arguments */ 253 - alignment = PAGE_SIZE << max(MAX_ORDER, pageblock_order); 253 + alignment = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order); 254 254 base = ALIGN(base, alignment); 255 255 size = ALIGN(size, alignment); 256 256 limit &= ~(alignment - 1);