Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'dma-mapping-5.9-1' of git://git.infradead.org/users/hch/dma-mapping

Pull dma-mapping fixes from Christoph Hellwig:
"Fix more fallout from the dma-pool changes (Nicolas Saenz Julienne,
me)"

* tag 'dma-mapping-5.9-1' of git://git.infradead.org/users/hch/dma-mapping:
dma-pool: Only allocate from CMA when in same memory zone
dma-pool: fix coherent pool allocations for IOMMU mappings

+93 -79
+2 -2
drivers/iommu/dma-iommu.c
··· 1035 1035 1036 1036 if (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) && 1037 1037 !gfpflags_allow_blocking(gfp) && !coherent) 1038 - cpu_addr = dma_alloc_from_pool(dev, PAGE_ALIGN(size), &page, 1039 - gfp); 1038 + page = dma_alloc_from_pool(dev, PAGE_ALIGN(size), &cpu_addr, 1039 + gfp, NULL); 1040 1040 else 1041 1041 cpu_addr = iommu_dma_alloc_pages(dev, size, &page, gfp, attrs); 1042 1042 if (!cpu_addr)
-3
include/linux/dma-direct.h
··· 73 73 } 74 74 75 75 u64 dma_direct_get_required_mask(struct device *dev); 76 - gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask, 77 - u64 *phys_mask); 78 - bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size); 79 76 void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, 80 77 gfp_t gfp, unsigned long attrs); 81 78 void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
+3 -2
include/linux/dma-mapping.h
··· 522 522 pgprot_t prot, const void *caller); 523 523 void dma_common_free_remap(void *cpu_addr, size_t size); 524 524 525 - void *dma_alloc_from_pool(struct device *dev, size_t size, 526 - struct page **ret_page, gfp_t flags); 525 + struct page *dma_alloc_from_pool(struct device *dev, size_t size, 526 + void **cpu_addr, gfp_t flags, 527 + bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t)); 527 528 bool dma_free_from_pool(struct device *dev, void *start, size_t size); 528 529 529 530 int
+9 -4
kernel/dma/direct.c
··· 43 43 return (1ULL << (fls64(max_dma) - 1)) * 2 - 1; 44 44 } 45 45 46 - gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask, 46 + static gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask, 47 47 u64 *phys_limit) 48 48 { 49 49 u64 dma_limit = min_not_zero(dma_mask, dev->bus_dma_limit); ··· 68 68 return 0; 69 69 } 70 70 71 - bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size) 71 + static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size) 72 72 { 73 73 return phys_to_dma_direct(dev, phys) + size - 1 <= 74 74 min_not_zero(dev->coherent_dma_mask, dev->bus_dma_limit); ··· 161 161 size = PAGE_ALIGN(size); 162 162 163 163 if (dma_should_alloc_from_pool(dev, gfp, attrs)) { 164 - ret = dma_alloc_from_pool(dev, size, &page, gfp); 165 - if (!ret) 164 + u64 phys_mask; 165 + 166 + gfp |= dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask, 167 + &phys_mask); 168 + page = dma_alloc_from_pool(dev, size, &ret, gfp, 169 + dma_coherent_ok); 170 + if (!page) 166 171 return NULL; 167 172 goto done; 168 173 }
+79 -68
kernel/dma/pool.c
··· 3 3 * Copyright (C) 2012 ARM Ltd. 4 4 * Copyright (C) 2020 Google LLC 5 5 */ 6 + #include <linux/cma.h> 6 7 #include <linux/debugfs.h> 8 + #include <linux/dma-contiguous.h> 7 9 #include <linux/dma-direct.h> 8 10 #include <linux/dma-noncoherent.h> 9 11 #include <linux/init.h> ··· 57 55 pool_size_kernel += size; 58 56 } 59 57 58 + static bool cma_in_zone(gfp_t gfp) 59 + { 60 + unsigned long size; 61 + phys_addr_t end; 62 + struct cma *cma; 63 + 64 + cma = dev_get_cma_area(NULL); 65 + if (!cma) 66 + return false; 67 + 68 + size = cma_get_size(cma); 69 + if (!size) 70 + return false; 71 + 72 + /* CMA can't cross zone boundaries, see cma_activate_area() */ 73 + end = cma_get_base(cma) + size - 1; 74 + if (IS_ENABLED(CONFIG_ZONE_DMA) && (gfp & GFP_DMA)) 75 + return end <= DMA_BIT_MASK(zone_dma_bits); 76 + if (IS_ENABLED(CONFIG_ZONE_DMA32) && (gfp & GFP_DMA32)) 77 + return end <= DMA_BIT_MASK(32); 78 + return true; 79 + } 80 + 60 81 static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size, 61 82 gfp_t gfp) 62 83 { ··· 93 68 94 69 do { 95 70 pool_size = 1 << (PAGE_SHIFT + order); 96 - page = alloc_pages(gfp, order); 71 + if (cma_in_zone(gfp)) 72 + page = dma_alloc_from_contiguous(NULL, 1 << order, 73 + order, false); 74 + if (!page) 75 + page = alloc_pages(gfp, order); 97 76 } while (!page && order-- > 0); 98 77 if (!page) 99 78 goto out; ··· 225 196 } 226 197 postcore_initcall(dma_atomic_pool_init); 227 198 228 - static inline struct gen_pool *dma_guess_pool_from_device(struct device *dev) 199 + static inline struct gen_pool *dma_guess_pool(struct gen_pool *prev, gfp_t gfp) 229 200 { 230 - u64 phys_mask; 231 - gfp_t gfp; 232 - 233 - gfp = dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask, 234 - &phys_mask); 235 - if (IS_ENABLED(CONFIG_ZONE_DMA) && gfp == GFP_DMA) 201 + if (prev == NULL) { 202 + if (IS_ENABLED(CONFIG_ZONE_DMA32) && (gfp & GFP_DMA32)) 203 + return atomic_pool_dma32; 204 + if (IS_ENABLED(CONFIG_ZONE_DMA) && (gfp & GFP_DMA)) 205 + return atomic_pool_dma; 206 + return atomic_pool_kernel; 207 + } 208 + if (prev == atomic_pool_kernel) 209 + return atomic_pool_dma32 ? atomic_pool_dma32 : atomic_pool_dma; 210 + if (prev == atomic_pool_dma32) 236 211 return atomic_pool_dma; 237 - if (IS_ENABLED(CONFIG_ZONE_DMA32) && gfp == GFP_DMA32) 238 - return atomic_pool_dma32; 239 - return atomic_pool_kernel; 240 - } 241 - 242 - static inline struct gen_pool *dma_get_safer_pool(struct gen_pool *bad_pool) 243 - { 244 - if (bad_pool == atomic_pool_kernel) 245 - return atomic_pool_dma32 ? : atomic_pool_dma; 246 - 247 - if (bad_pool == atomic_pool_dma32) 248 - return atomic_pool_dma; 249 - 250 212 return NULL; 251 213 } 252 214 253 - static inline struct gen_pool *dma_guess_pool(struct device *dev, 254 - struct gen_pool *bad_pool) 215 + static struct page *__dma_alloc_from_pool(struct device *dev, size_t size, 216 + struct gen_pool *pool, void **cpu_addr, 217 + bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t)) 255 218 { 256 - if (bad_pool) 257 - return dma_get_safer_pool(bad_pool); 258 - 259 - return dma_guess_pool_from_device(dev); 260 - } 261 - 262 - void *dma_alloc_from_pool(struct device *dev, size_t size, 263 - struct page **ret_page, gfp_t flags) 264 - { 265 - struct gen_pool *pool = NULL; 266 - unsigned long val = 0; 267 - void *ptr = NULL; 219 + unsigned long addr; 268 220 phys_addr_t phys; 269 221 270 - while (1) { 271 - pool = dma_guess_pool(dev, pool); 272 - if (!pool) { 273 - WARN(1, "Failed to get suitable pool for %s\n", 274 - dev_name(dev)); 275 - break; 276 - } 222 + addr = gen_pool_alloc(pool, size); 223 + if (!addr) 224 + return NULL; 277 225 278 - val = gen_pool_alloc(pool, size); 279 - if (!val) 280 - continue; 281 - 282 - phys = gen_pool_virt_to_phys(pool, val); 283 - if (dma_coherent_ok(dev, phys, size)) 284 - break; 285 - 286 - gen_pool_free(pool, val, size); 287 - val = 0; 226 + phys = gen_pool_virt_to_phys(pool, addr); 227 + if (phys_addr_ok && !phys_addr_ok(dev, phys, size)) { 228 + gen_pool_free(pool, addr, size); 229 + return NULL; 288 230 } 289 231 232 + if (gen_pool_avail(pool) < atomic_pool_size) 233 + schedule_work(&atomic_pool_work); 290 234 291 - if (val) { 292 - *ret_page = pfn_to_page(__phys_to_pfn(phys)); 293 - ptr = (void *)val; 294 - memset(ptr, 0, size); 235 + *cpu_addr = (void *)addr; 236 + memset(*cpu_addr, 0, size); 237 + return pfn_to_page(__phys_to_pfn(phys)); 238 + } 295 239 296 - if (gen_pool_avail(pool) < atomic_pool_size) 297 - schedule_work(&atomic_pool_work); 240 + struct page *dma_alloc_from_pool(struct device *dev, size_t size, 241 + void **cpu_addr, gfp_t gfp, 242 + bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t)) 243 + { 244 + struct gen_pool *pool = NULL; 245 + struct page *page; 246 + 247 + while ((pool = dma_guess_pool(pool, gfp))) { 248 + page = __dma_alloc_from_pool(dev, size, pool, cpu_addr, 249 + phys_addr_ok); 250 + if (page) 251 + return page; 298 252 } 299 253 300 - return ptr; 254 + WARN(1, "Failed to get suitable pool for %s\n", dev_name(dev)); 255 + return NULL; 301 256 } 302 257 303 258 bool dma_free_from_pool(struct device *dev, void *start, size_t size) 304 259 { 305 260 struct gen_pool *pool = NULL; 306 261 307 - while (1) { 308 - pool = dma_guess_pool(dev, pool); 309 - if (!pool) 310 - return false; 311 - 312 - if (gen_pool_has_addr(pool, (unsigned long)start, size)) { 313 - gen_pool_free(pool, (unsigned long)start, size); 314 - return true; 315 - } 262 + while ((pool = dma_guess_pool(pool, 0))) { 263 + if (!gen_pool_has_addr(pool, (unsigned long)start, size)) 264 + continue; 265 + gen_pool_free(pool, (unsigned long)start, size); 266 + return true; 316 267 } 268 + 269 + return false; 317 270 }