Merge tag '6.10-rc1-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6
[sfrench/cifs-2.6.git] / drivers / gpu / drm / i915 / i915_vma_resource.h
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Copyright © 2021 Intel Corporation
4  */
5
6 #ifndef __I915_VMA_RESOURCE_H__
7 #define __I915_VMA_RESOURCE_H__
8
9 #include <linux/dma-fence.h>
10 #include <linux/refcount.h>
11
12 #include "i915_gem.h"
13 #include "i915_scatterlist.h"
14 #include "i915_sw_fence.h"
15 #include "intel_runtime_pm.h"
16
17 struct intel_memory_region;
18
19 struct i915_page_sizes {
20         /**
21          * The sg mask of the pages sg_table. i.e the mask of
22          * the lengths for each sg entry.
23          */
24         unsigned int phys;
25
26         /**
27          * The gtt page sizes we are allowed to use given the
28          * sg mask and the supported page sizes. This will
29          * express the smallest unit we can use for the whole
30          * object, as well as the larger sizes we may be able
31          * to use opportunistically.
32          */
33         unsigned int sg;
34 };
35
36 /**
37  * struct i915_vma_bindinfo - Information needed for async bind
38  * only but that can be dropped after the bind has taken place.
39  * Consider making this a separate argument to the bind_vma
40  * op, coalescing with other arguments like vm, stash, cache_level
41  * and flags
42  * @pages: The pages sg-table.
43  * @page_sizes: Page sizes of the pages.
44  * @pages_rsgt: Refcounted sg-table when delayed object destruction
45  * is supported. May be NULL.
46  * @readonly: Whether the vma should be bound read-only.
47  * @lmem: Whether the vma points to lmem.
48  */
49 struct i915_vma_bindinfo {
50         struct sg_table *pages;
51         struct i915_page_sizes page_sizes;
52         struct i915_refct_sgt *pages_rsgt;
53         bool readonly:1;
54         bool lmem:1;
55 };
56
57 /**
58  * struct i915_vma_resource - Snapshotted unbind information.
59  * @unbind_fence: Fence to mark unbinding complete. Note that this fence
60  * is not considered published until unbind is scheduled, and as such it
61  * is illegal to access this fence before scheduled unbind other than
62  * for refcounting.
63  * @lock: The @unbind_fence lock.
64  * @hold_count: Number of holders blocking the fence from finishing.
65  * The vma itself is keeping a hold, which is released when unbind
66  * is scheduled.
67  * @work: Work struct for deferred unbind work.
68  * @chain: Pointer to struct i915_sw_fence used to await dependencies.
69  * @rb: Rb node for the vm's pending unbind interval tree.
70  * @__subtree_last: Interval tree private member.
71  * @wakeref: wakeref.
72  * @vm: non-refcounted pointer to the vm. This is for internal use only and
73  * this member is cleared after vm_resource unbind.
74  * @mr: The memory region of the object pointed to by the vma.
75  * @ops: Pointer to the backend i915_vma_ops.
76  * @private: Bind backend private info.
77  * @start: Offset into the address space of bind range start. Note that
78  * this is after any padding that might have been allocated.
79  * @node_size: Size of the allocated range manager node with padding
80  * subtracted.
81  * @vma_size: Bind size.
82  * @guard: The size of guard area preceding and trailing the bind.
83  * @page_sizes_gtt: Resulting page sizes from the bind operation.
84  * @bound_flags: Flags indicating binding status.
85  * @allocated: Backend private data. TODO: Should move into @private.
86  * @immediate_unbind: Unbind can be done immediately and doesn't need to be
87  * deferred to a work item awaiting unsignaled fences. This is a hack.
88  * (dma_fence_work uses a fence flag for this, but this seems slightly
89  * cleaner).
90  * @needs_wakeref: Whether a wakeref is needed during unbind. Since we can't
91  * take a wakeref in the dma-fence signalling critical path, it needs to be
92  * taken when the unbind is scheduled.
93  * @skip_pte_rewrite: During ggtt suspend and vm takedown pte rewriting
94  * needs to be skipped for unbind.
95  * @tlb: pointer for obj->mm.tlb, if async unbind. Otherwise, NULL
96  *
97  * The lifetime of a struct i915_vma_resource is from a binding request to
98  * the actual possible asynchronous unbind has completed.
99  */
100 struct i915_vma_resource {
101         struct dma_fence unbind_fence;
102         /* See above for description of the lock. */
103         spinlock_t lock;
104         refcount_t hold_count;
105         struct work_struct work;
106         struct i915_sw_fence chain;
107         struct rb_node rb;
108         u64 __subtree_last;
109         struct i915_address_space *vm;
110         intel_wakeref_t wakeref;
111
112         /**
113          * @bi: Information needed for async bind only but that can be dropped
114          * after the bind has taken place.
115          *
116          * Consider making this a separate argument to the bind_vma op,
117          * coalescing with other arguments like vm, stash, cache_level and flags
118          */
119         struct i915_vma_bindinfo bi;
120
121 #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
122         struct intel_memory_region *mr;
123 #endif
124         const struct i915_vma_ops *ops;
125         void *private;
126         u64 start;
127         u64 node_size;
128         u64 vma_size;
129         u32 guard;
130         u32 page_sizes_gtt;
131
132         u32 bound_flags;
133         bool allocated:1;
134         bool immediate_unbind:1;
135         bool needs_wakeref:1;
136         bool skip_pte_rewrite:1;
137
138         u32 *tlb;
139 };
140
141 bool i915_vma_resource_hold(struct i915_vma_resource *vma_res,
142                             bool *lockdep_cookie);
143
144 void i915_vma_resource_unhold(struct i915_vma_resource *vma_res,
145                               bool lockdep_cookie);
146
147 struct i915_vma_resource *i915_vma_resource_alloc(void);
148
149 void i915_vma_resource_free(struct i915_vma_resource *vma_res);
150
151 struct dma_fence *i915_vma_resource_unbind(struct i915_vma_resource *vma_res,
152                                            u32 *tlb);
153
154 void __i915_vma_resource_init(struct i915_vma_resource *vma_res);
155
156 /**
157  * i915_vma_resource_get - Take a reference on a vma resource
158  * @vma_res: The vma resource on which to take a reference.
159  *
160  * Return: The @vma_res pointer
161  */
162 static inline struct i915_vma_resource
163 *i915_vma_resource_get(struct i915_vma_resource *vma_res)
164 {
165         dma_fence_get(&vma_res->unbind_fence);
166         return vma_res;
167 }
168
169 /**
170  * i915_vma_resource_put - Release a reference to a struct i915_vma_resource
171  * @vma_res: The resource
172  */
173 static inline void i915_vma_resource_put(struct i915_vma_resource *vma_res)
174 {
175         dma_fence_put(&vma_res->unbind_fence);
176 }
177
178 /**
179  * i915_vma_resource_init - Initialize a vma resource.
180  * @vma_res: The vma resource to initialize
181  * @vm: Pointer to the vm.
182  * @pages: The pages sg-table.
183  * @page_sizes: Page sizes of the pages.
184  * @pages_rsgt: Pointer to a struct i915_refct_sgt of an object with
185  * delayed destruction.
186  * @readonly: Whether the vma should be bound read-only.
187  * @lmem: Whether the vma points to lmem.
188  * @mr: The memory region of the object the vma points to.
189  * @ops: The backend ops.
190  * @private: Bind backend private info.
191  * @start: Offset into the address space of bind range start after padding.
192  * @node_size: Size of the allocated range manager node minus padding.
193  * @size: Bind size.
194  * @guard: The size of the guard area preceding and trailing the bind.
195  *
196  * Initializes a vma resource allocated using i915_vma_resource_alloc().
197  * The reason for having separate allocate and initialize function is that
198  * initialization may need to be performed from under a lock where
199  * allocation is not allowed.
200  */
201 static inline void i915_vma_resource_init(struct i915_vma_resource *vma_res,
202                                           struct i915_address_space *vm,
203                                           struct sg_table *pages,
204                                           const struct i915_page_sizes *page_sizes,
205                                           struct i915_refct_sgt *pages_rsgt,
206                                           bool readonly,
207                                           bool lmem,
208                                           struct intel_memory_region *mr,
209                                           const struct i915_vma_ops *ops,
210                                           void *private,
211                                           u64 start,
212                                           u64 node_size,
213                                           u64 size,
214                                           u32 guard)
215 {
216         __i915_vma_resource_init(vma_res);
217         vma_res->vm = vm;
218         vma_res->bi.pages = pages;
219         vma_res->bi.page_sizes = *page_sizes;
220         if (pages_rsgt)
221                 vma_res->bi.pages_rsgt = i915_refct_sgt_get(pages_rsgt);
222         vma_res->bi.readonly = readonly;
223         vma_res->bi.lmem = lmem;
224 #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
225         vma_res->mr = mr;
226 #endif
227         vma_res->ops = ops;
228         vma_res->private = private;
229         vma_res->start = start;
230         vma_res->node_size = node_size;
231         vma_res->vma_size = size;
232         vma_res->guard = guard;
233 }
234
235 static inline void i915_vma_resource_fini(struct i915_vma_resource *vma_res)
236 {
237         GEM_BUG_ON(refcount_read(&vma_res->hold_count) != 1);
238         if (vma_res->bi.pages_rsgt)
239                 i915_refct_sgt_put(vma_res->bi.pages_rsgt);
240         i915_sw_fence_fini(&vma_res->chain);
241 }
242
243 int i915_vma_resource_bind_dep_sync(struct i915_address_space *vm,
244                                     u64 first,
245                                     u64 last,
246                                     bool intr);
247
248 int i915_vma_resource_bind_dep_await(struct i915_address_space *vm,
249                                      struct i915_sw_fence *sw_fence,
250                                      u64 first,
251                                      u64 last,
252                                      bool intr,
253                                      gfp_t gfp);
254
255 void i915_vma_resource_bind_dep_sync_all(struct i915_address_space *vm);
256
257 void i915_vma_resource_module_exit(void);
258
259 int i915_vma_resource_module_init(void);
260
261 #endif