Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915: Pull scatterlist utils out of i915_gem.h

Out scatterlist utility routines can be pulled out of i915_gem.h for a
bit more decluttering.

v2: Push I915_GTT_PAGE_SIZE out of i915_scatterlist itself and into the
caller.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190528092956.14910-9-chris@chris-wilson.co.uk

+188 -142
+1
drivers/gpu/drm/i915/Makefile
··· 44 44 i915_irq.o \ 45 45 i915_params.o \ 46 46 i915_pci.o \ 47 + i915_scatterlist.o \ 47 48 i915_suspend.o \ 48 49 i915_sysfs.o \ 49 50 intel_csr.o \
+1
drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
··· 10 10 11 11 #include "i915_drv.h" 12 12 #include "i915_gem_object.h" 13 + #include "i915_scatterlist.h" 13 14 14 15 static struct drm_i915_gem_object *dma_buf_to_obj(struct dma_buf *buf) 15 16 {
+1
drivers/gpu/drm/i915/gem/i915_gem_internal.c
··· 13 13 #include "i915_drv.h" 14 14 #include "i915_gem.h" 15 15 #include "i915_gem_object.h" 16 + #include "i915_scatterlist.h" 16 17 #include "i915_utils.h" 17 18 18 19 #define QUIET (__GFP_NORETRY | __GFP_NOWARN)
+1
drivers/gpu/drm/i915/gem/i915_gem_pages.c
··· 6 6 7 7 #include "i915_drv.h" 8 8 #include "i915_gem_object.h" 9 + #include "i915_scatterlist.h" 9 10 10 11 void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, 11 12 struct sg_table *pages,
+1
drivers/gpu/drm/i915/gem/i915_gem_phys.c
··· 15 15 16 16 #include "i915_drv.h" 17 17 #include "i915_gem_object.h" 18 + #include "i915_scatterlist.h" 18 19 19 20 static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) 20 21 {
+1
drivers/gpu/drm/i915/gem/i915_gem_shmem.c
··· 9 9 10 10 #include "i915_drv.h" 11 11 #include "i915_gem_object.h" 12 + #include "i915_scatterlist.h" 12 13 13 14 /* 14 15 * Move pages to appropriate lru and release the pagevec, decrementing the
+1
drivers/gpu/drm/i915/gem/i915_gem_userptr.c
··· 14 14 15 15 #include "i915_gem_ioctls.h" 16 16 #include "i915_gem_object.h" 17 + #include "i915_scatterlist.h" 17 18 #include "i915_trace.h" 18 19 #include "intel_drv.h" 19 20
+2
drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c
··· 4 4 * Copyright © 2016 Intel Corporation 5 5 */ 6 6 7 + #include "i915_scatterlist.h" 8 + 7 9 #include "huge_gem_object.h" 8 10 9 11 static void huge_free_pages(struct drm_i915_gem_object *obj,
+1
drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
··· 4 4 * Copyright © 2016 Intel Corporation 5 5 */ 6 6 7 + #include "i915_drv.h" 7 8 #include "i915_selftest.h" 8 9 9 10 #include "mock_dmabuf.h"
-110
drivers/gpu/drm/i915/i915_drv.h
··· 2169 2169 GENMASK(INTEL_FRONTBUFFER_BITS_PER_PIPE * ((pipe) + 1) - 1, \ 2170 2170 INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)) 2171 2171 2172 - /* 2173 - * Optimised SGL iterator for GEM objects 2174 - */ 2175 - static __always_inline struct sgt_iter { 2176 - struct scatterlist *sgp; 2177 - union { 2178 - unsigned long pfn; 2179 - dma_addr_t dma; 2180 - }; 2181 - unsigned int curr; 2182 - unsigned int max; 2183 - } __sgt_iter(struct scatterlist *sgl, bool dma) { 2184 - struct sgt_iter s = { .sgp = sgl }; 2185 - 2186 - if (s.sgp) { 2187 - s.max = s.curr = s.sgp->offset; 2188 - s.max += s.sgp->length; 2189 - if (dma) 2190 - s.dma = sg_dma_address(s.sgp); 2191 - else 2192 - s.pfn = page_to_pfn(sg_page(s.sgp)); 2193 - } 2194 - 2195 - return s; 2196 - } 2197 - 2198 - static inline struct scatterlist *____sg_next(struct scatterlist *sg) 2199 - { 2200 - ++sg; 2201 - if (unlikely(sg_is_chain(sg))) 2202 - sg = sg_chain_ptr(sg); 2203 - return sg; 2204 - } 2205 - 2206 - /** 2207 - * __sg_next - return the next scatterlist entry in a list 2208 - * @sg: The current sg entry 2209 - * 2210 - * Description: 2211 - * If the entry is the last, return NULL; otherwise, step to the next 2212 - * element in the array (@sg@+1). If that's a chain pointer, follow it; 2213 - * otherwise just return the pointer to the current element. 2214 - **/ 2215 - static inline struct scatterlist *__sg_next(struct scatterlist *sg) 2216 - { 2217 - return sg_is_last(sg) ? NULL : ____sg_next(sg); 2218 - } 2219 - 2220 - /** 2221 - * for_each_sgt_dma - iterate over the DMA addresses of the given sg_table 2222 - * @__dmap: DMA address (output) 2223 - * @__iter: 'struct sgt_iter' (iterator state, internal) 2224 - * @__sgt: sg_table to iterate over (input) 2225 - */ 2226 - #define for_each_sgt_dma(__dmap, __iter, __sgt) \ 2227 - for ((__iter) = __sgt_iter((__sgt)->sgl, true); \ 2228 - ((__dmap) = (__iter).dma + (__iter).curr); \ 2229 - (((__iter).curr += I915_GTT_PAGE_SIZE) >= (__iter).max) ? \ 2230 - (__iter) = __sgt_iter(__sg_next((__iter).sgp), true), 0 : 0) 2231 - 2232 - /** 2233 - * for_each_sgt_page - iterate over the pages of the given sg_table 2234 - * @__pp: page pointer (output) 2235 - * @__iter: 'struct sgt_iter' (iterator state, internal) 2236 - * @__sgt: sg_table to iterate over (input) 2237 - */ 2238 - #define for_each_sgt_page(__pp, __iter, __sgt) \ 2239 - for ((__iter) = __sgt_iter((__sgt)->sgl, false); \ 2240 - ((__pp) = (__iter).pfn == 0 ? NULL : \ 2241 - pfn_to_page((__iter).pfn + ((__iter).curr >> PAGE_SHIFT))); \ 2242 - (((__iter).curr += PAGE_SIZE) >= (__iter).max) ? \ 2243 - (__iter) = __sgt_iter(__sg_next((__iter).sgp), false), 0 : 0) 2244 - 2245 - bool i915_sg_trim(struct sg_table *orig_st); 2246 - 2247 - static inline unsigned int i915_sg_page_sizes(struct scatterlist *sg) 2248 - { 2249 - unsigned int page_sizes; 2250 - 2251 - page_sizes = 0; 2252 - while (sg) { 2253 - GEM_BUG_ON(sg->offset); 2254 - GEM_BUG_ON(!IS_ALIGNED(sg->length, PAGE_SIZE)); 2255 - page_sizes |= sg->length; 2256 - sg = __sg_next(sg); 2257 - } 2258 - 2259 - return page_sizes; 2260 - } 2261 - 2262 - static inline unsigned int i915_sg_segment_size(void) 2263 - { 2264 - unsigned int size = swiotlb_max_segment(); 2265 - 2266 - if (size == 0) 2267 - return SCATTERLIST_MAX_SEGMENT; 2268 - 2269 - size = rounddown(size, PAGE_SIZE); 2270 - /* swiotlb_max_segment_size can return 1 byte when it means one page. */ 2271 - if (size < PAGE_SIZE) 2272 - size = PAGE_SIZE; 2273 - 2274 - return size; 2275 - } 2276 - 2277 2172 #define INTEL_INFO(dev_priv) (&(dev_priv)->__info) 2278 2173 #define RUNTIME_INFO(dev_priv) (&(dev_priv)->__runtime) 2279 2174 #define DRIVER_CAPS(dev_priv) (&(dev_priv)->caps) ··· 2703 2808 int i915_gem_object_unbind(struct drm_i915_gem_object *obj); 2704 2809 2705 2810 void i915_gem_runtime_suspend(struct drm_i915_private *dev_priv); 2706 - 2707 - static inline int __sg_page_count(const struct scatterlist *sg) 2708 - { 2709 - return sg->length >> PAGE_SHIFT; 2710 - } 2711 2811 2712 2812 static inline int __must_check 2713 2813 i915_mutex_lock_interruptible(struct drm_device *dev)
+1 -29
drivers/gpu/drm/i915/i915_gem.c
··· 50 50 #include "gt/intel_workarounds.h" 51 51 52 52 #include "i915_drv.h" 53 + #include "i915_scatterlist.h" 53 54 #include "i915_trace.h" 54 55 #include "i915_vgpu.h" 55 56 ··· 1084 1083 GEM_BUG_ON(i915_vma_has_userfault(reg->vma)); 1085 1084 reg->dirty = true; 1086 1085 } 1087 - } 1088 - 1089 - bool i915_sg_trim(struct sg_table *orig_st) 1090 - { 1091 - struct sg_table new_st; 1092 - struct scatterlist *sg, *new_sg; 1093 - unsigned int i; 1094 - 1095 - if (orig_st->nents == orig_st->orig_nents) 1096 - return false; 1097 - 1098 - if (sg_alloc_table(&new_st, orig_st->nents, GFP_KERNEL | __GFP_NOWARN)) 1099 - return false; 1100 - 1101 - new_sg = new_st.sgl; 1102 - for_each_sg(orig_st->sgl, sg, orig_st->nents, i) { 1103 - sg_set_page(new_sg, sg_page(sg), sg->length, 0); 1104 - sg_dma_address(new_sg) = sg_dma_address(sg); 1105 - sg_dma_len(new_sg) = sg_dma_len(sg); 1106 - 1107 - new_sg = sg_next(new_sg); 1108 - } 1109 - GEM_BUG_ON(new_sg); /* Should walk exactly nents and hit the end */ 1110 - 1111 - sg_free_table(orig_st); 1112 - 1113 - *orig_st = new_st; 1114 - return true; 1115 1086 } 1116 1087 1117 1088 static unsigned long to_wait_timeout(s64 timeout_ns) ··· 2343 2370 } 2344 2371 2345 2372 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) 2346 - #include "selftests/scatterlist.c" 2347 2373 #include "selftests/mock_gem_device.c" 2348 2374 #include "selftests/i915_gem.c" 2349 2375 #endif
+2
drivers/gpu/drm/i915/i915_gem_fence_reg.c
··· 22 22 */ 23 23 24 24 #include <drm/i915_drm.h> 25 + 25 26 #include "i915_drv.h" 27 + #include "i915_scatterlist.h" 26 28 27 29 /** 28 30 * DOC: fence register handling
+2 -1
drivers/gpu/drm/i915/i915_gem_gtt.c
··· 36 36 #include <drm/i915_drm.h> 37 37 38 38 #include "i915_drv.h" 39 - #include "i915_vgpu.h" 39 + #include "i915_scatterlist.h" 40 40 #include "i915_trace.h" 41 + #include "i915_vgpu.h" 41 42 #include "intel_drv.h" 42 43 #include "intel_frontbuffer.h" 43 44
+3 -1
drivers/gpu/drm/i915/i915_gem_gtt.h
··· 40 40 41 41 #include "gt/intel_reset.h" 42 42 #include "i915_request.h" 43 + #include "i915_scatterlist.h" 43 44 #include "i915_selftest.h" 44 45 #include "i915_timeline.h" 45 46 ··· 163 162 #define GEN8_PDE_IPS_64K BIT(11) 164 163 #define GEN8_PDE_PS_2M BIT(7) 165 164 166 - struct sg_table; 165 + #define for_each_sgt_dma(__dmap, __iter, __sgt) \ 166 + __for_each_sgt_dma(__dmap, __iter, __sgt, I915_GTT_PAGE_SIZE) 167 167 168 168 struct intel_remapped_plane_info { 169 169 /* in gtt pages */
+1
drivers/gpu/drm/i915/i915_gpu_error.c
··· 40 40 41 41 #include "i915_drv.h" 42 42 #include "i915_gpu_error.h" 43 + #include "i915_scatterlist.h" 43 44 #include "intel_atomic.h" 44 45 #include "intel_csr.h" 45 46 #include "intel_overlay.h"
+39
drivers/gpu/drm/i915/i915_scatterlist.c
··· 1 + /* 2 + * SPDX-License-Identifier: MIT 3 + * 4 + * Copyright © 2016 Intel Corporation 5 + */ 6 + 7 + #include "i915_scatterlist.h" 8 + 9 + bool i915_sg_trim(struct sg_table *orig_st) 10 + { 11 + struct sg_table new_st; 12 + struct scatterlist *sg, *new_sg; 13 + unsigned int i; 14 + 15 + if (orig_st->nents == orig_st->orig_nents) 16 + return false; 17 + 18 + if (sg_alloc_table(&new_st, orig_st->nents, GFP_KERNEL | __GFP_NOWARN)) 19 + return false; 20 + 21 + new_sg = new_st.sgl; 22 + for_each_sg(orig_st->sgl, sg, orig_st->nents, i) { 23 + sg_set_page(new_sg, sg_page(sg), sg->length, 0); 24 + sg_dma_address(new_sg) = sg_dma_address(sg); 25 + sg_dma_len(new_sg) = sg_dma_len(sg); 26 + 27 + new_sg = sg_next(new_sg); 28 + } 29 + GEM_BUG_ON(new_sg); /* Should walk exactly nents and hit the end */ 30 + 31 + sg_free_table(orig_st); 32 + 33 + *orig_st = new_st; 34 + return true; 35 + } 36 + 37 + #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) 38 + #include "selftests/scatterlist.c" 39 + #endif
+127
drivers/gpu/drm/i915/i915_scatterlist.h
··· 1 + /* 2 + * SPDX-License-Identifier: MIT 3 + * 4 + * Copyright © 2016 Intel Corporation 5 + */ 6 + 7 + #ifndef I915_SCATTERLIST_H 8 + #define I915_SCATTERLIST_H 9 + 10 + #include <linux/pfn.h> 11 + #include <linux/scatterlist.h> 12 + #include <linux/swiotlb.h> 13 + 14 + #include "i915_gem.h" 15 + 16 + /* 17 + * Optimised SGL iterator for GEM objects 18 + */ 19 + static __always_inline struct sgt_iter { 20 + struct scatterlist *sgp; 21 + union { 22 + unsigned long pfn; 23 + dma_addr_t dma; 24 + }; 25 + unsigned int curr; 26 + unsigned int max; 27 + } __sgt_iter(struct scatterlist *sgl, bool dma) { 28 + struct sgt_iter s = { .sgp = sgl }; 29 + 30 + if (s.sgp) { 31 + s.max = s.curr = s.sgp->offset; 32 + s.max += s.sgp->length; 33 + if (dma) 34 + s.dma = sg_dma_address(s.sgp); 35 + else 36 + s.pfn = page_to_pfn(sg_page(s.sgp)); 37 + } 38 + 39 + return s; 40 + } 41 + 42 + static inline int __sg_page_count(const struct scatterlist *sg) 43 + { 44 + return sg->length >> PAGE_SHIFT; 45 + } 46 + 47 + static inline struct scatterlist *____sg_next(struct scatterlist *sg) 48 + { 49 + ++sg; 50 + if (unlikely(sg_is_chain(sg))) 51 + sg = sg_chain_ptr(sg); 52 + return sg; 53 + } 54 + 55 + /** 56 + * __sg_next - return the next scatterlist entry in a list 57 + * @sg: The current sg entry 58 + * 59 + * Description: 60 + * If the entry is the last, return NULL; otherwise, step to the next 61 + * element in the array (@sg@+1). If that's a chain pointer, follow it; 62 + * otherwise just return the pointer to the current element. 63 + **/ 64 + static inline struct scatterlist *__sg_next(struct scatterlist *sg) 65 + { 66 + return sg_is_last(sg) ? NULL : ____sg_next(sg); 67 + } 68 + 69 + /** 70 + * __for_each_sgt_dma - iterate over the DMA addresses of the given sg_table 71 + * @__dmap: DMA address (output) 72 + * @__iter: 'struct sgt_iter' (iterator state, internal) 73 + * @__sgt: sg_table to iterate over (input) 74 + * @__step: step size 75 + */ 76 + #define __for_each_sgt_dma(__dmap, __iter, __sgt, __step) \ 77 + for ((__iter) = __sgt_iter((__sgt)->sgl, true); \ 78 + ((__dmap) = (__iter).dma + (__iter).curr); \ 79 + (((__iter).curr += (__step)) >= (__iter).max) ? \ 80 + (__iter) = __sgt_iter(__sg_next((__iter).sgp), true), 0 : 0) 81 + 82 + /** 83 + * for_each_sgt_page - iterate over the pages of the given sg_table 84 + * @__pp: page pointer (output) 85 + * @__iter: 'struct sgt_iter' (iterator state, internal) 86 + * @__sgt: sg_table to iterate over (input) 87 + */ 88 + #define for_each_sgt_page(__pp, __iter, __sgt) \ 89 + for ((__iter) = __sgt_iter((__sgt)->sgl, false); \ 90 + ((__pp) = (__iter).pfn == 0 ? NULL : \ 91 + pfn_to_page((__iter).pfn + ((__iter).curr >> PAGE_SHIFT))); \ 92 + (((__iter).curr += PAGE_SIZE) >= (__iter).max) ? \ 93 + (__iter) = __sgt_iter(__sg_next((__iter).sgp), false), 0 : 0) 94 + 95 + static inline unsigned int i915_sg_page_sizes(struct scatterlist *sg) 96 + { 97 + unsigned int page_sizes; 98 + 99 + page_sizes = 0; 100 + while (sg) { 101 + GEM_BUG_ON(sg->offset); 102 + GEM_BUG_ON(!IS_ALIGNED(sg->length, PAGE_SIZE)); 103 + page_sizes |= sg->length; 104 + sg = __sg_next(sg); 105 + } 106 + 107 + return page_sizes; 108 + } 109 + 110 + static inline unsigned int i915_sg_segment_size(void) 111 + { 112 + unsigned int size = swiotlb_max_segment(); 113 + 114 + if (size == 0) 115 + return SCATTERLIST_MAX_SEGMENT; 116 + 117 + size = rounddown(size, PAGE_SIZE); 118 + /* swiotlb_max_segment_size can return 1 byte when it means one page. */ 119 + if (size < PAGE_SIZE) 120 + size = PAGE_SIZE; 121 + 122 + return size; 123 + } 124 + 125 + bool i915_sg_trim(struct sg_table *orig_st); 126 + 127 + #endif
+1
drivers/gpu/drm/i915/selftests/i915_vma.c
··· 26 26 27 27 #include "gem/selftests/mock_context.h" 28 28 29 + #include "i915_scatterlist.h" 29 30 #include "i915_selftest.h" 30 31 31 32 #include "mock_gem_device.h"
+2 -1
drivers/gpu/drm/i915/selftests/scatterlist.c
··· 24 24 #include <linux/prime_numbers.h> 25 25 #include <linux/random.h> 26 26 27 - #include "../i915_selftest.h" 27 + #include "i915_selftest.h" 28 + #include "i915_utils.h" 28 29 29 30 #define PFN_BIAS (1 << 10) 30 31