[PATCH 1/6] drm/i915/uapi: introduce drm_i915_gem_create_ext

2022-02-24 Thread Pallavi Mishra
From: Matthew Auld 

Same old gem_create but with now with extensions support. This is needed
to support various upcoming usecases.

v2:(Chris)
- Use separate ioctl number for gem_create_ext, instead of hijacking
  the existing gem_create ioctl, otherwise we run into the issue
  with being unable to detect if the kernel supports the new extension
  behaviour.
- We now have gem_create_ext.flags, which should be zeroed.
- I915_GEM_CREATE_EXT_SETPARAM value is now zero, since this is the
  index into our array of extensions.
- Setup a "vanilla" object which we can directly apply our extensions
  to.
v3:(Daniel & Jason)
- drop I915_GEM_CREATE_EXT_SETPARAM. Instead just have each extension
  do one thing only, instead of generic setparam which can cover
  various use cases.
- add some kernel-doc.

Signed-off-by: Matthew Auld 
Signed-off-by: CQ Tang 
Cc: Joonas Lahtinen 
Cc: Daniele Ceraolo Spurio 
Cc: Lionel Landwerlin 
Cc: Jordan Justen 
Cc: Daniel Vetter 
Cc: Kenneth Graunke 
Cc: Jason Ekstrand 
Cc: Dave Airlie 
Cc: dri-de...@lists.freedesktop.org
Cc: mesa-dev@lists.freedesktop.org
Reviewed-by: Kenneth Graunke 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210429103056.407067-5-matthew.a...@intel.com
(cherry picked from commit ebcb40298947bdb0622e53c69734e6b4fb64b348)
---
 drivers/gpu/drm/i915/gem/i915_gem_create.c | 56 ++
 drivers/gpu/drm/i915/gem/i915_gem_ioctls.h |  2 +
 drivers/gpu/drm/i915/i915_driver.c |  1 +
 include/uapi/drm/i915_drm.h| 42 
 4 files changed, 101 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c 
b/drivers/gpu/drm/i915/gem/i915_gem_create.c
index 409226df0dd2..1e82633a3898 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
@@ -8,6 +8,7 @@
 
 #include "i915_drv.h"
 #include "i915_trace.h"
+#include "i915_user_extensions.h"
 
 static int i915_gem_publish(struct drm_i915_gem_object *obj,
struct drm_file *file,
@@ -149,3 +150,58 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
i915_gem_object_free(obj);
return ret;
 }
+
+struct create_ext {
+   struct drm_i915_private *i915;
+   struct drm_i915_gem_object *vanilla_object;
+};
+
+static const i915_user_extension_fn create_extensions[] = {
+};
+
+/**
+ * Creates a new mm object and returns a handle to it.
+ * @dev: drm device pointer
+ * @data: ioctl data blob
+ * @file: drm file pointer
+ */
+int
+i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+   struct drm_i915_private *i915 = to_i915(dev);
+   struct drm_i915_gem_create_ext *args = data;
+   struct create_ext ext_data = { .i915 = i915 };
+   struct drm_i915_gem_object *obj;
+   int ret;
+
+   if (args->flags)
+   return -EINVAL;
+
+   i915_gem_flush_free_objects(i915);
+
+   obj = i915_gem_object_alloc();
+   if (!obj)
+   return -ENOMEM;
+
+   ext_data.vanilla_object = obj;
+   ret = i915_user_extensions(u64_to_user_ptr(args->extensions),
+  create_extensions,
+  ARRAY_SIZE(create_extensions),
+  &ext_data);
+   if (ret)
+   goto object_free;
+
+   ret = i915_gem_setup(obj,
+intel_memory_region_by_type(i915,
+INTEL_MEMORY_SYSTEM),
+args->size);
+   if (ret)
+   goto object_free;
+
+   return i915_gem_publish(obj, file, &args->size, &args->handle);
+
+object_free:
+   i915_gem_object_free(obj);
+   return ret;
+}
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h 
b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
index 7fd22f3efbef..28d6526e32ab 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h
@@ -14,6 +14,8 @@ int i915_gem_busy_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
 int i915_gem_create_ioctl(struct drm_device *dev, void *data,
  struct drm_file *file);
+int i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file);
 int i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file);
 int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/i915_driver.c 
b/drivers/gpu/drm/i915/i915_driver.c
index 8b06e56f7d09..11c6d3318308 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -1758,6 +1758,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, drm_noop, 
DRM_AUTH|DRM_MASTER|DRM_ROOT

[PATCH 2/6] drm/i915/uapi: implement object placement extension

2022-02-24 Thread Pallavi Mishra
From: Matthew Auld 

