diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-13 18:52:23 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-13 18:52:23 -0500 |
| commit | b5cab0da75c292ffa0fbd68dd2c820066b2842de (patch) | |
| tree | 3b8d4483b8ce6d1ea997cde2c89445564cba7b0f | |
| parent | 93173b5bf2841da7e3a9b0cb1312ef5c87251524 (diff) | |
| parent | d29fa0cb7602fa3e96c9eee05e14d14d3e823c89 (diff) | |
Merge branch 'stable/for-linus-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb
Pull swiotlb updates from Konrad Rzeszutek Wilk:
- minor fixes (rate limiting), remove certain functions
- support for DMA_ATTR_SKIP_CPU_SYNC which is an optimization
in the DMA API
* 'stable/for-linus-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb:
swiotlb: Minor fix-ups for DMA_ATTR_SKIP_CPU_SYNC support
swiotlb: Add support for DMA_ATTR_SKIP_CPU_SYNC
swiotlb-xen: Enforce return of DMA_ERROR_CODE in mapping function
swiotlb: Drop unused functions swiotlb_map_sg and swiotlb_unmap_sg
swiotlb: Rate-limit printing when running out of SW-IOMMU space
| -rw-r--r-- | arch/arm/xen/mm.c | 1 | ||||
| -rw-r--r-- | arch/x86/xen/pci-swiotlb-xen.c | 1 | ||||
| -rw-r--r-- | drivers/xen/swiotlb-xen.c | 27 | ||||
| -rw-r--r-- | include/linux/swiotlb.h | 14 | ||||
| -rw-r--r-- | include/xen/swiotlb-xen.h | 3 | ||||
| -rw-r--r-- | lib/swiotlb.c | 81 |
6 files changed, 57 insertions, 70 deletions
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c index d062f08f5020..bd62d94f8ac5 100644 --- a/arch/arm/xen/mm.c +++ b/arch/arm/xen/mm.c | |||
| @@ -186,7 +186,6 @@ struct dma_map_ops *xen_dma_ops; | |||
| 186 | EXPORT_SYMBOL(xen_dma_ops); | 186 | EXPORT_SYMBOL(xen_dma_ops); |
| 187 | 187 | ||
| 188 | static struct dma_map_ops xen_swiotlb_dma_ops = { | 188 | static struct dma_map_ops xen_swiotlb_dma_ops = { |
| 189 | .mapping_error = xen_swiotlb_dma_mapping_error, | ||
| 190 | .alloc = xen_swiotlb_alloc_coherent, | 189 | .alloc = xen_swiotlb_alloc_coherent, |
| 191 | .free = xen_swiotlb_free_coherent, | 190 | .free = xen_swiotlb_free_coherent, |
| 192 | .sync_single_for_cpu = xen_swiotlb_sync_single_for_cpu, | 191 | .sync_single_for_cpu = xen_swiotlb_sync_single_for_cpu, |
diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c index 0e98e5d241d0..a9fafb5c8738 100644 --- a/arch/x86/xen/pci-swiotlb-xen.c +++ b/arch/x86/xen/pci-swiotlb-xen.c | |||
| @@ -19,7 +19,6 @@ | |||
| 19 | int xen_swiotlb __read_mostly; | 19 | int xen_swiotlb __read_mostly; |
| 20 | 20 | ||
| 21 | static struct dma_map_ops xen_swiotlb_dma_ops = { | 21 | static struct dma_map_ops xen_swiotlb_dma_ops = { |
| 22 | .mapping_error = xen_swiotlb_dma_mapping_error, | ||
| 23 | .alloc = xen_swiotlb_alloc_coherent, | 22 | .alloc = xen_swiotlb_alloc_coherent, |
| 24 | .free = xen_swiotlb_free_coherent, | 23 | .free = xen_swiotlb_free_coherent, |
| 25 | .sync_single_for_cpu = xen_swiotlb_sync_single_for_cpu, | 24 | .sync_single_for_cpu = xen_swiotlb_sync_single_for_cpu, |
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 87e6035c9e81..478fb91e3df2 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c | |||
| @@ -405,7 +405,8 @@ dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page, | |||
| 405 | */ | 405 | */ |
| 406 | trace_swiotlb_bounced(dev, dev_addr, size, swiotlb_force); | 406 | trace_swiotlb_bounced(dev, dev_addr, size, swiotlb_force); |
| 407 | 407 | ||
| 408 | map = swiotlb_tbl_map_single(dev, start_dma_addr, phys, size, dir); | 408 | map = swiotlb_tbl_map_single(dev, start_dma_addr, phys, size, dir, |
| 409 | attrs); | ||
| 409 | if (map == SWIOTLB_MAP_ERROR) | 410 | if (map == SWIOTLB_MAP_ERROR) |
| 410 | return DMA_ERROR_CODE; | 411 | return DMA_ERROR_CODE; |
| 411 | 412 | ||
| @@ -416,11 +417,13 @@ dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page, | |||
| 416 | /* | 417 | /* |
| 417 | * Ensure that the address returned is DMA'ble | 418 | * Ensure that the address returned is DMA'ble |
| 418 | */ | 419 | */ |
| 419 | if (!dma_capable(dev, dev_addr, size)) { | 420 | if (dma_capable(dev, dev_addr, size)) |
| 420 | swiotlb_tbl_unmap_single(dev, map, size, dir); | 421 | return dev_addr; |
| 421 | dev_addr = 0; | 422 | |
| 422 | } | 423 | attrs |= DMA_ATTR_SKIP_CPU_SYNC; |
| 423 | return dev_addr; | 424 | swiotlb_tbl_unmap_single(dev, map, size, dir, attrs); |
| 425 | |||
| 426 | return DMA_ERROR_CODE; | ||
| 424 | } | 427 | } |
| 425 | EXPORT_SYMBOL_GPL(xen_swiotlb_map_page); | 428 | EXPORT_SYMBOL_GPL(xen_swiotlb_map_page); |
| 426 | 429 | ||
| @@ -444,7 +447,7 @@ static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr, | |||
| 444 | 447 | ||
| 445 | /* NOTE: We use dev_addr here, not paddr! */ | 448 | /* NOTE: We use dev_addr here, not paddr! */ |
| 446 | if (is_xen_swiotlb_buffer(dev_addr)) { | 449 | if (is_xen_swiotlb_buffer(dev_addr)) { |
| 447 | swiotlb_tbl_unmap_single(hwdev, paddr, size, dir); | 450 | swiotlb_tbl_unmap_single(hwdev, paddr, size, dir, attrs); |
| 448 | return; | 451 | return; |
| 449 | } | 452 | } |
| 450 | 453 | ||
| @@ -557,11 +560,12 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, | |||
| 557 | start_dma_addr, | 560 | start_dma_addr, |
| 558 | sg_phys(sg), | 561 | sg_phys(sg), |
| 559 | sg->length, | 562 | sg->length, |
| 560 | dir); | 563 | dir, attrs); |
| 561 | if (map == SWIOTLB_MAP_ERROR) { | 564 | if (map == SWIOTLB_MAP_ERROR) { |
| 562 | dev_warn(hwdev, "swiotlb buffer is full\n"); | 565 | dev_warn(hwdev, "swiotlb buffer is full\n"); |
| 563 | /* Don't panic here, we expect map_sg users | 566 | /* Don't panic here, we expect map_sg users |
| 564 | to do proper error handling. */ | 567 | to do proper error handling. */ |
| 568 | attrs |= DMA_ATTR_SKIP_CPU_SYNC; | ||
| 565 | xen_swiotlb_unmap_sg_attrs(hwdev, sgl, i, dir, | 569 | xen_swiotlb_unmap_sg_attrs(hwdev, sgl, i, dir, |
| 566 | attrs); | 570 | attrs); |
| 567 | sg_dma_len(sgl) = 0; | 571 | sg_dma_len(sgl) = 0; |
| @@ -648,13 +652,6 @@ xen_swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, | |||
| 648 | } | 652 | } |
| 649 | EXPORT_SYMBOL_GPL(xen_swiotlb_sync_sg_for_device); | 653 | EXPORT_SYMBOL_GPL(xen_swiotlb_sync_sg_for_device); |
| 650 | 654 | ||
| 651 | int | ||
| 652 | xen_swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr) | ||
| 653 | { | ||
| 654 | return !dma_addr; | ||
| 655 | } | ||
| 656 | EXPORT_SYMBOL_GPL(xen_swiotlb_dma_mapping_error); | ||
| 657 | |||
| 658 | /* | 655 | /* |
| 659 | * Return whether the given device DMA address mask can be supported | 656 | * Return whether the given device DMA address mask can be supported |
| 660 | * properly. For example, if your device can only drive the low 24-bits | 657 | * properly. For example, if your device can only drive the low 24-bits |
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index 5f81f8a187f2..183f37c8a5e1 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h | |||
| @@ -44,11 +44,13 @@ enum dma_sync_target { | |||
| 44 | extern phys_addr_t swiotlb_tbl_map_single(struct device *hwdev, | 44 | extern phys_addr_t swiotlb_tbl_map_single(struct device *hwdev, |
| 45 | dma_addr_t tbl_dma_addr, | 45 | dma_addr_t tbl_dma_addr, |
| 46 | phys_addr_t phys, size_t size, | 46 | phys_addr_t phys, size_t size, |
| 47 | enum dma_data_direction dir); | 47 | enum dma_data_direction dir, |
| 48 | unsigned long attrs); | ||
| 48 | 49 | ||
| 49 | extern void swiotlb_tbl_unmap_single(struct device *hwdev, | 50 | extern void swiotlb_tbl_unmap_single(struct device *hwdev, |
| 50 | phys_addr_t tlb_addr, | 51 | phys_addr_t tlb_addr, |
| 51 | size_t size, enum dma_data_direction dir); | 52 | size_t size, enum dma_data_direction dir, |
| 53 | unsigned long attrs); | ||
| 52 | 54 | ||
| 53 | extern void swiotlb_tbl_sync_single(struct device *hwdev, | 55 | extern void swiotlb_tbl_sync_single(struct device *hwdev, |
| 54 | phys_addr_t tlb_addr, | 56 | phys_addr_t tlb_addr, |
| @@ -73,14 +75,6 @@ extern void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr, | |||
| 73 | unsigned long attrs); | 75 | unsigned long attrs); |
| 74 | 76 | ||
| 75 | extern int | 77 | extern int |
| 76 | swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, | ||
| 77 | enum dma_data_direction dir); | ||
| 78 | |||
| 79 | extern void | ||
| 80 | swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, | ||
| 81 | enum dma_data_direction dir); | ||
| 82 | |||
| 83 | extern int | ||
| 84 | swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems, | 78 | swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems, |
| 85 | enum dma_data_direction dir, | 79 | enum dma_data_direction dir, |
| 86 | unsigned long attrs); | 80 | unsigned long attrs); |
diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h index 7c35e279d1e3..a0083be5d529 100644 --- a/include/xen/swiotlb-xen.h +++ b/include/xen/swiotlb-xen.h | |||
| @@ -51,9 +51,6 @@ xen_swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, | |||
| 51 | int nelems, enum dma_data_direction dir); | 51 | int nelems, enum dma_data_direction dir); |
| 52 | 52 | ||
| 53 | extern int | 53 | extern int |
| 54 | xen_swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr); | ||
| 55 | |||
| 56 | extern int | ||
| 57 | xen_swiotlb_dma_supported(struct device *hwdev, u64 mask); | 54 | xen_swiotlb_dma_supported(struct device *hwdev, u64 mask); |
| 58 | 55 | ||
| 59 | extern int | 56 | extern int |
diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 22e13a0e19d7..cb1b54ee8527 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c | |||
| @@ -425,7 +425,8 @@ static void swiotlb_bounce(phys_addr_t orig_addr, phys_addr_t tlb_addr, | |||
| 425 | phys_addr_t swiotlb_tbl_map_single(struct device *hwdev, | 425 | phys_addr_t swiotlb_tbl_map_single(struct device *hwdev, |
| 426 | dma_addr_t tbl_dma_addr, | 426 | dma_addr_t tbl_dma_addr, |
| 427 | phys_addr_t orig_addr, size_t size, | 427 | phys_addr_t orig_addr, size_t size, |
| 428 | enum dma_data_direction dir) | 428 | enum dma_data_direction dir, |
| 429 | unsigned long attrs) | ||
| 429 | { | 430 | { |
| 430 | unsigned long flags; | 431 | unsigned long flags; |
| 431 | phys_addr_t tlb_addr; | 432 | phys_addr_t tlb_addr; |
| @@ -526,7 +527,8 @@ found: | |||
| 526 | */ | 527 | */ |
| 527 | for (i = 0; i < nslots; i++) | 528 | for (i = 0; i < nslots; i++) |
| 528 | io_tlb_orig_addr[index+i] = orig_addr + (i << IO_TLB_SHIFT); | 529 | io_tlb_orig_addr[index+i] = orig_addr + (i << IO_TLB_SHIFT); |
| 529 | if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) | 530 | if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC) && |
| 531 | (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) | ||
| 530 | swiotlb_bounce(orig_addr, tlb_addr, size, DMA_TO_DEVICE); | 532 | swiotlb_bounce(orig_addr, tlb_addr, size, DMA_TO_DEVICE); |
| 531 | 533 | ||
| 532 | return tlb_addr; | 534 | return tlb_addr; |
| @@ -539,18 +541,20 @@ EXPORT_SYMBOL_GPL(swiotlb_tbl_map_single); | |||
| 539 | 541 | ||
| 540 | static phys_addr_t | 542 | static phys_addr_t |
| 541 | map_single(struct device *hwdev, phys_addr_t phys, size_t size, | 543 | map_single(struct device *hwdev, phys_addr_t phys, size_t size, |
| 542 | enum dma_data_direction dir) | 544 | enum dma_data_direction dir, unsigned long attrs) |
| 543 | { | 545 | { |
| 544 | dma_addr_t start_dma_addr = phys_to_dma(hwdev, io_tlb_start); | 546 | dma_addr_t |
