[PATCH v3 30/37] drm/i915: Introduce DRM_I915_GEM_MMAP_OFFSET

Chris Wilson chris at chris-wilson.co.uk
Sat Aug 10 11:32:38 UTC 2019


Quoting Matthew Auld (2019-08-09 23:26:36)
> From: Abdiel Janulgue <abdiel.janulgue at linux.intel.com>
> 
> Add a new CPU mmap implementation that allows multiple fault handlers
> that depends on the object's backing pages.
> 
> Note that we multiplex mmap_gtt and mmap_offset through the same ioctl,
> and use the zero extending behaviour of drm to differentiate between
> them, when we inspect the flags.
> 
> Signed-off-by: Abdiel Janulgue <abdiel.janulgue at linux.intel.com>
> Signed-off-by: Matthew Auld <matthew.auld at intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_ioctls.h    |  2 ++
>  drivers/gpu/drm/i915/gem/i915_gem_mman.c      | 30 ++++++++++++++++++
>  .../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 ++
>  drivers/gpu/drm/i915/i915_drv.c               |  2 +-
>  drivers/gpu/drm/i915/i915_getparam.c          |  1 +
>  include/uapi/drm/i915_drm.h                   | 31 +++++++++++++++++++
>  6 files changed, 68 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
> index ddc7f2a52b3e..5abd5b2172f2 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
> @@ -30,6 +30,8 @@ int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
>                         struct drm_file *file);
>  int i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
>                             struct drm_file *file);
> +int i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
> +                              struct drm_file *file_priv);

mmap_offset_ioctl is replacing mmap_gtt_ioctl, you don't need to keep
the old one public.

(Or vice versa apparently.)

