All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Introduce a new create ioctl for user specified
@ 2014-06-20 10:02 sourab.gupta
  2014-06-20 10:02 ` [PATCH 1/4] drm/i915: Clearing buffer objects via blitter engine sourab.gupta
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: sourab.gupta @ 2014-06-20 10:02 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter, Akash Goel, Sourab Gupta

From: Sourab Gupta <sourab.gupta@intel.com>

This patch series introduces a new gem create ioctl for user specified
placement.

Despite being a unified memory architecture (UMA) some bits of memory
are more equal than others. In particular we have the thorny issue of
stolen memory, memory stolen from the system by the BIOS and reserved
for igfx use. Stolen memory is required for some functions of the GPU
and display engine, but in general it goes wasted. Whilst we cannot
return it back to the system, we need to find some other method for
utilising it. As we do not support direct access to the physical address
in the stolen region, it behaves like a different class of memory,
closer in kin to local GPU memory. This strongly suggests that we need a
placement model like TTM if we are to fully utilize these discrete
chunks of differing memory.
    
This new create ioctl therefore exists to allow the user to create these
second class buffer objects from stolen memory. At the moment direct
access by the CPU through mmaps and pread/pwrite are verboten on the
objects, and so the user must be aware of the limitations of the objects
created. Yet, those limitations rarely reduce the desired functionality
in many use cases and so the user should be able to easily fill the
stolen memory and so help to reduce overall memory pressure.
    
The most obvious use case for stolen memory is for the creation of objects
for the display engine which already have very similar restrictions on
access. However, we want a reasonably general ioctl in order to cater
for diverse scenarios beyond the author's imagination.

Chris Wilson (3):
  drm/i915: Clearing buffer objects via blitter engine
  drm/i915: Introduce a new create ioctl for user specified placement
  drm/i915: Add support for stealing purgable stolen pages

Deepak S (1):
  drm/i915: Clearing buffer objects via blitter engine for Gen8

 drivers/gpu/drm/i915/Makefile          |   1 +
 drivers/gpu/drm/i915/i915_dma.c        |   5 +-
 drivers/gpu/drm/i915/i915_drv.h        |  18 ++-
 drivers/gpu/drm/i915/i915_gem.c        | 208 ++++++++++++++++++++++++++++++---
 drivers/gpu/drm/i915/i915_gem_exec.c   | 139 ++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_stolen.c | 121 +++++++++++++++++--
 drivers/gpu/drm/i915/i915_gem_tiling.c | 106 +++++++++--------
 include/uapi/drm/i915_drm.h            | 107 +++++++++++++++++
 8 files changed, 623 insertions(+), 82 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_gem_exec.c

-- 
1.8.5.1

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/4] drm/i915: Clearing buffer objects via blitter engine
  2014-06-20 10:02 [PATCH 0/4] Introduce a new create ioctl for user specified sourab.gupta
@ 2014-06-20 10:02 ` sourab.gupta
  2014-06-20 10:02 ` [PATCH 2/4] drm/i915: Clearing buffer objects via blitter engine for Gen8 sourab.gupta
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: sourab.gupta @ 2014-06-20 10:02 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter, Akash Goel

From: Chris Wilson <chris@chris-wilson.co.uk>

This patch adds support for clearing buffer objects via blitter
engines. This is particularly useful for clearing out the memory
from stolen region.

testcase: igt/gem_create2

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/Makefile        |   1 +
 drivers/gpu/drm/i915/i915_drv.h      |   3 +
 drivers/gpu/drm/i915/i915_gem_exec.c | 120 +++++++++++++++++++++++++++++++++++
 3 files changed, 124 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/i915_gem_exec.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index cad1683..a18f7e5 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -22,6 +22,7 @@ i915-y += i915_cmd_parser.o \
 	  i915_gem_debug.o \
 	  i915_gem_dmabuf.o \
 	  i915_gem_evict.o \
+	  i915_gem_exec.o \
 	  i915_gem_execbuffer.o \
 	  i915_gem_gtt.o \
 	  i915_gem.o \
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8cea596..4470105 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2480,6 +2480,9 @@ int __must_check i915_gem_evict_something(struct drm_device *dev,
 int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle);
 int i915_gem_evict_everything(struct drm_device *dev);
 
+/* i915_gem_exec.c */
+int i915_gem_exec_clear_object(struct drm_i915_gem_object *obj);
+
 /* belongs in i915_gem_gtt.h */
 static inline void i915_gem_chipset_flush(struct drm_device *dev)
 {
diff --git a/drivers/gpu/drm/i915/i915_gem_exec.c b/drivers/gpu/drm/i915/i915_gem_exec.c
new file mode 100644
index 0000000..374f1e1
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gem_exec.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chris Wilson <chris@chris-wilson.co.uk>
+ *
+ */
+
+#include <drm/drmP.h>
+#include <drm/i915_drm.h>
+#include "i915_drv.h"
+
+#define COLOR_BLT_CMD (2<<29 | 0x40<<22)
+#define BLT_WRITE_ALPHA (1<<21)
+#define BLT_WRITE_RGB (1<<20)
+#define BLT_WRITE_RGBA (BLT_WRITE_RGB|BLT_WRITE_ALPHA)
+
+#define BPP_8 0
+#define BPP_16 (1<<24)
+#define BPP_32 (1<<25 | 1<<24)
+
+#define ROP_FILL_COPY (0xf0 << 16)
+
+static int i915_gem_exec_flush_object(struct drm_i915_gem_object *obj,
+				      struct intel_engine_cs *ring)
+{
+	int ret;
+
+	ret = i915_gem_object_sync(obj, ring);
+	if (ret)
+		return ret;
+
+	if (obj->base.write_domain & I915_GEM_DOMAIN_CPU) {
+		if (i915_gem_clflush_object(obj, false))
+			i915_gem_chipset_flush(obj->base.dev);
+		obj->base.write_domain &= ~I915_GEM_DOMAIN_CPU;
+	}
+	if (obj->base.write_domain & I915_GEM_DOMAIN_GTT) {
+		wmb();
+		obj->base.write_domain &= ~I915_GEM_DOMAIN_GTT;
+	}
+
+	return intel_ring_invalidate_all_caches(ring);
+}
+
+static void i915_gem_exec_dirty_object(struct drm_i915_gem_object *obj,
+				       struct intel_engine_cs *ring)
+{
+	obj->fenced_gpu_access = false;
+	obj->base.read_domains = I915_GEM_DOMAIN_RENDER;
+	obj->base.write_domain = I915_GEM_DOMAIN_RENDER;
+	i915_vma_move_to_active(i915_gem_obj_to_ggtt(obj), ring);
+	obj->last_write_seqno = intel_ring_get_seqno(ring);
+	obj->dirty = 1;
+
+	ring->gpu_caches_dirty = true;
+}
+
+int i915_gem_exec_clear_object(struct drm_i915_gem_object *obj)
+{
+	struct drm_device *dev = obj->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_engine_cs *ring;
+	int ret;
+
+	lockdep_assert_held(&dev->struct_mutex);
+
+	ring = &dev_priv->ring[HAS_BLT(dev) ? BCS : RCS];
+
+	ret = i915_gem_obj_ggtt_pin(obj, 0, 0);
+	if (ret)
+		return ret;
+
+	if (obj->tiling_mode && INTEL_INFO(dev)->gen <= 3) {
+		ret = i915_gem_object_put_fence(obj);
+		if (ret)
+			goto unpin;
+	}
+
+	ret = i915_gem_exec_flush_object(obj, ring);
+	if (ret)
+		goto unpin;
+
+	ret = intel_ring_begin(ring, 6);
+	if (ret)
+		goto unpin;
+
+	intel_ring_emit(ring, COLOR_BLT_CMD | BLT_WRITE_RGBA | (5-2));
+	intel_ring_emit(ring, BPP_32 | ROP_FILL_COPY | PAGE_SIZE);
+	intel_ring_emit(ring, obj->base.size >> PAGE_SHIFT << 16 | PAGE_SIZE);
+	intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj));
+	intel_ring_emit(ring, 0);
+	intel_ring_emit(ring, MI_NOOP);
+
+	__intel_ring_advance(ring);
+	i915_gem_exec_dirty_object(obj, ring);
+
+unpin:
+	i915_gem_object_ggtt_unpin(obj);
+	return ret;
+}
-- 
1.8.5.1

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

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/4] drm/i915: Clearing buffer objects via blitter engine for Gen8
  2014-06-20 10:02 [PATCH 0/4] Introduce a new create ioctl for user specified sourab.gupta
  2014-06-20 10:02 ` [PATCH 1/4] drm/i915: Clearing buffer objects via blitter engine sourab.gupta
