aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2016-11-02 07:13:02 -0400
committerKonrad Rzeszutek Wilk <konrad@kernel.org>2016-11-07 15:06:33 -0500
commit0443fa003fa199f41bfbed3012f314d02c5b1f24 (patch)
tree401aaffdf993230e7ddf69279f531b28c5557ffb
parent7641842164c34b672ef3e70e881e8a72735305c1 (diff)
swiotlb: Add support for DMA_ATTR_SKIP_CPU_SYNC
As a first step to making DMA_ATTR_SKIP_CPU_SYNC apply to architectures beyond just ARM I need to make it so that the swiotlb will respect the flag. In order to do that I also need to update the swiotlb-xen since it heavily makes use of the functionality. Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad@kernel.org>
-rw-r--r--drivers/xen/swiotlb-xen.c11
-rw-r--r--include/linux/swiotlb.h6
-rw-r--r--lib/swiotlb.c59
3 files changed, 49 insertions, 27 deletions
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index b8014bf2b2ed..3d048afcee38 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
@@ -419,7 +420,8 @@ dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
419 if (dma_capable(dev, dev_addr, size)) 420 if (dma_capable(dev, dev_addr, size))
420 return dev_addr; 421 return dev_addr;
421 422
422 swiotlb_tbl_unmap_single(dev, map, size, dir); 423 swiotlb_tbl_unmap_single(dev, map, size, dir,
424 attrs | DMA_ATTR_SKIP_CPU_SYNC);
423 425
424 return DMA_ERROR_CODE; 426 return DMA_ERROR_CODE;
425} 427}
@@ -445,7 +447,7 @@ static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
445 447
446 /* NOTE: We use dev_addr here, not paddr! */ 448 /* NOTE: We use dev_addr here, not paddr! */
447 if (is_xen_swiotlb_buffer(dev_addr)) { 449 if (is_xen_swiotlb_buffer(dev_addr)) {
448 swiotlb_tbl_unmap_single(hwdev, paddr, size, dir); 450 swiotlb_tbl_unmap_single(hwdev, paddr, size, dir, attrs);
449 return; 451 return;
450 } 452 }
451 453
@@ -558,11 +560,12 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
558 start_dma_addr, 560 start_dma_addr,
559 sg_phys(sg), 561 sg_phys(sg),
560 sg->length, 562 sg->length,
561 dir); 563 dir, attrs);
562 if (map == SWIOTLB_MAP_ERROR) { 564 if (map == SWIOTLB_MAP_ERROR) {
563 dev_warn(hwdev, "swiotlb buffer is full\n"); 565 dev_warn(hwdev, "swiotlb buffer is full\n");
564 /* Don't panic here, we expect map_sg users 566 /* Don't panic here, we expect map_sg users
565 to do proper error handling. */ 567 to do proper error handling. */
568 attrs |= DMA_ATTR_SKIP_CPU_SYNC;
566 xen_swiotlb_unmap_sg_attrs(hwdev, sgl, i, dir, 569 xen_swiotlb_unmap_sg_attrs(hwdev, sgl, i, dir,
567 attrs); 570 attrs);
568 sg_dma_len(sgl) = 0; 571 sg_dma_len(sgl) = 0;
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index f0d258967869..183f37c8a5e1 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -44,11 +44,13 @@ enum dma_sync_target {
44extern phys_addr_t swiotlb_tbl_map_single(struct device *hwdev, 44extern 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
49extern void swiotlb_tbl_unmap_single(struct device *hwdev, 50extern 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
53extern void swiotlb_tbl_sync_single(struct device *hwdev, 55extern void swiotlb_tbl_sync_single(struct device *hwdev,
54 phys_addr_t tlb_addr, 56 phys_addr_t tlb_addr,
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index bdcc0d8a7405..8e883c762728 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,
425phys_addr_t swiotlb_tbl_map_single(struct device *hwdev, 425phys_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
540static phys_addr_t 542static phys_addr_t
541map_single(struct device *hwdev, phys_addr_t phys, size_t size, 543map_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 start_dma_addr = phys_to_dma(hwdev, io_tlb_start);
545 547
546 return swiotlb_tbl_map_single(hwdev, start_dma_addr, phys, size, dir); 548 return swiotlb_tbl_map_single(hwdev, start_dma_addr, phys, size,
549 dir, attrs);
547} 550}
548 551
549/* 552/*
550 * dma_addr is the kernel virtual address of the bounce buffer to unmap. 553 * dma_addr is the kernel virtual address of the bounce buffer to unmap.
551 */ 554 */
552void swiotlb_tbl_unmap_single(struct device *hwdev, phys_addr_t tlb_addr, 555void swiotlb_tbl_unmap_single(struct device *hwdev, phys_addr_t tlb_addr,
553 size_t size, enum dma_data_direction dir) 556 size_t size, enum dma_data_direction dir,
557 unsigned long attrs)
554{ 558{
555 unsigned long flags; 559 unsigned long flags;
556 int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; 560 int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
@@ -561,6 +565,7 @@ void swiotlb_tbl_unmap_single(struct device *hwdev, phys_addr_t tlb_addr,
561 * First, sync the memory before unmapping the entry 565 * First, sync the memory before unmapping the entry
562 */ 566 */
563 if (orig_addr != INVALID_PHYS_ADDR && 567 if (orig_addr != INVALID_PHYS_ADDR &&
568 !(attrs & DMA_ATTR_SKIP_CPU_SYNC) &&
564 ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) 569 ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL)))
565 swiotlb_bounce(orig_addr, tlb_addr, size, DMA_FROM_DEVICE); 570 swiotlb_bounce(orig_addr, tlb_addr, size, DMA_FROM_DEVICE);
566 571
@@ -654,7 +659,8 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
654 * GFP_DMA memory; fall back on map_single(), which 659 * GFP_DMA memory; fall back on map_single(), which
655 * will grab memory from the lowest available address range. 660 * will grab memory from the lowest available address range.
656 */ 661 */
657 phys_addr_t paddr = map_single(hwdev, 0, size, DMA_FROM_DEVICE); 662 phys_addr_t paddr = map_single(hwdev, 0, size,
663 DMA_FROM_DEVICE, 0);
658 if (paddr == SWIOTLB_MAP_ERROR) 664 if (paddr == SWIOTLB_MAP_ERROR)
659 goto err_warn; 665 goto err_warn;
660 666
@@ -667,9 +673,13 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
667 (unsigned long long)dma_mask, 673 (unsigned long long)dma_mask,
668 (unsigned long long)dev_addr); 674 (unsigned long long)dev_addr);
669 675
670 /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ 676 /*
677 * DMA_TO_DEVICE to avoid memcpy in unmap_single.
678 * The DMA_ATTR_SKIP_CPU_SYNC is optional.
679 */
671 swiotlb_tbl_unmap_single(hwdev, paddr, 680 swiotlb_tbl_unmap_single(hwdev, paddr,
672 size, DMA_TO_DEVICE); 681 size, DMA_TO_DEVICE,
682 DMA_ATTR_SKIP_CPU_SYNC);
673 goto err_warn; 683 goto err_warn;
674 } 684 }
675 } 685 }
@@ -698,8 +708,12 @@ swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
698 if (!is_swiotlb_buffer(paddr)) 708 if (!is_swiotlb_buffer(paddr))
699 free_pages((unsigned long)vaddr, get_order(size)); 709 free_pages((unsigned long)vaddr, get_order(size));
700 else 710 else
701 /* DMA_TO_DEVICE to avoid memcpy in swiotlb_tbl_unmap_single */ 711 /*
702 swiotlb_tbl_unmap_single(hwdev, paddr, size, DMA_TO_DEVICE); 712 * DMA_TO_DEVICE to avoid memcpy in swiotlb_tbl_unmap_single.
713 * DMA_ATTR_SKIP_CPU_SYNC is optional.
714 */
715 swiotlb_tbl_unmap_single(hwdev, paddr, size, DMA_TO_DEVICE,
716 DMA_ATTR_SKIP_CPU_SYNC);
703} 717}
704EXPORT_SYMBOL(swiotlb_free_coherent); 718EXPORT_SYMBOL(swiotlb_free_coherent);
705 719
@@ -755,7 +769,7 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
755 trace_swiotlb_bounced(dev, dev_addr, size, swiotlb_force); 769 trace_swiotlb_bounced(dev, dev_addr, size, swiotlb_force);
756 770
757 /* Oh well, have to allocate and map a bounce buffer. */ 771 /* Oh well, have to allocate and map a bounce buffer. */
758 map = map_single(dev, phys, size, dir); 772 map = map_single(dev, phys, size, dir, attrs);
759 if (map == SWIOTLB_MAP_ERROR) { 773 if (map == SWIOTLB_MAP_ERROR) {
760 swiotlb_full(dev, size, dir, 1); 774 swiotlb_full(dev, size, dir, 1);
761 return phys_to_dma(dev, io_tlb_overflow_buffer); 775 return phys_to_dma(dev, io_tlb_overflow_buffer);
@@ -764,12 +778,13 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
764 dev_addr = phys_to_dma(dev, map); 778 dev_addr = phys_to_dma(dev, map);
765 779
766 /* Ensure that the address returned is DMA'ble */ 780 /* Ensure that the address returned is DMA'ble */
767 if (!dma_capable(dev, dev_addr, size)) { 781 if (dma_capable(dev, dev_addr, size))
768 swiotlb_tbl_unmap_single(dev, map, size, dir); 782 return dev_addr;
769 return phys_to_dma(dev, io_tlb_overflow_buffer); 783
770 } 784 swiotlb_tbl_unmap_single(dev, map, size, dir,
785 attrs | DMA_ATTR_SKIP_CPU_SYNC);
771 786
772 return dev_addr; 787 return phys_to_dma(dev, io_tlb_overflow_buffer);
773} 788}
774EXPORT_SYMBOL_GPL(swiotlb_map_page); 789EXPORT_SYMBOL_GPL(swiotlb_map_page);
775 790
@@ -782,14 +797,15 @@ EXPORT_SYMBOL_GPL(swiotlb_map_page);
782 * whatever the device wrote there. 797 * whatever the device wrote there.
783 */ 798 */
784static void unmap_single(struct device *hwdev, dma_addr_t dev_addr, 799static void unmap_single(struct device *hwdev, dma_addr_t dev_addr,
785 size_t size, enum dma_data_direction dir) 800 size_t size, enum dma_data_direction dir,
801 unsigned long attrs)
786{ 802{
787 phys_addr_t paddr = dma_to_phys(hwdev, dev_addr); 803 phys_addr_t paddr = dma_to_phys(hwdev, dev_addr);
788 804
789 BUG_ON(dir == DMA_NONE); 805 BUG_ON(dir == DMA_NONE);
790 806
791 if (is_swiotlb_buffer(paddr)) { 807 if (is_swiotlb_buffer(paddr)) {
792 swiotlb_tbl_unmap_single(hwdev, paddr, size, dir); 808 swiotlb_tbl_unmap_single(hwdev, paddr, size, dir, attrs);
793 return; 809 return;
794 } 810 }
795 811
@@ -809,7 +825,7 @@ void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
809 size_t size, enum dma_data_direction dir, 825 size_t size, enum dma_data_direction dir,
810 unsigned long attrs) 826 unsigned long attrs)
811{ 827{
812 unmap_single(hwdev, dev_addr, size, dir); 828 unmap_single(hwdev, dev_addr, size, dir, attrs);
813} 829}
814EXPORT_SYMBOL_GPL(swiotlb_unmap_page); 830EXPORT_SYMBOL_GPL(swiotlb_unmap_page);
815 831
@@ -891,7 +907,7 @@ swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
891 if (swiotlb_force || 907 if (swiotlb_force ||
892 !dma_capable(hwdev, dev_addr, sg->length)) { 908 !dma_capable(hwdev, dev_addr, sg->length)) {
893 phys_addr_t map = map_single(hwdev, sg_phys(sg), 909 phys_addr_t map = map_single(hwdev, sg_phys(sg),
894 sg->length, dir); 910 sg->length, dir, attrs);
895 if (map == SWIOTLB_MAP_ERROR) { 911 if (map == SWIOTLB_MAP_ERROR) {
896 /* Don't panic here, we expect map_sg users 912 /* Don't panic here, we expect map_sg users
897 to do proper error handling. */ 913 to do proper error handling. */
@@ -925,7 +941,8 @@ swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
925 BUG_ON(dir == DMA_NONE); 941 BUG_ON(dir == DMA_NONE);
926 942
927 for_each_sg(sgl, sg, nelems, i) 943 for_each_sg(sgl, sg, nelems, i)
928 unmap_single(hwdev, sg->dma_address, sg_dma_len(sg), dir); 944 unmap_single(hwdev, sg->dma_address, sg_dma_len(sg), dir,
945 attrs);
929 946
930} 947}
931EXPORT_SYMBOL(swiotlb_unmap_sg_attrs); 948EXPORT_SYMBOL(swiotlb_unmap_sg_attrs);