[Mesa-dev] [PATCH] anv: Always set the reloc value to match the presumed_offset

Jason Ekstrand jason at jlekstrand.net
Fri May 5 19:33:54 UTC 2017


On Fri, May 5, 2017 at 5:09 AM, Chris Wilson <chris at chris-wilson.co.uk>
wrote:

> It is a requirement, not just of using the NO_RELOC mode, that all
> relocation values in the execobjects match their reloc.presumed_offset,
> as the kernel will skip performing *any* relocation if the presumed_offset
> matches the target object. As anv is setting unknown relocations to -1
> irrespective of the actual value, if the kernel placed the target at -1
> (i.e. 0xfffffffff000 for 48bit GTT), it would happily skip the relocation.
> To prevent this, we need to always do the userspace relocations to ensure
> the values match. To improve further, set the unknown object offset to 0
> (a valid location) on the offchance it is available and the migration
> skipped.
>

Is this a real issue?  I specifically chose -1 because it *wasn't*
page-aligned.  I don't think the kernel whacks off the bottom 12 bits
before doing the comparison to determine whether or not the relocation
needs to happen.

--Jason


> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Jason Ekstrand <jason.ekstrand at intel.com>
> ---
>  src/intel/vulkan/anv_batch_chain.c | 97 ++++++++++++------------------
> --------
>  src/intel/vulkan/anv_private.h     |  2 +-
>  2 files changed, 32 insertions(+), 67 deletions(-)
>
> diff --git a/src/intel/vulkan/anv_batch_chain.c
> b/src/intel/vulkan/anv_batch_chain.c
> index 0529f22b84..46c4ce6efb 100644
> --- a/src/intel/vulkan/anv_batch_chain.c
> +++ b/src/intel/vulkan/anv_batch_chain.c
> @@ -1205,28 +1205,10 @@ anv_reloc_list_apply(struct anv_device *device,
>   * probably the fastest mechanism for doing relocations since the kernel
> would
>   * have to make a full copy of all the relocations lists.
>   */
> -static bool
> +static void
>  relocate_cmd_buffer(struct anv_cmd_buffer *cmd_buffer,
>                      struct anv_execbuf *exec)
>  {
> -   static int userspace_relocs = -1;
> -   if (userspace_relocs < 0)
> -      userspace_relocs = env_var_as_boolean("ANV_USERSPACE_RELOCS",
> true);
> -   if (!userspace_relocs)
> -      return false;
> -
> -   /* First, we have to check to see whether or not we can even do the
> -    * relocation.  New buffers which have never been submitted to the
> kernel
> -    * don't have a valid offset so we need to let the kernel do
> relocations so
> -    * that we can get offsets for them.  On future execbuf2 calls, those
> -    * buffers will have offsets and we will be able to skip relocating.
> -    * Invalid offsets are indicated by anv_bo::offset == (uint64_t)-1.
> -    */
> -   for (uint32_t i = 0; i < exec->bo_count; i++) {
> -      if (exec->bos[i]->offset == (uint64_t)-1)
> -         return false;
> -   }
> -
>     /* Since surface states are shared between command buffers and we don't
>      * know what order they will be submitted to the kernel, we don't know
>      * what address is actually written in the surface state object at any
> @@ -1248,8 +1230,6 @@ relocate_cmd_buffer(struct anv_cmd_buffer
> *cmd_buffer,
>
>     for (uint32_t i = 0; i < exec->bo_count; i++)
>        exec->objects[i].offset = exec->bos[i]->offset;
> -
> -   return true;
>  }
>
>  static VkResult
> @@ -1334,55 +1314,40 @@ setup_execbuf_for_cmd_buffer(struct anv_execbuf
> *execbuf,
>        .buffer_count = execbuf->bo_count,
>        .batch_start_offset = 0,
>        .batch_len = batch->next - batch->start,
> -      .cliprects_ptr = 0,
> -      .num_cliprects = 0,
> -      .DR1 = 0,
> -      .DR4 = 0,
> -      .flags = I915_EXEC_HANDLE_LUT | I915_EXEC_RENDER |
> -               I915_EXEC_CONSTANTS_REL_GENERAL,
> +      .flags =
> +             I915_EXEC_RENDER |
> +             I915_EXEC_HANDLE_LUT |
> +             I915_EXEC_NO_RELOC |
> +             I915_EXEC_CONSTANTS_REL_GENERAL,
>        .rsvd1 = cmd_buffer->device->context_id,
>        .rsvd2 = 0,
>     };
>
> -   if (relocate_cmd_buffer(cmd_buffer, execbuf)) {
> -      /* If we were able to successfully relocate everything, tell the
> kernel
> -       * that it can skip doing relocations. The requirement for using
> -       * NO_RELOC is:
> -       *
> -       *  1) The addresses written in the objects must match the
> corresponding
> -       *     reloc.presumed_offset which in turn must match the
> corresponding
> -       *     execobject.offset.
> -       *
> -       *  2) To avoid stalling, execobject.offset should match the current
> -       *     address of that object within the active context.
> -       *
> -       * In order to satisfy all of the invariants that make userspace
> -       * relocations to be safe (see relocate_cmd_buffer()), we need to
> -       * further ensure that the addresses we use match those used by the
> -       * kernel for the most recent execbuf2.
> -       *
> -       * The kernel may still choose to do relocations anyway if
> something has
> -       * moved in the GTT. In this case, the relocation list still needs
> to be
> -       * valid.  All relocations on the batch buffers are already valid
> and
> -       * kept up-to-date.  For surface state relocations, by applying the
> -       * relocations in relocate_cmd_buffer, we ensured that the address
> in
> -       * the RENDER_SURFACE_STATE matches presumed_offset, so it should be
> -       * safe for the kernel to relocate them as needed.
> -       */
> -      execbuf->execbuf.flags |= I915_EXEC_NO_RELOC;
> -   } else {
> -      /* In the case where we fall back to doing kernel relocations, we
> need
> -       * to ensure that the relocation list is valid.  All relocations on
> the
> -       * batch buffers are already valid and kept up-to-date.  Since
> surface
> -       * states are shared between command buffers and we don't know what
> -       * order they will be submitted to the kernel, we don't know what
> -       * address is actually written in the surface state object at any
> given
> -       * time.  The only option is to set a bogus presumed offset and let
> the
> -       * kernel relocate them.
> -       */
> -      for (size_t i = 0; i < cmd_buffer->surface_relocs.num_relocs; i++)
> -         cmd_buffer->surface_relocs.relocs[i].presumed_offset = -1;
> -   }
> +   /* If we were able to successfully relocate everything, tell the kernel
> +    * that it can skip doing relocations. The requirement for using
> +    * NO_RELOC is:
> +    *
> +    *  1) The addresses written in the objects must match the
> corresponding
> +    *     reloc.presumed_offset which in turn must match the corresponding
> +    *     execobject.offset.
> +    *
> +    *  2) To avoid stalling, execobject.offset should match the current
> +    *     address of that object within the active context.
> +    *
> +    * In order to satisfy all of the invariants that make userspace
> +    * relocations to be safe (see relocate_cmd_buffer()), we need to
> +    * further ensure that the addresses we use match those used by the
> +    * kernel for the most recent execbuf2.
> +    *
> +    * The kernel may still choose to do relocations anyway if something
> has
> +    * moved in the GTT. In this case, the relocation list still needs to
> be
> +    * valid.  All relocations on the batch buffers are already valid and
> +    * kept up-to-date.  For surface state relocations, by applying the
> +    * relocations in relocate_cmd_buffer, we ensured that the address in
> +    * the RENDER_SURFACE_STATE matches presumed_offset, so it should be
> +    * safe for the kernel to relocate them as needed.
> +    */
> +   relocate_cmd_buffer(cmd_buffer, execbuf);
>
>     return VK_SUCCESS;
>  }
> diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_
> private.h
> index 21d0ac2122..f9381fb8eb 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -400,7 +400,7 @@ anv_bo_init(struct anv_bo *bo, uint32_t gem_handle,
> uint64_t size)
>  {
>     bo->gem_handle = gem_handle;
>     bo->index = 0;
> -   bo->offset = -1;
> +   bo->offset = 0;
>     bo->size = size;
>     bo->map = NULL;
>     bo->flags = 0;
> --
> 2.11.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20170505/3cbda795/attachment.html>


More information about the mesa-dev mailing list