@ 2014-06-20 10:02 ` sourab.gupta
  2014-06-20 10:02 ` [PATCH v4 3/4] drm/i915: Introduce a new create ioctl for user specified placement sourab.gupta
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: sourab.gupta @ 2014-06-20 10:02 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter, Akash Goel

From: Deepak S <deepak.s@linux.intel.com>

On Gen8, COLOR BLT commands are different. Add gen8 specific command to clearing
buffer objects via blitter engines.

Signed-off-by: Deepak S <deepak.s@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_exec.c | 39 +++++++++++++++++++++++++++---------
 1 file changed, 29 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_exec.c b/drivers/gpu/drm/i915/i915_gem_exec.c
index 374f1e1..fc9e454 100644
--- a/drivers/gpu/drm/i915/i915_gem_exec.c
+++ b/drivers/gpu/drm/i915/i915_gem_exec.c
@@ -29,6 +29,8 @@
 #include <drm/i915_drm.h>
 #include "i915_drv.h"
 
+#define GEN8_COLOR_BLT_CMD (2<<29 | 0x50<<22)
+
 #define COLOR_BLT_CMD (2<<29 | 0x40<<22)
 #define BLT_WRITE_ALPHA (1<<21)
 #define BLT_WRITE_RGB (1<<20)
@@ -100,18 +102,35 @@ int i915_gem_exec_clear_object(struct drm_i915_gem_object *obj)
 	if (ret)
 		goto unpin;
 
-	ret = intel_ring_begin(ring, 6);
-	if (ret)
-		goto unpin;
+	if (IS_GEN8(dev)) {
+		ret = intel_ring_begin(ring, 8);
+		if (ret)
+			goto unpin;
 
-	intel_ring_emit(ring, COLOR_BLT_CMD | BLT_WRITE_RGBA | (5-2));
-	intel_ring_emit(ring, BPP_32 | ROP_FILL_COPY | PAGE_SIZE);
-	intel_ring_emit(ring, obj->base.size >> PAGE_SHIFT << 16 | PAGE_SIZE);
-	intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj));
-	intel_ring_emit(ring, 0);
-	intel_ring_emit(ring, MI_NOOP);
+		intel_ring_emit(ring, GEN8_COLOR_BLT_CMD | BLT_WRITE_RGBA | (7-2));
+		intel_ring_emit(ring, BPP_32 | ROP_FILL_COPY | PAGE_SIZE);
+		intel_ring_emit(ring, 0);
+		intel_ring_emit(ring, obj->base.size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4);
+		intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj));
+		intel_ring_emit(ring, 0);
+		intel_ring_emit(ring, 0);
+		intel_ring_emit(ring, MI_NOOP);
+
+		__intel_ring_advance(ring);
+	} else {
+		ret = intel_ring_begin(ring, 6);
+		if (ret)
+			goto unpin;
 
-	__intel_ring_advance(ring);
+		intel_ring_emit(ring, COLOR_BLT_CMD | BLT_WRITE_RGBA | (5-2));
+		intel_ring_emit(ring, BPP_32 | ROP_FILL_COPY | PAGE_SIZE);
+		intel_ring_emit(ring, obj->base.size >> PAGE_SHIFT << 16 | PAGE_SIZE);
+		intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj));
+		intel_ring_emit(ring, 0);
+		intel_ring_emit(ring, MI_NOOP);
+
+		__intel_ring_advance(ring);
+	}
 	i915_gem_exec_dirty_object(obj, ring);
 
 unpin:
-- 
1.8.5.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4 3/4] drm/i915: Introduce a new create ioctl for user specified placement
  2014-06-20 10:02 [PATCH 0/4] Introduce a new create ioctl for user specified sourab.gupta
  2014-06-20 10:02 ` [PATCH 1/4] drm/i915: Clearing buffer objects via blitter engine sourab.gupta
  2014-06-20 10:02 ` [PATCH 2/4] drm/i915: Clearing buffer objects via blitter engine for Gen8 sourab.gupta
