Pull dma-mapping fixes from Christoph Hellwig: - fix more dma-debug fallout (Gerald Schaefer, Hamza Mahfooz) - fix a kerneldoc warning (Logan Gunthorpe) * tag 'dma-mapping-5.15-2' of git://git.infradead.org/users/hch/dma-mapping: dma-debug: teach add_dma_entry() about DMA_ATTR_SKIP_CPU_SYNC dma-debug: fix sg checks in debug_dma_map_sg() dma-mapping: fix the kerneldoc for dma_map_sgtable()
Showing the changes to kernel (3 of 3 files). Show all
Unified · Split
| @@ -552,7 +552,7 @@ static void active_cacheline_remove(struct dma_debug_entry *entry) · 551 unmodified lines | |||
| 552 | * Wrapper function for adding an entry to the hash. | 552 | * Wrapper function for adding an entry to the hash. |
| 553 | * This function takes care of locking itself. | 553 | * This function takes care of locking itself. |
| 554 | */ | 554 | */ |
| 555 | static void add_dma_entry(struct dma_debug_entry *entry) | 555 | static void add_dma_entry(struct dma_debug_entry *entry, unsigned long attrs) |
| 556 | { | 556 | { |
| 557 | struct hash_bucket *bucket; | 557 | struct hash_bucket *bucket; |
| 558 | unsigned long flags; | 558 | unsigned long flags; |
| @@ -566,7 +566,7 @@ static void add_dma_entry(struct dma_debug_entry *entry) · 7 unmodified lines | |||
| 566 | if (rc == -ENOMEM) { | 566 | if (rc == -ENOMEM) { |
| 567 | pr_err("cacheline tracking ENOMEM, dma-debug disabled\n"); | 567 | pr_err("cacheline tracking ENOMEM, dma-debug disabled\n"); |
| 568 | global_disable = true; | 568 | global_disable = true; |
| 569 | } else if (rc == -EEXIST) { | 569 | } else if (rc == -EEXIST && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) { |
| 570 | err_printk(entry->dev, entry, | 570 | err_printk(entry->dev, entry, |
| 571 | "cacheline tracking EEXIST, overlapping mappings aren't supported\n"); | 571 | "cacheline tracking EEXIST, overlapping mappings aren't supported\n"); |
| 572 | } | 572 | } |
| @@ -1191,7 +1191,8 @@ void debug_dma_map_single(struct device *dev, const void *addr, · 618 unmodified lines | |||
| 1191 | EXPORT_SYMBOL(debug_dma_map_single); | 1191 | EXPORT_SYMBOL(debug_dma_map_single); |
| 1192 | 1192 | ||
| 1193 | void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, | 1193 | void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, |
| 1194 | size_t size, int direction, dma_addr_t dma_addr) | 1194 | size_t size, int direction, dma_addr_t dma_addr, |
| 1195 | unsigned long attrs) | ||
| 1195 | { | 1196 | { |
| 1196 | struct dma_debug_entry *entry; | 1197 | struct dma_debug_entry *entry; |
| 1197 | 1198 | ||
| @@ -1222,7 +1223,7 @@ void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, · 24 unmodified lines | |||
| 1222 | check_for_illegal_area(dev, addr, size); | 1223 | check_for_illegal_area(dev, addr, size); |
| 1223 | } | 1224 | } |
| 1224 | 1225 | ||
| 1225 | add_dma_entry(entry); | 1226 | add_dma_entry(entry, attrs); |
| 1226 | } | 1227 | } |
| 1227 | 1228 | ||
| 1228 | void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | 1229 | void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) |
| @@ -1280,7 +1281,8 @@ void debug_dma_unmap_page(struct device *dev, dma_addr_t addr, · 51 unmodified lines | |||
| 1280 | } | 1281 | } |
| 1281 | 1282 | ||
| 1282 | void debug_dma_map_sg(struct device *dev, struct scatterlist *sg, | 1283 | void debug_dma_map_sg(struct device *dev, struct scatterlist *sg, |
| 1283 | int nents, int mapped_ents, int direction) | 1284 | int nents, int mapped_ents, int direction, |
| 1285 | unsigned long attrs) | ||
| 1284 | { | 1286 | { |
| 1285 | struct dma_debug_entry *entry; | 1287 | struct dma_debug_entry *entry; |
| 1286 | struct scatterlist *s; | 1288 | struct scatterlist *s; |
| @@ -1289,6 +1291,12 @@ void debug_dma_map_sg(struct device *dev, struct scatterlist *sg, · 2 unmodified lines | |||
| 1289 | if (unlikely(dma_debug_disabled())) | 1291 | if (unlikely(dma_debug_disabled())) |
| 1290 | return; | 1292 | return; |
| 1291 | 1293 | ||
| 1294 | for_each_sg(sg, s, nents, i) { | ||
| 1295 | check_for_stack(dev, sg_page(s), s->offset); | ||
| 1296 | if (!PageHighMem(sg_page(s))) | ||
| 1297 | check_for_illegal_area(dev, sg_virt(s), s->length); | ||
| 1298 | } | ||
| 1299 | |||
| 1292 | for_each_sg(sg, s, mapped_ents, i) { | 1300 | for_each_sg(sg, s, mapped_ents, i) { |
| 1293 | entry = dma_entry_alloc(); | 1301 | entry = dma_entry_alloc(); |
| 1294 | if (!entry) | 1302 | if (!entry) |
| @@ -1304,15 +1312,9 @@ void debug_dma_map_sg(struct device *dev, struct scatterlist *sg, · 9 unmodified lines | |||
| 1304 | entry->sg_call_ents = nents; | 1312 | entry->sg_call_ents = nents; |
| 1305 | entry->sg_mapped_ents = mapped_ents; | 1313 | entry->sg_mapped_ents = mapped_ents; |
| 1306 | 1314 | ||
| 1307 | check_for_stack(dev, sg_page(s), s->offset); | ||
| 1308 | |||
| 1309 | if (!PageHighMem(sg_page(s))) { | ||
| 1310 | check_for_illegal_area(dev, sg_virt(s), sg_dma_len(s)); | ||
| 1311 | } | ||
| 1312 | |||
| 1313 | check_sg_segment(dev, s); | 1315 | check_sg_segment(dev, s); |
| 1314 | 1316 | ||
| 1315 | add_dma_entry(entry); | 1317 | add_dma_entry(entry, attrs); |
| 1316 | } | 1318 | } |
| 1317 | } | 1319 | } |
| 1318 | 1320 | ||
| @@ -1368,7 +1370,8 @@ void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, · 49 unmodified lines | |||
| 1368 | } | 1370 | } |
| 1369 | 1371 | ||
| 1370 | void debug_dma_alloc_coherent(struct device *dev, size_t size, | 1372 | void debug_dma_alloc_coherent(struct device *dev, size_t size, |
| 1371 | dma_addr_t dma_addr, void *virt) | 1373 | dma_addr_t dma_addr, void *virt, |
| 1374 | unsigned long attrs) | ||
| 1372 | { | 1375 | { |
| 1373 | struct dma_debug_entry *entry; | 1376 | struct dma_debug_entry *entry; |
| 1374 | 1377 | ||
| @@ -1398,7 +1401,7 @@ void debug_dma_alloc_coherent(struct device *dev, size_t size, · 23 unmodified lines | |||
| 1398 | else | 1401 | else |
| 1399 | entry->pfn = page_to_pfn(virt_to_page(virt)); | 1402 | entry->pfn = page_to_pfn(virt_to_page(virt)); |
| 1400 | 1403 | ||
| 1401 | add_dma_entry(entry); | 1404 | add_dma_entry(entry, attrs); |
| 1402 | } | 1405 | } |
| 1403 | 1406 | ||
| 1404 | void debug_dma_free_coherent(struct device *dev, size_t size, | 1407 | void debug_dma_free_coherent(struct device *dev, size_t size, |
| @@ -1429,7 +1432,8 @@ void debug_dma_free_coherent(struct device *dev, size_t size, · 24 unmodified lines | |||
| 1429 | } | 1432 | } |
| 1430 | 1433 | ||
| 1431 | void debug_dma_map_resource(struct device *dev, phys_addr_t addr, size_t size, | 1434 | void debug_dma_map_resource(struct device *dev, phys_addr_t addr, size_t size, |
| 1432 | int direction, dma_addr_t dma_addr) | 1435 | int direction, dma_addr_t dma_addr, |
| 1436 | unsigned long attrs) | ||
| 1433 | { | 1437 | { |
| 1434 | struct dma_debug_entry *entry; | 1438 | struct dma_debug_entry *entry; |
| 1435 | 1439 | ||
| @@ -1449,7 +1453,7 @@ void debug_dma_map_resource(struct device *dev, phys_addr_t addr, size_t size, · 13 unmodified lines | |||
| 1449 | entry->direction = direction; | 1453 | entry->direction = direction; |
| 1450 | entry->map_err_type = MAP_ERR_NOT_CHECKED; | 1454 | entry->map_err_type = MAP_ERR_NOT_CHECKED; |
| 1451 | 1455 | ||
| 1452 | add_dma_entry(entry); | 1456 | add_dma_entry(entry, attrs); |
| 1453 | } | 1457 | } |
| 1454 | 1458 | ||
| 1455 | void debug_dma_unmap_resource(struct device *dev, dma_addr_t dma_addr, | 1459 | void debug_dma_unmap_resource(struct device *dev, dma_addr_t dma_addr, |
| @@ -11,26 +11,30 @@ · 10 unmodified lines | |||
| 11 | #ifdef CONFIG_DMA_API_DEBUG | 11 | #ifdef CONFIG_DMA_API_DEBUG |
| 12 | extern void debug_dma_map_page(struct device *dev, struct page *page, | 12 | extern void debug_dma_map_page(struct device *dev, struct page *page, |
| 13 | size_t offset, size_t size, | 13 | size_t offset, size_t size, |
| 14 | int direction, dma_addr_t dma_addr); | 14 | int direction, dma_addr_t dma_addr, |
| 15 | unsigned long attrs); | ||
| 15 | 16 | ||
| 16 | extern void debug_dma_unmap_page(struct device *dev, dma_addr_t addr, | 17 | extern void debug_dma_unmap_page(struct device *dev, dma_addr_t addr, |
| 17 | size_t size, int direction); | 18 | size_t size, int direction); |
| 18 | 19 | ||
| 19 | extern void debug_dma_map_sg(struct device *dev, struct scatterlist *sg, | 20 | extern void debug_dma_map_sg(struct device *dev, struct scatterlist *sg, |
| 20 | int nents, int mapped_ents, int direction); | 21 | int nents, int mapped_ents, int direction, |
| 22 | unsigned long attrs); | ||
| 21 | 23 | ||
| 22 | extern void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, | 24 | extern void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, |
| 23 | int nelems, int dir); | 25 | int nelems, int dir); |
| 24 | 26 | ||
| 25 | extern void debug_dma_alloc_coherent(struct device *dev, size_t size, | 27 | extern void debug_dma_alloc_coherent(struct device *dev, size_t size, |
| 26 | dma_addr_t dma_addr, void *virt); | 28 | dma_addr_t dma_addr, void *virt, |
| 29 | unsigned long attrs); | ||
| 27 | 30 | ||
| 28 | extern void debug_dma_free_coherent(struct device *dev, size_t size, | 31 | extern void debug_dma_free_coherent(struct device *dev, size_t size, |
| 29 | void *virt, dma_addr_t addr); | 32 | void *virt, dma_addr_t addr); |
| 30 | 33 | ||
| 31 | extern void debug_dma_map_resource(struct device *dev, phys_addr_t addr, | 34 | extern void debug_dma_map_resource(struct device *dev, phys_addr_t addr, |
| 32 | size_t size, int direction, | 35 | size_t size, int direction, |
| 33 | dma_addr_t dma_addr); | 36 | dma_addr_t dma_addr, |
| 37 | unsigned long attrs); | ||
| 34 | 38 | ||
| 35 | extern void debug_dma_unmap_resource(struct device *dev, dma_addr_t dma_addr, | 39 | extern void debug_dma_unmap_resource(struct device *dev, dma_addr_t dma_addr, |
| 36 | size_t size, int direction); | 40 | size_t size, int direction); |
| @@ -53,7 +57,8 @@ extern void debug_dma_sync_sg_for_device(struct device *dev, · 16 unmodified lines | |||
| 53 | #else /* CONFIG_DMA_API_DEBUG */ | 57 | #else /* CONFIG_DMA_API_DEBUG */ |
| 54 | static inline void debug_dma_map_page(struct device *dev, struct page *page, | 58 | static inline void debug_dma_map_page(struct device *dev, struct page *page, |
| 55 | size_t offset, size_t size, | 59 | size_t offset, size_t size, |
| 56 | int direction, dma_addr_t dma_addr) | 60 | int direction, dma_addr_t dma_addr, |
| 61 | unsigned long attrs) | ||
| 57 | { | 62 | { |
| 58 | } | 63 | } |
| 59 | 64 | ||
| @@ -63,7 +68,8 @@ static inline void debug_dma_unmap_page(struct device *dev, dma_addr_t addr, · 3 unmodified lines | |||
| 63 | } | 68 | } |
| 64 | 69 | ||
| 65 | static inline void debug_dma_map_sg(struct device *dev, struct scatterlist *sg, | 70 | static inline void debug_dma_map_sg(struct device *dev, struct scatterlist *sg, |
| 66 | int nents, int mapped_ents, int direction) | 71 | int nents, int mapped_ents, int direction, |
| 72 | unsigned long attrs) | ||
| 67 | { | 73 | { |
| 68 | } | 74 | } |
| 69 | 75 | ||
| @@ -74,7 +80,8 @@ static inline void debug_dma_unmap_sg(struct device *dev, · 4 unmodified lines | |||
| 74 | } | 80 | } |
| 75 | 81 | ||
| 76 | static inline void debug_dma_alloc_coherent(struct device *dev, size_t size, | 82 | static inline void debug_dma_alloc_coherent(struct device *dev, size_t size, |
| 77 | dma_addr_t dma_addr, void *virt) | 83 | dma_addr_t dma_addr, void *virt, |
| 84 | unsigned long attrs) | ||
| 78 | { | 85 | { |
| 79 | } | 86 | } |
| 80 | 87 | ||
| @@ -85,7 +92,8 @@ static inline void debug_dma_free_coherent(struct device *dev, size_t size, · 4 unmodified lines | |||
| 85 | 92 | ||
| 86 | static inline void debug_dma_map_resource(struct device *dev, phys_addr_t addr, | 93 | static inline void debug_dma_map_resource(struct device *dev, phys_addr_t addr, |
| 87 | size_t size, int direction, | 94 | size_t size, int direction, |
| 88 | dma_addr_t dma_addr) | 95 | dma_addr_t dma_addr, |
| 96 | unsigned long attrs) | ||
| 89 | { | 97 | { |
| 90 | } | 98 | } |
| 91 | 99 | ||
| @@ -156,7 +156,7 @@ dma_addr_t dma_map_page_attrs(struct device *dev, struct page *page, · 155 unmodified lines | |||
| 156 | addr = dma_direct_map_page(dev, page, offset, size, dir, attrs); | 156 | addr = dma_direct_map_page(dev, page, offset, size, dir, attrs); |
| 157 | else | 157 | else |
| 158 | addr = ops->map_page(dev, page, offset, size, dir, attrs); | 158 | addr = ops->map_page(dev, page, offset, size, dir, attrs); |
| 159 | debug_dma_map_page(dev, page, offset, size, dir, addr); | 159 | debug_dma_map_page(dev, page, offset, size, dir, addr, attrs); |
| 160 | 160 | ||
| 161 | return addr; | 161 | return addr; |
| 162 | } | 162 | } |
| @@ -195,7 +195,7 @@ static int __dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, · 32 unmodified lines | |||
| 195 | ents = ops->map_sg(dev, sg, nents, dir, attrs); | 195 | ents = ops->map_sg(dev, sg, nents, dir, attrs); |
| 196 | 196 | ||
| 197 | if (ents > 0) | 197 | if (ents > 0) |
| 198 | debug_dma_map_sg(dev, sg, nents, ents, dir); | 198 | debug_dma_map_sg(dev, sg, nents, ents, dir, attrs); |
| 199 | else if (WARN_ON_ONCE(ents != -EINVAL && ents != -ENOMEM && | 199 | else if (WARN_ON_ONCE(ents != -EINVAL && ents != -ENOMEM && |
| 200 | ents != -EIO)) | 200 | ents != -EIO)) |
| 201 | return -EIO; | 201 | return -EIO; |
| @@ -249,12 +249,12 @@ EXPORT_SYMBOL(dma_map_sg_attrs); · 47 unmodified lines | |||
| 249 | * Returns 0 on success or a negative error code on error. The following | 249 | * Returns 0 on success or a negative error code on error. The following |
| 250 | * error codes are supported with the given meaning: | 250 | * error codes are supported with the given meaning: |
| 251 | * | 251 | * |
| 252 | * -EINVAL - An invalid argument, unaligned access or other error | 252 | * -EINVAL An invalid argument, unaligned access or other error |
| 253 | * in usage. Will not succeed if retried. | 253 | * in usage. Will not succeed if retried. |
| 254 | * -ENOMEM - Insufficient resources (like memory or IOVA space) to | 254 | * -ENOMEM Insufficient resources (like memory or IOVA space) to |
| 255 | * complete the mapping. Should succeed if retried later. | 255 | * complete the mapping. Should succeed if retried later. |
| 256 | * -EIO - Legacy error code with an unknown meaning. eg. this is | 256 | * -EIO Legacy error code with an unknown meaning. eg. this is |
| 257 | * returned if a lower level call returned DMA_MAPPING_ERROR. | 257 | * returned if a lower level call returned DMA_MAPPING_ERROR. |
| 258 | */ | 258 | */ |
| 259 | int dma_map_sgtable(struct device *dev, struct sg_table *sgt, | 259 | int dma_map_sgtable(struct device *dev, struct sg_table *sgt, |
| 260 | enum dma_data_direction dir, unsigned long attrs) | 260 | enum dma_data_direction dir, unsigned long attrs) |
| @@ -305,7 +305,7 @@ dma_addr_t dma_map_resource(struct device *dev, phys_addr_t phys_addr, · 44 unmodified lines | |||
| 305 | else if (ops->map_resource) | 305 | else if (ops->map_resource) |
| 306 | addr = ops->map_resource(dev, phys_addr, size, dir, attrs); | 306 | addr = ops->map_resource(dev, phys_addr, size, dir, attrs); |
| 307 | 307 | ||
| 308 | debug_dma_map_resource(dev, phys_addr, size, dir, addr); | 308 | debug_dma_map_resource(dev, phys_addr, size, dir, addr, attrs); |
| 309 | return addr; | 309 | return addr; |
| 310 | } | 310 | } |
| 311 | EXPORT_SYMBOL(dma_map_resource); | 311 | EXPORT_SYMBOL(dma_map_resource); |
| @@ -510,7 +510,7 @@ void *dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle, · 198 unmodified lines | |||
| 510 | else | 510 | else |
| 511 | return NULL; | 511 | return NULL; |
| 512 | 512 | ||
| 513 | debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr); | 513 | debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr, attrs); |
| 514 | return cpu_addr; | 514 | return cpu_addr; |
| 515 | } | 515 | } |
| 516 | EXPORT_SYMBOL(dma_alloc_attrs); | 516 | EXPORT_SYMBOL(dma_alloc_attrs); |
| @@ -566,7 +566,7 @@ struct page *dma_alloc_pages(struct device *dev, size_t size, · 49 unmodified lines | |||
| 566 | struct page *page = __dma_alloc_pages(dev, size, dma_handle, dir, gfp); | 566 | struct page *page = __dma_alloc_pages(dev, size, dma_handle, dir, gfp); |
| 567 | 567 | ||
| 568 | if (page) | 568 | if (page) |
| 569 | debug_dma_map_page(dev, page, 0, size, dir, *dma_handle); | 569 | debug_dma_map_page(dev, page, 0, size, dir, *dma_handle, 0); |
| 570 | return page; | 570 | return page; |
| 571 | } | 571 | } |
| 572 | EXPORT_SYMBOL_GPL(dma_alloc_pages); | 572 | EXPORT_SYMBOL_GPL(dma_alloc_pages); |
| @@ -644,7 +644,7 @@ struct sg_table *dma_alloc_noncontiguous(struct device *dev, size_t size, · 71 unmodified lines | |||
| 644 | 644 | ||
| 645 | if (sgt) { | 645 | if (sgt) { |
| 646 | sgt->nents = 1; | 646 | sgt->nents = 1; |
| 647 | debug_dma_map_sg(dev, sgt->sgl, sgt->orig_nents, 1, dir); | 647 | debug_dma_map_sg(dev, sgt->sgl, sgt->orig_nents, 1, dir, attrs); |
| 648 | } | 648 | } |
| 649 | return sgt; | 649 | return sgt; |
| 650 | } | 650 | } |