Add new extension to support setting an immutable-priority-list of
potential placements, at creation time.

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.

v2(Daniel & Jason):
- Add a bunch of kernel-doc
- Simplify design for placements extension

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 
Signed-off-by: CQ Tang 
Cc: Joonas Lahtinen 
Cc: Daniele Ceraolo Spurio 
Cc: Lionel Landwerlin 
Cc: Jordan Justen 
Cc: Daniel Vetter 
Cc: Kenneth Graunke 
Cc: Jason Ekstrand 
Cc: Dave Airlie 
Cc: dri-de...@lists.freedesktop.org
Cc: mesa-dev@lists.freedesktop.org
Reviewed-by: Kenneth Graunke 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210429103056.407067-6-matthew.a...@intel.com
(cherry picked from commit 2459e56fd8af0b47fcbfbdff2fdc02e4077680ec)
---
 drivers/gpu/drm/i915/gem/i915_gem_create.c| 218 --
 drivers/gpu/drm/i915/gem/i915_gem_object.c|   3 +
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |   6 +
 .../drm/i915/gem/selftests/i915_gem_mman.c|  26 +++
 drivers/gpu/drm/i915/intel_memory_region.c|  16 ++
 drivers/gpu/drm/i915/intel_memory_region.h|   4 +
 include/uapi/drm/i915_drm.h   |  62 +
 7 files changed, 318 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c 
b/drivers/gpu/drm/i915/gem/i915_gem_create.c
index 1e82633a3898..957f790c644b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
@@ -4,12 +4,51 @@
  */
 
 #include "gem/i915_gem_ioctls.h"
+#include "gem/i915_gem_lmem.h"
 #include "gem/i915_gem_region.h"
 
 #include "i915_drv.h"
 #include "i915_trace.h"
 #include "i915_user_extensions.h"
 
+static u32 object_max_page_size(struct drm_i915_gem_object *obj)
+{
+   u32 max_page_size = 0;
+   int i;
+
+   for (i = 0; i < obj->mm.n_placements; i++) {
+   struct intel_memory_region *mr = obj->mm.placements[i];
+
+   GEM_BUG_ON(!is_power_of_2(mr->min_page_size));
+   max_page_size = max_t(u32, max_page_size, mr->min_page_size);
+   }
+
+   GEM_BUG_ON(!max_page_size);
+   return max_page_size;
+}
+
+static void object_set_placements(struct drm_i915_gem_object *obj,
+ struct intel_memory_region **placements,
+ unsigned int n_placements)
+{
+   GEM_BUG_ON(!n_placements);
+
+   /*
+* For the common case of one memory region, skip storing an
+* allocated array and just point at the region directly.
+*/
+   if (n_placements == 1) {
+   struct intel_memory_region *mr = placements[0];
+   struct drm_i915_private *i915 = mr->i915;
+
+   obj->mm.placements = &i915->mm.regions[mr->id];
+   obj->mm.n_placements = 1;
+   } else {
+   obj->mm.placements = placements;
+   obj->mm.n_placements = n_placements;
+   }
+}
+
 static int i915_gem_publish(struct drm_i915_gem_object *obj,
struct drm_file *file,
u64 *size_p,
@@ -29,14 +68,12 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
 }
 
 static int
