diff options
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 11 | ||||
| -rw-r--r-- | drivers/xen/swiotlb-xen.c | 4 | ||||
| -rw-r--r-- | include/linux/swiotlb.h | 3 | ||||
| -rw-r--r-- | lib/swiotlb.c | 26 |
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 | ||
| 2293 | static 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 | |||
| 2302 | static void i915_sg_trim(struct sg_table *orig_st) | 2293 | static 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; |
| 279 | error: | 283 | error: |
| 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 |
| 116 | extern void __init swiotlb_free(void); | 116 | extern void __init swiotlb_free(void); |
| 117 | unsigned int swiotlb_max_segment(void); | ||
| 117 | #else | 118 | #else |
| 118 | static inline void swiotlb_free(void) { } | 119 | static inline void swiotlb_free(void) { } |
| 120 | static inline unsigned int swiotlb_max_segment(void) { return 0; } | ||
| 119 | #endif | 121 | #endif |
| 120 | 122 | ||
| 121 | extern void swiotlb_print_info(void); | 123 | extern void swiotlb_print_info(void); |
| 122 | extern int is_swiotlb_buffer(phys_addr_t paddr); | 124 | extern int is_swiotlb_buffer(phys_addr_t paddr); |
| 125 | extern 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; | |||
| 83 | static unsigned int io_tlb_index; | 83 | static 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 | */ | ||
| 89 | unsigned 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 | } |
| 125 | EXPORT_SYMBOL_GPL(swiotlb_nr_tbl); | 131 | EXPORT_SYMBOL_GPL(swiotlb_nr_tbl); |
| 126 | 132 | ||
| 133 | unsigned int swiotlb_max_segment(void) | ||
| 134 | { | ||
| 135 | return max_segment; | ||
| 136 | } | ||
| 137 | EXPORT_SYMBOL_GPL(swiotlb_max_segment); | ||
| 138 | |||
| 139 | void 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) |
| 129 | unsigned long swiotlb_size_or_default(void) | 149 | unsigned 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 | ||
| 342 | cleanup4: | 366 | cleanup4: |
| @@ -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 | ||
| 384 | int is_swiotlb_buffer(phys_addr_t paddr) | 410 | int is_swiotlb_buffer(phys_addr_t paddr) |
