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()
Unified · Split
| @@ -552,7 +552,7 @@ static void active_cacheline_remove(struct dma_debug_entry *entry) · 551 unmodified lines | ||
| 552 | 552 | * Wrapper function for adding an entry to the hash. |
| 553 | 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 | 557 | struct hash_bucket *bucket; |
| 558 | 558 | unsigned long flags; |
| @@ -566,7 +566,7 @@ static void add_dma_entry(struct dma_debug_entry *entry) · 7 unmodified lines | ||
| 566 | 566 | if (rc == -ENOMEM) { |
| 567 | 567 | pr_err("cacheline tracking ENOMEM, dma-debug disabled\n"); |
| 568 | 568 | global_disable = true; |
| 569 | − } else if (rc == -EEXIST) { | |
| 569 | + } else if (rc == -EEXIST && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) { | |
| 570 | 570 | err_printk(entry->dev, entry, |
| 571 | 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 | 1191 | EXPORT_SYMBOL(debug_dma_map_single); |
| 1192 | 1192 | |
| 1193 | 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 | 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 | 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 | 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 | 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 | 1287 | struct dma_debug_entry *entry; |
| 1286 | 1288 | struct scatterlist *s; |
| @@ -1289,6 +1291,12 @@ void debug_dma_map_sg(struct device *dev, struct scatterlist *sg, · 2 unmodified lines | ||
| 1289 | 1291 | if (unlikely(dma_debug_disabled())) |
| 1290 | 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 | 1300 | for_each_sg(sg, s, mapped_ents, i) { |
| 1293 | 1301 | entry = dma_entry_alloc(); |
| 1294 | 1302 | if (!entry) |
| @@ -1304,15 +1312,9 @@ void debug_dma_map_sg(struct device *dev, struct scatterlist *sg, · 9 unmodified lines | ||
| 1304 | 1312 | entry->sg_call_ents = nents; |
| 1305 | 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 | 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 | 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 | 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 | 1401 | else |
| 1399 | 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 | 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 | 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 | 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 | 1453 | entry->direction = direction; |
| 1450 | 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 | 1459 | void debug_dma_unmap_resource(struct device *dev, dma_addr_t dma_addr, |
| @@ -11,26 +11,30 @@ · 10 unmodified lines | ||
| 11 | 11 | #ifdef CONFIG_DMA_API_DEBUG |
| 12 | 12 | extern void debug_dma_map_page(struct device *dev, struct page *page, |
| 13 | 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 | 17 | extern void debug_dma_unmap_page(struct device *dev, dma_addr_t addr, |
| 17 | 18 | size_t size, int direction); |
| 18 | 19 | |
| 19 | 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 | 24 | extern void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, |
| 23 | 25 | int nelems, int dir); |
| 24 | 26 | |
| 25 | 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 | 31 | extern void debug_dma_free_coherent(struct device *dev, size_t size, |
| 29 | 32 | void *virt, dma_addr_t addr); |
| 30 | 33 | |
| 31 | 34 | extern void debug_dma_map_resource(struct device *dev, phys_addr_t addr, |
| 32 | 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 | 39 | extern void debug_dma_unmap_resource(struct device *dev, dma_addr_t dma_addr, |
| 36 | 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 | 57 | #else /* CONFIG_DMA_API_DEBUG */ |
| 54 | 58 | static inline void debug_dma_map_page(struct device *dev, struct page *page, |
| 55 | 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 | 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 | 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 | 93 | static inline void debug_dma_map_resource(struct device *dev, phys_addr_t addr, |
| 87 | 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 | 156 | addr = dma_direct_map_page(dev, page, offset, size, dir, attrs); |
| 157 | 157 | else |
| 158 | 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 | 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 | 195 | ents = ops->map_sg(dev, sg, nents, dir, attrs); |
| 196 | 196 | |
| 197 | 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 | 199 | else if (WARN_ON_ONCE(ents != -EINVAL && ents != -ENOMEM && |
| 200 | 200 | ents != -EIO)) |
| 201 | 201 | return -EIO; |
| @@ -249,12 +249,12 @@ EXPORT_SYMBOL(dma_map_sg_attrs); · 47 unmodified lines | ||
| 249 | 249 | * Returns 0 on success or a negative error code on error. The following |
| 250 | 250 | * error codes are supported with the given meaning: |
| 251 | 251 | * |
| 252 | − * -EINVAL - An invalid argument, unaligned access or other error | |
| 253 | − * in usage. Will not succeed if retried. | |
| 254 | − * -ENOMEM - Insufficient resources (like memory or IOVA space) to | |
| 255 | − * complete the mapping. Should succeed if retried later. | |
| 256 | − * -EIO - Legacy error code with an unknown meaning. eg. this is | |
| 257 | − * returned if a lower level call returned DMA_MAPPING_ERROR. | |
| 252 | + * -EINVAL An invalid argument, unaligned access or other error | |
| 253 | + * in usage. Will not succeed if retried. | |
| 254 | + * -ENOMEM Insufficient resources (like memory or IOVA space) to | |
| 255 | + * complete the mapping. Should succeed if retried later. | |
| 256 | + * -EIO Legacy error code with an unknown meaning. eg. this is | |
| 257 | + * returned if a lower level call returned DMA_MAPPING_ERROR. | |
| 258 | 258 | */ |
| 259 | 259 | int dma_map_sgtable(struct device *dev, struct sg_table *sgt, |
| 260 | 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 | 305 | else if (ops->map_resource) |
| 306 | 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 | 309 | return addr; |
| 310 | 310 | } |
| 311 | 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 | 510 | else |
| 511 | 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 | 514 | return cpu_addr; |
| 515 | 515 | } |
| 516 | 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 | 566 | struct page *page = __dma_alloc_pages(dev, size, dma_handle, dir, gfp); |
| 567 | 567 | |
| 568 | 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 | 570 | return page; |
| 571 | 571 | } |
| 572 | 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 | 645 | if (sgt) { |
| 646 | 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 | 649 | return sgt; |
| 650 | 650 | } |