On Thu, Nov 14, 2019 at 09:09:08PM +0200, Abdiel Janulgue wrote:
This is really just an alias of mmap_gtt. The 'mmap offset' nomenclature
comes from the value returned by this ioctl which is the offset into the
device fd which userpace uses with mmap(2).

mmap_gtt was our initial mmap_offset implementation, this extends
our CPU mmap support to allow additional 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.

v2:
- Drop the alias, just rename the struct (Chris)
- Don't bail out on no PAT when doing WB mmaps
- Prepare uAPI for further extensions
v3:
- drop MMAP_OFFSET_FLAGS

I'm missing the accompanying igt tests for this. The only series I could
find is old, https://patchwork.freedesktop.org/series/65171/, with
pending fixes to do.


Lucas De Marchi



Signed-off-by: Abdiel Janulgue <abdiel.janul...@linux.intel.com>
Signed-off-by: Matthew Auld <matthew.a...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
---
drivers/gpu/drm/i915/gem/i915_gem_mman.c      | 44 ++++++++++++++++++-
.../gpu/drm/i915/gem/i915_gem_object_types.h  |  3 ++
include/uapi/drm/i915_drm.h                   | 27 +++++++++++-
3 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index e2df6379c7a7..5c173c29b3d2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -144,6 +144,9 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
 * 3 - Remove implicit set-domain(GTT) and synchronisation on initial
 *     pagefault; swapin remains transparent.
 *
+ * 4 - Support multiple fault handlers per object depending on object's
+ *     backing storage (a.k.a. MMAP_OFFSET).
+ *
 * Restrictions:
 *
 *  * snoopable objects cannot be accessed via the GTT. It can cause machine
@@ -171,7 +174,7 @@ static unsigned int tile_row_pages(const struct 
drm_i915_gem_object *obj)
 */
int i915_gem_mmap_gtt_version(void)
{
-       return 3;
+       return 4;
}

static inline struct i915_ggtt_view
@@ -535,6 +538,35 @@ __assign_gem_object_mmap_data(struct drm_file *file,
        return ret;
}

+static int gem_mmap_offset(struct drm_device *dev, void *data,
+                          struct drm_file *file)
+{
+       struct drm_i915_gem_mmap_offset *args = data;
+       enum i915_mmap_type type;
+
+       switch (args->flags) {
+       case I915_MMAP_OFFSET_WC:
+               if (!boot_cpu_has(X86_FEATURE_PAT))
+                       return -ENODEV;
+               type = I915_MMAP_TYPE_WC;
+               break;
+       case I915_MMAP_OFFSET_WB:
+               type = I915_MMAP_TYPE_WB;
+               break;
+       case I915_MMAP_OFFSET_UC:
+               if (!boot_cpu_has(X86_FEATURE_PAT))
+                       return -ENODEV;
+               type = I915_MMAP_TYPE_UC;
+               break;
+       default:
+               return -EINVAL;
+
+       };
+
+       return __assign_gem_object_mmap_data(file, args->handle, type,
+                                            &args->offset);
+}
+
/**
 * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing
 * @dev: DRM device
@@ -554,7 +586,15 @@ int
i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
                        struct drm_file *file)
{
-       struct drm_i915_gem_mmap_gtt *args = data;
+       struct drm_i915_gem_mmap_offset *args = data;
+       struct drm_i915_private *i915 = to_i915(dev);
+
+       if (args->flags)
+               return gem_mmap_offset(dev, data, file);
+
+       if (!i915_ggtt_has_aperture(&i915->ggtt))
+               /* No aperture, cannot mmap via legacy GTT */
+               return -ENODEV;

        return __assign_gem_object_mmap_data(file, args->handle,
                                             I915_MMAP_TYPE_GTT,
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 632d6b804cfb..07237fbfdaac 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -65,6 +65,9 @@ struct drm_i915_gem_object_ops {

enum i915_mmap_type {
        I915_MMAP_TYPE_GTT = 0,
+       I915_MMAP_TYPE_WC,
+       I915_MMAP_TYPE_WB,
+       I915_MMAP_TYPE_UC,
};

struct i915_mmap_offset {
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 5400d7e057f1..e99999a80b94 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -394,7 +394,7 @@ typedef struct _drm_i915_sarea {
#define DRM_IOCTL_I915_GEM_PREAD        DRM_IOW (DRM_COMMAND_BASE + 
DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
#define DRM_IOCTL_I915_GEM_PWRITE       DRM_IOW (DRM_COMMAND_BASE + 
DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
#define DRM_IOCTL_I915_GEM_MMAP         DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
-#define DRM_IOCTL_I915_GEM_MMAP_GTT    DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_gtt)
+#define DRM_IOCTL_I915_GEM_MMAP_GTT    DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_offset)
#define DRM_IOCTL_I915_GEM_SET_DOMAIN   DRM_IOW (DRM_COMMAND_BASE + 
DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain)
#define DRM_IOCTL_I915_GEM_SW_FINISH    DRM_IOW (DRM_COMMAND_BASE + 
DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish)
#define DRM_IOCTL_I915_GEM_SET_TILING   DRM_IOWR (DRM_COMMAND_BASE + 
DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
@@ -793,6 +793,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 MMAP_OFFSET flags
+        * should be passed here.
+        */
+       __u64 flags;
+#define I915_MMAP_OFFSET_WC 1
+#define I915_MMAP_OFFSET_WB 2
+#define I915_MMAP_OFFSET_UC 3
+
+       __u64 extensions;
+};
+
struct drm_i915_gem_set_domain {
        /** Handle for the object */
        __u32 handle;
--
2.23.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to