aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2016-12-20 10:02:02 -0500
committerKonrad Rzeszutek Wilk <konrad@kernel.org>2017-01-06 13:00:01 -0500
commit7453c549f5f6485c0d79cad7844870dcc7d1b34d (patch)
treed6303358532275cd114b471810d6fc2333780367
parentfff5d99225107f5f13fe4a9805adc2a1c4b5fb00 (diff)
swiotlb: Export swiotlb_max_segment to users
So they can figure out what is the optimal number of pages that can be contingously stitched together without fear of bounce buffer. We also expose an mechanism for sub-users of SWIOTLB API, such as Xen-SWIOTLB to set the max segment value. And lastly if swiotlb=force is set (which mandates we bounce buffer everything) we set max_segment so at least we can bounce buffer one 4K page instead of a giant 512KB one for which we may not have space. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Reported-and-Tested-by: Juergen Gross <jgross@suse.com>
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c11
-rw-r--r--drivers/xen/swiotlb-xen.c4
-rw-r--r--include/linux/swiotlb.h3
-rw-r--r--lib/swiotlb.c26
4 files changed, 34 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index d0dcaf35b429..115fa399608c 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2290,15 +2290,6 @@ unlock:
2290 mutex_unlock(&obj->mm.lock); 2290 mutex_unlock(&obj->mm.lock);
2291} 2291}
2292 2292
2293static unsigned int swiotlb_max_size(void)
2294{
2295#if IS_ENABLED(CONFIG_SWIOTLB)
2296 return rounddown(swiotlb_nr_tbl() << IO_TLB_SHIFT, PAGE_SIZE);
2297#else
2298 return 0;
2299#endif
2300}
2301
2302static void i915_sg_trim(struct sg_table *orig_st) 2293static void i915_sg_trim(struct sg_table *orig_st)
2303{ 2294{
2304 struct sg_table new_st; 2295 struct sg_table new_st;
@@ -2345,7 +2336,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
2345 GEM_BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS); 2336 GEM_BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS);
2346 GEM_BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS); 2337 GEM_BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS);
2347 2338
2348 max_segment = swiotlb_max_size(); 2339 max_segment = swiotlb_max_segment();
2349 if (!max_segment) 2340 if (!max_segment)
2350 max_segment = rounddown(UINT_MAX, PAGE_SIZE); 2341 max_segment = rounddown(UINT_MAX, PAGE_SIZE);
2351 2342
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index aba12009422e..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--) {
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index d9c84a9cde3d..4ee479f2f355 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -114,11 +114,14 @@ swiotlb_dma_supported(struct device *hwdev, u64 mask);
114 114
115#ifdef CONFIG_SWIOTLB 115#ifdef CONFIG_SWIOTLB
116extern void __init swiotlb_free(void); 116extern void __init swiotlb_free(void);
117unsigned int swiotlb_max_segment(void);
117#else 118#else
118static inline void swiotlb_free(void) { } 119static inline void swiotlb_free(void) { }
120static inline unsigned int swiotlb_max_segment(void) { return 0; }
119#endif 121#endif
120 122
121extern void swiotlb_print_info(void); 123extern void swiotlb_print_info(void);
122extern 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);
123 126
124#endif /* __LINUX_SWIOTLB_H */ 127#endif /* __LINUX_SWIOTLB_H */
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 9def738af4f4..975b8fc4f1e1 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -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 */
@@ -124,6 +130,20 @@ unsigned long swiotlb_nr_tbl(void)
124} 130}
125EXPORT_SYMBOL_GPL(swiotlb_nr_tbl); 131EXPORT_SYMBOL_GPL(swiotlb_nr_tbl);
126 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
127/* default to 64MB */ 147/* default to 64MB */
128#define IO_TLB_DEFAULT_SIZE (64UL<<20) 148#define IO_TLB_DEFAULT_SIZE (64UL<<20)
129unsigned long swiotlb_size_or_default(void) 149unsigned long swiotlb_size_or_default(void)
@@ -205,6 +225,7 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
205 if (verbose) 225 if (verbose)
206 swiotlb_print_info(); 226 swiotlb_print_info();
207 227
228 swiotlb_set_max_segment(io_tlb_nslabs << IO_TLB_SHIFT);
208 return 0; 229 return 0;
209} 230}
210 231
@@ -283,6 +304,7 @@ swiotlb_late_init_with_default_size(size_t default_size)
283 rc = swiotlb_late_init_with_tbl(vstart, io_tlb_nslabs); 304 rc = swiotlb_late_init_with_tbl(vstart, io_tlb_nslabs);
284 if (rc) 305 if (rc)
285 free_pages((unsigned long)vstart, order); 306 free_pages((unsigned long)vstart, order);
307
286 return rc; 308 return rc;
287} 309}
288 310
@@ -337,6 +359,8 @@ swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs)
337 359
338 late_alloc = 1; 360 late_alloc = 1;
339 361
362 swiotlb_set_max_segment(io_tlb_nslabs << IO_TLB_SHIFT);
363
340 return 0; 364 return 0;
341 365
342cleanup4: 366cleanup4:
@@ -351,6 +375,7 @@ cleanup2:
351 io_tlb_end = 0; 375 io_tlb_end = 0;
352 io_tlb_start = 0; 376 io_tlb_start = 0;
353 io_tlb_nslabs = 0; 377 io_tlb_nslabs = 0;
378 max_segment = 0;
354 return -ENOMEM; 379 return -ENOMEM;
355} 380}
356 381
@@ -379,6 +404,7 @@ void __init swiotlb_free(void)
379 PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT)); 404 PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT));
380 } 405 }
381 io_tlb_nslabs = 0; 406 io_tlb_nslabs = 0;
407 max_segment = 0;
382} 408}
383 409
384int is_swiotlb_buffer(phys_addr_t paddr) 410int is_swiotlb_buffer(phys_addr_t paddr)