/* SPDX-License-Identifier: MIT */ /* * Copyright © 2021 Intel Corporation */ #ifndef __I915_VMA_RESOURCE_H__ #define __I915_VMA_RESOURCE_H__ #include <linux/dma-fence.h> #include <linux/refcount.h> #include "i915_gem.h" #include "i915_scatterlist.h" #include "i915_sw_fence.h" #include "intel_runtime_pm.h" struct intel_memory_region; struct i915_page_sizes { … }; /** * struct i915_vma_bindinfo - Information needed for async bind * only but that can be dropped after the bind has taken place. * Consider making this a separate argument to the bind_vma * op, coalescing with other arguments like vm, stash, cache_level * and flags * @pages: The pages sg-table. * @page_sizes: Page sizes of the pages. * @pages_rsgt: Refcounted sg-table when delayed object destruction * is supported. May be NULL. * @readonly: Whether the vma should be bound read-only. * @lmem: Whether the vma points to lmem. */ struct i915_vma_bindinfo { … }; /** * struct i915_vma_resource - Snapshotted unbind information. * @unbind_fence: Fence to mark unbinding complete. Note that this fence * is not considered published until unbind is scheduled, and as such it * is illegal to access this fence before scheduled unbind other than * for refcounting. * @lock: The @unbind_fence lock. * @hold_count: Number of holders blocking the fence from finishing. * The vma itself is keeping a hold, which is released when unbind * is scheduled. * @work: Work struct for deferred unbind work. * @chain: Pointer to struct i915_sw_fence used to await dependencies. * @rb: Rb node for the vm's pending unbind interval tree. * @__subtree_last: Interval tree private member. * @wakeref: wakeref. * @vm: non-refcounted pointer to the vm. This is for internal use only and * this member is cleared after vm_resource unbind. * @mr: The memory region of the object pointed to by the vma. * @ops: Pointer to the backend i915_vma_ops. * @private: Bind backend private info. * @start: Offset into the address space of bind range start. Note that * this is after any padding that might have been allocated. * @node_size: Size of the allocated range manager node with padding * subtracted. * @vma_size: Bind size. * @guard: The size of guard area preceding and trailing the bind. * @page_sizes_gtt: Resulting page sizes from the bind operation. * @bound_flags: Flags indicating binding status. * @allocated: Backend private data. TODO: Should move into @private. * @immediate_unbind: Unbind can be done immediately and doesn't need to be * deferred to a work item awaiting unsignaled fences. This is a hack. * (dma_fence_work uses a fence flag for this, but this seems slightly * cleaner). * @needs_wakeref: Whether a wakeref is needed during unbind. Since we can't * take a wakeref in the dma-fence signalling critical path, it needs to be * taken when the unbind is scheduled. * @skip_pte_rewrite: During ggtt suspend and vm takedown pte rewriting * needs to be skipped for unbind. * @tlb: pointer for obj->mm.tlb, if async unbind. Otherwise, NULL * * The lifetime of a struct i915_vma_resource is from a binding request to * the actual possible asynchronous unbind has completed. */ struct i915_vma_resource { … }; bool i915_vma_resource_hold(struct i915_vma_resource *vma_res, bool *lockdep_cookie); void i915_vma_resource_unhold(struct i915_vma_resource *vma_res, bool lockdep_cookie); struct i915_vma_resource *i915_vma_resource_alloc(void); void i915_vma_resource_free(struct i915_vma_resource *vma_res); struct dma_fence *i915_vma_resource_unbind(struct i915_vma_resource *vma_res, u32 *tlb); void __i915_vma_resource_init(struct i915_vma_resource *vma_res); /** * i915_vma_resource_get - Take a reference on a vma resource * @vma_res: The vma resource on which to take a reference. * * Return: The @vma_res pointer */ static inline struct i915_vma_resource *i915_vma_resource_get(struct i915_vma_resource *vma_res) { … } /** * i915_vma_resource_put - Release a reference to a struct i915_vma_resource * @vma_res: The resource */ static inline void i915_vma_resource_put(struct i915_vma_resource *vma_res) { … } /** * i915_vma_resource_init - Initialize a vma resource. * @vma_res: The vma resource to initialize * @vm: Pointer to the vm. * @pages: The pages sg-table. * @page_sizes: Page sizes of the pages. * @pages_rsgt: Pointer to a struct i915_refct_sgt of an object with * delayed destruction. * @readonly: Whether the vma should be bound read-only. * @lmem: Whether the vma points to lmem. * @mr: The memory region of the object the vma points to. * @ops: The backend ops. * @private: Bind backend private info. * @start: Offset into the address space of bind range start after padding. * @node_size: Size of the allocated range manager node minus padding. * @size: Bind size. * @guard: The size of the guard area preceding and trailing the bind. * * Initializes a vma resource allocated using i915_vma_resource_alloc(). * The reason for having separate allocate and initialize function is that * initialization may need to be performed from under a lock where * allocation is not allowed. */ static inline void i915_vma_resource_init(struct i915_vma_resource *vma_res, struct i915_address_space *vm, struct sg_table *pages, const struct i915_page_sizes *page_sizes, struct i915_refct_sgt *pages_rsgt, bool readonly, bool lmem, struct intel_memory_region *mr, const struct i915_vma_ops *ops, void *private, u64 start, u64 node_size, u64 size, u32 guard) { … } static inline void i915_vma_resource_fini(struct i915_vma_resource *vma_res) { … } int i915_vma_resource_bind_dep_sync(struct i915_address_space *vm, u64 first, u64 last, bool intr); int i915_vma_resource_bind_dep_await(struct i915_address_space *vm, struct i915_sw_fence *sw_fence, u64 first, u64 last, bool intr, gfp_t gfp); void i915_vma_resource_bind_dep_sync_all(struct i915_address_space *vm); void i915_vma_resource_module_exit(void); int i915_vma_resource_module_init(void); #endif