@ 2014-06-20 10:02 ` sourab.gupta
  2014-06-20 10:02 ` [PATCH v2 4/4] drm/i915: Add support for stealing purgable stolen pages sourab.gupta
  2014-07-06 12:58 ` [PATCH 0/4] Introduce a new create ioctl for user specified Gupta, Sourab
  4 siblings, 0 replies; 9+ messages in thread
From: sourab.gupta @ 2014-06-20 10:02 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter, Akash Goel

From: Chris Wilson <chris@chris-wilson.co.uk>

Despite being a unified memory architecture (UMA) some bits of memory
are more equal than others. In particular we have the thorny issue of
stolen memory, memory stolen from the system by the BIOS and reserved
for igfx use. Stolen memory is required for some functions of the GPU
and display engine, but in general it goes wasted. Whilst we cannot
return it back to the system, we need to find some other method for
utilising it. As we do not support direct access to the physical address
in the stolen region, it behaves like a different class of memory,
closer in kin to local GPU memory. This strongly suggests that we need a
placement model like TTM if we are to fully utilize these discrete
chunks of differing memory.

This new create ioctl therefore exists to allow the user to create these
second class buffer objects from stolen memory. At the moment direct
access by the CPU through mmaps and pread/pwrite are verboten on the
objects, and so the user must be aware of the limitations of the objects
created. Yet, those limitations rarely reduce the desired functionality
in many use cases and so the user should be able to easily fill the
stolen memory and so help to reduce overall memory pressure.

The most obvious use case for stolen memory is for the creation of objects
for the display engine which already have very similar restrictions on
access. However, we want a reasonably general ioctl in order to cater
for diverse scenarios beyond the author's imagination.

v2: Expand the struct slightly to include cache domains, and ensure that
all memory allocated by the kernel for userspace is zeroed.

v3: Ben suggested the idea of binding the object at a known offset into
the target context upon creation.

v4: Revert the removal of DRM_AUTH from some ioctls, which got squashed
in by mistake (Damien)

testcase: igt/gem_create2

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_dma.c        |   5 +-
 drivers/gpu/drm/i915/i915_drv.h        |  15 ++-
 drivers/gpu/drm/i915/i915_gem.c        | 208 ++++++++++++++++++++++++++++++---
 drivers/gpu/drm/i915/i915_gem_tiling.c | 106 +++++++++--------
 include/uapi/drm/i915_drm.h            | 107 +++++++++++++++++
 5 files changed, 370 insertions(+), 71 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 5e583a1..0ab390a 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -2010,8 +2010,8 @@ const struct drm_ioctl_desc i915_ioctls[] = {
 	DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
-	DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED|DRM_RENDER_ALLOW),
-	DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED|DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED),
 	DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
@@ -2025,6 +2025,7 @@ const struct drm_ioctl_desc i915_ioctls[] = {
 	DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GET_RESET_STATS, i915_get_reset_stats_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_CREATE2, i915_gem_create2_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
 };
 
 int i915_max_ioctl = ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4470105..78f64fd 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2157,6 +2157,8 @@ int i915_gem_init_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_priv);
 int i915_gem_create_ioctl(struct drm_device *dev, void *data,
 			  struct drm_file *file_priv);
+int i915_gem_create2_ioctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv);
 int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
 			 struct drm_file *file_priv);
 int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
@@ -2191,10 +2193,10 @@ int i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
 			   struct drm_file *file_priv);
 int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
 			   struct drm_file *file_priv);
-int i915_gem_set_tiling(struct drm_device *dev, void *data,
-			struct drm_file *file_priv);
-int i915_gem_get_tiling(struct drm_device *dev, void *data,
-			struct drm_file *file_priv);
+int i915_gem_set_tiling_ioctl(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv);
+int i915_gem_get_tiling_ioctl(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv);
 int i915_gem_init_userptr(struct drm_device *dev);
 int i915_gem_userptr_ioctl(struct drm_device *dev, void *data,
 			   struct drm_file *file);
@@ -2319,6 +2321,8 @@ static inline bool i915_stop_ring_allow_warn(struct drm_i915_private *dev_priv)
 
 void i915_gem_reset(struct drm_device *dev);
 bool i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force);
+int __must_check i915_gem_object_set_tiling(struct drm_i915_gem_object *obj,
+					    int tiling_mode, int pitch);
 int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj);
 int __must_check i915_gem_init(struct drm_device *dev);
 int __must_check i915_gem_init_hw(struct drm_device *dev);
@@ -2351,6 +2355,9 @@ int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
 int i915_gem_open(struct drm_device *dev, struct drm_file *file);
 void i915_gem_release(struct drm_device *dev, struct drm_file *file);
 
+bool
+i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode);
+
 uint32_t
 i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode);
 uint32_t
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f6d1238..613571a 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -53,6 +53,14 @@ static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
 					 struct drm_i915_fence_reg *fence,
 					 bool enable);
 
+#define PIN_OFFSET_VALID 0x1
+static struct i915_vma *
+i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
+			   struct i915_address_space *vm,
+			   uint64_t offset,
+			   unsigned alignment,
+			   uint64_t flags);
+
 static unsigned long i915_gem_shrinker_count(struct shrinker *shrinker,
 					     struct shrink_control *sc);
 static unsigned long i915_gem_shrinker_scan(struct shrinker *shrinker,
@@ -380,8 +388,7 @@ i915_gem_dumb_create(struct drm_file *file,
 	/* have to work out size/pitch and return them */
 	args->pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 64);
 	args->size = args->pitch * args->height;
-	return i915_gem_create(file, dev,
-			       args->size, &args->handle);
+	return i915_gem_create(file, dev, args->size, &args->handle);
 }
 
 /**
@@ -392,9 +399,155 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
 		      struct drm_file *file)
 {
 	struct drm_i915_gem_create *args = data;
+	return i915_gem_create(file, dev, args->size, &args->handle);
+}
+
+int
+i915_gem_create2_ioctl(struct drm_device *dev, void *data,
+		       struct drm_file *file)
+{
+	struct drm_i915_gem_create2 *args = data;
+	struct drm_i915_gem_object *obj;
+	unsigned cache_level;
+	enum {
+		ASYNC_CLEAR = 0x1,
+	} flags = 0;
+	int ret;
+
+	if (args->pad)
+		return -EINVAL;
+
+	if (args->flags & ~(0))
+		return -EINVAL;
+
+	if (!i915_tiling_ok(dev, args->stride, args->size, args->tiling_mode))
+		return -EINVAL;
+
+	switch (args->domain) {
+	case 0:
+	case I915_GEM_DOMAIN_CPU:
+	case I915_GEM_DOMAIN_GTT:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (args->caching) {
+	case I915_CACHING_NONE:
+		cache_level = I915_CACHE_NONE;
+		break;
+	case I915_CACHING_CACHED:
+		cache_level = I915_CACHE_LLC;
+		break;
+	case I915_CACHING_DISPLAY:
+		cache_level = HAS_WT(dev) ? I915_CACHE_WT : I915_CACHE_NONE;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (args->madvise) {
+	case I915_MADV_DONTNEED:
+	case I915_MADV_WILLNEED:
+	    break;
+	default:
+	    return -EINVAL;
+	}
+
+	if (args->size == 0 || args->size & 4095)
+		return -EINVAL;
+
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ret;
+
+	obj = NULL;
+	switch (args->placement) {
+	case I915_CREATE_PLACEMENT_SYSTEM:
+		obj = i915_gem_alloc_object(dev, args->size);
+		break;
+	case I915_CREATE_PLACEMENT_STOLEN:
+		obj = i915_gem_object_create_stolen(dev, args->size);
+		flags |= ASYNC_CLEAR;
+		break;
+	default:
+		ret = -EINVAL;
+		goto unlock;
+	}
+	if (obj == NULL) {
+		ret = -ENOMEM;
+		goto unlock;
+	}
+
+	ret =  i915_gem_object_set_cache_level(obj, cache_level);
+	if (ret)
+		goto err;
+
+	ret = i915_gem_object_set_tiling(obj, args->tiling_mode, args->stride);
+	if (ret)
+		goto err;
 
-	return i915_gem_create(file, dev,
-			       args->size, &args->handle);
+	if (args->offset & I915_CREATE_OFFSET_VALID) {
+		struct intel_context *ctx;
+		struct i915_vma *vma;
+
+		ctx = i915_gem_context_get(file->driver_priv, args->context);
+		if (IS_ERR(ctx)) {
+			ret = PTR_ERR(ctx);
+			goto err;
+		}
+
+		vma = i915_gem_obj_to_vma(obj, ctx->vm);
+		if (vma && drm_mm_node_allocated(&vma->node)) {
+			if (vma->node.start != (args->offset &
+						~I915_CREATE_OFFSET_VALID)) {
+				ret = i915_vma_unbind(vma);
+				if (ret)
+					goto err;
+
+				vma = NULL;
+			}
+		}
+
+		if (vma == NULL || !drm_mm_node_allocated(&vma->node)) {
+			vma = i915_gem_object_bind_to_vm(obj, ctx->vm,
+					args->offset, 0, flags);
+			if (IS_ERR(vma)) {
+				ret = PTR_ERR(vma);
+				goto err;
+			}
+		}
+	}
+
+	if (flags & ASYNC_CLEAR) {
+		ret = i915_gem_exec_clear_object(obj);
+		if (ret)
+			goto err;
+	}
+
+	if (args->domain) {
+		if (args->domain == I915_GEM_DOMAIN_GTT) {
+			ret = i915_gem_object_set_to_gtt_domain(obj, true);
+			if (ret == -EINVAL) /* unbound */
+				ret = 0;
+		} else {
+			ret = i915_gem_object_set_to_cpu_domain(obj, true);
+		}
+		if (ret)
+			goto err;
+	}
+
+	ret = drm_gem_handle_create(file, &obj->base, &args->handle);
+	if (ret)
+		goto err;
+
+	obj->madv = args->madvise;
+	trace_i915_gem_object_create(obj);
+err:
+	drm_gem_object_unreference(&obj->base);
+unlock:
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
 }
 
 static inline int
@@ -3377,6 +3530,7 @@ static void i915_gem_verify_gtt(struct drm_device *dev)
 static struct i915_vma *
 i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
 			   struct i915_address_space *vm,
+			   uint64_t offset,
 			   unsigned alignment,
 			   uint64_t flags)
 {
@@ -3432,22 +3586,38 @@ i915_gem_object_bind_to_vm(struct drm_i915_gem_object *obj,
 	if (IS_ERR(vma))
 		goto err_unpin;
 
+	if (offset & PIN_OFFSET_VALID) {
+		offset &= ~PIN_OFFSET_VALID;
+		if (alignment && offset & (alignment - 1)) {
+			vma = ERR_PTR(-EINVAL);
+			goto err_free_vma;
+		}
+
+		vma->node.start = offset;
+		vma->node.size = size;
+		vma->node.color = obj->cache_level;
+		ret = drm_mm_reserve_node(&vm->mm, &vma->node);
+		if (ret) {
+			vma = ERR_PTR(ret);
+			goto err_free_vma;
+		}
+	} else {
 search_free:
-	ret = drm_mm_insert_node_in_range_generic(&vm->mm, &vma->node,
-						  size, alignment,
-						  obj->cache_level,
-						  start, end,
-						  DRM_MM_SEARCH_DEFAULT,
-						  DRM_MM_CREATE_DEFAULT);
-	if (ret) {
-		ret = i915_gem_evict_something(dev, vm, size, alignment,
-					       obj->cache_level,
-					       start, end,
-					       flags);
-		if (ret == 0)
-			goto search_free;
+		ret = drm_mm_insert_node_in_range_generic(&vm->mm, &vma->node,
+				size, alignment,
+				obj->cache_level,
+				start, end,
+				DRM_MM_SEARCH_DEFAULT,
+				DRM_MM_CREATE_DEFAULT);
+		if (ret) {
+			ret = i915_gem_evict_something(dev, vm, size, alignment,
+						obj->cache_level,
+						start, end, flags);
+			if (ret == 0)
+				goto search_free;
 
-		goto err_free_vma;
+			goto err_free_vma;
+		}
 	}
 	if (WARN_ON(!i915_gem_valid_gtt_space(dev, &vma->node,
 					      obj->cache_level))) {
@@ -4085,7 +4255,7 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
 	}
 
 	if (vma == NULL || !drm_mm_node_allocated(&vma->node)) {
-		vma = i915_gem_object_bind_to_vm(obj, vm, alignment, flags);
+		vma = i915_gem_object_bind_to_vm(obj, vm, 0, alignment, flags);
 		if (IS_ERR(vma))
 			return PTR_ERR(vma);
 	}
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index cb150e8..683e0853 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -201,7 +201,7 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
 }
 
 /* Check pitch constriants for all chips & tiling formats */
-static bool
+bool
 i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
 {
 	int tile_width;
@@ -285,12 +285,68 @@ i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode)
 	return true;
 }
 
+int
+i915_gem_object_set_tiling(struct drm_i915_gem_object *obj,
+			   int tiling_mode, int stride)
+{
+	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+	int ret;
+
+	if (tiling_mode == obj->tiling_mode && stride == obj->stride)
+		return 0;
+
+	/* We need to rebind the object if its current allocation
+	 * no longer meets the alignment restrictions for its new
+	 * tiling mode. Otherwise we can just leave it alone, but
+	 * need to ensure that any fence register is updated before
+	 * the next fenced (either through the GTT or by the BLT unit
+	 * on older GPUs) access.
+	 *
+	 * After updating the tiling parameters, we then flag whether
+	 * we need to update an associated fence register. Note this
+	 * has to also include the unfenced register the GPU uses
+	 * whilst executing a fenced command for an untiled object.
+	 */
+
+	obj->map_and_fenceable =
+		!i915_gem_obj_ggtt_bound(obj) ||
+		((i915_gem_obj_ggtt_offset(obj) + obj->base.size)
+		 <= dev_priv->gtt.mappable_end &&
+		 i915_gem_object_fence_ok(obj, tiling_mode));
+
+	/* Rebind if we need a change of alignment */
+	ret = 0;
+	if (!obj->map_and_fenceable) {
+		u32 unfenced_alignment =
+			i915_gem_get_gtt_alignment(dev_priv->dev,
+						   obj->base.size, tiling_mode,
+						   false);
+		if (i915_gem_obj_ggtt_offset(obj) & (unfenced_alignment - 1))
+			ret = i915_gem_object_ggtt_unbind(obj);
+	}
+
+	if (ret == 0) {
+		obj->fence_dirty =
+			obj->fenced_gpu_access ||
+			obj->fence_reg != I915_FENCE_REG_NONE;
+
+		obj->tiling_mode = tiling_mode;
+		obj->stride = stride;
+
+		/* Force the fence to be reacquired for GTT access */
+		i915_gem_release_mmap(obj);
+	}
+
+	return ret;
+}
+
+
 /**
  * Sets the tiling mode of an object, returning the required swizzling of
  * bit 6 of addresses in the object.
  */
 int
-i915_gem_set_tiling(struct drm_device *dev, void *data,
+i915_gem_set_tiling_ioctl(struct drm_device *dev, void *data,
 		   struct drm_file *file)
 {
 	struct drm_i915_gem_set_tiling *args = data;
@@ -343,49 +399,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
 	}
 
 	mutex_lock(&dev->struct_mutex);
-	if (args->tiling_mode != obj->tiling_mode ||
-	    args->stride != obj->stride) {
-		/* We need to rebind the object if its current allocation
-		 * no longer meets the alignment restrictions for its new
-		 * tiling mode. Otherwise we can just leave it alone, but
-		 * need to ensure that any fence register is updated before
-		 * the next fenced (either through the GTT or by the BLT unit
-		 * on older GPUs) access.
-		 *
-		 * After updating the tiling parameters, we then flag whether
-		 * we need to update an associated fence register. Note this
-		 * has to also include the unfenced register the GPU uses
-		 * whilst executing a fenced command for an untiled object.
-		 */
-
-		obj->map_and_fenceable =
-			!i915_gem_obj_ggtt_bound(obj) ||
-			(i915_gem_obj_ggtt_offset(obj) +
-			 obj->base.size <= dev_priv->gtt.mappable_end &&
-			 i915_gem_object_fence_ok(obj, args->tiling_mode));
-
-		/* Rebind if we need a change of alignment */
-		if (!obj->map_and_fenceable) {
-			u32 unfenced_align =
-				i915_gem_get_gtt_alignment(dev, obj->base.size,
-							    args->tiling_mode,
-							    false);
-			if (i915_gem_obj_ggtt_offset(obj) & (unfenced_align - 1))
-				ret = i915_gem_object_ggtt_unbind(obj);
-		}
-
-		if (ret == 0) {
-			obj->fence_dirty =
-				obj->fenced_gpu_access ||
-				obj->fence_reg != I915_FENCE_REG_NONE;
-
-			obj->tiling_mode = args->tiling_mode;
-			obj->stride = args->stride;
-
-			/* Force the fence to be reacquired for GTT access */
-			i915_gem_release_mmap(obj);
-		}
-	}
+	ret = i915_gem_object_set_tiling(obj, args->tiling_mode, args->stride);
 	/* we have to maintain this existing ABI... */
 	args->stride = obj->stride;
 	args->tiling_mode = obj->tiling_mode;
@@ -411,7 +425,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
  * Returns the current tiling mode and required bit 6 swizzling for the object.
  */
 int
-i915_gem_get_tiling(struct drm_device *dev, void *data,
+i915_gem_get_tiling_ioctl(struct drm_device *dev, void *data,
 		   struct drm_file *file)
 {
 	struct drm_i915_gem_get_tiling *args = data;
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index ff57f07..7cf2382 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -224,6 +224,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_I915_REG_READ		0x31
 #define DRM_I915_GET_RESET_STATS	0x32
 #define DRM_I915_GEM_USERPTR		0x33
+#define DRM_I915_GEM_CREATE2		0x34
 
 #define DRM_IOCTL_I915_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
 #define DRM_IOCTL_I915_FLUSH		DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -254,6 +255,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_GEM_ENTERVT	DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
 #define DRM_IOCTL_I915_GEM_LEAVEVT	DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
 #define DRM_IOCTL_I915_GEM_CREATE	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create)
+#define DRM_IOCTL_I915_GEM_CREATE2	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE2, struct drm_i915_gem_create2)
 #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)
@@ -437,6 +439,111 @@ struct drm_i915_gem_create {
 	__u32 pad;
 };
 
+struct drm_i915_gem_create2 {
+	/**
+	 * Requested size for the object.
+	 *
+	 * The (page-aligned) allocated size for the object will be returned.
+	 */
+	__u64 size;
+
+	/**
+	 * Requested offset for the object.
+	 *
+	 * Can be used for "soft-pinning" the object into the per-process
+	 * GTT of the target context upon creation. Only possible if using
+	 * contexts and per-process GTTs.
+	 *
+	 * The address must be page-aligned, and have the valid bit set.
+	 */
+	__u64 offset;
+#define I915_CREATE_OFFSET_VALID (1<<0)
+
+	/**
+	 * Target context of the object.
+	 *
+	 * The context of the object can be used for setting the initial offset
+	 * of the object in the per-process GTT.
+	 */
+	__u32 context;
+
+	/**
+	 * Requested placement (which memory domain)
+	 *
+	 * You can request that the object be created from special memory
+	 * rather than regular system pages. Such irregular objects may
+	 * have certain restrictions (such as CPU access to a stolen
+	 * object is verboten).
+	 */
+	__u32 placement;
+#define I915_CREATE_PLACEMENT_SYSTEM 0
+#define I915_CREATE_PLACEMENT_STOLEN 1 /* Cannot use CPU mmaps or pread/pwrite */
+	/**
+	 * Requested domain (which cache domain)
+	 *
+	 * You can request that the object be created from memory in a
+	 * certain cache domain (such as RENDER, CPU or GTT). In some cases,
+	 * this then may allocate from a pool of such pages to avoid any
+	 * migration overhead, but it is always equivalent to performing
+	 * an explicit set-domain(read=DOMAIN, write=DOMAIN) on the
+	 * constructed object.
+	 *
+	 * Set to 0, to leave the initial domain unspecified and defaulting
+	 * to the domain set by the constructor.
+	 *
+	 * See DRM_IOCTL_I915_GEM_SET_DOMAIN
+	 */
+	__u32 domain;
+
+	/**
+	 * Requested cache level.
+	 *
+	 * See DRM_IOCTL_I915_GEM_SET_CACHING
+	 */
+	__u32 caching;
+
+	/**
+	 * Requested tiling mode.
+	 *
+	 * See DRM_IOCTL_I915_GEM_SET_TILING
+	 */
+	__u32 tiling_mode;
+	/**
+	 * Requested stride for tiling.
+	 *
+	 * See DRM_IOCTL_I915_GEM_SET_TILING
+	 */
+	__u32 stride;
+
+	/**
+	 * Requested madvise priority.
+	 *
+	 * See DRM_IOCTL_I915_GEM_MADVISE
+	 */
+	__u32 madvise;
+
+	/**
+	 * Additional miscellaneous flags
+	 *
+	 * Reserved for future use, must be zero.
+	 */
+	__u32 flags;
+
+	/**
+	 * Padding for 64-bit struct alignment.
+	 *
+	 * Reserved for future use, must be zero.
+	 */
+	__u32 pad;
+
+	/**
+	 * Returned handle for the object.
+	 *
+	 * Object handles are nonzero.
+	 */
+	__u32 handle;
+};
+
 struct drm_i915_gem_pread {
 	/** Handle for the object being read. */
 	__u32 handle;
-- 
1.8.5.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 4/4] drm/i915: Add support for stealing purgable stolen pages
  2014-06-20 10:02 [PATCH 0/4] Introduce a new create ioctl for user specified sourab.gupta
                   ` (2 preceding siblings ...)
  2014-06-20 10:02 ` [PATCH v4 3/4] drm/i915: Introduce a new create ioctl for user specified placement sourab.gupta
@ 2014-06-20 10:02 ` sourab.gupta
  2014-07-06 12:58 ` [PATCH 0/4] Introduce a new create ioctl for user specified Gupta, Sourab
  4 siblings, 0 replies; 9+ messages in thread
From: sourab.gupta @ 2014-06-20 10:02 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter, Akash Goel, Gupta, Sourab

From: Chris Wilson <chris@chris-wilson.co.uk>

If we run out of stolen memory when trying to allocate an object, see if
we can reap enough purgeable objects to free up enough contiguous free
space for the allocation. This is in principle very much like evicting
objects to free up enough contiguous space in the vma when binding
a new object - and you will be forgiven for thinking that the code looks
very similar.

At the moment, we do not allow userspace to allocate objects in stolen,
so there is neither the memory pressure to trigger stolen eviction nor
any purgeable objects inside the stolen arena. However, this will change
in the near future, and so better management and defragmentation of
stolen memory will become a real issue.

v2: Remember to remove the drm_mm_node.

testcase: igt/gem_create2

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: "Gupta, Sourab" <sourab.gupta@intel.com>
Cc: "Goel, Akash" <akash.goel@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_stolen.c | 121 ++++++++++++++++++++++++++++++---
 1 file changed, 110 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 6441178..042ae61 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -340,18 +340,29 @@ cleanup:
 	return NULL;
 }
 
-struct drm_i915_gem_object *
-i915_gem_object_create_stolen(struct drm_device *dev, u32 size)
+static bool mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind)
+{
+	if (obj->stolen == NULL)
+		return false;
+
+	if (obj->madv != I915_MADV_DONTNEED)
+		return false;
+
+	if (i915_gem_obj_is_pinned(obj))
+		return false;
+
+	list_add(&obj->obj_exec_link, unwind);
+	return drm_mm_scan_add_block(obj->stolen);
+}
+
+static struct drm_mm_node *
+stolen_alloc(struct drm_i915_private *dev_priv, u32 size)
 {
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct drm_i915_gem_object *obj;
 	struct drm_mm_node *stolen;
+	struct drm_i915_gem_object *obj;
+	struct list_head unwind, evict;
 	int ret;
 
-	if (!drm_mm_initialized(&dev_priv->mm.stolen))
-		return NULL;
-
-	DRM_DEBUG_KMS("creating stolen object: size=%x\n", size);
 	if (size == 0)
 		return NULL;
 
@@ -361,11 +372,99 @@ i915_gem_object_create_stolen(struct drm_device *dev, u32 size)
 
 	ret = drm_mm_insert_node(&dev_priv->mm.stolen, stolen, size,
 				 4096, DRM_MM_SEARCH_DEFAULT);
-	if (ret) {
-		kfree(stolen);
-		return NULL;
+	if (ret == 0)
+		return stolen;
+
+	/* No more stolen memory available, or too fragmented.
+	 * Try evicting purgeable objects and search again.
+	 */
+
+	drm_mm_init_scan(&dev_priv->mm.stolen, size, 4096, 0);
+	INIT_LIST_HEAD(&unwind);
+
+	list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list)
+		if (mark_free(obj, &unwind))
+			goto found;
+
+	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list)
+		if (mark_free(obj, &unwind))
+			goto found;
+
+found:
+	INIT_LIST_HEAD(&evict);
+	while (!list_empty(&unwind)) {
+		obj = list_first_entry(&unwind,
+				       struct drm_i915_gem_object,
+				       obj_exec_link);
+		list_del_init(&obj->obj_exec_link);
+
+		if (drm_mm_scan_remove_block(obj->stolen)) {
+			list_add(&obj->obj_exec_link, &evict);
+			drm_gem_object_reference(&obj->base);
+		}
 	}
 
+	ret = 0;
+	while (!list_empty(&evict)) {
+		obj = list_first_entry(&evict,
+				       struct drm_i915_gem_object,
+				       obj_exec_link);
+		list_del_init(&obj->obj_exec_link);
+
+		if (ret == 0) {
+			struct i915_vma *vma, *vma_next;
+
+			list_for_each_entry_safe(vma, vma_next,
+						 &obj->vma_list,
+						 vma_link)
+				if (i915_vma_unbind(vma))
+					break;
+
+			/* Stolen pins its pages to prevent the
+			 * normal shrinker from processing stolen
+			 * objects.
+			 */
+			i915_gem_object_unpin_pages(obj);
+
+			ret = i915_gem_object_put_pages(obj);
+			if (ret == 0) {
+				i915_gem_object_release_stolen(obj);
+				obj->madv = __I915_MADV_PURGED;
+			} else
+				i915_gem_object_pin_pages(obj);
+		}
+
+		drm_gem_object_unreference(&obj->base);
+	}
+
+	if (ret == 0)
+		ret = drm_mm_insert_node(&dev_priv->mm.stolen, stolen, size,
+					 4096, DRM_MM_SEARCH_DEFAULT);
+	if (ret == 0)
+		return stolen;
+
+	kfree(stolen);
+	return NULL;
+}
+
+struct drm_i915_gem_object *
+i915_gem_object_create_stolen(struct drm_device *dev, u32 size)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj;
+	struct drm_mm_node *stolen;
+
+	lockdep_assert_held(&dev->struct_mutex);
+
+	if (!drm_mm_initialized(&dev_priv->mm.stolen))
+		return NULL;
+
+	DRM_DEBUG_KMS("creating stolen object: size=%x\n", size);
+
+	stolen = stolen_alloc(dev_priv, size);
+	if (stolen == NULL)
+		return NULL;
+
 	obj = _i915_gem_object_create_stolen(dev, stolen);
 	if (obj)
 		return obj;
-- 
1.8.5.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/4] Introduce a new create ioctl for user specified
  2014-06-20 10:02 [PATCH 0/4] Introduce a new create ioctl for user specified sourab.gupta
                   ` (3 preceding siblings ...)
  2014-06-20 10:02 ` [PATCH v2 4/4] drm/i915: Add support for stealing purgable stolen pages sourab.gupta
@ 2014-07-06 12:58 ` Gupta, Sourab
  2014-07-14  9:53   ` Gupta, Sourab
  4 siblings, 1 reply; 9+ messages in thread
From: Gupta, Sourab @ 2014-07-06 12:58 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter, Goel, Akash

On Fri, 2014-06-20 at 10:02 +0000, Gupta, Sourab wrote:
> From: Sourab Gupta <sourab.gupta@intel.com>
> 
> This patch series introduces a new gem create ioctl for user specified
> placement.
> 
> Despite being a unified memory architecture (UMA) some bits of memory
> are more equal than others. In particular we have the thorny issue of
> stolen memory, memory stolen from the system by the BIOS and reserved
> for igfx use. Stolen memory is required for some functions of the GPU
> and display engine, but in general it goes wasted. Whilst we cannot
> return it back to the system, we need to find some other method for
> utilising it. As we do not support direct access to the physical address
> in the stolen region, it behaves like a different class of memory,
> closer in kin to local GPU memory. This strongly suggests that we need a
> placement model like TTM if we are to fully utilize these discrete
> chunks of differing memory.
>     
> This new create ioctl therefore exists to allow the user to create these
> second class buffer objects from stolen memory. At the moment direct
> access by the CPU through mmaps and pread/pwrite are verboten on the
> objects, and so the user must be aware of the limitations of the objects
> created. Yet, those limitations rarely reduce the desired functionality
> in many use cases and so the user should be able to easily fill the
> stolen memory and so help to reduce overall memory pressure.
>     
> The most obvious use case for stolen memory is for the creation of objects
> for the display engine which already have very similar restrictions on
> access. However, we want a reasonably general ioctl in order to cater
> for diverse scenarios beyond the author's imagination.
> 
> Chris Wilson (3):
>   drm/i915: Clearing buffer objects via blitter engine
>   drm/i915: Introduce a new create ioctl for user specified placement
>   drm/i915: Add support for stealing purgable stolen pages
> 
> Deepak S (1):
>   drm/i915: Clearing buffer objects via blitter engine for Gen8
> 
>  drivers/gpu/drm/i915/Makefile          |   1 +
>  drivers/gpu/drm/i915/i915_dma.c        |   5 +-
>  drivers/gpu/drm/i915/i915_drv.h        |  18 ++-
>  drivers/gpu/drm/i915/i915_gem.c        | 208 ++++++++++++++++++++++++++++++---
>  drivers/gpu/drm/i915/i915_gem_exec.c   | 139 ++++++++++++++++++++++
>  drivers/gpu/drm/i915/i915_gem_stolen.c | 121 +++++++++++++++++--
>  drivers/gpu/drm/i915/i915_gem_tiling.c | 106 +++++++++--------
>  include/uapi/drm/i915_drm.h            | 107 +++++++++++++++++
>  8 files changed, 623 insertions(+), 82 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/i915_gem_exec.c
> 

Hi,
Can somebody please review this patch series, alongwith the libdrm
changes(http://lists.freedesktop.org/archives/intel-gfx/2014-June/047296.html) and igt (http://lists.freedesktop.org/archives/intel-gfx/2014-June/047295.html)

Thanks,
Sourab

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/4] Introduce a new create ioctl for user specified
  2014-07-06 12:58 ` [PATCH 0/4] Introduce a new create ioctl for user specified Gupta, Sourab
