/* 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 {
/**
* The sg mask of the pages sg_table . i . e the mask of
* the lengths for each sg entry .
*/
unsigned int phys;
/**
* The gtt page sizes we are allowed to use given the
* sg mask and the supported page sizes . This will
* express the smallest unit we can use for the whole
* object , as well as the larger sizes we may be able
* to use opportunistically .
*/
unsigned int sg;
};
/**
* 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 sg_table *pages;
struct i915_page_sizes page_sizes;
struct i915_refct_sgt *pages_rsgt;
bool readonly:1 ;
bool lmem:1 ;
};
/**
* 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 {
struct dma_fence unbind_fence;
/* See above for description of the lock. */
spinlock_t lock;
refcount_t hold_count;
struct work_struct work;
struct i915_sw_fence chain;
struct rb_node rb;
u64 __subtree_last;
struct i915_address_space *vm;
intel_wakeref_t wakeref;
/**
* @ bi : 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
*/
struct i915_vma_bindinfo bi;
#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
struct intel_memory_region *mr;
#endif
const struct i915_vma_ops *ops;
void *private ;
u64 start;
u64 node_size;
u64 vma_size;
u32 guard;
u32 page_sizes_gtt;
u32 bound_flags;
bool allocated:1 ;
bool immediate_unbind:1 ;
bool needs_wakeref:1 ;
bool skip_pte_rewrite:1 ;
u32 *tlb;
};
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)
{
dma_fence_get(&vma_res->unbind_fence);
return 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)
{
dma_fence_put(&vma_res->unbind_fence);
}
/**
* 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)
{
__i915_vma_resource_init(vma_res);
vma_res->vm = vm;
vma_res->bi.pages = pages;
vma_res->bi.page_sizes = *page_sizes;
if (pages_rsgt)
vma_res->bi.pages_rsgt = i915_refct_sgt_get(pages_rsgt);
vma_res->bi.readonly = readonly;
vma_res->bi.lmem = lmem;
#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
vma_res->mr = mr;
#endif
vma_res->ops = ops;
vma_res->private = private ;
vma_res->start = start;
vma_res->node_size = node_size;
vma_res->vma_size = size;
vma_res->guard = guard;
}
static inline void i915_vma_resource_fini(struct i915_vma_resource *vma_res)
{
GEM_BUG_ON(refcount_read(&vma_res->hold_count) != 1 );
if (vma_res->bi.pages_rsgt)
i915_refct_sgt_put(vma_res->bi.pages_rsgt);
i915_sw_fence_fini(&vma_res->chain);
}
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
Messung V0.5 in Prozent C=97 H=100 G=98
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland