dma-coherent: introduce interface for default DMA pool

Christoph noticed [1] that default DMA pool in current form overload
the DMA coherent infrastructure. In reply, Robin suggested [2] to
split the per-device vs. global pool interfaces, so allocation/release
from default DMA pool is driven by dma ops implementation.

This patch implements Robin's idea and provide interface to
allocate/release/mmap the default (aka global) DMA pool.

To make it clear that existing *_from_coherent routines work on
per-device pool rename them to *_from_dev_coherent.

[1] https://lkml.org/lkml/2017/7/7/370
[2] https://lkml.org/lkml/2017/7/7/431

Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Suggested-by: Robin Murphy <robin.murphy@arm.com>
Tested-by: Andras Szemzo <sza@esh.hu>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>

authored by

Vladimir Murzin and committed by
Christoph Hellwig
43fc509c 5771a8c0

+149 -77
+1 -1
arch/arc/mm/dma.c
··· 117 117 118 118 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 119 119 120 - if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) 120 + if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret)) 121 121 return ret; 122 122 123 123 if (off < count && user_count <= (count - off)) {
+1 -1
arch/arm/mm/dma-mapping.c
··· 851 851 unsigned long pfn = dma_to_pfn(dev, dma_addr); 852 852 unsigned long off = vma->vm_pgoff; 853 853 854 - if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) 854 + if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret)) 855 855 return ret; 856 856 857 857 if (off < nr_pages && nr_vma_pages <= (nr_pages - off)) {
+2 -2
arch/arm64/mm/dma-mapping.c
··· 329 329 vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot, 330 330 is_device_dma_coherent(dev)); 331 331 332 - if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) 332 + if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret)) 333 333 return ret; 334 334 335 335 return __swiotlb_mmap_pfn(vma, pfn, size); ··· 706 706 vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot, 707 707 is_device_dma_coherent(dev)); 708 708 709 - if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) 709 + if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret)) 710 710 return ret; 711 711 712 712 if (attrs & DMA_ATTR_FORCE_CONTIGUOUS) {
+1 -1
arch/mips/mm/dma-default.c
··· 232 232 else 233 233 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 234 234 235 - if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) 235 + if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret)) 236 236 return ret; 237 237 238 238 if (off < count && user_count <= (count - off)) {
+111 -63
drivers/base/dma-coherent.c
··· 25 25 { 26 26 if (dev && dev->dma_mem) 27 27 return dev->dma_mem; 28 - return dma_coherent_default_memory; 28 + return NULL; 29 29 } 30 30 31 31 static inline dma_addr_t dma_get_device_base(struct device *dev, ··· 165 165 } 166 166 EXPORT_SYMBOL(dma_mark_declared_memory_occupied); 167 167 168 + static void *__dma_alloc_from_coherent(struct dma_coherent_mem *mem, 169 + ssize_t size, dma_addr_t *dma_handle) 170 + { 171 + int order = get_order(size); 172 + unsigned long flags; 173 + int pageno; 174 + int dma_memory_map; 175 + void *ret; 176 + 177 + spin_lock_irqsave(&mem->spinlock, flags); 178 + 179 + if (unlikely(size > (mem->size << PAGE_SHIFT))) 180 + goto err; 181 + 182 + pageno = bitmap_find_free_region(mem->bitmap, mem->size, order); 183 + if (unlikely(pageno < 0)) 184 + goto err; 185 + 186 + /* 187 + * Memory was found in the coherent area. 188 + */ 189 + *dma_handle = mem->device_base + (pageno << PAGE_SHIFT); 190 + ret = mem->virt_base + (pageno << PAGE_SHIFT); 191 + dma_memory_map = (mem->flags & DMA_MEMORY_MAP); 192 + spin_unlock_irqrestore(&mem->spinlock, flags); 193 + if (dma_memory_map) 194 + memset(ret, 0, size); 195 + else 196 + memset_io(ret, 0, size); 197 + 198 + return ret; 199 + 200 + err: 201 + spin_unlock_irqrestore(&mem->spinlock, flags); 202 + return NULL; 203 + } 204 + 168 205 /** 169 - * dma_alloc_from_coherent() - try to allocate memory from the per-device coherent area 170 - * 206 + * dma_alloc_from_dev_coherent() - allocate memory from device coherent pool 171 207 * @dev: device from which we allocate memory 172 208 * @size: size of requested memory area 173 209 * @dma_handle: This will be filled with the correct dma handle ··· 216 180 * Returns 0 if dma_alloc_coherent should continue with allocating from 217 181 * generic memory areas, or !0 if dma_alloc_coherent should return @ret. 218 182 */ 219 - int dma_alloc_from_coherent(struct device *dev, ssize_t size, 220 - dma_addr_t *dma_handle, void **ret) 183 + int dma_alloc_from_dev_coherent(struct device *dev, ssize_t size, 184 + dma_addr_t *dma_handle, void **ret) 221 185 { 222 186 struct dma_coherent_mem *mem = dev_get_coherent_memory(dev); 223 - int order = get_order(size); 224 - unsigned long flags; 225 - int pageno; 226 - int dma_memory_map; 227 187 228 188 if (!mem) 229 189 return 0; 230 190 231 - *ret = NULL; 232 - spin_lock_irqsave(&mem->spinlock, flags); 191 + *ret = __dma_alloc_from_coherent(mem, size, dma_handle); 192 + if (*ret) 193 + return 1; 233 194 234 - if (unlikely(size > (mem->size << PAGE_SHIFT))) 235 - goto err; 236 - 237 - pageno = bitmap_find_free_region(mem->bitmap, mem->size, order); 238 - if (unlikely(pageno < 0)) 239 - goto err; 240 - 241 - /* 242 - * Memory was found in the per-device area. 243 - */ 244 - *dma_handle = dma_get_device_base(dev, mem) + (pageno << PAGE_SHIFT); 245 - *ret = mem->virt_base + (pageno << PAGE_SHIFT); 246 - dma_memory_map = (mem->flags & DMA_MEMORY_MAP); 247 - spin_unlock_irqrestore(&mem->spinlock, flags); 248 - if (dma_memory_map) 249 - memset(*ret, 0, size); 250 - else 251 - memset_io(*ret, 0, size); 252 - 253 - return 1; 254 - 255 - err: 256 - spin_unlock_irqrestore(&mem->spinlock, flags); 257 195 /* 258 196 * In the case where the allocation can not be satisfied from the 259 197 * per-device area, try to fall back to generic memory if the ··· 235 225 */ 236 226 return mem->flags & DMA_MEMORY_EXCLUSIVE; 237 227 } 238 - EXPORT_SYMBOL(dma_alloc_from_coherent); 228 + EXPORT_SYMBOL(dma_alloc_from_dev_coherent); 239 229 240 - /** 241 - * dma_release_from_coherent() - try to free the memory allocated from per-device coherent memory pool 242 - * @dev: device from which the memory was allocated 243 - * @order: the order of pages allocated 244 - * @vaddr: virtual address of allocated pages 245 - * 246 - * This checks whether the memory was allocated from the per-device 247 - * coherent memory pool and if so, releases that memory. 248 - * 249 - * Returns 1 if we correctly released the memory, or 0 if 250 - * dma_release_coherent() should proceed with releasing memory from 251 - * generic pools. 252 - */ 253 - int dma_release_from_coherent(struct device *dev, int order, void *vaddr) 230 + void *dma_alloc_from_global_coherent(ssize_t size, dma_addr_t *dma_handle) 254 231 { 255 - struct dma_coherent_mem *mem = dev_get_coherent_memory(dev); 232 + if (!dma_coherent_default_memory) 233 + return NULL; 256 234 235 + return __dma_alloc_from_coherent(dma_coherent_default_memory, size, 236 + dma_handle); 237 + } 238 + 239 + static int __dma_release_from_coherent(struct dma_coherent_mem *mem, 240 + int order, void *vaddr) 241 + { 257 242 if (mem && vaddr >= mem->virt_base && vaddr < 258 243 (mem->virt_base + (mem->size << PAGE_SHIFT))) { 259 244 int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; ··· 261 256 } 262 257 return 0; 263 258 } 264 - EXPORT_SYMBOL(dma_release_from_coherent); 265 259 266 260 /** 267 - * dma_mmap_from_coherent() - try to mmap the memory allocated from 268 - * per-device coherent memory pool to userspace 261 + * dma_release_from_dev_coherent() - free memory to device coherent memory pool 269 262 * @dev: device from which the memory was allocated 270 - * @vma: vm_area for the userspace memory 271 - * @vaddr: cpu address returned by dma_alloc_from_coherent 272 - * @size: size of the memory buffer allocated by dma_alloc_from_coherent 273 - * @ret: result from remap_pfn_range() 263 + * @order: the order of pages allocated 264 + * @vaddr: virtual address of allocated pages 274 265 * 275 266 * This checks whether the memory was allocated from the per-device 276 - * coherent memory pool and if so, maps that memory to the provided vma. 267 + * coherent memory pool and if so, releases that memory. 277 268 * 278 - * Returns 1 if we correctly mapped the memory, or 0 if the caller should 279 - * proceed with mapping memory from generic pools. 269 + * Returns 1 if we correctly released the memory, or 0 if the caller should 270 + * proceed with releasing memory from generic pools. 280 271 */ 281 - int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma, 282 - void *vaddr, size_t size, int *ret) 272 + int dma_release_from_dev_coherent(struct device *dev, int order, void *vaddr) 283 273 { 284 274 struct dma_coherent_mem *mem = dev_get_coherent_memory(dev); 285 275 276 + return __dma_release_from_coherent(mem, order, vaddr); 277 + } 278 + EXPORT_SYMBOL(dma_release_from_dev_coherent); 279 + 280 + int dma_release_from_global_coherent(int order, void *vaddr) 281 + { 282 + if (!dma_coherent_default_memory) 283 + return 0; 284 + 285 + return __dma_release_from_coherent(dma_coherent_default_memory, order, 286 + vaddr); 287 + } 288 + 289 + static int __dma_mmap_from_coherent(struct dma_coherent_mem *mem, 290 + struct vm_area_struct *vma, void *vaddr, size_t size, int *ret) 291 + { 286 292 if (mem && vaddr >= mem->virt_base && vaddr + size <= 287 293 (mem->virt_base + (mem->size << PAGE_SHIFT))) { 288 294 unsigned long off = vma->vm_pgoff; ··· 312 296 } 313 297 return 0; 314 298 } 315 - EXPORT_SYMBOL(dma_mmap_from_coherent); 299 + 300 + /** 301 + * dma_mmap_from_dev_coherent() - mmap memory from the device coherent pool 302 + * @dev: device from which the memory was allocated 303 + * @vma: vm_area for the userspace memory 304 + * @vaddr: cpu address returned by dma_alloc_from_dev_coherent 305 + * @size: size of the memory buffer allocated 306 + * @ret: result from remap_pfn_range() 307 + * 308 + * This checks whether the memory was allocated from the per-device 309 + * coherent memory pool and if so, maps that memory to the provided vma. 310 + * 311 + * Returns 1 if we correctly mapped the memory, or 0 if the caller should 312 + * proceed with mapping memory from generic pools. 313 + */ 314 + int dma_mmap_from_dev_coherent(struct device *dev, struct vm_area_struct *vma, 315 + void *vaddr, size_t size, int *ret) 316 + { 317 + struct dma_coherent_mem *mem = dev_get_coherent_memory(dev); 318 + 319 + return __dma_mmap_from_coherent(mem, vma, vaddr, size, ret); 320 + } 321 + EXPORT_SYMBOL(dma_mmap_from_dev_coherent); 322 + 323 + int dma_mmap_from_global_coherent(struct vm_area_struct *vma, void *vaddr, 324 + size_t size, int *ret) 325 + { 326 + if (!dma_coherent_default_memory) 327 + return 0; 328 + 329 + return __dma_mmap_from_coherent(dma_coherent_default_memory, vma, 330 + vaddr, size, ret); 331 + } 316 332 317 333 /* 318 334 * Support for reserved memory regions defined in device tree
+1 -1
drivers/base/dma-mapping.c
··· 235 235 236 236 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 237 237 238 - if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) 238 + if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret)) 239 239 return ret; 240 240 241 241 if (off < count && user_count <= (count - off)) {
+32 -8
include/linux/dma-mapping.h
··· 157 157 * These three functions are only for dma allocator. 158 158 * Don't use them in device drivers. 159 159 */ 160 - int dma_alloc_from_coherent(struct device *dev, ssize_t size, 160 + int dma_alloc_from_dev_coherent(struct device *dev, ssize_t size, 161 161 dma_addr_t *dma_handle, void **ret); 162 - int dma_release_from_coherent(struct device *dev, int order, void *vaddr); 162 + int dma_release_from_dev_coherent(struct device *dev, int order, void *vaddr); 163 163 164 - int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma, 164 + int dma_mmap_from_dev_coherent(struct device *dev, struct vm_area_struct *vma, 165 165 void *cpu_addr, size_t size, int *ret); 166 + 167 + void *dma_alloc_from_global_coherent(ssize_t size, dma_addr_t *dma_handle); 168 + int dma_release_from_global_coherent(int order, void *vaddr); 169 + int dma_mmap_from_global_coherent(struct vm_area_struct *vma, void *cpu_addr, 170 + size_t size, int *ret); 171 + 166 172 #else 167 - #define dma_alloc_from_coherent(dev, size, handle, ret) (0) 168 - #define dma_release_from_coherent(dev, order, vaddr) (0) 169 - #define dma_mmap_from_coherent(dev, vma, vaddr, order, ret) (0) 173 + #define dma_alloc_from_dev_coherent(dev, size, handle, ret) (0) 174 + #define dma_release_from_dev_coherent(dev, order, vaddr) (0) 175 + #define dma_mmap_from_dev_coherent(dev, vma, vaddr, order, ret) (0) 176 + 177 + static inline void *dma_alloc_from_global_coherent(ssize_t size, 178 + dma_addr_t *dma_handle) 179 + { 180 + return NULL; 181 + } 182 + 183 + static inline int dma_release_from_global_coherent(int order, void *vaddr) 184 + { 185 + return 0; 186 + } 187 + 188 + static inline int dma_mmap_from_global_coherent(struct vm_area_struct *vma, 189 + void *cpu_addr, size_t size, 190 + int *ret) 191 + { 192 + return 0; 193 + } 170 194 #endif /* CONFIG_HAVE_GENERIC_DMA_COHERENT */ 171 195 172 196 #ifdef CONFIG_HAS_DMA ··· 505 481 506 482 BUG_ON(!ops); 507 483 508 - if (dma_alloc_from_coherent(dev, size, dma_handle, &cpu_addr)) 484 + if (dma_alloc_from_dev_coherent(dev, size, dma_handle, &cpu_addr)) 509 485 return cpu_addr; 510 486 511 487 if (!arch_dma_alloc_attrs(&dev, &flag)) ··· 527 503 BUG_ON(!ops); 528 504 WARN_ON(irqs_disabled()); 529 505 530 - if (dma_release_from_coherent(dev, get_order(size), cpu_addr)) 506 + if (dma_release_from_dev_coherent(dev, get_order(size), cpu_addr)) 531 507 return; 532 508 533 509 if (!ops->free || !cpu_addr)