@ 2014-07-14  9:53   ` Gupta, Sourab
  2014-07-25  8:43     ` Daniel Vetter
  0 siblings, 1 reply; 9+ messages in thread
From: Gupta, Sourab @ 2014-07-14  9:53 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter, Goel, Akash

On Sun, 2014-07-06 at 18:29 +0530, sourab gupta wrote:
> On Fri, 2014-06-20 at 10:02 +0000, Gupta, Sourab wrote:
> > From: Sourab Gupta <sourab.gupta@intel.com>
> > 
> > This patch series introduces a new gem create ioctl for user specified
> > placement.
> > 
> > Despite being a unified memory architecture (UMA) some bits of memory
> > are more equal than others. In particular we have the thorny issue of
> > stolen memory, memory stolen from the system by the BIOS and reserved
> > for igfx use. Stolen memory is required for some functions of the GPU
> > and display engine, but in general it goes wasted. Whilst we cannot
> > return it back to the system, we need to find some other method for
> > utilising it. As we do not support direct access to the physical address
> > in the stolen region, it behaves like a different class of memory,
> > closer in kin to local GPU memory. This strongly suggests that we need a
> > placement model like TTM if we are to fully utilize these discrete
> > chunks of differing memory.
> >     
> > This new create ioctl therefore exists to allow the user to create these
> > second class buffer objects from stolen memory. At the moment direct
> > access by the CPU through mmaps and pread/pwrite are verboten on the
> > objects, and so the user must be aware of the limitations of the objects
> > created. Yet, those limitations rarely reduce the desired functionality
> > in many use cases and so the user should be able to easily fill the
> > stolen memory and so help to reduce overall memory pressure.
> >     
> > The most obvious use case for stolen memory is for the creation of objects
> > for the display engine which already have very similar restrictions on
> > access. However, we want a reasonably general ioctl in order to cater
> > for diverse scenarios beyond the author's imagination.
> > 
> > Chris Wilson (3):
> >   drm/i915: Clearing buffer objects via blitter engine
> >   drm/i915: Introduce a new create ioctl for user specified placement
> >   drm/i915: Add support for stealing purgable stolen pages
> > 
> > Deepak S (1):
> >   drm/i915: Clearing buffer objects via blitter engine for Gen8
> > 
> >  drivers/gpu/drm/i915/Makefile          |   1 +
> >  drivers/gpu/drm/i915/i915_dma.c        |   5 +-
> >  drivers/gpu/drm/i915/i915_drv.h        |  18 ++-
> >  drivers/gpu/drm/i915/i915_gem.c        | 208 ++++++++++++++++++++++++++++++---
> >  drivers/gpu/drm/i915/i915_gem_exec.c   | 139 ++++++++++++++++++++++
> >  drivers/gpu/drm/i915/i915_gem_stolen.c | 121 +++++++++++++++++--
> >  drivers/gpu/drm/i915/i915_gem_tiling.c | 106 +++++++++--------
> >  include/uapi/drm/i915_drm.h            | 107 +++++++++++++++++
> >  8 files changed, 623 insertions(+), 82 deletions(-)
> >  create mode 100644 drivers/gpu/drm/i915/i915_gem_exec.c
> > 
> 
> Hi,
> Can somebody please review this patch series, alongwith the libdrm
> changes(http://lists.freedesktop.org/archives/intel-gfx/2014-June/047296.html) and igt (http://lists.freedesktop.org/archives/intel-gfx/2014-June/047295.html)
> 
> Thanks,
> Sourab

Hi,
Can you please review this patch series.
Thanks,
Sourab

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/4] Introduce a new create ioctl for user specified
  2014-07-14  9:53   ` Gupta, Sourab
@ 2014-07-25  8:43     ` Daniel Vetter
  2014-07-29  3:04       ` Deepak S
  0 siblings, 1 reply; 9+ messages in thread
From: Daniel Vetter @ 2014-07-25  8:43 UTC (permalink / raw)
  To: Gupta, Sourab; +Cc: Daniel Vetter, intel-gfx, Goel, Akash

On Mon, Jul 14, 2014 at 09:53:38AM +0000, Gupta, Sourab wrote:
> On Sun, 2014-07-06 at 18:29 +0530, sourab gupta wrote:
> > On Fri, 2014-06-20 at 10:02 +0000, Gupta, Sourab wrote:
> > > From: Sourab Gupta <sourab.gupta@intel.com>
> > > 
> > > This patch series introduces a new gem create ioctl for user specified
> > > placement.
> > > 
> > > Despite being a unified memory architecture (UMA) some bits of memory
> > > are more equal than others. In particular we have the thorny issue of
> > > stolen memory, memory stolen from the system by the BIOS and reserved
> > > for igfx use. Stolen memory is required for some functions of the GPU
> > > and display engine, but in general it goes wasted. Whilst we cannot
> > > return it back to the system, we need to find some other method for
> > > utilising it. As we do not support direct access to the physical address
> > > in the stolen region, it behaves like a different class of memory,
> > > closer in kin to local GPU memory. This strongly suggests that we need a
> > > placement model like TTM if we are to fully utilize these discrete
> > > chunks of differing memory.
> > >     
> > > This new create ioctl therefore exists to allow the user to create these
> > > second class buffer objects from stolen memory. At the moment direct
> > > access by the CPU through mmaps and pread/pwrite are verboten on the
> > > objects, and so the user must be aware of the limitations of the objects
> > > created. Yet, those limitations rarely reduce the desired functionality
> > > in many use cases and so the user should be able to easily fill the
> > > stolen memory and so help to reduce overall memory pressure.
> > >     
> > > The most obvious use case for stolen memory is for the creation of objects
> > > for the display engine which already have very similar restrictions on
> > > access. However, we want a reasonably general ioctl in order to cater
> > > for diverse scenarios beyond the author's imagination.
> > > 
> > > Chris Wilson (3):
> > >   drm/i915: Clearing buffer objects via blitter engine
> > >   drm/i915: Introduce a new create ioctl for user specified placement
> > >   drm/i915: Add support for stealing purgable stolen pages
> > > 
> > > Deepak S (1):
> > >   drm/i915: Clearing buffer objects via blitter engine for Gen8
> > > 
> > >  drivers/gpu/drm/i915/Makefile          |   1 +
> > >  drivers/gpu/drm/i915/i915_dma.c        |   5 +-
> > >  drivers/gpu/drm/i915/i915_drv.h        |  18 ++-
> > >  drivers/gpu/drm/i915/i915_gem.c        | 208 ++++++++++++++++++++++++++++++---
> > >  drivers/gpu/drm/i915/i915_gem_exec.c   | 139 ++++++++++++++++++++++
> > >  drivers/gpu/drm/i915/i915_gem_stolen.c | 121 +++++++++++++++++--
> > >  drivers/gpu/drm/i915/i915_gem_tiling.c | 106 +++++++++--------
> > >  include/uapi/drm/i915_drm.h            | 107 +++++++++++++++++
> > >  8 files changed, 623 insertions(+), 82 deletions(-)
> > >  create mode 100644 drivers/gpu/drm/i915/i915_gem_exec.c
> > > 
> > 
> > Hi,
> > Can somebody please review this patch series, alongwith the libdrm
> > changes(http://lists.freedesktop.org/archives/intel-gfx/2014-June/047296.html) and igt (http://lists.freedesktop.org/archives/intel-gfx/2014-June/047295.html)
> > 
> > Thanks,
> > Sourab
> 
> Hi,
> Can you please review this patch series.

So on a quick look the kernel side looks sane. The async blitter clear
will have integration issues with the execlist stuff, so having a cpu
clear might be useful and adding the blt clear as a second step. Please
coordinate with the execlist owner.

What's definitely missing is igt coverage. I think we need at least:
- Basic ioctl coverage for create2, including cross-checking with older
  ioctls.
- Testcase for stolen memory including checking that impossible operations
  are all caught correctly.
- Exercising the stolen reaping of purgeable objects.
- Checking that stolen objects are properly cleared.

See http://blog.ffwll.ch/2013/11/testing-requirements-for-drmi915.html for
general testing requirements and
http://blog.ffwll.ch/2013/11/botching-up-ioctls.html for the special
considerations ioctls require.

Thanks, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/4] Introduce a new create ioctl for user specified
  2014-07-25  8:43     ` Daniel Vetter
