aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-01-06 13:53:21 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-01-06 13:53:21 -0500
commit2fd8774c79a455a1f12f75208d96f2f0cc3728c9 (patch)
treeba158796fe63c94c662d76f474e37aeb1c079b87
parent65cdc405b37a0f43af9c0fb6cf011304b3959ef8 (diff)
parent7453c549f5f6485c0d79cad7844870dcc7d1b34d (diff)
Merge branch 'stable/for-linus-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb
Pull swiotlb fixes from Konrad Rzeszutek Wilk: "This has one fix to make i915 work when using Xen SWIOTLB, and a feature from Geert to aid in debugging of devices that can't do DMA outside the 32-bit address space. The feature from Geert is on top of v4.10 merge window commit (specifically you pulling my previous branch), as his changes were dependent on the Documentation/ movement patches. I figured it would just easier than me trying than to cherry-pick the Documentation patches to satisfy git. The patches have been soaking since 12/20, albeit I updated the last patch due to linux-next catching an compiler error and adding an Tested-and-Reported-by tag" * 'stable/for-linus-4.10' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb: swiotlb: Export swiotlb_max_segment to users swiotlb: Add swiotlb=noforce debug option swiotlb: Convert swiotlb_force from int to enum x86, swiotlb: Simplify pci_swiotlb_detect_override()
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt3
-rw-r--r--arch/arm64/mm/dma-mapping.c3
-rw-r--r--arch/arm64/mm/init.c3
-rw-r--r--arch/x86/kernel/pci-swiotlb.c6
-rw-r--r--arch/x86/xen/pci-swiotlb-xen.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c11
-rw-r--r--drivers/xen/swiotlb-xen.c8
-rw-r--r--include/linux/swiotlb.h11
-rw-r--r--include/trace/events/swiotlb.h17
-rw-r--r--lib/swiotlb.c52
10 files changed, 82 insertions, 34 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index d1eec5ed1134..be7c0d9506b1 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3821,10 +3821,11 @@
3821 it if 0 is given (See Documentation/cgroup-v1/memory.txt) 3821 it if 0 is given (See Documentation/cgroup-v1/memory.txt)
3822 3822
3823 swiotlb= [ARM,IA-64,PPC,MIPS,X86] 3823 swiotlb= [ARM,IA-64,PPC,MIPS,X86]
3824 Format: { <int> | force } 3824 Format: { <int> | force | noforce }
3825 <int> -- Number of I/O TLB slabs 3825 <int> -- Number of I/O TLB slabs
3826 force -- force using of bounce buffers even if they 3826 force -- force using of bounce buffers even if they
3827 wouldn't be automatically used by the kernel 3827 wouldn't be automatically used by the kernel
3828 noforce -- Never use bounce buffers (for debugging)
3828 3829
3829 switches= [HW,M68k] 3830 switches= [HW,M68k]
3830 3831
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 290a84f3351f..e04082700bb1 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -524,7 +524,8 @@ EXPORT_SYMBOL(dummy_dma_ops);
524 524
525static int __init arm64_dma_init(void) 525static int __init arm64_dma_init(void)
526{ 526{
527 if (swiotlb_force || max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT)) 527 if (swiotlb_force == SWIOTLB_FORCE ||
528 max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT))
528 swiotlb = 1; 529 swiotlb = 1;
529 530
530 return atomic_pool_init(); 531 return atomic_pool_init();
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 212c4d1e2f26..716d1226ba69 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -401,7 +401,8 @@ static void __init free_unused_memmap(void)
401 */ 401 */
402void __init mem_init(void) 402void __init mem_init(void)
403{ 403{
404 if (swiotlb_force || max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT)) 404 if (swiotlb_force == SWIOTLB_FORCE ||
405 max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT))
405 swiotlb_init(1); 406 swiotlb_init(1);
406 407
407 set_max_mapnr(pfn_to_page(max_pfn) - mem_map); 408 set_max_mapnr(pfn_to_page(max_pfn) - mem_map);
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c
index b47edb8f5256..410efb2c7b80 100644
--- a/arch/x86/kernel/pci-swiotlb.c
+++ b/arch/x86/kernel/pci-swiotlb.c
@@ -68,12 +68,10 @@ static struct dma_map_ops swiotlb_dma_ops = {
68 */ 68 */
69int __init pci_swiotlb_detect_override(void) 69int __init pci_swiotlb_detect_override(void)
70{ 70{
71 int use_swiotlb = swiotlb | swiotlb_force; 71 if (swiotlb_force == SWIOTLB_FORCE)
72
73 if (swiotlb_force)
74 swiotlb = 1; 72 swiotlb = 1;
75 73
76 return use_swiotlb; 74 return swiotlb;
77} 75}
78IOMMU_INIT_FINISH(pci_swiotlb_detect_override, 76IOMMU_INIT_FINISH(pci_swiotlb_detect_override,
79 pci_xen_swiotlb_detect, 77 pci_xen_swiotlb_detect,
diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c
index a9fafb5c8738..a0b36a9d5df1 100644
--- a/arch/x86/xen/pci-swiotlb-xen.c
+++ b/arch/x86/xen/pci-swiotlb-xen.c
@@ -48,7 +48,7 @@ int __init pci_xen_swiotlb_detect(void)
48 * activate this IOMMU. If running as PV privileged, activate it 48 * activate this IOMMU. If running as PV privileged, activate it
49 * irregardless. 49 * irregardless.
50 */ 50 */
51 if ((xen_initial_domain() || swiotlb || swiotlb_force)) 51 if (xen_initial_domain() || swiotlb || swiotlb_force == SWIOTLB_FORCE)
52 xen_swiotlb = 1; 52 xen_swiotlb = 1;
53 53
54 /* If we are running under Xen, we MUST disable the native SWIOTLB. 54 /* If we are running under Xen, we MUST disable the native SWIOTLB.
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 1e505d30b71e..3dd7fc662859 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2306,15 +2306,6 @@ unlock:
2306 mutex_unlock(&obj->mm.lock); 2306 mutex_unlock(&obj->mm.lock);
2307} 2307}
2308 2308
2309static unsigned int swiotlb_max_size(void)
2310{
2311#if IS_ENABLED(CONFIG_SWIOTLB)
2312 return rounddown(swiotlb_nr_tbl() << IO_TLB_SHIFT, PAGE_SIZE);
2313#else
2314 return 0;
2315#endif
2316}
2317
2318static void i915_sg_trim(struct sg_table *orig_st) 2309static void i915_sg_trim(struct sg_table *orig_st)
2319{ 2310{
2320 struct sg_table new_st; 2311 struct sg_table new_st;
@@ -2362,7 +2353,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
2362 GEM_BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS); 2353 GEM_BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS);
2363 GEM_BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS); 2354 GEM_BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS);
2364 2355
2365 max_segment = swiotlb_max_size(); 2356 max_segment = swiotlb_max_segment();
2366 if (!max_segment) 2357 if (!max_segment)
2367 max_segment = rounddown(UINT_MAX, PAGE_SIZE); 2358 max_segment = rounddown(UINT_MAX, PAGE_SIZE);
2368 2359
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 478fb91e3df2..f905d6eeb048 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -275,6 +275,10 @@ retry:
275 rc = 0; 275 rc = 0;
276 } else 276 } else
277 rc = swiotlb_late_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs); 277 rc = swiotlb_late_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs);
278
279 if (!rc)
280 swiotlb_set_max_segment(PAGE_SIZE);
281
278 return rc; 282 return rc;
279error: 283error:
280 if (repeat--) { 284 if (repeat--) {
@@ -392,7 +396,7 @@ dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
392 if (dma_capable(dev, dev_addr, size) && 396 if (dma_capable(dev, dev_addr, size) &&
393 !range_straddles_page_boundary(phys, size) && 397 !range_straddles_page_boundary(phys, size) &&
394 !xen_arch_need_swiotlb(dev, phys, dev_addr) && 398 !xen_arch_need_swiotlb(dev, phys, dev_addr) &&
395 !swiotlb_force) { 399 (swiotlb_force != SWIOTLB_FORCE)) {
396 /* we are not interested in the dma_addr returned by 400 /* we are not interested in the dma_addr returned by
397 * xen_dma_map_page, only in the potential cache flushes executed 401 * xen_dma_map_page, only in the potential cache flushes executed
398 * by the function. */ 402 * by the function. */
@@ -552,7 +556,7 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
552 phys_addr_t paddr = sg_phys(sg); 556 phys_addr_t paddr = sg_phys(sg);
553 dma_addr_t dev_addr = xen_phys_to_bus(paddr); 557 dma_addr_t dev_addr = xen_phys_to_bus(paddr);
554 558
555 if (swiotlb_force || 559 if (swiotlb_force == SWIOTLB_FORCE ||
556 xen_arch_need_swiotlb(hwdev, paddr, dev_addr) || 560 xen_arch_need_swiotlb(hwdev, paddr, dev_addr) ||
557 !dma_capable(hwdev, dev_addr, sg->length) || 561 !dma_capable(hwdev, dev_addr, sg->length) ||
558 range_straddles_page_boundary(paddr, sg->length)) { 562 range_straddles_page_boundary(paddr, sg->length)) {
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 183f37c8a5e1..4ee479f2f355 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -9,7 +9,13 @@ struct device;
9struct page; 9struct page;
10struct scatterlist; 10struct scatterlist;
11 11
12extern int swiotlb_force; 12enum swiotlb_force {
13 SWIOTLB_NORMAL, /* Default - depending on HW DMA mask etc. */
14 SWIOTLB_FORCE, /* swiotlb=force */
15 SWIOTLB_NO_FORCE, /* swiotlb=noforce */
16};
17
18extern enum swiotlb_force swiotlb_force;
13 19
14/* 20/*
15 * Maximum allowable number of contiguous slabs to map, 21 * Maximum allowable number of contiguous slabs to map,
@@ -108,11 +114,14 @@ swiotlb_dma_supported(struct device *hwdev, u64 mask);
108 114
109#ifdef CONFIG_SWIOTLB 115#ifdef CONFIG_SWIOTLB
110extern void __init swiotlb_free(void); 116extern void __init swiotlb_free(void);
117unsigned int swiotlb_max_segment(void);
111#else 118#else
112static inline void swiotlb_free(void) { } 119static inline void swiotlb_free(void) { }
120static inline unsigned int swiotlb_max_segment(void) { return 0; }
113#endif 121#endif
114 122
115extern void swiotlb_print_info(void); 123extern void swiotlb_print_info(void);
116extern int is_swiotlb_buffer(phys_addr_t paddr); 124extern int is_swiotlb_buffer(phys_addr_t paddr);
125extern void swiotlb_set_max_segment(unsigned int);
117 126
118#endif /* __LINUX_SWIOTLB_H */ 127#endif /* __LINUX_SWIOTLB_H */
diff --git a/include/trace/events/swiotlb.h b/include/trace/events/swiotlb.h
index 7ea4c5e7c448..288c0c54a2b4 100644
--- a/include/trace/events/swiotlb.h
+++ b/include/trace/events/swiotlb.h
@@ -11,16 +11,16 @@ TRACE_EVENT(swiotlb_bounced,
11 TP_PROTO(struct device *dev, 11 TP_PROTO(struct device *dev,
12 dma_addr_t dev_addr, 12 dma_addr_t dev_addr,
13 size_t size, 13 size_t size,
14 int swiotlb_force), 14 enum swiotlb_force swiotlb_force),
15 15
16 TP_ARGS(dev, dev_addr, size, swiotlb_force), 16 TP_ARGS(dev, dev_addr, size, swiotlb_force),
17 17
18 TP_STRUCT__entry( 18 TP_STRUCT__entry(
19 __string( dev_name, dev_name(dev) ) 19 __string( dev_name, dev_name(dev) )
20 __field( u64, dma_mask ) 20 __field( u64, dma_mask )
21 __field( dma_addr_t, dev_addr ) 21 __field( dma_addr_t, dev_addr )
22 __field( size_t, size ) 22 __field( size_t, size )
23 __field( int, swiotlb_force ) 23 __field( enum swiotlb_force, swiotlb_force )
24 ), 24 ),
25 25
26 TP_fast_assign( 26 TP_fast_assign(
@@ -37,7 +37,10 @@ TRACE_EVENT(swiotlb_bounced,
37 __entry->dma_mask, 37 __entry->dma_mask,
38 (unsigned long long)__entry->dev_addr, 38 (unsigned long long)__entry->dev_addr,
39 __entry->size, 39 __entry->size,
40 __entry->swiotlb_force ? "swiotlb_force" : "" ) 40 __print_symbolic(__entry->swiotlb_force,
41 { SWIOTLB_NORMAL, "NORMAL" },
42 { SWIOTLB_FORCE, "FORCE" },
43 { SWIOTLB_NO_FORCE, "NO_FORCE" }))
41); 44);
42 45
43#endif /* _TRACE_SWIOTLB_H */ 46#endif /* _TRACE_SWIOTLB_H */
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index cb1b54ee8527..975b8fc4f1e1 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -53,7 +53,7 @@
53 */ 53 */
54#define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT) 54#define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT)
55 55
56int swiotlb_force; 56enum swiotlb_force swiotlb_force;
57 57
58/* 58/*
59 * Used to do a quick range check in swiotlb_tbl_unmap_single and 59 * Used to do a quick range check in swiotlb_tbl_unmap_single and
@@ -83,6 +83,12 @@ static unsigned int *io_tlb_list;
83static unsigned int io_tlb_index; 83static unsigned int io_tlb_index;
84 84
85/* 85/*
86 * Max segment that we can provide which (if pages are contingous) will
87 * not be bounced (unless SWIOTLB_FORCE is set).
88 */
89unsigned int max_segment;
90
91/*
86 * We need to save away the original address corresponding to a mapped entry 92 * We need to save away the original address corresponding to a mapped entry
87 * for the sync operations. 93 * for the sync operations.
88 */ 94 */
@@ -106,8 +112,12 @@ setup_io_tlb_npages(char *str)
106 } 112 }
107 if (*str == ',') 113 if (*str == ',')
108 ++str; 114 ++str;
109 if (!strcmp(str, "force")) 115 if (!strcmp(str, "force")) {
110 swiotlb_force = 1; 116 swiotlb_force = SWIOTLB_FORCE;
117 } else if (!strcmp(str, "noforce")) {
118 swiotlb_force = SWIOTLB_NO_FORCE;
119 io_tlb_nslabs = 1;
120 }
111 121
112 return 0; 122 return 0;
113} 123}
@@ -120,6 +130,20 @@ unsigned long swiotlb_nr_tbl(void)
120} 130}
121EXPORT_SYMBOL_GPL(swiotlb_nr_tbl); 131EXPORT_SYMBOL_GPL(swiotlb_nr_tbl);
122 132
133unsigned int swiotlb_max_segment(void)
134{
135 return max_segment;
136}
137EXPORT_SYMBOL_GPL(swiotlb_max_segment);
138
139void swiotlb_set_max_segment(unsigned int val)
140{
141 if (swiotlb_force == SWIOTLB_FORCE)
142 max_segment = 1;
143 else
144 max_segment = rounddown(val, PAGE_SIZE);
145}
146
123/* default to 64MB */ 147/* default to 64MB */
124#define IO_TLB_DEFAULT_SIZE (64UL<<20) 148#define IO_TLB_DEFAULT_SIZE (64UL<<20)
125unsigned long swiotlb_size_or_default(void) 149unsigned long swiotlb_size_or_default(void)
@@ -201,6 +225,7 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
201 if (verbose) 225 if (verbose)
202 swiotlb_print_info(); 226 swiotlb_print_info();
203 227
228 swiotlb_set_max_segment(io_tlb_nslabs << IO_TLB_SHIFT);
204 return 0; 229 return 0;
205} 230}
206 231
@@ -279,6 +304,7 @@ swiotlb_late_init_with_default_size(size_t default_size)
279 rc = swiotlb_late_init_with_tbl(vstart, io_tlb_nslabs); 304 rc = swiotlb_late_init_with_tbl(vstart, io_tlb_nslabs);
280 if (rc) 305 if (rc)
281 free_pages((unsigned long)vstart, order); 306 free_pages((unsigned long)vstart, order);
307
282 return rc; 308 return rc;
283} 309}
284 310
@@ -333,6 +359,8 @@ swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs)
333 359
334 late_alloc = 1; 360 late_alloc = 1;
335 361
362 swiotlb_set_max_segment(io_tlb_nslabs << IO_TLB_SHIFT);
363
336 return 0; 364 return 0;
337 365
338cleanup4: 366cleanup4:
@@ -347,6 +375,7 @@ cleanup2:
347 io_tlb_end = 0; 375 io_tlb_end = 0;
348 io_tlb_start = 0; 376 io_tlb_start = 0;
349 io_tlb_nslabs = 0; 377 io_tlb_nslabs = 0;
378 max_segment = 0;
350 return -ENOMEM; 379 return -ENOMEM;
351} 380}
352 381
@@ -375,6 +404,7 @@ void __init swiotlb_free(void)
375 PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT)); 404 PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT));
376 } 405 }
377 io_tlb_nslabs = 0; 406 io_tlb_nslabs = 0;
407 max_segment = 0;
378} 408}
379 409
380int is_swiotlb_buffer(phys_addr_t paddr) 410int is_swiotlb_buffer(phys_addr_t paddr)
@@ -543,8 +573,15 @@ static phys_addr_t
543map_single(struct device *hwdev, phys_addr_t phys, size_t size, 573map_single(struct device *hwdev, phys_addr_t phys, size_t size,
544 enum dma_data_direction dir, unsigned long attrs) 574 enum dma_data_direction dir, unsigned long attrs)
545{ 575{
546 dma_addr_t start_dma_addr = phys_to_dma(hwdev, io_tlb_start); 576 dma_addr_t start_dma_addr;
547 577
578 if (swiotlb_force == SWIOTLB_NO_FORCE) {
579 dev_warn_ratelimited(hwdev, "Cannot do DMA to address %pa\n",
580 &phys);
581 return SWIOTLB_MAP_ERROR;
582 }
583
584 start_dma_addr = phys_to_dma(hwdev, io_tlb_start);
548 return swiotlb_tbl_map_single(hwdev, start_dma_addr, phys, size, 585 return swiotlb_tbl_map_single(hwdev, start_dma_addr, phys, size,
549 dir, attrs); 586 dir, attrs);
550} 587}
@@ -721,6 +758,9 @@ static void
721swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir, 758swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir,
722 int do_panic) 759 int do_panic)
723{ 760{
761 if (swiotlb_force == SWIOTLB_NO_FORCE)
762 return;
763
724 /* 764 /*
725 * Ran out of IOMMU space for this operation. This is very bad. 765 * Ran out of IOMMU space for this operation. This is very bad.
726 * Unfortunately the drivers cannot handle this operation properly. 766 * Unfortunately the drivers cannot handle this operation properly.
@@ -763,7 +803,7 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
763 * we can safely return the device addr and not worry about bounce 803 * we can safely return the device addr and not worry about bounce
764 * buffering it. 804 * buffering it.
765 */ 805 */
766 if (dma_capable(dev, dev_addr, size) && !swiotlb_force) 806 if (dma_capable(dev, dev_addr, size) && swiotlb_force != SWIOTLB_FORCE)
767 return dev_addr; 807 return dev_addr;
768 808
769 trace_swiotlb_bounced(dev, dev_addr, size, swiotlb_force); 809 trace_swiotlb_bounced(dev, dev_addr, size, swiotlb_force);
@@ -904,7 +944,7 @@ swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
904 phys_addr_t paddr = sg_phys(sg); 944 phys_addr_t paddr = sg_phys(sg);
905 dma_addr_t dev_addr = phys_to_dma(hwdev, paddr); 945 dma_addr_t dev_addr = phys_to_dma(hwdev, paddr);
906 946
907 if (swiotlb_force || 947 if (swiotlb_force == SWIOTLB_FORCE ||
908 !dma_capable(hwdev, dev_addr, sg->length)) { 948 !dma_capable(hwdev, dev_addr, sg->length)) {
909 phys_addr_t map = map_single(hwdev, sg_phys(sg), 949 phys_addr_t map = map_single(hwdev, sg_phys(sg),
910 sg->length, dir, attrs); 950 sg->length, dir, attrs);