/** * struct drm_gpusvm_ops - Operations structure for GPU SVM * * This structure defines the operations for GPU Shared Virtual Memory (SVM). * These operations are provided by the GPU driver to manage SVM ranges and * notifiers.
*/ struct drm_gpusvm_ops { /** * @notifier_alloc: Allocate a GPU SVM notifier (optional) * * Allocate a GPU SVM notifier. * * Return: Pointer to the allocated GPU SVM notifier on success, NULL on failure.
*/ struct drm_gpusvm_notifier *(*notifier_alloc)(void);
/** * @notifier_free: Free a GPU SVM notifier (optional) * @notifier: Pointer to the GPU SVM notifier to be freed * * Free a GPU SVM notifier.
*/ void (*notifier_free)(struct drm_gpusvm_notifier *notifier);
/** * @range_alloc: Allocate a GPU SVM range (optional) * @gpusvm: Pointer to the GPU SVM * * Allocate a GPU SVM range. * * Return: Pointer to the allocated GPU SVM range on success, NULL on failure.
*/ struct drm_gpusvm_range *(*range_alloc)(struct drm_gpusvm *gpusvm);
/** * @range_free: Free a GPU SVM range (optional) * @range: Pointer to the GPU SVM range to be freed * * Free a GPU SVM range.
*/ void (*range_free)(struct drm_gpusvm_range *range);
/** * @invalidate: Invalidate GPU SVM notifier (required) * @gpusvm: Pointer to the GPU SVM * @notifier: Pointer to the GPU SVM notifier * @mmu_range: Pointer to the mmu_notifier_range structure * * Invalidate the GPU page tables. It can safely walk the notifier range * RB tree/list in this function. Called while holding the notifier lock.
*/ void (*invalidate)(struct drm_gpusvm *gpusvm, struct drm_gpusvm_notifier *notifier, conststruct mmu_notifier_range *mmu_range);
};
/** * struct drm_gpusvm_notifier - Structure representing a GPU SVM notifier * * @gpusvm: Pointer to the GPU SVM structure * @notifier: MMU interval notifier * @itree: Interval tree node for the notifier (inserted in GPU SVM) * @entry: List entry to fast interval tree traversal * @root: Cached root node of the RB tree containing ranges * @range_list: List head containing of ranges in the same order they appear in * interval tree. This is useful to keep iterating ranges while * doing modifications to RB tree. * @flags: Flags for notifier * @flags.removed: Flag indicating whether the MMU interval notifier has been * removed * * This structure represents a GPU SVM notifier.
*/ struct drm_gpusvm_notifier { struct drm_gpusvm *gpusvm; struct mmu_interval_notifier notifier; struct interval_tree_node itree; struct list_head entry; struct rb_root_cached root; struct list_head range_list; struct {
u32 removed : 1;
} flags;
};
/** * struct drm_gpusvm_range_flags - Structure representing a GPU SVM range flags * * @migrate_devmem: Flag indicating whether the range can be migrated to device memory * @unmapped: Flag indicating if the range has been unmapped * @partial_unmap: Flag indicating if the range has been partially unmapped * @has_devmem_pages: Flag indicating if the range has devmem pages * @has_dma_mapping: Flag indicating if the range has a DMA mapping * @__flags: Flags for range in u16 form (used for READ_ONCE)
*/ struct drm_gpusvm_range_flags { union { struct { /* All flags below must be set upon creation */
u16 migrate_devmem : 1; /* All flags below must be set / cleared under notifier lock */
u16 unmapped : 1;
u16 partial_unmap : 1;
u16 has_devmem_pages : 1;
u16 has_dma_mapping : 1;
};
u16 __flags;
};
};
/** * struct drm_gpusvm_range - Structure representing a GPU SVM range * * @gpusvm: Pointer to the GPU SVM structure * @notifier: Pointer to the GPU SVM notifier * @refcount: Reference count for the range * @itree: Interval tree node for the range (inserted in GPU SVM notifier) * @entry: List entry to fast interval tree traversal * @notifier_seq: Notifier sequence number of the range's pages * @dma_addr: Device address array * @dpagemap: The struct drm_pagemap of the device pages we're dma-mapping. * Note this is assuming only one drm_pagemap per range is allowed. * @flags: Flags for range * * This structure represents a GPU SVM range used for tracking memory ranges * mapped in a DRM device.
*/ struct drm_gpusvm_range { struct drm_gpusvm *gpusvm; struct drm_gpusvm_notifier *notifier; struct kref refcount; struct interval_tree_node itree; struct list_head entry; unsignedlong notifier_seq; struct drm_pagemap_device_addr *dma_addr; struct drm_pagemap *dpagemap; struct drm_gpusvm_range_flags flags;
};
/** * struct drm_gpusvm - GPU SVM structure * * @name: Name of the GPU SVM * @drm: Pointer to the DRM device structure * @mm: Pointer to the mm_struct for the address space * @device_private_page_owner: Device private pages owner * @mm_start: Start address of GPU SVM * @mm_range: Range of the GPU SVM * @notifier_size: Size of individual notifiers * @ops: Pointer to the operations structure for GPU SVM * @chunk_sizes: Pointer to the array of chunk sizes used in range allocation. * Entries should be powers of 2 in descending order. * @num_chunks: Number of chunks * @notifier_lock: Read-write semaphore for protecting notifier operations * @root: Cached root node of the Red-Black tree containing GPU SVM notifiers * @notifier_list: list head containing of notifiers in the same order they * appear in interval tree. This is useful to keep iterating * notifiers while doing modifications to RB tree. * * This structure represents a GPU SVM (Shared Virtual Memory) used for tracking * memory ranges mapped in a DRM (Direct Rendering Manager) device. * * No reference counting is provided, as this is expected to be embedded in the * driver VM structure along with the struct drm_gpuvm, which handles reference * counting.
*/ struct drm_gpusvm { constchar *name; struct drm_device *drm; struct mm_struct *mm; void *device_private_page_owner; unsignedlong mm_start; unsignedlong mm_range; unsignedlong notifier_size; conststruct drm_gpusvm_ops *ops; constunsignedlong *chunk_sizes; int num_chunks; struct rw_semaphore notifier_lock; struct rb_root_cached root; struct list_head notifier_list; #ifdef CONFIG_LOCKDEP /** * @lock_dep_map: Annotates drm_gpusvm_range_find_or_insert and * drm_gpusvm_range_remove with a driver provided lock.
*/ struct lockdep_map *lock_dep_map; #endif
};
/** * struct drm_gpusvm_ctx - DRM GPU SVM context * * @check_pages_threshold: Check CPU pages for present if chunk is less than or * equal to threshold. If not present, reduce chunk * size. * @timeslice_ms: The timeslice MS which in minimum time a piece of memory * remains with either exclusive GPU or CPU access. * @in_notifier: entering from a MMU notifier * @read_only: operating on read-only memory * @devmem_possible: possible to use device memory * @devmem_only: use only device memory * * Context that is DRM GPUSVM is operating in (i.e. user arguments).
*/ struct drm_gpusvm_ctx { unsignedlong check_pages_threshold; unsignedlong timeslice_ms; unsignedint in_notifier :1; unsignedint read_only :1; unsignedint devmem_possible :1; unsignedint devmem_only :1;
};
#ifdef CONFIG_LOCKDEP /** * drm_gpusvm_driver_set_lock() - Set the lock protecting accesses to GPU SVM * @gpusvm: Pointer to the GPU SVM structure. * @lock: the lock used to protect the gpuva list. The locking primitive * must contain a dep_map field. * * Call this to annotate drm_gpusvm_range_find_or_insert and * drm_gpusvm_range_remove.
*/ #define drm_gpusvm_driver_set_lock(gpusvm, lock) \ do { \ if (!WARN((gpusvm)->lock_dep_map, \ "GPUSVM range lock should be set only once."))\
(gpusvm)->lock_dep_map = &(lock)->dep_map; \
} while (0) #else #define drm_gpusvm_driver_set_lock(gpusvm, lock) do {} while (0) #endif
/** * __drm_gpusvm_range_next() - Get the next GPU SVM range in the list * @range: a pointer to the current GPU SVM range * * Return: A pointer to the next drm_gpusvm_range if available, or NULL if the * current range is the last one or if the input range is NULL.
*/ staticinlinestruct drm_gpusvm_range *
__drm_gpusvm_range_next(struct drm_gpusvm_range *range)
{ if (range && !list_is_last(&range->entry,
&range->notifier->range_list)) return list_next_entry(range, entry);
return NULL;
}
/** * drm_gpusvm_for_each_range() - Iterate over GPU SVM ranges in a notifier * @range__: Iterator variable for the ranges. If set, it indicates the start of * the iterator. If NULL, call drm_gpusvm_range_find() to get the range. * @notifier__: Pointer to the GPU SVM notifier * @start__: Start address of the range * @end__: End address of the range * * This macro is used to iterate over GPU SVM ranges in a notifier. It is safe * to use while holding the driver SVM lock or the notifier lock.
*/ #define drm_gpusvm_for_each_range(range__, notifier__, start__, end__) \ for ((range__) = (range__) ?: \
drm_gpusvm_range_find((notifier__), (start__), (end__)); \
(range__) && (drm_gpusvm_range_start(range__) < (end__)); \
(range__) = __drm_gpusvm_range_next(range__))
#endif/* __DRM_GPUSVM_H__ */
Messung V0.5
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.