aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-12-13 18:52:23 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-13 18:52:23 -0500
commitb5cab0da75c292ffa0fbd68dd2c820066b2842de (patch)
tree3b8d4483b8ce6d1ea997cde2c89445564cba7b0f
parent93173b5bf2841da7e3a9b0cb1312ef5c87251524 (diff)
parentd29fa0cb7602fa3e96c9eee05e14d14d3e823c89 (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.c1
-rw-r--r--arch/x86/xen/pci-swiotlb-xen.c1
-rw-r--r--drivers/xen/swiotlb-xen.c27
-rw-r--r--include/linux/swiotlb.h14
-rw-r--r--include/xen/swiotlb-xen.h3
-rw-r--r--lib/swiotlb.c81
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;
186EXPORT_SYMBOL(xen_dma_ops); 186EXPORT_SYMBOL(xen_dma_ops);
187 187
188static struct dma_map_ops xen_swiotlb_dma_ops = { 188static 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 @@
19int xen_swiotlb __read_mostly; 19int xen_swiotlb __read_mostly;
20 20
21static struct dma_map_ops xen_swiotlb_dma_ops = { 21static 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}
425EXPORT_SYMBOL_GPL(xen_swiotlb_map_page); 428EXPORT_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}
649EXPORT_SYMBOL_GPL(xen_swiotlb_sync_sg_for_device); 653EXPORT_SYMBOL_GPL(xen_swiotlb_sync_sg_for_device);
650 654
651int
652xen_swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr)
653{
654 return !dma_addr;
655}
656EXPORT_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 {
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,
@@ -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
75extern int 77extern int
76swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
77 enum dma_data_direction dir);
78
79extern void
80swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
81 enum dma_data_direction dir);
82
83extern int
84swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems, 78swiotlb_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
53extern int 53extern int
54xen_swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr);
55
56extern int
57xen_swiotlb_dma_supported(struct device *hwdev, u64 mask); 54xen_swiotlb_dma_supported(struct device *hwdev, u64 mask);
58 55
59extern int 56extern 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,
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