@ 2014-07-29  3:04       ` Deepak S
  0 siblings, 0 replies; 9+ messages in thread
From: Deepak S @ 2014-07-29  3:04 UTC (permalink / raw)
  To: Daniel Vetter, Gupta, Sourab; +Cc: Daniel Vetter, intel-gfx, Goel, Akash


On Friday 25 July 2014 02:13 PM, Daniel Vetter wrote:
> On Mon, Jul 14, 2014 at 09:53:38AM +0000, Gupta, Sourab wrote:
>> On Sun, 2014-07-06 at 18:29 +0530, sourab gupta wrote:
>>> On Fri, 2014-06-20 at 10:02 +0000, Gupta, Sourab wrote:
>>>> From: Sourab Gupta <sourab.gupta@intel.com>
>>>>
>>>> This patch series introduces a new gem create ioctl for user specified
>>>> placement.
>>>>
>>>> Despite being a unified memory architecture (UMA) some bits of memory
>>>> are more equal than others. In particular we have the thorny issue of
>>>> stolen memory, memory stolen from the system by the BIOS and reserved
>>>> for igfx use. Stolen memory is required for some functions of the GPU
>>>> and display engine, but in general it goes wasted. Whilst we cannot
>>>> return it back to the system, we need to find some other method for
>>>> utilising it. As we do not support direct access to the physical address
>>>> in the stolen region, it behaves like a different class of memory,
>>>> closer in kin to local GPU memory. This strongly suggests that we need a
>>>> placement model like TTM if we are to fully utilize these discrete
>>>> chunks of differing memory.
>>>>      
>>>> This new create ioctl therefore exists to allow the user to create these
>>>> second class buffer objects from stolen memory. At the moment direct
>>>> access by the CPU through mmaps and pread/pwrite are verboten on the
>>>> objects, and so the user must be aware of the limitations of the objects
>>>> created. Yet, those limitations rarely reduce the desired functionality
>>>> in many use cases and so the user should be able to easily fill the
>>>> stolen memory and so help to reduce overall memory pressure.
>>>>      
>>>> The most obvious use case for stolen memory is for the creation of objects
>>>> for the display engine which already have very similar restrictions on
>>>> access. However, we want a reasonably general ioctl in order to cater
>>>> for diverse scenarios beyond the author's imagination.
>>>>
>>>> Chris Wilson (3):
>>>>    drm/i915: Clearing buffer objects via blitter engine
>>>>    drm/i915: Introduce a new create ioctl for user specified placement
>>>>    drm/i915: Add support for stealing purgable stolen pages
>>>>
>>>> Deepak S (1):
>>>>    drm/i915: Clearing buffer objects via blitter engine for Gen8
>>>>
>>>>   drivers/gpu/drm/i915/Makefile          |   1 +
>>>>   drivers/gpu/drm/i915/i915_dma.c        |   5 +-
>>>>   drivers/gpu/drm/i915/i915_drv.h        |  18 ++-
>>>>   drivers/gpu/drm/i915/i915_gem.c        | 208 ++++++++++++++++++++++++++++++---
>>>>   drivers/gpu/drm/i915/i915_gem_exec.c   | 139 ++++++++++++++++++++++
>>>>   drivers/gpu/drm/i915/i915_gem_stolen.c | 121 +++++++++++++++++--
>>>>   drivers/gpu/drm/i915/i915_gem_tiling.c | 106 +++++++++--------
>>>>   include/uapi/drm/i915_drm.h            | 107 +++++++++++++++++
>>>>   8 files changed, 623 insertions(+), 82 deletions(-)
>>>>   create mode 100644 drivers/gpu/drm/i915/i915_gem_exec.c
>>>>
>>> Hi,
>>> Can somebody please review this patch series, alongwith the libdrm
>>> changes(http://lists.freedesktop.org/archives/intel-gfx/2014-June/047296.html) and igt (http://lists.freedesktop.org/archives/intel-gfx/2014-June/047295.html)
>>>
>>> Thanks,
>>> Sourab
>> Hi,
>> Can you please review this patch series.
> So on a quick look the kernel side looks sane. The async blitter clear
> will have integration issues with the execlist stuff, so having a cpu
> clear might be useful and adding the blt clear as a second step. Please
> coordinate with the execlist owner.

+ Thomas to help us with this.

> What's definitely missing is igt coverage. I think we need at least:
> - Basic ioctl coverage for create2, including cross-checking with older
>    ioctls.
> - Testcase for stolen memory including checking that impossible operations
>    are all caught correctly.
> - Exercising the stolen reaping of purgeable objects.
> - Checking that stolen objects are properly cleared.
>
> See http://blog.ffwll.ch/2013/11/testing-requirements-for-drmi915.html for
> general testing requirements and
> http://blog.ffwll.ch/2013/11/botching-up-ioctls.html for the special
> considerations ioctls require.
>
> Thanks, Daniel

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2014-07-28  3:09 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-20 10:02 [PATCH 0/4] Introduce a new create ioctl for user specified sourab.gupta
2014-06-20 10:02 ` [PATCH 1/4] drm/i915: Clearing buffer objects via blitter engine sourab.gupta
2014-06-20 10:02 ` [PATCH 2/4] drm/i915: Clearing buffer objects via blitter engine for Gen8 sourab.gupta
2014-06-20 10:02 ` [PATCH v4 3/4] drm/i915: Introduce a new create ioctl for user specified placement sourab.gupta
2014-06-20 10:02 ` [PATCH v2 4/4] drm/i915: Add support for stealing purgable stolen pages sourab.gupta
2014-07-06 12:58 ` [PATCH 0/4] Introduce a new create ioctl for user specified Gupta, Sourab
2014-07-14  9:53   ` Gupta, Sourab
2014-07-25  8:43     ` Daniel Vetter
2014-07-29  3:04       ` Deepak S

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.