>  int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
>                          struct drm_file *file);
>  int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> index d4a9d59803a7..a62657a1f011 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
> @@ -538,12 +538,42 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
>                         struct drm_file *file)
>  {
>         struct drm_i915_gem_mmap_offset *args = data;
> +       struct drm_i915_private *i915 = to_i915(dev);
> +
> +       if (args->flags & I915_MMAP_OFFSET_FLAGS)
> +               return i915_gem_mmap_offset_ioctl(dev, data, file);
> +
> +       if (!HAS_MAPPABLE_APERTURE(i915)) {
> +               DRM_ERROR("No aperture, cannot mmap via legacy GTT\n");
> +               return -ENODEV;
> +       }
>  
>         return __assign_gem_object_mmap_data(file, args->handle,
>                                              I915_MMAP_TYPE_GTT,
>                                              &args->offset);
>  }
>  
> +int i915_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
> +                              struct drm_file *file)
> +{
> +       struct drm_i915_gem_mmap_offset *args = data;
> +       enum i915_mmap_type type;
> +
> +       if ((args->flags & (I915_MMAP_OFFSET_WC | I915_MMAP_OFFSET_WB)) &&
> +           !boot_cpu_has(X86_FEATURE_PAT))
> +               return -ENODEV;
> +
> +       if (args->flags & I915_MMAP_OFFSET_WC)
> +               type = I915_MMAP_TYPE_OFFSET_WC;
> +       else if (args->flags & I915_MMAP_OFFSET_WB)
> +               type = I915_MMAP_TYPE_OFFSET_WB;
> +       else if (args->flags & I915_MMAP_OFFSET_UC)
> +               type = I915_MMAP_TYPE_OFFSET_UC;
> +
> +       return __assign_gem_object_mmap_data(file, args->handle, type,
> +                                            &args->offset);
> +}
> +
>  void i915_mmap_offset_object_release(struct kref *ref)
>  {
>         struct i915_mmap_offset *mmo = container_of(ref,
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> index a3745f7d57a1..4ea78d3c92a9 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> @@ -64,6 +64,9 @@ struct drm_i915_gem_object_ops {
>  
>  enum i915_mmap_type {
>         I915_MMAP_TYPE_GTT = 0,
> +       I915_MMAP_TYPE_OFFSET_WC,
> +       I915_MMAP_TYPE_OFFSET_WB,
> +       I915_MMAP_TYPE_OFFSET_UC,
>  };
>  
>  struct i915_mmap_offset {
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index fcee06ed3469..cf390092c927 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -2710,7 +2710,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
>         DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_RENDER_ALLOW),
>         DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_RENDER_ALLOW),
>         DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW),
> -       DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_RENDER_ALLOW),
> +       DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_OFFSET, i915_gem_mmap_gtt_ioctl, DRM_RENDER_ALLOW),
>         DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_RENDER_ALLOW),
>         DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_RENDER_ALLOW),
>         DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling_ioctl, DRM_RENDER_ALLOW),
> diff --git a/drivers/gpu/drm/i915/i915_getparam.c b/drivers/gpu/drm/i915/i915_getparam.c
> index 5d9101376a3d..28120249a250 100644
> --- a/drivers/gpu/drm/i915/i915_getparam.c
> +++ b/drivers/gpu/drm/i915/i915_getparam.c
> @@ -130,6 +130,7 @@ int i915_getparam_ioctl(struct drm_device *dev, void *data,
>         case I915_PARAM_HAS_EXEC_BATCH_FIRST:
>         case I915_PARAM_HAS_EXEC_FENCE_ARRAY:
>         case I915_PARAM_HAS_EXEC_SUBMIT_FENCE:
> +       case I915_PARAM_MMAP_OFFSET_VERSION:

Funny. You do realise this is just MMAP_GT_VERSION for the new struct +
ABI.

>                 /* For the time being all of these are always true;
>                  * if some supported hardware does not have one of these
>                  * features this value needs to be provided from
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index 469dc512cca3..fb84aed10825 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -359,6 +359,7 @@ typedef struct _drm_i915_sarea {
>  #define DRM_I915_QUERY                 0x39
>  #define DRM_I915_GEM_VM_CREATE         0x3a
>  #define DRM_I915_GEM_VM_DESTROY                0x3b
> +#define DRM_I915_GEM_MMAP_OFFSET       DRM_I915_GEM_MMAP_GTT
>  /* Must be kept compact -- no holes */
>  
>  #define DRM_IOCTL_I915_INIT            DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
> @@ -421,6 +422,7 @@ typedef struct _drm_i915_sarea {
>  #define DRM_IOCTL_I915_QUERY                   DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query)
>  #define DRM_IOCTL_I915_GEM_VM_CREATE   DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_CREATE, struct drm_i915_gem_vm_control)
>  #define DRM_IOCTL_I915_GEM_VM_DESTROY  DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_VM_DESTROY, struct drm_i915_gem_vm_control)
> +#define DRM_IOCTL_I915_GEM_MMAP_OFFSET         DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP_OFFSET, struct drm_i915_gem_mmap_offset)
>  
>  /* Allow drivers to submit batchbuffers directly to hardware, relying
>   * on the security mechanisms provided by hardware.
> @@ -611,6 +613,10 @@ typedef struct drm_i915_irq_wait {
>   * See I915_EXEC_FENCE_OUT and I915_EXEC_FENCE_SUBMIT.
>   */
>  #define I915_PARAM_HAS_EXEC_SUBMIT_FENCE 53
> +
> +/* Mmap offset ioctl */
> +#define I915_PARAM_MMAP_OFFSET_VERSION 54

No, it's just MMAP_GTT_VERSION.

>  /* Must be kept compact -- no holes and well documented */
>  
>  typedef struct drm_i915_getparam {
> @@ -786,6 +792,31 @@ struct drm_i915_gem_mmap_gtt {
>         __u64 offset;
>  };
>  
> +struct drm_i915_gem_mmap_offset {
> +       /** Handle for the object being mapped. */
> +       __u32 handle;
> +       __u32 pad;
> +       /**
> +        * Fake offset to use for subsequent mmap call
> +        *
> +        * This is a fixed-size type for 32/64 compatibility.
> +        */
> +       __u64 offset;
> +
> +       /**
> +        * Flags for extended behaviour.
> +        *
> +        * It is mandatory that either one of the _WC/_WB flags
> +        * should be passed here.
> +        */
> +       __u64 flags;
> +#define I915_MMAP_OFFSET_WC (1 << 0)
> +#define I915_MMAP_OFFSET_WB (1 << 1)
> +#define I915_MMAP_OFFSET_UC (1 << 2)
> +#define I915_MMAP_OFFSET_FLAGS \
> +       (I915_MMAP_OFFSET_WC | I915_MMAP_OFFSET_WB | I915_MMAP_OFFSET_UC)

You missed the extension struct.

> +};
> +
>  struct drm_i915_gem_set_domain {
>         /** Handle for the object */
>         __u32 handle;
> -- 
> 2.20.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


More information about the dri-devel mailing list