-i915_gem_setup(struct drm_i915_gem_object *obj,
-  struct intel_memory_region *mr,
-  u64 size)
+i915_gem_setup(struct drm_i915_gem_object *obj, u64 size)
 {
+   struct intel_memory_region *mr = obj->mm.placements[0];
int ret;
 
-   GEM_BUG_ON(!is_power_of_2(mr->min_page_size));
-   size = round_up(size, mr->min_page_size);
+   size = round_up(size, object_max_page_size(obj));
if (size == 0)
return -EINVAL;
 
@@ -62,6 +99,7 @@ i915_gem_dumb_create(struct drm_file *file,
 struct drm_mode_create_dumb *args)
 {
struct drm_i915_gem_object *obj;
+   struct intel_memory_region *mr;
enum intel_memory_type mem_type;
int cpp = DIV_ROUND_UP(args->bpp, 8);
u32 format;
@@ -102,10 +140,10 @@ i915_gem_dumb_create(struct drm_file *file,
if (!obj)
return -ENOMEM;
 
-   ret = i915_gem_setup(obj,
-intel_memory_region_by_type(to_i915(dev),
-mem_type),
-args->size);
+   mr = intel_memory_region_by_type(to_i915(dev), mem_type);
+   object_set_placements(obj, &mr, 1);
+
+   ret = i915_gem_setup(obj, args->size);
if (ret)
goto object_free;
 
@@ -129,6 +167,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
struct drm_i915_private *i915 = to_i915(dev);
struct drm_i915_gem_create *args 

[PATCH 3/6] drm/i915/gem: clear userspace buffers for LMEM

2022-02-24 Thread Pallavi Mishra
From: Matthew Auld 

All userspace objects must be cleared when allocating the backing store,
before they are potentially visible to userspace.  For now use simple
CPU based clearing to do this for device local-memory objects, note that
in the near future this will instead use the blitter engine.

Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Thomas Hellström 
Cc: Daniele Ceraolo Spurio 
Cc: Lionel Landwerlin 
Cc: Jon Bloomfield 
Cc: Jordan Justen 
Cc: Daniel Vetter 
Cc: Kenneth Graunke 
Cc: Jason Ekstrand 
Cc: Dave Airlie 
Cc: dri-de...@lists.freedesktop.org
Cc: mesa-dev@lists.freedesktop.org
Reviewed-by: Kenneth Graunke 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210429103056.407067-8-matthew.a...@intel.com
(cherry picked from commit 0e997a36ecb61b161a22980ec9240ee7537f3f62)
---
 drivers/gpu/drm/i915/gem/i915_gem_create.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c 
b/drivers/gpu/drm/i915/gem/i915_gem_create.c
index 957f790c644b..f6729feae582 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
@@ -71,6 +71,7 @@ static int
 i915_gem_setup(struct drm_i915_gem_object *obj, u64 size)
 {
struct intel_memory_region *mr = obj->mm.placements[0];
+   unsigned int flags;
int ret;
 
size = round_up(size, object_max_page_size(obj));
@@ -83,7 +84,16 @@ i915_gem_setup(struct drm_i915_gem_object *obj, u64 size)
if (i915_gem_object_size_2big(size))
return -E2BIG;
 
-   ret = mr->ops->init_object(mr, obj, size, 0);
+   /*
+* For now resort to CPU based clearing for device local-memory, in the
+* near future this will use the blitter engine for accelerated, GPU
+* based clearing.
+*/
+   flags = 0;
+   if (mr->type == INTEL_MEMORY_LOCAL)
+   flags = I915_BO_ALLOC_CPU_CLEAR;
+
+   ret = mr->ops->init_object(mr, obj, size, flags);
if (ret)
return ret;
 


[PATCH 4/6] drm/i915/gem: hide new uAPI behind CONFIG_BROKEN

2022-02-24 Thread Pallavi Mishra
From: Matthew Auld 

Treat it the same as the fake local-memory stuff, where it is disabled
for normal kernels, in case some random UMD is tempted to use this. Once
we have all the other bits and pieces in place, like the TTM conversion,
we can turn this on for real.

Signed-off-by: Matthew Auld 
Cc: Joonas Lahtinen 
Cc: Thomas Hellström 
Cc: Daniele Ceraolo Spurio 
Cc: Lionel Landwerlin 
Cc: Jon Bloomfield 
Cc: Jordan Justen 
Cc: Daniel Vetter 
Cc: Kenneth Graunke 
Cc: Jason Ekstrand 
Cc: Dave Airlie 
Cc: dri-de...@lists.freedesktop.org
Cc: mesa-dev@lists.freedesktop.org
Reviewed-by: Kenneth Graunke 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210429103056.407067-9-matthew.a...@intel.com
(cherry picked from commit 0a46be95c282956a9d3229a46e33ba701c26594c)
---
 drivers/gpu/drm/i915/gem/i915_gem_create.c | 3 +++
 drivers/gpu/drm/i915/i915_query.c  | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c 
b/drivers/gpu/drm/i915/gem/i915_gem_create.c
index f6729feae582..548ddf39d853 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
@@ -335,6 +335,9 @@ static int ext_set_placements(struct i915_user_extension 
__user *base,
 {
struct drm_i915_gem_create_ext_memory_regions ext;
 
+   if (!IS_ENABLED(CONFIG_DRM_I915_UNSTABLE_FAKE_LMEM))
+   return -ENODEV;
+
if (copy_from_user(&ext, base, sizeof(ext)))
return -EFAULT;
 
diff --git a/drivers/gpu/drm/i915/i915_query.c 
b/drivers/gpu/drm/i915/i915_query.c
index 51b368be0fc4..8a72923fbdba 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -434,6 +434,9 @@ static int query_memregion_info(struct drm_i915_private 
*i915,
u32 total_length;
int ret, id, i;
 
+   if (!IS_ENABLED(CONFIG_DRM_I915_UNSTABLE_FAKE_LMEM))
+   return -ENODEV;
+
if (query_item->flags != 0)
return -EINVAL;