[Intel-gfx] [RFC PATCH 092/162] drm/i915/uapi: introduce drm_i915_gem_create_ext

Chris Wilson chris at chris-wilson.co.uk
Fri Nov 27 13:25:40 UTC 2020


Quoting Matthew Auld (2020-11-27 12:06:08)
> Same old gem_create but with now with extensions support. This is needed
> to support various upcoming usecases. For now we use the extensions
> mechanism to support setting an immutable-priority-list of potential
> placements, at creation time.
> 
> If we wish to set the placements/regions we can simply do:
> 
> struct drm_i915_gem_object_param region_param = { … }; /* Unchanged */
> struct drm_i915_gem_create_ext_setparam setparam_region = {
>     .base = { .name = I915_GEM_CREATE_EXT_SETPARAM },
>     .param = region_param,
> }
> 
> struct drm_i915_gem_create_ext create_ext = {
>         .size = 16 * PAGE_SIZE,
>         .extensions = (uintptr_t)&setparam_region,
> };
> int err = ioctl(fd, DRM_IOCTL_I915_GEM_CREATE_EXT, &create_ext);
> if (err) ...
> 
> If we use the normal gem_create or gem_create_ext without the
> extensions/placements then we still get the old behaviour with only
> placing the object in system memory.
> 
> One important change here is the returned size will now be rounded up to
> the correct size, depending on the list of placements, where we might
> have minimum page-size restrictions on some platforms when dealing with
> device local-memory.
> 
> Also, we still keep around the i915_gem_object_setparam ioctl, although
> that is now restricted by the placement list(i.e we are not allowed to
> add new placements), and longer term that will be going away wrt setting
> placements, since it was deemed that the kernel doesn't need to support
> a dynamic list of placements, which is now solidified by this uapi
> change.
> 
> Testcase: igt/gem_create/create-ext-placement-sanity-check
> Testcase: igt/gem_create/create-ext-placement-each
> Testcase: igt/gem_create/create-ext-placement-all
> Signed-off-by: Matthew Auld <matthew.auld at intel.com>
> Signed-off-by: CQ Tang <cq.tang at intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
> ---
>  drivers/gpu/drm/i915/Makefile                 |   1 +
>  drivers/gpu/drm/i915/gem/i915_gem_create.c    | 398 ++++++++++++++++++
>  drivers/gpu/drm/i915/gem/i915_gem_object.c    |   2 +
>  .../gpu/drm/i915/gem/i915_gem_object_types.h  |   9 +
>  drivers/gpu/drm/i915/gem/i915_gem_region.c    |   4 +
>  drivers/gpu/drm/i915/i915_drv.c               |   2 +-
>  drivers/gpu/drm/i915/i915_gem.c               | 103 +----
>  drivers/gpu/drm/i915/intel_memory_region.c    |  20 +
>  drivers/gpu/drm/i915/intel_memory_region.h    |   4 +
>  include/uapi/drm/i915_drm.h                   |  60 +++
>  10 files changed, 500 insertions(+), 103 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_create.c
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index ec361d61230b..3955134feca7 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -134,6 +134,7 @@ gem-y += \
>         gem/i915_gem_clflush.o \
>         gem/i915_gem_client_blt.o \
>         gem/i915_gem_context.o \
> +       gem/i915_gem_create.o \
>         gem/i915_gem_dmabuf.o \
>         gem/i915_gem_domain.o \
>         gem/i915_gem_execbuffer.o \
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> new file mode 100644
> index 000000000000..6f6dd4f1ce7e
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> @@ -0,0 +1,398 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2020 Intel Corporation
> + */
> +
> +#include "gem/i915_gem_ioctls.h"
> +#include "gem/i915_gem_lmem.h"
> +#include "gem/i915_gem_object_blt.h"
> +#include "gem/i915_gem_region.h"
> +
> +#include "i915_drv.h"
> +#include "i915_user_extensions.h"
> +
> +static u32 max_page_size(struct intel_memory_region **placements,
> +                        int n_placements)
> +{
> +       u32 max_page_size = 0;
> +       int i;
> +
> +       for (i = 0; i < n_placements; ++i) {
> +               max_page_size = max_t(u32, max_page_size,
> +                                     placements[i]->min_page_size);
> +       }
> +
> +       GEM_BUG_ON(!max_page_size);
> +       return max_page_size;
> +}
> +
> +static int
> +i915_gem_create(struct drm_file *file,
> +               struct intel_memory_region **placements,
> +               int n_placements,
> +               u64 *size_p,
> +               u32 *handle_p)
> +{
> +       struct drm_i915_gem_object *obj;
> +       u32 handle;
> +       u64 size;
> +       int ret;
> +
> +       size = round_up(*size_p, max_page_size(placements, n_placements));
> +       if (size == 0)
> +               return -EINVAL;
> +
> +       /* For most of the ABI (e.g. mmap) we think in system pages */
> +       GEM_BUG_ON(!IS_ALIGNED(size, PAGE_SIZE));
> +
> +       /* Allocate the new object */
> +       obj = i915_gem_object_create_region(placements[0], size, 0);
> +       if (IS_ERR(obj))
> +               return PTR_ERR(obj);
> +
> +       if (i915_gem_object_is_lmem(obj)) {
> +               struct intel_gt *gt = obj->mm.region->gt;
> +               struct intel_context *ce = gt->engine[BCS0]->blitter_context;
> +
> +               /*
> +                * XXX: We really want to move this to get_pages(), but we
> +                * require grabbing the BKL for the blitting operation which is
> +                * annoying. In the pipeline is support for async get_pages()
> +                * which should fit nicely for this. Also note that the actual
> +                * clear should be done async(we currently do an object_wait
> +                * which is pure garbage), we just need to take care if
> +                * userspace opts of implicit sync for the execbuf, to avoid any
> +                * potential info leak.
> +                */

Not just XXX, but the design should be completed first.
-Chris


More information about the dri-devel mailing list