Home | History | Annotate | Line # | Download | only in i915
i915_vma.h revision 1.4
      1 /*	$NetBSD: i915_vma.h,v 1.4 2021/12/19 11:11:59 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright  2016 Intel Corporation
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the next
     14  * paragraph) shall be included in all copies or substantial portions of the
     15  * Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     23  * IN THE SOFTWARE.
     24  *
     25  */
     26 
     27 #ifndef __I915_VMA_H__
     28 #define __I915_VMA_H__
     29 
     30 #include <linux/io-mapping.h>
     31 #include <linux/rbtree.h>
     32 
     33 #include <drm/drm_mm.h>
     34 
     35 #include "gem/i915_gem_object.h"
     36 
     37 #include "i915_gem_gtt.h"
     38 #include "i915_gem_fence_reg.h"
     39 
     40 #include "i915_active.h"
     41 #include "i915_request.h"
     42 #include "i915_vma_types.h"
     43 
     44 struct i915_vma *
     45 i915_vma_instance(struct drm_i915_gem_object *obj,
     46 		  struct i915_address_space *vm,
     47 		  const struct i915_ggtt_view *view);
     48 
     49 void i915_vma_unpin_and_release(struct i915_vma **p_vma, unsigned int flags);
     50 #define I915_VMA_RELEASE_MAP BIT(0)
     51 
     52 static inline bool i915_vma_is_active(struct i915_vma *vma)
     53 {
     54 	return !i915_active_is_idle(&vma->active);
     55 }
     56 
     57 int __must_check __i915_vma_move_to_active(struct i915_vma *vma,
     58 					   struct i915_request *rq);
     59 int __must_check i915_vma_move_to_active(struct i915_vma *vma,
     60 					 struct i915_request *rq,
     61 					 unsigned int flags);
     62 
     63 #ifdef __linux__
     64 #define __i915_vma_flags(v) ((unsigned long *)&(v)->flags.counter)
     65 #else
     66 #define __i915_vma_flags(v) ((unsigned long *)&(v)->flags)
     67 #endif
     68 
     69 
     70 static inline bool i915_vma_is_ggtt(struct i915_vma *vma)
     71 {
     72 	return test_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(vma));
     73 }
     74 
     75 static inline bool i915_vma_has_ggtt_write(struct i915_vma *vma)
     76 {
     77 	return test_bit(I915_VMA_GGTT_WRITE_BIT, __i915_vma_flags(vma));
     78 }
     79 
     80 static inline void i915_vma_set_ggtt_write(struct i915_vma *vma)
     81 {
     82 	GEM_BUG_ON(!i915_vma_is_ggtt(vma));
     83 	set_bit(I915_VMA_GGTT_WRITE_BIT, __i915_vma_flags(vma));
     84 }
     85 
     86 static inline bool i915_vma_unset_ggtt_write(struct i915_vma *vma)
     87 {
     88 	return test_and_clear_bit(I915_VMA_GGTT_WRITE_BIT,
     89 				  __i915_vma_flags(vma));
     90 }
     91 
     92 void i915_vma_flush_writes(struct i915_vma *vma);
     93 
     94 static inline bool i915_vma_is_map_and_fenceable(struct i915_vma *vma)
     95 {
     96 	return test_bit(I915_VMA_CAN_FENCE_BIT, __i915_vma_flags(vma));
     97 }
     98 
     99 static inline bool i915_vma_set_userfault(struct i915_vma *vma)
    100 {
    101 	GEM_BUG_ON(!i915_vma_is_map_and_fenceable(vma));
    102 	return test_and_set_bit(I915_VMA_USERFAULT_BIT, __i915_vma_flags(vma));
    103 }
    104 
    105 static inline void i915_vma_unset_userfault(struct i915_vma *vma)
    106 {
    107 	return clear_bit(I915_VMA_USERFAULT_BIT, __i915_vma_flags(vma));
    108 }
    109 
    110 static inline bool i915_vma_has_userfault(struct i915_vma *vma)
    111 {
    112 	return test_bit(I915_VMA_USERFAULT_BIT, __i915_vma_flags(vma));
    113 }
    114 
    115 static inline bool i915_vma_is_closed(struct i915_vma *vma)
    116 {
    117 	return !list_empty(&vma->closed_link);
    118 }
    119 
    120 static inline u32 i915_ggtt_offset(struct i915_vma *vma)
    121 {
    122 	GEM_BUG_ON(!i915_vma_is_ggtt(vma));
    123 	GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
    124 	GEM_BUG_ON(upper_32_bits(vma->node.start));
    125 	GEM_BUG_ON(upper_32_bits(vma->node.start + vma->node.size - 1));
    126 	return lower_32_bits(vma->node.start);
    127 }
    128 
    129 static inline u32 i915_ggtt_pin_bias(struct i915_vma *vma)
    130 {
    131 	return i915_vm_to_ggtt(vma->vm)->pin_bias;
    132 }
    133 
    134 static inline struct i915_vma *i915_vma_get(struct i915_vma *vma)
    135 {
    136 	i915_gem_object_get(vma->obj);
    137 	return vma;
    138 }
    139 
    140 static inline struct i915_vma *i915_vma_tryget(struct i915_vma *vma)
    141 {
    142 	if (likely(kref_get_unless_zero(&vma->obj->base.refcount)))
    143 		return vma;
    144 
    145 	return NULL;
    146 }
    147 
    148 static inline void i915_vma_put(struct i915_vma *vma)
    149 {
    150 	i915_gem_object_put(vma->obj);
    151 }
    152 
    153 static __always_inline ptrdiff_t ptrdiff(const void *a, const void *b)
    154 {
    155 	return (const char *)a - (const char *)b;
    156 }
    157 
    158 static inline long
    159 i915_vma_compare(struct i915_vma *vma,
    160 		 struct i915_address_space *vm,
    161 		 const struct i915_ggtt_view *view)
    162 {
    163 	ptrdiff_t cmp;
    164 
    165 	GEM_BUG_ON(view && !i915_is_ggtt(vm));
    166 
    167 	cmp = ptrdiff(vma->vm, vm);
    168 	if (cmp)
    169 		return cmp;
    170 
    171 	BUILD_BUG_ON(I915_GGTT_VIEW_NORMAL != 0);
    172 	cmp = vma->ggtt_view.type;
    173 	if (!view)
    174 		return cmp;
    175 
    176 	cmp -= view->type;
    177 	if (cmp)
    178 		return cmp;
    179 
    180 	assert_i915_gem_gtt_types();
    181 
    182 	/* ggtt_view.type also encodes its size so that we both distinguish
    183 	 * different views using it as a "type" and also use a compact (no
    184 	 * accessing of uninitialised padding bytes) memcmp without storing
    185 	 * an extra parameter or adding more code.
    186 	 *
    187 	 * To ensure that the memcmp is valid for all branches of the union,
    188 	 * even though the code looks like it is just comparing one branch,
    189 	 * we assert above that all branches have the same address, and that
    190 	 * each branch has a unique type/size.
    191 	 */
    192 	BUILD_BUG_ON(I915_GGTT_VIEW_NORMAL >= I915_GGTT_VIEW_PARTIAL);
    193 	BUILD_BUG_ON(I915_GGTT_VIEW_PARTIAL >= I915_GGTT_VIEW_ROTATED);
    194 	BUILD_BUG_ON(I915_GGTT_VIEW_ROTATED >= I915_GGTT_VIEW_REMAPPED);
    195 	BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
    196 		     offsetof(typeof(*view), partial));
    197 	BUILD_BUG_ON(offsetof(typeof(*view), rotated) !=
    198 		     offsetof(typeof(*view), remapped));
    199 	return memcmp(&vma->ggtt_view.partial, &view->partial, view->type);
    200 }
    201 
    202 struct i915_vma_work *i915_vma_work(void);
    203 int i915_vma_bind(struct i915_vma *vma,
    204 		  enum i915_cache_level cache_level,
    205 		  u32 flags,
    206 		  struct i915_vma_work *work);
    207 
    208 bool i915_gem_valid_gtt_space(struct i915_vma *vma, unsigned long color);
    209 bool i915_vma_misplaced(struct i915_vma *vma,
    210 			u64 size, u64 alignment, u64 flags);
    211 void __i915_vma_set_map_and_fenceable(struct i915_vma *vma);
    212 void i915_vma_revoke_mmap(struct i915_vma *vma);
    213 int __i915_vma_unbind(struct i915_vma *vma);
    214 int __must_check i915_vma_unbind(struct i915_vma *vma);
    215 void i915_vma_unlink_ctx(struct i915_vma *vma);
    216 void i915_vma_close(struct i915_vma *vma);
    217 void i915_vma_reopen(struct i915_vma *vma);
    218 
    219 static inline struct i915_vma *__i915_vma_get(struct i915_vma *vma)
    220 {
    221 	if (kref_get_unless_zero(&vma->ref))
    222 		return vma;
    223 
    224 	return NULL;
    225 }
    226 
    227 void i915_vma_release(struct kref *ref);
    228 static inline void __i915_vma_put(struct i915_vma *vma)
    229 {
    230 	kref_put(&vma->ref, i915_vma_release);
    231 }
    232 
    233 #define assert_vma_held(vma) dma_resv_assert_held((vma)->resv)
    234 
    235 static inline void i915_vma_lock(struct i915_vma *vma)
    236 {
    237 	dma_resv_lock(vma->resv, NULL);
    238 }
    239 
    240 static inline void i915_vma_unlock(struct i915_vma *vma)
    241 {
    242 	dma_resv_unlock(vma->resv);
    243 }
    244 
    245 int __must_check
    246 i915_vma_pin(struct i915_vma *vma, u64 size, u64 alignment, u64 flags);
    247 int i915_ggtt_pin(struct i915_vma *vma, u32 align, unsigned int flags);
    248 
    249 static inline int i915_vma_pin_count(struct i915_vma *vma)
    250 {
    251 	return atomic_read(&vma->flags) & I915_VMA_PIN_MASK;
    252 }
    253 
    254 static inline bool i915_vma_is_pinned(struct i915_vma *vma)
    255 {
    256 	return i915_vma_pin_count(vma);
    257 }
    258 
    259 static inline void __i915_vma_pin(struct i915_vma *vma)
    260 {
    261 	atomic_inc(&vma->flags);
    262 	GEM_BUG_ON(!i915_vma_is_pinned(vma));
    263 }
    264 
    265 static inline void __i915_vma_unpin(struct i915_vma *vma)
    266 {
    267 	GEM_BUG_ON(!i915_vma_is_pinned(vma));
    268 	atomic_dec(&vma->flags);
    269 }
    270 
    271 static inline void i915_vma_unpin(struct i915_vma *vma)
    272 {
    273 	GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
    274 	__i915_vma_unpin(vma);
    275 }
    276 
    277 static inline bool i915_vma_is_bound(struct i915_vma *vma,
    278 				     unsigned int where)
    279 {
    280 	return atomic_read(&vma->flags) & where;
    281 }
    282 
    283 static inline bool i915_node_color_differs(const struct drm_mm_node *node,
    284 					   unsigned long color)
    285 {
    286 	return drm_mm_node_allocated(node) && node->color != color;
    287 }
    288 
    289 /**
    290  * i915_vma_pin_iomap - calls ioremap_wc to map the GGTT VMA via the aperture
    291  * @vma: VMA to iomap
    292  *
    293  * The passed in VMA has to be pinned in the global GTT mappable region.
    294  * An extra pinning of the VMA is acquired for the return iomapping,
    295  * the caller must call i915_vma_unpin_iomap to relinquish the pinning
    296  * after the iomapping is no longer required.
    297  *
    298  * Returns a valid iomapped pointer or ERR_PTR.
    299  */
    300 void __iomem *i915_vma_pin_iomap(struct i915_vma *vma);
    301 #define IO_ERR_PTR(x) ((void __iomem *)ERR_PTR(x))
    302 
    303 /**
    304  * i915_vma_unpin_iomap - unpins the mapping returned from i915_vma_iomap
    305  * @vma: VMA to unpin
    306  *
    307  * Unpins the previously iomapped VMA from i915_vma_pin_iomap().
    308  *
    309  * This function is only valid to be called on a VMA previously
    310  * iomapped by the caller with i915_vma_pin_iomap().
    311  */
    312 void i915_vma_unpin_iomap(struct i915_vma *vma);
    313 
    314 static inline struct page *i915_vma_first_page(struct i915_vma *vma)
    315 {
    316 	GEM_BUG_ON(!vma->pages);
    317 #ifdef __NetBSD__
    318 	GEM_BUG_ON(!vma->segs);
    319 	return container_of(PHYS_TO_VM_PAGE(vma->segs[0].ds_addr), struct page,
    320 	    p_vmp);
    321 #else
    322 	return sg_page(vma->pages->sgl);
    323 #endif
    324 }
    325 
    326 /**
    327  * i915_vma_pin_fence - pin fencing state
    328  * @vma: vma to pin fencing for
    329  *
    330  * This pins the fencing state (whether tiled or untiled) to make sure the
    331  * vma (and its object) is ready to be used as a scanout target. Fencing
    332  * status must be synchronize first by calling i915_vma_get_fence():
    333  *
    334  * The resulting fence pin reference must be released again with
    335  * i915_vma_unpin_fence().
    336  *
    337  * Returns:
    338  *
    339  * True if the vma has a fence, false otherwise.
    340  */
    341 int __must_check i915_vma_pin_fence(struct i915_vma *vma);
    342 int __must_check i915_vma_revoke_fence(struct i915_vma *vma);
    343 
    344 int __i915_vma_pin_fence(struct i915_vma *vma);
    345 
    346 static inline void __i915_vma_unpin_fence(struct i915_vma *vma)
    347 {
    348 	GEM_BUG_ON(atomic_read(&vma->fence->pin_count) <= 0);
    349 	atomic_dec(&vma->fence->pin_count);
    350 }
    351 
    352 /**
    353  * i915_vma_unpin_fence - unpin fencing state
    354  * @vma: vma to unpin fencing for
    355  *
    356  * This releases the fence pin reference acquired through
    357  * i915_vma_pin_fence. It will handle both objects with and without an
    358  * attached fence correctly, callers do not need to distinguish this.
    359  */
    360 static inline void
    361 i915_vma_unpin_fence(struct i915_vma *vma)
    362 {
    363 	if (vma->fence)
    364 		__i915_vma_unpin_fence(vma);
    365 }
    366 
    367 void i915_vma_parked(struct intel_gt *gt);
    368 
    369 #define for_each_until(cond) if (cond) break; else
    370 
    371 /**
    372  * for_each_ggtt_vma - Iterate over the GGTT VMA belonging to an object.
    373  * @V: the #i915_vma iterator
    374  * @OBJ: the #drm_i915_gem_object
    375  *
    376  * GGTT VMA are placed at the being of the object's vma_list, see
    377  * vma_create(), so we can stop our walk as soon as we see a ppgtt VMA,
    378  * or the list is empty ofc.
    379  */
    380 #define for_each_ggtt_vma(V, OBJ) \
    381 	list_for_each_entry(V, &(OBJ)->vma.list, obj_link)		\
    382 		for_each_until(!i915_vma_is_ggtt(V))
    383 
    384 struct i915_vma *i915_vma_alloc(void);
    385 void i915_vma_free(struct i915_vma *vma);
    386 
    387 struct i915_vma *i915_vma_make_unshrinkable(struct i915_vma *vma);
    388 void i915_vma_make_shrinkable(struct i915_vma *vma);
    389 void i915_vma_make_purgeable(struct i915_vma *vma);
    390 
    391 static inline int i915_vma_sync(struct i915_vma *vma)
    392 {
    393 	/* Wait for the asynchronous bindings and pending GPU reads */
    394 	return i915_active_wait(&vma->active);
    395 }
    396 
    397 #endif
    398