// SPDX-License-Identifier: MIT /* * Copyright © 2010 Daniel Vetter * Copyright © 2020 Intel Corporation */ #include <linux/slab.h> /* fault-inject.h is not standalone! */ #include <linux/fault-inject.h> #include <linux/log2.h> #include <linux/random.h> #include <linux/seq_file.h> #include <linux/stop_machine.h> #include <asm/set_memory.h> #include <asm/smp.h> #include "gt/intel_gt.h" #include "gt/intel_gt_requests.h" #include "i915_drv.h" #include "i915_gem_evict.h" #include "i915_scatterlist.h" #include "i915_trace.h" #include "i915_vgpu.h" int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj, struct sg_table *pages) { … } void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj, struct sg_table *pages) { … } /** * i915_gem_gtt_reserve - reserve a node in an address_space (GTT) * @vm: the &struct i915_address_space * @ww: An optional struct i915_gem_ww_ctx. * @node: the &struct drm_mm_node (typically i915_vma.mode) * @size: how much space to allocate inside the GTT, * must be #I915_GTT_PAGE_SIZE aligned * @offset: where to insert inside the GTT, * must be #I915_GTT_MIN_ALIGNMENT aligned, and the node * (@offset + @size) must fit within the address space * @color: color to apply to node, if this node is not from a VMA, * color must be #I915_COLOR_UNEVICTABLE * @flags: control search and eviction behaviour * * i915_gem_gtt_reserve() tries to insert the @node at the exact @offset inside * the address space (using @size and @color). If the @node does not fit, it * tries to evict any overlapping nodes from the GTT, including any * neighbouring nodes if the colors do not match (to ensure guard pages between * differing domains). See i915_gem_evict_for_node() for the gory details * on the eviction algorithm. #PIN_NONBLOCK may used to prevent waiting on * evicting active overlapping objects, and any overlapping node that is pinned * or marked as unevictable will also result in failure. * * Returns: 0 on success, -ENOSPC if no suitable hole is found, -EINTR if * asked to wait for eviction and interrupted. */ int i915_gem_gtt_reserve(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww, struct drm_mm_node *node, u64 size, u64 offset, unsigned long color, unsigned int flags) { … } static u64 random_offset(u64 start, u64 end, u64 len, u64 align) { … } /** * i915_gem_gtt_insert - insert a node into an address_space (GTT) * @vm: the &struct i915_address_space * @ww: An optional struct i915_gem_ww_ctx. * @node: the &struct drm_mm_node (typically i915_vma.node) * @size: how much space to allocate inside the GTT, * must be #I915_GTT_PAGE_SIZE aligned * @alignment: required alignment of starting offset, may be 0 but * if specified, this must be a power-of-two and at least * #I915_GTT_MIN_ALIGNMENT * @color: color to apply to node * @start: start of any range restriction inside GTT (0 for all), * must be #I915_GTT_PAGE_SIZE aligned * @end: end of any range restriction inside GTT (U64_MAX for all), * must be #I915_GTT_PAGE_SIZE aligned if not U64_MAX * @flags: control search and eviction behaviour * * i915_gem_gtt_insert() first searches for an available hole into which * is can insert the node. The hole address is aligned to @alignment and * its @size must then fit entirely within the [@start, @end] bounds. The * nodes on either side of the hole must match @color, or else a guard page * will be inserted between the two nodes (or the node evicted). If no * suitable hole is found, first a victim is randomly selected and tested * for eviction, otherwise then the LRU list of objects within the GTT * is scanned to find the first set of replacement nodes to create the hole. * Those old overlapping nodes are evicted from the GTT (and so must be * rebound before any future use). Any node that is currently pinned cannot * be evicted (see i915_vma_pin()). Similar if the node's VMA is currently * active and #PIN_NONBLOCK is specified, that node is also skipped when * searching for an eviction candidate. See i915_gem_evict_something() for * the gory details on the eviction algorithm. * * Returns: 0 on success, -ENOSPC if no suitable hole is found, -EINTR if * asked to wait for eviction and interrupted. */ int i915_gem_gtt_insert(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww, struct drm_mm_node *node, u64 size, u64 alignment, unsigned long color, u64 start, u64 end, unsigned int flags) { … } #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) #include "selftests/i915_gem_gtt.c" #endif