[Intel-gfx] [igvt-g-dev] [PATCH v2 2/3] drm/i915: Extract reserving space in the GTT to a helper
Zhenyu Wang
zhenyuw at linux.intel.com
Thu Jan 12 02:13:51 UTC 2017
On 2017.01.11 11:23:11 +0000, Chris Wilson wrote:
> Extract drm_mm_reserve_node + calling i915_gem_evict_for_node into its
> own routine so that it can be shared rather than duplicated.
>
> v2: Kerneldoc
>
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
> Cc: igvt-g-dev at lists.01.org
> Reviewed-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
> ---
Looks good for vgpu balloon change.
Acked-by: Zhenyu Wang <zhenyuw at linux.intel.com>
> drivers/gpu/drm/i915/i915_drv.h | 5 ++--
> drivers/gpu/drm/i915/i915_gem_evict.c | 33 ++++++++++++----------
> drivers/gpu/drm/i915/i915_gem_gtt.c | 51 ++++++++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/i915_gem_gtt.h | 5 ++++
> drivers/gpu/drm/i915/i915_gem_stolen.c | 7 ++---
> drivers/gpu/drm/i915/i915_trace.h | 16 +++++------
> drivers/gpu/drm/i915/i915_vgpu.c | 33 ++++++++--------------
> drivers/gpu/drm/i915/i915_vma.c | 16 ++++-------
> 8 files changed, 105 insertions(+), 61 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 89e0038ea26b..a29d138b6906 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -3468,8 +3468,9 @@ int __must_check i915_gem_evict_something(struct i915_address_space *vm,
> unsigned cache_level,
> u64 start, u64 end,
> unsigned flags);
> -int __must_check i915_gem_evict_for_vma(struct i915_vma *vma,
> - unsigned int flags);
> +int __must_check i915_gem_evict_for_node(struct i915_address_space *vm,
> + struct drm_mm_node *node,
> + unsigned int flags);
> int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle);
>
> /* belongs in i915_gem_gtt.h */
> diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
> index 6a5415e31acf..50b4645bf627 100644
> --- a/drivers/gpu/drm/i915/i915_gem_evict.c
> +++ b/drivers/gpu/drm/i915/i915_gem_evict.c
> @@ -231,7 +231,8 @@ i915_gem_evict_something(struct i915_address_space *vm,
>
> /**
> * i915_gem_evict_for_vma - Evict vmas to make room for binding a new one
> - * @target: address space and range to evict for
> + * @vm: address space to evict from
> + * @target: range (and color) to evict for
> * @flags: additional flags to control the eviction algorithm
> *
> * This function will try to evict vmas that overlap the target node.
> @@ -239,18 +240,20 @@ i915_gem_evict_something(struct i915_address_space *vm,
> * To clarify: This is for freeing up virtual address space, not for freeing
> * memory in e.g. the shrinker.
> */
> -int i915_gem_evict_for_vma(struct i915_vma *target, unsigned int flags)
> +int i915_gem_evict_for_node(struct i915_address_space *vm,
> + struct drm_mm_node *target,
> + unsigned int flags)
> {
> LIST_HEAD(eviction_list);
> struct drm_mm_node *node;
> - u64 start = target->node.start;
> - u64 end = start + target->node.size;
> + u64 start = target->start;
> + u64 end = start + target->size;
> struct i915_vma *vma, *next;
> bool check_color;
> int ret = 0;
>
> - lockdep_assert_held(&target->vm->i915->drm.struct_mutex);
> - trace_i915_gem_evict_vma(target, flags);
> + lockdep_assert_held(&vm->i915->drm.struct_mutex);
> + trace_i915_gem_evict_node(vm, target, flags);
>
> /* Retire before we search the active list. Although we have
> * reasonable accuracy in our retirement lists, we may have
> @@ -258,18 +261,18 @@ int i915_gem_evict_for_vma(struct i915_vma *target, unsigned int flags)
> * retiring.
> */
> if (!(flags & PIN_NONBLOCK))
> - i915_gem_retire_requests(target->vm->i915);
> + i915_gem_retire_requests(vm->i915);
>
> - check_color = target->vm->mm.color_adjust;
> + check_color = vm->mm.color_adjust;
> if (check_color) {
> /* Expand search to cover neighbouring guard pages (or lack!) */
> - if (start > target->vm->start)
> + if (start > vm->start)
> start -= I915_GTT_PAGE_SIZE;
> - if (end < target->vm->start + target->vm->total)
> + if (end < vm->start + vm->total)
> end += I915_GTT_PAGE_SIZE;
> }
>
> - drm_mm_for_each_node_in_range(node, &target->vm->mm, start, end) {
> + drm_mm_for_each_node_in_range(node, &vm->mm, start, end) {
> /* If we find any non-objects (!vma), we cannot evict them */
> if (node->color == I915_COLOR_UNEVICTABLE) {
> ret = -ENOSPC;
> @@ -285,12 +288,12 @@ int i915_gem_evict_for_vma(struct i915_vma *target, unsigned int flags)
> * those as well to make room for our guard pages.
> */
> if (check_color) {
> - if (vma->node.start + vma->node.size == target->node.start) {
> - if (vma->node.color == target->node.color)
> + if (vma->node.start + vma->node.size == node->start) {
> + if (vma->node.color == node->color)
> continue;
> }
> - if (vma->node.start == target->node.start + target->node.size) {
> - if (vma->node.color == target->node.color)
> + if (vma->node.start == node->start + node->size) {
> + if (vma->node.color == node->color)
> continue;
> }
> }
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 136f90ba95ab..92b907f27986 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -3555,6 +3555,57 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma)
> }
>
> /**
> + * i915_gem_gtt_reserve - reserve a node in an address_space (GTT)
> + * @vm - the &struct i915_address_space
> + * @node - the @struct drm_mm_node (typicallay 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
> + * @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 drm_mm_node *node,
> + u64 size, u64 offset, unsigned long color,
> + unsigned int flags)
> +{
> + int err;
> +
> + GEM_BUG_ON(!size);
> + GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_PAGE_SIZE));
> + GEM_BUG_ON(!IS_ALIGNED(offset, I915_GTT_MIN_ALIGNMENT));
> + GEM_BUG_ON(range_overflows(offset, size, vm->total));
> +
> + node->size = size;
> + node->start = offset;
> + node->color = color;
> +
> + err = drm_mm_reserve_node(&vm->mm, node);
> + if (err != -ENOSPC)
> + return err;
> +
> + err = i915_gem_evict_for_node(vm, node, flags);
> + if (err == 0)
> + err = drm_mm_reserve_node(&vm->mm, node);
> +
> + return err;
> +}
> +
> +/**
> * i915_gem_gtt_insert - insert a node into an address_space (GTT)
> * @vm - the &struct i915_address_space
> * @node - the @struct drm_mm_node (typicallay i915_vma.mode)
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> index 79198352a491..3e031a057f78 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> @@ -532,6 +532,11 @@ int __must_check i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj,
> void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj,
> struct sg_table *pages);
>
> +int i915_gem_gtt_reserve(struct i915_address_space *vm,
> + struct drm_mm_node *node,
> + u64 size, u64 offset, unsigned long color,
> + unsigned int flags);
> +
> int i915_gem_gtt_insert(struct i915_address_space *vm,
> struct drm_mm_node *node,
> u64 size, u64 alignment, unsigned long color,
> diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
> index e5be8e04bf3b..52dbb9bab268 100644
> --- a/drivers/gpu/drm/i915/i915_gem_stolen.c
> +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
> @@ -694,10 +694,9 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *dev_priv
> * setting up the GTT space. The actual reservation will occur
> * later.
> */
> - vma->node.start = gtt_offset;
> - vma->node.size = size;
> -
> - ret = drm_mm_reserve_node(&ggtt->base.mm, &vma->node);
> + ret = i915_gem_gtt_reserve(&ggtt->base, &vma->node,
> + size, gtt_offset, obj->cache_level,
> + 0);
> if (ret) {
> DRM_DEBUG_KMS("failed to allocate stolen GTT space\n");
> goto err_pages;
> diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
> index 18ae37c411fd..4461df5a94fe 100644
> --- a/drivers/gpu/drm/i915/i915_trace.h
> +++ b/drivers/gpu/drm/i915/i915_trace.h
> @@ -450,9 +450,9 @@ TRACE_EVENT(i915_gem_evict_vm,
> TP_printk("dev=%d, vm=%p", __entry->dev, __entry->vm)
> );
>
> -TRACE_EVENT(i915_gem_evict_vma,
> - TP_PROTO(struct i915_vma *vma, unsigned int flags),
> - TP_ARGS(vma, flags),
> +TRACE_EVENT(i915_gem_evict_node,
> + TP_PROTO(struct i915_address_space *vm, struct drm_mm_node *node, unsigned int flags),
> + TP_ARGS(vm, node, flags),
>
> TP_STRUCT__entry(
> __field(u32, dev)
> @@ -464,11 +464,11 @@ TRACE_EVENT(i915_gem_evict_vma,
> ),
>
> TP_fast_assign(
> - __entry->dev = vma->vm->i915->drm.primary->index;
> - __entry->vm = vma->vm;
> - __entry->start = vma->node.start;
> - __entry->size = vma->node.size;
> - __entry->color = vma->node.color;
> + __entry->dev = vm->i915->drm.primary->index;
> + __entry->vm = vm;
> + __entry->start = node->start;
> + __entry->size = node->size;
> + __entry->color = node->color;
> __entry->flags = flags;
> ),
>
> diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
> index dae340cfc6c7..f1ad4fbb5ba7 100644
> --- a/drivers/gpu/drm/i915/i915_vgpu.c
> +++ b/drivers/gpu/drm/i915/i915_vgpu.c
> @@ -116,22 +116,20 @@ void intel_vgt_deballoon(struct drm_i915_private *dev_priv)
> memset(&bl_info, 0, sizeof(bl_info));
> }
>
> -static int vgt_balloon_space(struct drm_mm *mm,
> +static int vgt_balloon_space(struct i915_ggtt *ggtt,
> struct drm_mm_node *node,
> unsigned long start, unsigned long end)
> {
> unsigned long size = end - start;
>
> - if (start == end)
> + if (start <= end)
> return -EINVAL;
>
> DRM_INFO("balloon space: range [ 0x%lx - 0x%lx ] %lu KiB.\n",
> start, end, size / 1024);
> -
> - node->start = start;
> - node->size = size;
> -
> - return drm_mm_reserve_node(mm, node);
> + return i915_gem_gtt_reserve(&ggtt->base, node,
> + size, start, I915_COLOR_UNEVICTABLE,
> + 0);
> }
>
> /**
> @@ -214,10 +212,8 @@ int intel_vgt_balloon(struct drm_i915_private *dev_priv)
>
> /* Unmappable graphic memory ballooning */
> if (unmappable_base > ggtt->mappable_end) {
> - ret = vgt_balloon_space(&ggtt->base.mm,
> - &bl_info.space[2],
> - ggtt->mappable_end,
> - unmappable_base);
> + ret = vgt_balloon_space(ggtt, &bl_info.space[2],
> + ggtt->mappable_end, unmappable_base);
>
> if (ret)
> goto err;
> @@ -228,18 +224,15 @@ int intel_vgt_balloon(struct drm_i915_private *dev_priv)
> * because it is reserved to the guard page.
> */
> if (unmappable_end < ggtt_end - PAGE_SIZE) {
> - ret = vgt_balloon_space(&ggtt->base.mm,
> - &bl_info.space[3],
> - unmappable_end,
> - ggtt_end - PAGE_SIZE);
> + ret = vgt_balloon_space(ggtt, &bl_info.space[3],
> + unmappable_end, ggtt_end - PAGE_SIZE);
> if (ret)
> goto err;
> }
>
> /* Mappable graphic memory ballooning */
> if (mappable_base > ggtt->base.start) {
> - ret = vgt_balloon_space(&ggtt->base.mm,
> - &bl_info.space[0],
> + ret = vgt_balloon_space(ggtt, &bl_info.space[0],
> ggtt->base.start, mappable_base);
>
> if (ret)
> @@ -247,10 +240,8 @@ int intel_vgt_balloon(struct drm_i915_private *dev_priv)
> }
>
> if (mappable_end < ggtt->mappable_end) {
> - ret = vgt_balloon_space(&ggtt->base.mm,
> - &bl_info.space[1],
> - mappable_end,
> - ggtt->mappable_end);
> + ret = vgt_balloon_space(ggtt, &bl_info.space[1],
> + mappable_end, ggtt->mappable_end);
>
> if (ret)
> goto err;
> diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
> index df3750d4c907..b74eeb73ae41 100644
> --- a/drivers/gpu/drm/i915/i915_vma.c
> +++ b/drivers/gpu/drm/i915/i915_vma.c
> @@ -419,17 +419,11 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
> goto err_unpin;
> }
>
> - vma->node.start = offset;
> - vma->node.size = size;
> - vma->node.color = obj->cache_level;
> - ret = drm_mm_reserve_node(&vma->vm->mm, &vma->node);
> - if (ret) {
> - ret = i915_gem_evict_for_vma(vma, flags);
> - if (ret == 0)
> - ret = drm_mm_reserve_node(&vma->vm->mm, &vma->node);
> - if (ret)
> - goto err_unpin;
> - }
> + ret = i915_gem_gtt_reserve(vma->vm, &vma->node,
> + size, offset, obj->cache_level,
> + flags);
> + if (ret)
> + goto err_unpin;
> } else {
> ret = i915_gem_gtt_insert(vma->vm, &vma->node,
> size, alignment, obj->cache_level,
> --
> 2.11.0
>
> _______________________________________________
> igvt-g-dev mailing list
> igvt-g-dev at lists.01.org
> https://lists.01.org/mailman/listinfo/igvt-g-dev
--
Open Source Technology Center, Intel ltd.
$gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 163 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/intel-gfx/attachments/20170112/5eeae6be/attachment-0001.sig>
More information about the Intel-gfx
mailing list