History

dma-mapping: remove CONFIG_DMA_REMAP

CONFIG_DMA_REMAP is used to build a few helpers around the core vmalloc code, and to use them in case there is a highmem page in dma-direct, and to make dma coherent allocations be able to use non-contiguous pages allocations for DMA allocations in the dma-iommu layer. Right now it needs to be explicitly selected by architectures, and is only done so by architectures that require remapping to deal with devices that are not DMA coherent. Make it unconditional for builds with CONFIG_MMU as it is very little extra code, but makes it much more likely that large DMA allocations succeed on x86. This fixes hot plugging a NVMe thunderbolt SSD for me, which tries to allocate a 1MB buffer that is otherwise hard to obtain due to memory fragmentation on a heavily used laptop.

Christoph Hellwig committed 4 years ago

Commit f5ff79f1 parent fba09096 files · +16 −29Browse files

Unified · Split

6 files
  1. arch/arm/Kconfig +1 −1
  2. arch/xtensa/Kconfig +1 −1
  3. drivers/iommu/dma-iommu.c +5 −9
  4. kernel/dma/Kconfig +1 −6
  5. kernel/dma/Makefile +1 −1
  6. kernel/dma/direct.c +7 −11
arch/arm/Kconfig+1−1
@@ -47,7 +47,7 @@ config ARM · 46 unmodified lines
47 select DMA_DECLARE_COHERENT47 select DMA_DECLARE_COHERENT
48 select DMA_GLOBAL_POOL if !MMU48 select DMA_GLOBAL_POOL if !MMU
49 select DMA_OPS49 select DMA_OPS
50 select DMA_REMAP if MMU50 select DMA_NONCOHERENT_MMAP if MMU
51 select EDAC_SUPPORT51 select EDAC_SUPPORT
52 select EDAC_ATOMIC_SCRUB52 select EDAC_ATOMIC_SCRUB
53 select GENERIC_ALLOCATOR53 select GENERIC_ALLOCATOR
arch/xtensa/Kconfig+1−1
@@ -17,7 +17,7 @@ config XTENSA · 16 unmodified lines
17 select BUILDTIME_TABLE_SORT17 select BUILDTIME_TABLE_SORT
18 select CLONE_BACKWARDS18 select CLONE_BACKWARDS
19 select COMMON_CLK19 select COMMON_CLK
20 select DMA_REMAP if MMU20 select DMA_NONCOHERENT_MMAP if MMU
21 select GENERIC_ATOMIC6421 select GENERIC_ATOMIC64
22 select GENERIC_IRQ_SHOW22 select GENERIC_IRQ_SHOW
23 select GENERIC_PCI_IOMAP23 select GENERIC_PCI_IOMAP
drivers/iommu/dma-iommu.c+5−9
@@ -852,7 +852,6 @@ out_unmap: · 851 unmodified lines
852 return NULL;852 return NULL;
853}853}
854 854
855#ifdef CONFIG_DMA_REMAP
856static struct sg_table *iommu_dma_alloc_noncontiguous(struct device *dev,855static struct sg_table *iommu_dma_alloc_noncontiguous(struct device *dev,
857 size_t size, enum dma_data_direction dir, gfp_t gfp,856 size_t size, enum dma_data_direction dir, gfp_t gfp,
858 unsigned long attrs)857 unsigned long attrs)
@@ -882,7 +881,6 @@ static void iommu_dma_free_noncontiguous(struct device *dev, size_t size, · 23 unmodified lines
882 sg_free_table(&sh->sgt);881 sg_free_table(&sh->sgt);
883 kfree(sh);882 kfree(sh);
884}883}
885#endif /* CONFIG_DMA_REMAP */
886 884
887static void iommu_dma_sync_single_for_cpu(struct device *dev,885static void iommu_dma_sync_single_for_cpu(struct device *dev,
888 dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)886 dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
@@ -1276,7 +1274,7 @@ static void __iommu_dma_free(struct device *dev, size_t size, void *cpu_addr) · 387 unmodified lines
1276 dma_free_from_pool(dev, cpu_addr, alloc_size))1274 dma_free_from_pool(dev, cpu_addr, alloc_size))
1277 return;1275 return;
1278 1276
1279 if (IS_ENABLED(CONFIG_DMA_REMAP) && is_vmalloc_addr(cpu_addr)) {1277 if (is_vmalloc_addr(cpu_addr)) {
1280 /*1278 /*
1281 * If it the address is remapped, then it's either non-coherent1279 * If it the address is remapped, then it's either non-coherent
1282 * or highmem CMA, or an iommu_dma_alloc_remap() construction.1280 * or highmem CMA, or an iommu_dma_alloc_remap() construction.
@@ -1318,7 +1316,7 @@ static void *iommu_dma_alloc_pages(struct device *dev, size_t size, · 35 unmodified lines
1318 if (!page)1316 if (!page)
1319 return NULL;1317 return NULL;
1320 1318
1321 if (IS_ENABLED(CONFIG_DMA_REMAP) && (!coherent || PageHighMem(page))) {1319 if (!coherent || PageHighMem(page)) {
1322 pgprot_t prot = dma_pgprot(dev, PAGE_KERNEL, attrs);1320 pgprot_t prot = dma_pgprot(dev, PAGE_KERNEL, attrs);
1323 1321
1324 cpu_addr = dma_common_contiguous_remap(page, alloc_size,1322 cpu_addr = dma_common_contiguous_remap(page, alloc_size,
@@ -1350,7 +1348,7 @@ static void *iommu_dma_alloc(struct device *dev, size_t size, · 25 unmodified lines
1350 1348
1351 gfp |= __GFP_ZERO;1349 gfp |= __GFP_ZERO;
1352 1350
1353 if (IS_ENABLED(CONFIG_DMA_REMAP) && gfpflags_allow_blocking(gfp) &&1351 if (gfpflags_allow_blocking(gfp) &&
1354 !(attrs & DMA_ATTR_FORCE_CONTIGUOUS)) {1352 !(attrs & DMA_ATTR_FORCE_CONTIGUOUS)) {
1355 return iommu_dma_alloc_remap(dev, size, handle, gfp,1353 return iommu_dma_alloc_remap(dev, size, handle, gfp,
1356 dma_pgprot(dev, PAGE_KERNEL, attrs), attrs);1354 dma_pgprot(dev, PAGE_KERNEL, attrs), attrs);
@@ -1391,7 +1389,7 @@ static int iommu_dma_mmap(struct device *dev, struct vm_area_struct *vma, · 34 unmodified lines
1391 if (off >= nr_pages || vma_pages(vma) > nr_pages - off)1389 if (off >= nr_pages || vma_pages(vma) > nr_pages - off)
1392 return -ENXIO;1390 return -ENXIO;
1393 1391
1394 if (IS_ENABLED(CONFIG_DMA_REMAP) && is_vmalloc_addr(cpu_addr)) {1392 if (is_vmalloc_addr(cpu_addr)) {
1395 struct page **pages = dma_common_find_pages(cpu_addr);1393 struct page **pages = dma_common_find_pages(cpu_addr);
1396 1394
1397 if (pages)1395 if (pages)
@@ -1413,7 +1411,7 @@ static int iommu_dma_get_sgtable(struct device *dev, struct sg_table *sgt, · 15 unmodified lines
1413 struct page *page;1411 struct page *page;
1414 int ret;1412 int ret;
1415 1413
1416 if (IS_ENABLED(CONFIG_DMA_REMAP) && is_vmalloc_addr(cpu_addr)) {1414 if (is_vmalloc_addr(cpu_addr)) {
1417 struct page **pages = dma_common_find_pages(cpu_addr);1415 struct page **pages = dma_common_find_pages(cpu_addr);
1418 1416
1419 if (pages) {1417 if (pages) {
@@ -1445,10 +1443,8 @@ static const struct dma_map_ops iommu_dma_ops = { · 25 unmodified lines
1445 .free = iommu_dma_free,1443 .free = iommu_dma_free,
1446 .alloc_pages = dma_common_alloc_pages,1444 .alloc_pages = dma_common_alloc_pages,
1447 .free_pages = dma_common_free_pages,1445 .free_pages = dma_common_free_pages,
1448#ifdef CONFIG_DMA_REMAP
1449 .alloc_noncontiguous = iommu_dma_alloc_noncontiguous,1446 .alloc_noncontiguous = iommu_dma_alloc_noncontiguous,
1450 .free_noncontiguous = iommu_dma_free_noncontiguous,1447 .free_noncontiguous = iommu_dma_free_noncontiguous,
1451#endif
1452 .mmap = iommu_dma_mmap,1448 .mmap = iommu_dma_mmap,
1453 .get_sgtable = iommu_dma_get_sgtable,1449 .get_sgtable = iommu_dma_get_sgtable,
1454 .map_page = iommu_dma_map_page,1450 .map_page = iommu_dma_map_page,
kernel/dma/Kconfig+1−6
@@ -110,15 +110,10 @@ config DMA_GLOBAL_POOL · 109 unmodified lines
110 select DMA_DECLARE_COHERENT110 select DMA_DECLARE_COHERENT
111 bool111 bool
112 112
113config DMA_REMAP
114 bool
115 depends on MMU
116 select DMA_NONCOHERENT_MMAP
117
118config DMA_DIRECT_REMAP113config DMA_DIRECT_REMAP
119 bool114 bool
120 select DMA_REMAP
121 select DMA_COHERENT_POOL115 select DMA_COHERENT_POOL
116 select DMA_NONCOHERENT_MMAP
122 117
123config DMA_CMA118config DMA_CMA
124 bool "DMA Contiguous Memory Allocator"119 bool "DMA Contiguous Memory Allocator"
kernel/dma/Makefile+1−1
@@ -8,5 +8,5 @@ obj-$(CONFIG_DMA_DECLARE_COHERENT) += coherent.o · 7 unmodified lines
8obj-$(CONFIG_DMA_API_DEBUG) += debug.o8obj-$(CONFIG_DMA_API_DEBUG) += debug.o
9obj-$(CONFIG_SWIOTLB) += swiotlb.o9obj-$(CONFIG_SWIOTLB) += swiotlb.o
10obj-$(CONFIG_DMA_COHERENT_POOL) += pool.o10obj-$(CONFIG_DMA_COHERENT_POOL) += pool.o
11obj-$(CONFIG_DMA_REMAP) += remap.o11obj-$(CONFIG_MMU) += remap.o
12obj-$(CONFIG_DMA_MAP_BENCHMARK) += map_benchmark.o12obj-$(CONFIG_DMA_MAP_BENCHMARK) += map_benchmark.o
kernel/dma/direct.c+7−11
@@ -265,17 +265,13 @@ void *dma_direct_alloc(struct device *dev, size_t size, · 264 unmodified lines
265 page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO);265 page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO);
266 if (!page)266 if (!page)
267 return NULL;267 return NULL;
268
269 /*
270 * dma_alloc_contiguous can return highmem pages depending on a
271 * combination the cma= arguments and per-arch setup. These need to be
272 * remapped to return a kernel virtual address.
273 */
268 if (PageHighMem(page)) {274 if (PageHighMem(page)) {
269 /*
270 * Depending on the cma= arguments and per-arch setup,
271 * dma_alloc_contiguous could return highmem pages.
272 * Without remapping there is no way to return them here, so
273 * log an error and fail.
274 */
275 if (!IS_ENABLED(CONFIG_DMA_REMAP)) {
276 dev_info(dev, "Rejecting highmem page from CMA.\n");
277 goto out_free_pages;
278 }
279 remap = true;275 remap = true;
280 set_uncached = false;276 set_uncached = false;
281 }277 }
@@ -349,7 +345,7 @@ void dma_direct_free(struct device *dev, size_t size, · 67 unmodified lines
349 dma_free_from_pool(dev, cpu_addr, PAGE_ALIGN(size)))345 dma_free_from_pool(dev, cpu_addr, PAGE_ALIGN(size)))
350 return;346 return;
351 347
352 if (IS_ENABLED(CONFIG_DMA_REMAP) && is_vmalloc_addr(cpu_addr)) {348 if (is_vmalloc_addr(cpu_addr)) {
353 vunmap(cpu_addr);349 vunmap(cpu_addr);
354 } else {350 } else {
355 if (IS_ENABLED(CONFIG_ARCH_HAS_DMA_CLEAR_UNCACHED))351 if (IS_ENABLED(CONFIG_ARCH_HAS_DMA_CLEAR_UNCACHED))