All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/23] huge gtt pages
@ 2017-08-21 18:34 Matthew Auld
  2017-08-21 18:34 ` [PATCH 01/23] mm/shmem: introduce shmem_file_setup_with_mnt Matthew Auld
                   ` (24 more replies)
  0 siblings, 25 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

Some more improvements as per Chris' comments.

Matthew Auld (23):
  mm/shmem: introduce shmem_file_setup_with_mnt
  drm/i915: introduce simple gemfs
  drm/i915/gemfs: enable THP
  drm/i915: introduce page_size_mask to dev_info
  drm/i915: push set_pages down to the callers
  drm/i915: introduce page_size members
  drm/i915: introduce vm set_pages/clear_pages
  drm/i915: align the vma start to the largest gtt page size
  drm/i915: align 64K objects to 2M
  drm/i915: enable IPS bit for 64K pages
  drm/i915: disable GTT cache for 2M/1G pages
  drm/i915: support 1G pages for the 48b PPGTT
  drm/i915: support 2M pages for the 48b PPGTT
  drm/i915: add support for 64K scratch page
  drm/i915: support 64K pages for the 48b PPGTT
  drm/i915: accurate page size tracking for the ppgtt
  drm/i915/debugfs: include some gtt page size metrics
  drm/i915/selftests: huge page tests
  drm/i915/selftests: mix huge pages
  drm/i915: disable platform support for vGPU huge gtt pages
  drm/i915: enable platform support for 64K pages
  drm/i915: enable platform support for 2M pages
  drm/i915: enable platform support for 1G pages

 drivers/gpu/drm/i915/Makefile                      |    1 +
 drivers/gpu/drm/i915/i915_debugfs.c                |   42 +-
 drivers/gpu/drm/i915/i915_drv.h                    |    9 +-
 drivers/gpu/drm/i915/i915_gem.c                    |  135 +-
 drivers/gpu/drm/i915/i915_gem_dmabuf.c             |   21 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c                |  268 +++-
 drivers/gpu/drm/i915/i915_gem_gtt.h                |   22 +-
 drivers/gpu/drm/i915/i915_gem_internal.c           |   18 +-
 drivers/gpu/drm/i915/i915_gem_object.h             |   29 +-
 drivers/gpu/drm/i915/i915_gem_stolen.c             |   16 +-
 drivers/gpu/drm/i915/i915_gem_userptr.c            |   23 +-
 drivers/gpu/drm/i915/i915_gemfs.c                  |   67 +
 drivers/gpu/drm/i915/i915_gemfs.h                  |   34 +
 drivers/gpu/drm/i915/i915_pci.c                    |   25 +
 drivers/gpu/drm/i915/i915_reg.h                    |    3 +
 drivers/gpu/drm/i915/i915_vma.c                    |   47 +-
 drivers/gpu/drm/i915/i915_vma.h                    |    1 +
 drivers/gpu/drm/i915/intel_pm.c                    |    9 +-
 drivers/gpu/drm/i915/selftests/huge_gem_object.c   |   14 +-
 drivers/gpu/drm/i915/selftests/huge_pages.c        | 1310 ++++++++++++++++++++
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c      |   14 +-
 .../gpu/drm/i915/selftests/i915_live_selftests.h   |    1 +
 .../gpu/drm/i915/selftests/i915_mock_selftests.h   |    1 +
 drivers/gpu/drm/i915/selftests/mock_gem_device.c   |   16 +-
 drivers/gpu/drm/i915/selftests/mock_gtt.c          |   11 +-
 drivers/gpu/drm/i915/selftests/scatterlist.c       |   15 +
 include/linux/shmem_fs.h                           |    2 +
 mm/shmem.c                                         |   30 +-
 28 files changed, 2055 insertions(+), 129 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_gemfs.c
 create mode 100644 drivers/gpu/drm/i915/i915_gemfs.h
 create mode 100644 drivers/gpu/drm/i915/selftests/huge_pages.c

-- 
2.13.5

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

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

* [PATCH 01/23] mm/shmem: introduce shmem_file_setup_with_mnt
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-08-23  9:31   ` Joonas Lahtinen
  2017-08-21 18:34   ` Matthew Auld
                   ` (23 subsequent siblings)
  24 siblings, 1 reply; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx
  Cc: Joonas Lahtinen, Chris Wilson, Dave Hansen, Kirill A . Shutemov,
	Hugh Dickins, linux-mm

We are planning to use our own tmpfs mnt in i915 in place of the
shm_mnt, such that we can control the mount options, in particular
huge=, which we require to support huge-gtt-pages. So rather than roll
our own version of __shmem_file_setup, it would be preferred if we could
just give shmem our mnt, and let it do the rest.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Kirill A. Shutemov <kirill@shutemov.name>
Cc: Hugh Dickins <hughd@google.com>
Cc: linux-mm@kvack.org
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 include/linux/shmem_fs.h |  2 ++
 mm/shmem.c               | 30 ++++++++++++++++++++++--------
 2 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index a7d6bd2a918f..27de676f0b63 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -53,6 +53,8 @@ extern struct file *shmem_file_setup(const char *name,
 					loff_t size, unsigned long flags);
 extern struct file *shmem_kernel_file_setup(const char *name, loff_t size,
 					    unsigned long flags);
+extern struct file *shmem_file_setup_with_mnt(struct vfsmount *mnt,
+		const char *name, loff_t size, unsigned long flags);
 extern int shmem_zero_setup(struct vm_area_struct *);
 extern unsigned long shmem_get_unmapped_area(struct file *, unsigned long addr,
 		unsigned long len, unsigned long pgoff, unsigned long flags);
diff --git a/mm/shmem.c b/mm/shmem.c
index 6540e5982444..0975e65ea61c 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -4141,7 +4141,7 @@ static const struct dentry_operations anon_ops = {
 	.d_dname = simple_dname
 };
 
-static struct file *__shmem_file_setup(const char *name, loff_t size,
+static struct file *__shmem_file_setup(struct vfsmount *mnt, const char *name, loff_t size,
 				       unsigned long flags, unsigned int i_flags)
 {
 	struct file *res;
@@ -4150,8 +4150,8 @@ static struct file *__shmem_file_setup(const char *name, loff_t size,
 	struct super_block *sb;
 	struct qstr this;
 
-	if (IS_ERR(shm_mnt))
-		return ERR_CAST(shm_mnt);
+	if (IS_ERR(mnt))
+		return ERR_CAST(mnt);
 
 	if (size < 0 || size > MAX_LFS_FILESIZE)
 		return ERR_PTR(-EINVAL);
@@ -4163,8 +4163,8 @@ static struct file *__shmem_file_setup(const char *name, loff_t size,
 	this.name = name;
 	this.len = strlen(name);
 	this.hash = 0; /* will go */
-	sb = shm_mnt->mnt_sb;
-	path.mnt = mntget(shm_mnt);
+	sb = mnt->mnt_sb;
+	path.mnt = mntget(mnt);
 	path.dentry = d_alloc_pseudo(sb, &this);
 	if (!path.dentry)
 		goto put_memory;
@@ -4209,7 +4209,7 @@ static struct file *__shmem_file_setup(const char *name, loff_t size,
  */
 struct file *shmem_kernel_file_setup(const char *name, loff_t size, unsigned long flags)
 {
-	return __shmem_file_setup(name, size, flags, S_PRIVATE);
+	return __shmem_file_setup(shm_mnt, name, size, flags, S_PRIVATE);
 }
 
 /**
@@ -4220,11 +4220,25 @@ struct file *shmem_kernel_file_setup(const char *name, loff_t size, unsigned lon
  */
 struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags)
 {
-	return __shmem_file_setup(name, size, flags, 0);
+	return __shmem_file_setup(shm_mnt, name, size, flags, 0);
 }
 EXPORT_SYMBOL_GPL(shmem_file_setup);
 
 /**
+ * shmem_file_setup_with_mnt - get an unlinked file living in tmpfs
+ * @mnt: the tmpfs mount where the file will be created
+ * @name: name for dentry (to be seen in /proc/<pid>/maps
+ * @size: size to be set for the file
+ * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size
+ */
+struct file *shmem_file_setup_with_mnt(struct vfsmount *mnt, const char *name,
+				       loff_t size, unsigned long flags)
+{
+	return __shmem_file_setup(mnt, name, size, flags, 0);
+}
+EXPORT_SYMBOL_GPL(shmem_file_setup_with_mnt);
+
+/**
  * shmem_zero_setup - setup a shared anonymous mapping
  * @vma: the vma to be mmapped is prepared by do_mmap_pgoff
  */
@@ -4239,7 +4253,7 @@ int shmem_zero_setup(struct vm_area_struct *vma)
 	 * accessible to the user through its mapping, use S_PRIVATE flag to
 	 * bypass file security, in the same way as shmem_kernel_file_setup().
 	 */
-	file = __shmem_file_setup("dev/zero", size, vma->vm_flags, S_PRIVATE);
+	file = shmem_kernel_file_setup("dev/zero", size, vma->vm_flags);
 	if (IS_ERR(file))
 		return PTR_ERR(file);
 
-- 
2.13.5

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 02/23] drm/i915: introduce simple gemfs
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
@ 2017-08-21 18:34   ` Matthew Auld
  2017-08-21 18:34   ` Matthew Auld
                     ` (23 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx
  Cc: Joonas Lahtinen, Chris Wilson, Dave Hansen, Kirill A . Shutemov,
	Hugh Dickins, linux-mm

Not a fully blown gemfs, just our very own tmpfs kernel mount. Doing so
moves us away from the shmemfs shm_mnt, and gives us the much needed
flexibility to do things like set our own mount options, namely huge=
which should allow us to enable the use of transparent-huge-pages for
our shmem backed objects.

v2: various improvements suggested by Joonas

v3: move gemfs instance to i915.mm and simplify now that we have
file_setup_with_mnt

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Kirill A. Shutemov <kirill@shutemov.name>
Cc: Hugh Dickins <hughd@google.com>
Cc: linux-mm@kvack.org
---
 drivers/gpu/drm/i915/Makefile                    |  1 +
 drivers/gpu/drm/i915/i915_drv.h                  |  3 ++
 drivers/gpu/drm/i915/i915_gem.c                  | 34 +++++++++++++++-
 drivers/gpu/drm/i915/i915_gemfs.c                | 52 ++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gemfs.h                | 34 ++++++++++++++++
 drivers/gpu/drm/i915/selftests/mock_gem_device.c | 10 ++++-
 6 files changed, 131 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_gemfs.c
 create mode 100644 drivers/gpu/drm/i915/i915_gemfs.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 892f52b53060..24c3f672256b 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -47,6 +47,7 @@ i915-y += i915_cmd_parser.o \
 	  i915_gem_tiling.o \
 	  i915_gem_timeline.o \
 	  i915_gem_userptr.o \
+	  i915_gemfs.o \
 	  i915_trace_points.o \
 	  i915_vma.o \
 	  intel_breadcrumbs.o \
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 60267e375e88..a3100f37bcae 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1468,6 +1468,9 @@ struct i915_gem_mm {
 	/** Usable portion of the GTT for GEM */
 	dma_addr_t stolen_base; /* limited to low memory (32-bit) */
 
+	/** tmpfs instance used for shmem backed objects */
+	struct vfsmount *gemfs;
+
 	/** PPGTT used for aliasing the PPGTT with the GTT */
 	struct i915_hw_ppgtt *aliasing_ppgtt;
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b9e8e0d6e97b..3aece90b96c7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -35,6 +35,7 @@
 #include "intel_drv.h"
 #include "intel_frontbuffer.h"
 #include "intel_mocs.h"
+#include "i915_gemfs.h"
 #include <linux/dma-fence-array.h>
 #include <linux/kthread.h>
 #include <linux/reservation.h>
@@ -4288,6 +4289,25 @@ static const struct drm_i915_gem_object_ops i915_gem_object_ops = {
 	.pwrite = i915_gem_object_pwrite_gtt,
 };
 
+static int i915_gem_object_create_shmem(struct drm_device *dev,
+					struct drm_gem_object *obj,
+					size_t size)
+{
+	struct drm_i915_private *i915 = to_i915(dev);
+	struct file *filp;
+
+	drm_gem_private_object_init(dev, obj, size);
+
+	filp = shmem_file_setup_with_mnt(i915->mm.gemfs, "i915", size,
+					 VM_NORESERVE);
+	if (IS_ERR(filp))
+		return PTR_ERR(filp);
+
+	obj->filp = filp;
+
+	return 0;
+}
+
 struct drm_i915_gem_object *
 i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size)
 {
@@ -4312,7 +4332,7 @@ i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size)
 	if (obj == NULL)
 		return ERR_PTR(-ENOMEM);
 
-	ret = drm_gem_object_init(&dev_priv->drm, &obj->base, size);
+	ret = i915_gem_object_create_shmem(&dev_priv->drm, &obj->base, size);
 	if (ret)
 		goto fail;
 
@@ -4887,7 +4907,13 @@ i915_gem_load_init_fences(struct drm_i915_private *dev_priv)
 int
 i915_gem_load_init(struct drm_i915_private *dev_priv)
 {
-	int err = -ENOMEM;
+	int err;
+
+	err = i915_gemfs_init(dev_priv);
+	if (err)
+		return err;
+
+	err = -ENOMEM;
 
 	dev_priv->objects = KMEM_CACHE(drm_i915_gem_object, SLAB_HWCACHE_ALIGN);
 	if (!dev_priv->objects)
@@ -4957,6 +4983,8 @@ i915_gem_load_init(struct drm_i915_private *dev_priv)
 err_objects:
 	kmem_cache_destroy(dev_priv->objects);
 err_out:
+	i915_gemfs_fini(dev_priv);
+
 	return err;
 }
 
@@ -4980,6 +5008,8 @@ void i915_gem_load_cleanup(struct drm_i915_private *dev_priv)
 
 	/* And ensure that our DESTROY_BY_RCU slabs are truly destroyed */
 	rcu_barrier();
+
+	i915_gemfs_fini(dev_priv);
 }
 
 int i915_gem_freeze(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/i915_gemfs.c b/drivers/gpu/drm/i915/i915_gemfs.c
new file mode 100644
index 000000000000..168d0bd98f60
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gemfs.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright A(C) 2017 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.
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/mount.h>
+
+#include "i915_drv.h"
+#include "i915_gemfs.h"
+
+int i915_gemfs_init(struct drm_i915_private *i915)
+{
+	struct file_system_type *type;
+	struct vfsmount *gemfs;
+
+	type = get_fs_type("tmpfs");
+	if (!type)
+		return -ENODEV;
+
+	gemfs = kern_mount(type);
+	if (IS_ERR(gemfs))
+		return PTR_ERR(gemfs);
+
+	i915->mm.gemfs = gemfs;
+
+	return 0;
+}
+
+void i915_gemfs_fini(struct drm_i915_private *i915)
+{
+	kern_unmount(i915->mm.gemfs);
+}
diff --git a/drivers/gpu/drm/i915/i915_gemfs.h b/drivers/gpu/drm/i915/i915_gemfs.h
new file mode 100644
index 000000000000..cca8bdc5b93e
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gemfs.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright A(C) 2017 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.
+ *
+ */
+
+#ifndef __I915_GEMFS_H__
+#define __I915_GEMFS_H__
+
+struct drm_i915_private;
+
+int i915_gemfs_init(struct drm_i915_private *i915);
+
+void i915_gemfs_fini(struct drm_i915_private *i915);
+
+#endif
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 678723430d78..4d82c978a769 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -83,6 +83,8 @@ static void mock_device_release(struct drm_device *dev)
 	kmem_cache_destroy(i915->vmas);
 	kmem_cache_destroy(i915->objects);
 
+	i915_gemfs_fini(i915);
+
 	drm_dev_fini(&i915->drm);
 	put_device(&i915->drm.pdev->dev);
 }
@@ -189,9 +191,13 @@ struct drm_i915_private *mock_gem_device(void)
 
 	i915->gt.awake = true;
 
+	err = i915_gemfs_init(i915);
+	if (err)
+		goto err_wq;
+
 	i915->objects = KMEM_CACHE(mock_object, SLAB_HWCACHE_ALIGN);
 	if (!i915->objects)
-		goto err_wq;
+		goto err_gemfs;
 
 	i915->vmas = KMEM_CACHE(i915_vma, SLAB_HWCACHE_ALIGN);
 	if (!i915->vmas)
@@ -249,6 +255,8 @@ struct drm_i915_private *mock_gem_device(void)
 	kmem_cache_destroy(i915->vmas);
 err_objects:
 	kmem_cache_destroy(i915->objects);
+err_gemfs:
+	i915_gemfs_fini(i915);
 err_wq:
 	destroy_workqueue(i915->wq);
 put_device:
-- 
2.13.5

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 02/23] drm/i915: introduce simple gemfs
@ 2017-08-21 18:34   ` Matthew Auld
  0 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx
  Cc: Joonas Lahtinen, Chris Wilson, Dave Hansen, Kirill A . Shutemov,
	Hugh Dickins, linux-mm

Not a fully blown gemfs, just our very own tmpfs kernel mount. Doing so
moves us away from the shmemfs shm_mnt, and gives us the much needed
flexibility to do things like set our own mount options, namely huge=
which should allow us to enable the use of transparent-huge-pages for
our shmem backed objects.

v2: various improvements suggested by Joonas

v3: move gemfs instance to i915.mm and simplify now that we have
file_setup_with_mnt

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Kirill A. Shutemov <kirill@shutemov.name>
Cc: Hugh Dickins <hughd@google.com>
Cc: linux-mm@kvack.org
---
 drivers/gpu/drm/i915/Makefile                    |  1 +
 drivers/gpu/drm/i915/i915_drv.h                  |  3 ++
 drivers/gpu/drm/i915/i915_gem.c                  | 34 +++++++++++++++-
 drivers/gpu/drm/i915/i915_gemfs.c                | 52 ++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gemfs.h                | 34 ++++++++++++++++
 drivers/gpu/drm/i915/selftests/mock_gem_device.c | 10 ++++-
 6 files changed, 131 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_gemfs.c
 create mode 100644 drivers/gpu/drm/i915/i915_gemfs.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 892f52b53060..24c3f672256b 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -47,6 +47,7 @@ i915-y += i915_cmd_parser.o \
 	  i915_gem_tiling.o \
 	  i915_gem_timeline.o \
 	  i915_gem_userptr.o \
+	  i915_gemfs.o \
 	  i915_trace_points.o \
 	  i915_vma.o \
 	  intel_breadcrumbs.o \
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 60267e375e88..a3100f37bcae 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1468,6 +1468,9 @@ struct i915_gem_mm {
 	/** Usable portion of the GTT for GEM */
 	dma_addr_t stolen_base; /* limited to low memory (32-bit) */
 
+	/** tmpfs instance used for shmem backed objects */
+	struct vfsmount *gemfs;
+
 	/** PPGTT used for aliasing the PPGTT with the GTT */
 	struct i915_hw_ppgtt *aliasing_ppgtt;
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b9e8e0d6e97b..3aece90b96c7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -35,6 +35,7 @@
 #include "intel_drv.h"
 #include "intel_frontbuffer.h"
 #include "intel_mocs.h"
+#include "i915_gemfs.h"
 #include <linux/dma-fence-array.h>
 #include <linux/kthread.h>
 #include <linux/reservation.h>
@@ -4288,6 +4289,25 @@ static const struct drm_i915_gem_object_ops i915_gem_object_ops = {
 	.pwrite = i915_gem_object_pwrite_gtt,
 };
 
+static int i915_gem_object_create_shmem(struct drm_device *dev,
+					struct drm_gem_object *obj,
+					size_t size)
+{
+	struct drm_i915_private *i915 = to_i915(dev);
+	struct file *filp;
+
+	drm_gem_private_object_init(dev, obj, size);
+
+	filp = shmem_file_setup_with_mnt(i915->mm.gemfs, "i915", size,
+					 VM_NORESERVE);
+	if (IS_ERR(filp))
+		return PTR_ERR(filp);
+
+	obj->filp = filp;
+
+	return 0;
+}
+
 struct drm_i915_gem_object *
 i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size)
 {
@@ -4312,7 +4332,7 @@ i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size)
 	if (obj == NULL)
 		return ERR_PTR(-ENOMEM);
 
-	ret = drm_gem_object_init(&dev_priv->drm, &obj->base, size);
+	ret = i915_gem_object_create_shmem(&dev_priv->drm, &obj->base, size);
 	if (ret)
 		goto fail;
 
@@ -4887,7 +4907,13 @@ i915_gem_load_init_fences(struct drm_i915_private *dev_priv)
 int
 i915_gem_load_init(struct drm_i915_private *dev_priv)
 {
-	int err = -ENOMEM;
+	int err;
+
+	err = i915_gemfs_init(dev_priv);
+	if (err)
+		return err;
+
+	err = -ENOMEM;
 
 	dev_priv->objects = KMEM_CACHE(drm_i915_gem_object, SLAB_HWCACHE_ALIGN);
 	if (!dev_priv->objects)
@@ -4957,6 +4983,8 @@ i915_gem_load_init(struct drm_i915_private *dev_priv)
 err_objects:
 	kmem_cache_destroy(dev_priv->objects);
 err_out:
+	i915_gemfs_fini(dev_priv);
+
 	return err;
 }
 
@@ -4980,6 +5008,8 @@ void i915_gem_load_cleanup(struct drm_i915_private *dev_priv)
 
 	/* And ensure that our DESTROY_BY_RCU slabs are truly destroyed */
 	rcu_barrier();
+
+	i915_gemfs_fini(dev_priv);
 }
 
 int i915_gem_freeze(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/i915_gemfs.c b/drivers/gpu/drm/i915/i915_gemfs.c
new file mode 100644
index 000000000000..168d0bd98f60
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gemfs.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright © 2017 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.
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/mount.h>
+
+#include "i915_drv.h"
+#include "i915_gemfs.h"
+
+int i915_gemfs_init(struct drm_i915_private *i915)
+{
+	struct file_system_type *type;
+	struct vfsmount *gemfs;
+
+	type = get_fs_type("tmpfs");
+	if (!type)
+		return -ENODEV;
+
+	gemfs = kern_mount(type);
+	if (IS_ERR(gemfs))
+		return PTR_ERR(gemfs);
+
+	i915->mm.gemfs = gemfs;
+
+	return 0;
+}
+
+void i915_gemfs_fini(struct drm_i915_private *i915)
+{
+	kern_unmount(i915->mm.gemfs);
+}
diff --git a/drivers/gpu/drm/i915/i915_gemfs.h b/drivers/gpu/drm/i915/i915_gemfs.h
new file mode 100644
index 000000000000..cca8bdc5b93e
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gemfs.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright © 2017 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.
+ *
+ */
+
+#ifndef __I915_GEMFS_H__
+#define __I915_GEMFS_H__
+
+struct drm_i915_private;
+
+int i915_gemfs_init(struct drm_i915_private *i915);
+
+void i915_gemfs_fini(struct drm_i915_private *i915);
+
+#endif
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 678723430d78..4d82c978a769 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -83,6 +83,8 @@ static void mock_device_release(struct drm_device *dev)
 	kmem_cache_destroy(i915->vmas);
 	kmem_cache_destroy(i915->objects);
 
+	i915_gemfs_fini(i915);
+
 	drm_dev_fini(&i915->drm);
 	put_device(&i915->drm.pdev->dev);
 }
@@ -189,9 +191,13 @@ struct drm_i915_private *mock_gem_device(void)
 
 	i915->gt.awake = true;
 
+	err = i915_gemfs_init(i915);
+	if (err)
+		goto err_wq;
+
 	i915->objects = KMEM_CACHE(mock_object, SLAB_HWCACHE_ALIGN);
 	if (!i915->objects)
-		goto err_wq;
+		goto err_gemfs;
 
 	i915->vmas = KMEM_CACHE(i915_vma, SLAB_HWCACHE_ALIGN);
 	if (!i915->vmas)
@@ -249,6 +255,8 @@ struct drm_i915_private *mock_gem_device(void)
 	kmem_cache_destroy(i915->vmas);
 err_objects:
 	kmem_cache_destroy(i915->objects);
+err_gemfs:
+	i915_gemfs_fini(i915);
 err_wq:
 	destroy_workqueue(i915->wq);
 put_device:
-- 
2.13.5

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* [PATCH 03/23] drm/i915/gemfs: enable THP
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
  2017-08-21 18:34 ` [PATCH 01/23] mm/shmem: introduce shmem_file_setup_with_mnt Matthew Auld
  2017-08-21 18:34   ` Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-08-29 14:49   ` Joonas Lahtinen
  2017-08-21 18:34 ` [PATCH 04/23] drm/i915: introduce page_size_mask to dev_info Matthew Auld
                   ` (21 subsequent siblings)
  24 siblings, 1 reply; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

Enable transparent-huge-pages through gemfs by mounting with
huge=within_size.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gemfs.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gemfs.c b/drivers/gpu/drm/i915/i915_gemfs.c
index 168d0bd98f60..999f0b6a2d64 100644
--- a/drivers/gpu/drm/i915/i915_gemfs.c
+++ b/drivers/gpu/drm/i915/i915_gemfs.c
@@ -24,6 +24,7 @@
 
 #include <linux/fs.h>
 #include <linux/mount.h>
+#include <linux/pagemap.h>
 
 #include "i915_drv.h"
 #include "i915_gemfs.h"
@@ -41,6 +42,20 @@ int i915_gemfs_init(struct drm_i915_private *i915)
 	if (IS_ERR(gemfs))
 		return PTR_ERR(gemfs);
 
+	if (has_transparent_hugepage()) {
+		struct super_block *sb = gemfs->mnt_sb;
+		char options[] = "huge=within_size";
+		int flags = 0;
+
+		/* We don't consider failure to remount fatal, since this should
+		 * only ever attempt to modify the mount options of the sb, and
+		 * so should always leave us with a working mount upon failure.
+		 * Hence decoupling this from the actual kern_mount is probably
+		 * advisable.
+		 */
+		WARN_ON(sb->s_op->remount_fs(sb, &flags, options));
+	}
+
 	i915->mm.gemfs = gemfs;
 
 	return 0;
-- 
2.13.5

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

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

* [PATCH 04/23] drm/i915: introduce page_size_mask to dev_info
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (2 preceding siblings ...)
  2017-08-21 18:34 ` [PATCH 03/23] drm/i915/gemfs: enable THP Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-08-21 18:34 ` [PATCH 05/23] drm/i915: push set_pages down to the callers Matthew Auld
                   ` (20 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

In preparation for huge gtt pages expose a page_size_mask as part of the
device info, to indicate the page sizes supported by the HW.  Currently
only 4K is supported.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h                  |  1 +
 drivers/gpu/drm/i915/i915_gem_gtt.h              |  8 +++++++-
 drivers/gpu/drm/i915/i915_pci.c                  | 20 ++++++++++++++++++++
 drivers/gpu/drm/i915/selftests/mock_gem_device.c |  3 +++
 4 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a3100f37bcae..224f8a8ae317 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -844,6 +844,7 @@ struct intel_device_info {
 	enum intel_platform platform;
 	u8 ring_mask; /* Rings supported by the HW */
 	u8 num_rings;
+	unsigned int page_size_mask; /* page sizes supported by the HW */
 #define DEFINE_FLAG(name) u8 name:1
 	DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG);
 #undef DEFINE_FLAG
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index b4e3aa7c0ce1..4c2f7d7c1e7d 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -42,7 +42,13 @@
 #include "i915_gem_request.h"
 #include "i915_selftest.h"
 
-#define I915_GTT_PAGE_SIZE 4096UL
+#define I915_GTT_PAGE_SIZE_4K BIT(12)
+#define I915_GTT_PAGE_SIZE_64K BIT(16)
+#define I915_GTT_PAGE_SIZE_2M BIT(21)
+#define I915_GTT_PAGE_SIZE_1G BIT(30)
+
+#define I915_GTT_PAGE_SIZE I915_GTT_PAGE_SIZE_4K
+
 #define I915_GTT_MIN_ALIGNMENT I915_GTT_PAGE_SIZE
 
 #define I915_FENCE_REG_NONE -1
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 09d97e0990b7..b07fabf1cd4f 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -56,6 +56,10 @@
 	.color = { .degamma_lut_size = 65, .gamma_lut_size = 257 }
 
 /* Keep in gen based order, and chronological order within a gen */
+
+#define GEN_DEFAULT_PAGE_SIZES \
+	.page_size_mask = I915_GTT_PAGE_SIZE_4K
+
 #define GEN2_FEATURES \
 	.gen = 2, .num_pipes = 1, \
 	.has_overlay = 1, .overlay_needs_physical = 1, \
@@ -64,6 +68,7 @@
 	.unfenced_needs_alignment = 1, \
 	.ring_mask = RENDER_RING, \
 	GEN_DEFAULT_PIPEOFFSETS, \
+	GEN_DEFAULT_PAGE_SIZES, \
 	CURSOR_OFFSETS
 
 static const struct intel_device_info intel_i830_info = {
@@ -96,6 +101,7 @@ static const struct intel_device_info intel_i865g_info = {
 	.has_gmch_display = 1, \
 	.ring_mask = RENDER_RING, \
 	GEN_DEFAULT_PIPEOFFSETS, \
+	GEN_DEFAULT_PAGE_SIZES, \
 	CURSOR_OFFSETS
 
 static const struct intel_device_info intel_i915g_info = {
@@ -158,6 +164,7 @@ static const struct intel_device_info intel_pineview_info = {
 	.has_gmch_display = 1, \
 	.ring_mask = RENDER_RING, \
 	GEN_DEFAULT_PIPEOFFSETS, \
+	GEN_DEFAULT_PAGE_SIZES, \
 	CURSOR_OFFSETS
 
 static const struct intel_device_info intel_i965g_info = {
@@ -198,6 +205,7 @@ static const struct intel_device_info intel_gm45_info = {
 	.has_gmbus_irq = 1, \
 	.ring_mask = RENDER_RING | BSD_RING, \
 	GEN_DEFAULT_PIPEOFFSETS, \
+	GEN_DEFAULT_PAGE_SIZES, \
 	CURSOR_OFFSETS
 
 static const struct intel_device_info intel_ironlake_d_info = {
@@ -222,6 +230,7 @@ static const struct intel_device_info intel_ironlake_m_info = {
 	.has_gmbus_irq = 1, \
 	.has_aliasing_ppgtt = 1, \
 	GEN_DEFAULT_PIPEOFFSETS, \
+	GEN_DEFAULT_PAGE_SIZES, \
 	CURSOR_OFFSETS
 
 static const struct intel_device_info intel_sandybridge_d_info = {
@@ -247,6 +256,7 @@ static const struct intel_device_info intel_sandybridge_m_info = {
 	.has_aliasing_ppgtt = 1, \
 	.has_full_ppgtt = 1, \
 	GEN_DEFAULT_PIPEOFFSETS, \
+	GEN_DEFAULT_PAGE_SIZES, \
 	IVB_CURSOR_OFFSETS
 
 static const struct intel_device_info intel_ivybridge_d_info = {
@@ -284,6 +294,7 @@ static const struct intel_device_info intel_valleyview_info = {
 	.has_full_ppgtt = 1,
 	.ring_mask = RENDER_RING | BSD_RING | BLT_RING,
 	.display_mmio_offset = VLV_DISPLAY_BASE,
+	GEN_DEFAULT_PAGE_SIZES,
 	GEN_DEFAULT_PIPEOFFSETS,
 	CURSOR_OFFSETS
 };
@@ -308,6 +319,7 @@ static const struct intel_device_info intel_haswell_info = {
 #define BDW_FEATURES \
 	HSW_FEATURES, \
 	BDW_COLORS, \
+	GEN_DEFAULT_PAGE_SIZES, \
 	.has_logical_ring_contexts = 1, \
 	.has_full_48bit_ppgtt = 1, \
 	.has_64bit_reloc = 1, \
@@ -345,13 +357,18 @@ static const struct intel_device_info intel_cherryview_info = {
 	.has_full_ppgtt = 1,
 	.has_reset_engine = 1,
 	.display_mmio_offset = VLV_DISPLAY_BASE,
+	GEN_DEFAULT_PAGE_SIZES,
 	GEN_CHV_PIPEOFFSETS,
 	CURSOR_OFFSETS,
 	CHV_COLORS,
 };
 
+#define GEN9_DEFAULT_PAGE_SIZES \
+	.page_size_mask = I915_GTT_PAGE_SIZE_4K
+
 #define SKL_PLATFORM \
 	BDW_FEATURES, \
+	GEN9_DEFAULT_PAGE_SIZES, \
 	.gen = 9, \
 	.platform = INTEL_SKYLAKE, \
 	.has_csr = 1, \
@@ -390,6 +407,7 @@ static const struct intel_device_info intel_skylake_gt3_info = {
 	.has_full_ppgtt = 1, \
 	.has_full_48bit_ppgtt = 1, \
 	.has_reset_engine = 1, \
+	GEN9_DEFAULT_PAGE_SIZES, \
 	GEN_DEFAULT_PIPEOFFSETS, \
 	IVB_CURSOR_OFFSETS, \
 	BDW_COLORS
@@ -410,6 +428,7 @@ static const struct intel_device_info intel_geminilake_info = {
 
 #define KBL_PLATFORM \
 	BDW_FEATURES, \
+	GEN9_DEFAULT_PAGE_SIZES, \
 	.gen = 9, \
 	.platform = INTEL_KABYLAKE, \
 	.has_csr = 1, \
@@ -445,6 +464,7 @@ static const struct intel_device_info intel_coffeelake_gt3_info = {
 
 static const struct intel_device_info intel_cannonlake_info = {
 	BDW_FEATURES,
+	GEN9_DEFAULT_PAGE_SIZES, \
 	.is_alpha_support = 1,
 	.platform = INTEL_CANNONLAKE,
 	.gen = 10,
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 4d82c978a769..39acab2396b2 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -169,6 +169,9 @@ struct drm_i915_private *mock_gem_device(void)
 
 	mkwrite_device_info(i915)->gen = -1;
 
+	mkwrite_device_info(i915)->page_size_mask =
+		I915_GTT_PAGE_SIZE_4K;
+
 	spin_lock_init(&i915->mm.object_stat_lock);
 	mock_uncore_init(i915);
 
-- 
2.13.5

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

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

* [PATCH 05/23] drm/i915: push set_pages down to the callers
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (3 preceding siblings ...)
  2017-08-21 18:34 ` [PATCH 04/23] drm/i915: introduce page_size_mask to dev_info Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-08-29 14:44   ` Joonas Lahtinen
  2017-08-21 18:34 ` [PATCH 06/23] drm/i915: introduce page_size members Matthew Auld
                   ` (19 subsequent siblings)
  24 siblings, 1 reply; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

Each backend is now responsible for calling __i915_gem_object_set_pages
upon successfully gathering its backing storage. This eliminates the
inconsistency between the async and sync paths, which stands out even
more when we start throwing around an sg_mask in a later patch.

Suggested-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem.c                  | 45 +++++++++++++-----------
 drivers/gpu/drm/i915/i915_gem_dmabuf.c           | 15 +++++---
 drivers/gpu/drm/i915/i915_gem_internal.c         | 15 ++++----
 drivers/gpu/drm/i915/i915_gem_object.h           |  2 +-
 drivers/gpu/drm/i915/i915_gem_stolen.c           | 16 ++++++---
 drivers/gpu/drm/i915/i915_gem_userptr.c          | 12 +++----
 drivers/gpu/drm/i915/selftests/huge_gem_object.c | 14 ++++----
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c    | 12 ++++---
 8 files changed, 77 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 3aece90b96c7..1c61d1b5eaa5 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -162,8 +162,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
 	return 0;
 }
 
-static struct sg_table *
-i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
+static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
 {
 	struct address_space *mapping = obj->base.filp->f_mapping;
 	drm_dma_handle_t *phys;
@@ -171,9 +170,10 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
 	struct scatterlist *sg;
 	char *vaddr;
 	int i;
+	int err;
 
 	if (WARN_ON(i915_gem_object_needs_bit17_swizzle(obj)))
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 
 	/* Always aligning to the object size, allows a single allocation
 	 * to handle all possible callers, and given typical object sizes,
@@ -183,7 +183,7 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
 			     obj->base.size,
 			     roundup_pow_of_two(obj->base.size));
 	if (!phys)
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 
 	vaddr = phys->vaddr;
 	for (i = 0; i < obj->base.size / PAGE_SIZE; i++) {
@@ -192,7 +192,7 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
 
 		page = shmem_read_mapping_page(mapping, i);
 		if (IS_ERR(page)) {
-			st = ERR_CAST(page);
+			err = PTR_ERR(page);
 			goto err_phys;
 		}
 
@@ -209,13 +209,13 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
 
 	st = kmalloc(sizeof(*st), GFP_KERNEL);
 	if (!st) {
-		st = ERR_PTR(-ENOMEM);
+		err = -ENOMEM;
 		goto err_phys;
 	}
 
 	if (sg_alloc_table(st, 1, GFP_KERNEL)) {
 		kfree(st);
-		st = ERR_PTR(-ENOMEM);
+		err = -ENOMEM;
 		goto err_phys;
 	}
 
@@ -227,11 +227,15 @@ i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
 	sg_dma_len(sg) = obj->base.size;
 
 	obj->phys_handle = phys;
-	return st;
+
+	__i915_gem_object_set_pages(obj, st);
+
+	return 0;
 
 err_phys:
 	drm_pci_free(obj->base.dev, phys);
-	return st;
+
+	return err;
 }
 
 static void __start_cpu_write(struct drm_i915_gem_object *obj)
@@ -2290,8 +2294,7 @@ static bool i915_sg_trim(struct sg_table *orig_st)
 	return true;
 }
 
-static struct sg_table *
-i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
+static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 {
 	struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
 	const unsigned long page_count = obj->base.size / PAGE_SIZE;
@@ -2319,12 +2322,12 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 
 	st = kmalloc(sizeof(*st), GFP_KERNEL);
 	if (st == NULL)
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 
 rebuild_st:
 	if (sg_alloc_table(st, page_count, GFP_KERNEL)) {
 		kfree(st);
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 	}
 
 	/* Get the list of pages out of our struct file.  They'll be pinned
@@ -2432,7 +2435,9 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 	if (i915_gem_object_needs_bit17_swizzle(obj))
 		i915_gem_object_do_bit_17_swizzle(obj, st);
 
-	return st;
+	__i915_gem_object_set_pages(obj, st);
+
+	return 0;
 
 err_sg:
 	sg_mark_end(sg);
@@ -2453,7 +2458,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 	if (ret == -ENOSPC)
 		ret = -ENOMEM;
 
-	return ERR_PTR(ret);
+	return ret;
 }
 
 void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
@@ -2476,7 +2481,7 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
 
 static int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
 {
-	struct sg_table *pages;
+	int ret;
 
 	GEM_BUG_ON(i915_gem_object_has_pinned_pages(obj));
 
@@ -2485,12 +2490,10 @@ static int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
 		return -EFAULT;
 	}
 
-	pages = obj->ops->get_pages(obj);
-	if (unlikely(IS_ERR(pages)))
-		return PTR_ERR(pages);
+	ret = obj->ops->get_pages(obj);
+	GEM_BUG_ON(ret == 0 && IS_ERR_OR_NULL(obj->mm.pages));
 
-	__i915_gem_object_set_pages(obj, pages);
-	return 0;
+	return ret;
 }
 
 /* Ensure that the associated pages are gathered from the backing storage
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index 6176e589cf09..4c4dc85159fb 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -256,11 +256,18 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
 	return drm_gem_dmabuf_export(dev, &exp_info);
 }
 
-static struct sg_table *
-i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
+static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
 {
-	return dma_buf_map_attachment(obj->base.import_attach,
-				      DMA_BIDIRECTIONAL);
+	struct sg_table *pages;
+
+	pages = dma_buf_map_attachment(obj->base.import_attach,
+				       DMA_BIDIRECTIONAL);
+	if (IS_ERR(pages))
+		return PTR_ERR(pages);
+
+	__i915_gem_object_set_pages(obj, pages);
+
+	return 0;
 }
 
 static void i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object *obj,
diff --git a/drivers/gpu/drm/i915/i915_gem_internal.c b/drivers/gpu/drm/i915/i915_gem_internal.c
index c1f64ddaf8aa..f59764da4254 100644
--- a/drivers/gpu/drm/i915/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/i915_gem_internal.c
@@ -44,8 +44,7 @@ static void internal_free_pages(struct sg_table *st)
 	kfree(st);
 }
 
-static struct sg_table *
-i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
+static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 {
 	struct drm_i915_private *i915 = to_i915(obj->base.dev);
 	struct sg_table *st;
@@ -78,12 +77,12 @@ i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 create_st:
 	st = kmalloc(sizeof(*st), GFP_KERNEL);
 	if (!st)
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 
 	npages = obj->base.size / PAGE_SIZE;
 	if (sg_alloc_table(st, npages, GFP_KERNEL)) {
 		kfree(st);
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 	}
 
 	sg = st->sgl;
@@ -132,13 +131,17 @@ i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 	 * object are only valid whilst active and pinned.
 	 */
 	obj->mm.madv = I915_MADV_DONTNEED;
-	return st;
+
+	__i915_gem_object_set_pages(obj, st);
+
+	return 0;
 
 err:
 	sg_set_page(sg, NULL, 0, 0);
 	sg_mark_end(sg);
 	internal_free_pages(st);
-	return ERR_PTR(-ENOMEM);
+
+	return -ENOMEM;
 }
 
 static void i915_gem_object_put_pages_internal(struct drm_i915_gem_object *obj,
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index c30d8f808185..036e847b27f0 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -69,7 +69,7 @@ struct drm_i915_gem_object_ops {
 	 * being released or under memory pressure (where we attempt to
 	 * reap pages for the shrinker).
 	 */
-	struct sg_table *(*get_pages)(struct drm_i915_gem_object *);
+	int (*get_pages)(struct drm_i915_gem_object *);
 	void (*put_pages)(struct drm_i915_gem_object *, struct sg_table *);
 
 	int (*pwrite)(struct drm_i915_gem_object *,
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 507c9f0d8df1..537ecb224db0 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -539,12 +539,18 @@ i915_pages_create_for_stolen(struct drm_device *dev,
 	return st;
 }
 
-static struct sg_table *
-i915_gem_object_get_pages_stolen(struct drm_i915_gem_object *obj)
+static int i915_gem_object_get_pages_stolen(struct drm_i915_gem_object *obj)
 {
-	return i915_pages_create_for_stolen(obj->base.dev,
-					    obj->stolen->start,
-					    obj->stolen->size);
+	struct sg_table *pages =
+		i915_pages_create_for_stolen(obj->base.dev,
+					     obj->stolen->start,
+					     obj->stolen->size);
+	if (IS_ERR(pages))
+		return PTR_ERR(pages);
+
+	__i915_gem_object_set_pages(obj, pages);
+
+	return 0;
 }
 
 static void i915_gem_object_put_pages_stolen(struct drm_i915_gem_object *obj,
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
index f152a38d7079..25da3c60e961 100644
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -456,6 +456,8 @@ __i915_gem_userptr_set_pages(struct drm_i915_gem_object *obj,
 		return ERR_PTR(ret);
 	}
 
+	__i915_gem_object_set_pages(obj, pages);
+
 	return pages;
 }
 
@@ -542,7 +544,6 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
 		if (pinned == npages) {
 			pages = __i915_gem_userptr_set_pages(obj, pvec, npages);
 			if (!IS_ERR(pages)) {
-				__i915_gem_object_set_pages(obj, pages);
 				pinned = 0;
 				pages = NULL;
 			}
@@ -603,8 +604,7 @@ __i915_gem_userptr_get_pages_schedule(struct drm_i915_gem_object *obj)
 	return ERR_PTR(-EAGAIN);
 }
 
-static struct sg_table *
-i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
+static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
 {
 	const int num_pages = obj->base.size >> PAGE_SHIFT;
 	struct mm_struct *mm = obj->userptr.mm->mm;
@@ -633,9 +633,9 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
 	if (obj->userptr.work) {
 		/* active flag should still be held for the pending work */
 		if (IS_ERR(obj->userptr.work))
-			return ERR_CAST(obj->userptr.work);
+			return PTR_ERR(obj->userptr.work);
 		else
-			return ERR_PTR(-EAGAIN);
+			return -EAGAIN;
 	}
 
 	pvec = NULL;
@@ -671,7 +671,7 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
 		release_pages(pvec, pinned, 0);
 	kvfree(pvec);
 
-	return pages;
+	return PTR_ERR_OR_ZERO(pages);
 }
 
 static void
diff --git a/drivers/gpu/drm/i915/selftests/huge_gem_object.c b/drivers/gpu/drm/i915/selftests/huge_gem_object.c
index c5c7e8efbdd3..41c15f3aa467 100644
--- a/drivers/gpu/drm/i915/selftests/huge_gem_object.c
+++ b/drivers/gpu/drm/i915/selftests/huge_gem_object.c
@@ -37,8 +37,7 @@ static void huge_free_pages(struct drm_i915_gem_object *obj,
 	kfree(pages);
 }
 
-static struct sg_table *
-huge_get_pages(struct drm_i915_gem_object *obj)
+static int huge_get_pages(struct drm_i915_gem_object *obj)
 {
 #define GFP (GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY)
 	const unsigned long nreal = obj->scratch / PAGE_SIZE;
@@ -49,11 +48,11 @@ huge_get_pages(struct drm_i915_gem_object *obj)
 
 	pages = kmalloc(sizeof(*pages), GFP);
 	if (!pages)
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 
 	if (sg_alloc_table(pages, npages, GFP)) {
 		kfree(pages);
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 	}
 
 	sg = pages->sgl;
@@ -81,11 +80,14 @@ huge_get_pages(struct drm_i915_gem_object *obj)
 	if (i915_gem_gtt_prepare_pages(obj, pages))
 		goto err;
 
-	return pages;
+	__i915_gem_object_set_pages(obj, pages);
+
+	return 0;
 
 err:
 	huge_free_pages(obj, pages);
-	return ERR_PTR(-ENOMEM);
+
+	return -ENOMEM;
 #undef GFP
 }
 
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 6b132caffa18..aa1db375d59a 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -39,8 +39,7 @@ static void fake_free_pages(struct drm_i915_gem_object *obj,
 	kfree(pages);
 }
 
-static struct sg_table *
-fake_get_pages(struct drm_i915_gem_object *obj)
+static int fake_get_pages(struct drm_i915_gem_object *obj)
 {
 #define GFP (GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY)
 #define PFN_BIAS 0x1000
@@ -50,12 +49,12 @@ fake_get_pages(struct drm_i915_gem_object *obj)
 
 	pages = kmalloc(sizeof(*pages), GFP);
 	if (!pages)
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 
 	rem = round_up(obj->base.size, BIT(31)) >> 31;
 	if (sg_alloc_table(pages, rem, GFP)) {
 		kfree(pages);
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 	}
 
 	rem = obj->base.size;
@@ -72,7 +71,10 @@ fake_get_pages(struct drm_i915_gem_object *obj)
 	GEM_BUG_ON(rem);
 
 	obj->mm.madv = I915_MADV_DONTNEED;
-	return pages;
+
+	__i915_gem_object_set_pages(obj, pages);
+
+	return 0;
 #undef GFP
 }
 
-- 
2.13.5

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

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

* [PATCH 06/23] drm/i915: introduce page_size members
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (4 preceding siblings ...)
  2017-08-21 18:34 ` [PATCH 05/23] drm/i915: push set_pages down to the callers Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-09-05  9:25   ` Joonas Lahtinen
  2017-08-21 18:34 ` [PATCH 07/23] drm/i915: introduce vm set_pages/clear_pages Matthew Auld
                   ` (18 subsequent siblings)
  24 siblings, 1 reply; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

In preparation for supporting huge gtt pages for the ppgtt, we introduce
page size members for gem objects.  We fill in the page sizes by
scanning the sg table.

v2: pass the sg_mask to set_pages

v3: calculate the sg_mask inline with populating the sg_table where
possible, and pass to set_pages along with the pages.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel@ffwll.ch>
---
 drivers/gpu/drm/i915/i915_drv.h                  |  5 +++-
 drivers/gpu/drm/i915/i915_gem.c                  | 35 ++++++++++++++++++++----
 drivers/gpu/drm/i915/i915_gem_dmabuf.c           |  8 +++++-
 drivers/gpu/drm/i915/i915_gem_internal.c         |  5 +++-
 drivers/gpu/drm/i915/i915_gem_object.h           | 17 ++++++++++++
 drivers/gpu/drm/i915/i915_gem_stolen.c           |  2 +-
 drivers/gpu/drm/i915/i915_gem_userptr.c          | 13 +++++++--
 drivers/gpu/drm/i915/selftests/huge_gem_object.c |  2 +-
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c    |  4 ++-
 9 files changed, 77 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 224f8a8ae317..202adc992e08 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3019,6 +3019,8 @@ intel_info(const struct drm_i915_private *dev_priv)
 #define USES_PPGTT(dev_priv)		(i915.enable_ppgtt)
 #define USES_FULL_PPGTT(dev_priv)	(i915.enable_ppgtt >= 2)
 #define USES_FULL_48BIT_PPGTT(dev_priv)	(i915.enable_ppgtt == 3)
+#define HAS_PAGE_SIZE(dev_priv, page_size) \
+	((dev_priv)->info.page_size_mask & (page_size))
 
 #define HAS_OVERLAY(dev_priv)		 ((dev_priv)->info.has_overlay)
 #define OVERLAY_NEEDS_PHYSICAL(dev_priv) \
@@ -3428,7 +3430,8 @@ i915_gem_object_get_dma_address(struct drm_i915_gem_object *obj,
 				unsigned long n);
 
 void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
-				 struct sg_table *pages);
+				 struct sg_table *pages,
+				 unsigned int sg_mask);
 int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj);
 
 static inline int __must_check
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 1c61d1b5eaa5..af3b9cfcc1fe 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -228,7 +228,7 @@ static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
 
 	obj->phys_handle = phys;
 
-	__i915_gem_object_set_pages(obj, st);
+	__i915_gem_object_set_pages(obj, st, sg->length);
 
 	return 0;
 
@@ -2264,6 +2264,8 @@ void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj,
 	if (!IS_ERR(pages))
 		obj->ops->put_pages(obj, pages);
 
+	obj->mm.page_sizes.phys = obj->mm.page_sizes.sg = 0;
+
 unlock:
 	mutex_unlock(&obj->mm.lock);
 }
@@ -2306,6 +2308,7 @@ static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 	struct page *page;
 	unsigned long last_pfn = 0;	/* suppress gcc warning */
 	unsigned int max_segment;
+	unsigned int sg_mask;
 	gfp_t noreclaim;
 	int ret;
 
@@ -2341,6 +2344,7 @@ static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 
 	sg = st->sgl;
 	st->nents = 0;
+	sg_mask = 0;
 	for (i = 0; i < page_count; i++) {
 		const unsigned int shrink[] = {
 			I915_SHRINK_BOUND | I915_SHRINK_UNBOUND | I915_SHRINK_PURGEABLE,
@@ -2393,8 +2397,10 @@ static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 		if (!i ||
 		    sg->length >= max_segment ||
 		    page_to_pfn(page) != last_pfn + 1) {
-			if (i)
+			if (i) {
+				sg_mask |= sg->length;
 				sg = sg_next(sg);
+			}
 			st->nents++;
 			sg_set_page(sg, page, PAGE_SIZE, 0);
 		} else {
@@ -2405,8 +2411,10 @@ static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 		/* Check that the i965g/gm workaround works. */
 		WARN_ON((gfp & __GFP_DMA32) && (last_pfn >= 0x00100000UL));
 	}
-	if (sg) /* loop terminated early; short sg table */
+	if (sg) { /* loop terminated early; short sg table */
+		sg_mask |= sg->length;
 		sg_mark_end(sg);
+	}
 
 	/* Trim unused sg entries to avoid wasting memory. */
 	i915_sg_trim(st);
@@ -2435,7 +2443,7 @@ static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 	if (i915_gem_object_needs_bit17_swizzle(obj))
 		i915_gem_object_do_bit_17_swizzle(obj, st);
 
-	__i915_gem_object_set_pages(obj, st);
+	__i915_gem_object_set_pages(obj, st, sg_mask);
 
 	return 0;
 
@@ -2462,8 +2470,13 @@ static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
 }
 
 void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
-				 struct sg_table *pages)
+				 struct sg_table *pages,
+				 unsigned int sg_mask)
 {
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+	unsigned long supported_page_sizes = INTEL_INFO(i915)->page_size_mask;
+	int bit;
+
 	lockdep_assert_held(&obj->mm.lock);
 
 	obj->mm.get_page.sg_pos = pages->sgl;
@@ -2477,6 +2490,18 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
 		__i915_gem_object_pin_pages(obj);
 		obj->mm.quirked = true;
 	}
+
+	GEM_BUG_ON(!sg_mask);
+
+	obj->mm.page_sizes.phys = sg_mask;
+
+	obj->mm.page_sizes.sg = 0;
+	for_each_set_bit(bit, &supported_page_sizes, BITS_PER_LONG) {
+		if (obj->mm.page_sizes.phys & ~0u << bit)
+			obj->mm.page_sizes.sg |= BIT(bit);
+	}
+
+	GEM_BUG_ON(!HAS_PAGE_SIZE(i915, obj->mm.page_sizes.sg));
 }
 
 static int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index 4c4dc85159fb..409747446854 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -259,13 +259,19 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
 static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
 {
 	struct sg_table *pages;
+	struct scatterlist *sg;
+	unsigned int sg_mask = 0;
+	int n;
 
 	pages = dma_buf_map_attachment(obj->base.import_attach,
 				       DMA_BIDIRECTIONAL);
 	if (IS_ERR(pages))
 		return PTR_ERR(pages);
 
-	__i915_gem_object_set_pages(obj, pages);
+	for_each_sg(pages->sgl, sg, pages->nents, n)
+		sg_mask |= sg->length;
+
+	__i915_gem_object_set_pages(obj, pages, sg_mask);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/i915_gem_internal.c b/drivers/gpu/drm/i915/i915_gem_internal.c
index f59764da4254..34ddfa70abf7 100644
--- a/drivers/gpu/drm/i915/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/i915_gem_internal.c
@@ -49,6 +49,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 	struct drm_i915_private *i915 = to_i915(obj->base.dev);
 	struct sg_table *st;
 	struct scatterlist *sg;
+	unsigned int sg_mask;
 	unsigned int npages;
 	int max_order;
 	gfp_t gfp;
@@ -75,6 +76,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 	}
 
 create_st:
+	sg_mask = 0;
 	st = kmalloc(sizeof(*st), GFP_KERNEL);
 	if (!st)
 		return -ENOMEM;
@@ -104,6 +106,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 		} while (1);
 
 		sg_set_page(sg, page, PAGE_SIZE << order, 0);
+		sg_mask |= PAGE_SIZE << order;
 		st->nents++;
 
 		npages -= 1 << order;
@@ -132,7 +135,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 	 */
 	obj->mm.madv = I915_MADV_DONTNEED;
 
-	__i915_gem_object_set_pages(obj, st);
+	__i915_gem_object_set_pages(obj, st, sg_mask);
 
 	return 0;
 
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index 036e847b27f0..110672952a1c 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -169,6 +169,23 @@ struct drm_i915_gem_object {
 		struct sg_table *pages;
 		void *mapping;
 
+		struct i915_page_sizes {
+			/**
+			 * The sg mask of the pages sg_table. i.e the mask of
+			 * of the lengths for each sg entry.
+			 */
+			unsigned int phys;
+
+			/**
+			 * The gtt page sizes we are allowed to use given the
+			 * sg mask and the supported page sizes. This will
+			 * express the smallest unit we can use for the whole
+			 * object, as well as the larger sizes we may be able
+			 * to use opportunistically.
+			 */
+			unsigned int sg;
+		} page_sizes;
+
 		struct i915_gem_object_page_iter {
 			struct scatterlist *sg_pos;
 			unsigned int sg_idx; /* in pages, but 32bit eek! */
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 537ecb224db0..54fd4cfa9d07 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -548,7 +548,7 @@ static int i915_gem_object_get_pages_stolen(struct drm_i915_gem_object *obj)
 	if (IS_ERR(pages))
 		return PTR_ERR(pages);
 
-	__i915_gem_object_set_pages(obj, pages);
+	__i915_gem_object_set_pages(obj, pages, obj->stolen->size);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
index 25da3c60e961..115dfff1d484 100644
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -406,7 +406,8 @@ struct get_pages_work {
 #endif
 
 static int
-st_set_pages(struct sg_table **st, struct page **pvec, int num_pages)
+st_set_pages(struct sg_table **st, struct page **pvec, int num_pages,
+	     unsigned int *sg_mask)
 {
 	struct scatterlist *sg;
 	int ret, n;
@@ -422,12 +423,17 @@ st_set_pages(struct sg_table **st, struct page **pvec, int num_pages)
 
 		for_each_sg((*st)->sgl, sg, num_pages, n)
 			sg_set_page(sg, pvec[n], PAGE_SIZE, 0);
+
+		*sg_mask = PAGE_SIZE;
 	} else {
 		ret = sg_alloc_table_from_pages(*st, pvec, num_pages,
 						0, num_pages << PAGE_SHIFT,
 						GFP_KERNEL);
 		if (ret)
 			goto err;
+
+		for_each_sg((*st)->sgl, sg, num_pages, n)
+			*sg_mask |= sg->length;
 	}
 
 	return 0;
@@ -443,9 +449,10 @@ __i915_gem_userptr_set_pages(struct drm_i915_gem_object *obj,
 			     struct page **pvec, int num_pages)
 {
 	struct sg_table *pages;
+	unsigned int sg_mask = 0;
 	int ret;
 
-	ret = st_set_pages(&pages, pvec, num_pages);
+	ret = st_set_pages(&pages, pvec, num_pages, &sg_mask);
 	if (ret)
 		return ERR_PTR(ret);
 
@@ -456,7 +463,7 @@ __i915_gem_userptr_set_pages(struct drm_i915_gem_object *obj,
 		return ERR_PTR(ret);
 	}
 
-	__i915_gem_object_set_pages(obj, pages);
+	__i915_gem_object_set_pages(obj, pages, sg_mask);
 
 	return pages;
 }
diff --git a/drivers/gpu/drm/i915/selftests/huge_gem_object.c b/drivers/gpu/drm/i915/selftests/huge_gem_object.c
index 41c15f3aa467..a2632df39173 100644
--- a/drivers/gpu/drm/i915/selftests/huge_gem_object.c
+++ b/drivers/gpu/drm/i915/selftests/huge_gem_object.c
@@ -80,7 +80,7 @@ static int huge_get_pages(struct drm_i915_gem_object *obj)
 	if (i915_gem_gtt_prepare_pages(obj, pages))
 		goto err;
 
-	__i915_gem_object_set_pages(obj, pages);
+	__i915_gem_object_set_pages(obj, pages, PAGE_SIZE);
 
 	return 0;
 
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index aa1db375d59a..2dd66f866a5d 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -45,6 +45,7 @@ static int fake_get_pages(struct drm_i915_gem_object *obj)
 #define PFN_BIAS 0x1000
 	struct sg_table *pages;
 	struct scatterlist *sg;
+	unsigned int sg_mask = 0;
 	typeof(obj->base.size) rem;
 
 	pages = kmalloc(sizeof(*pages), GFP);
@@ -65,6 +66,7 @@ static int fake_get_pages(struct drm_i915_gem_object *obj)
 		sg_set_page(sg, pfn_to_page(PFN_BIAS), len, 0);
 		sg_dma_address(sg) = page_to_phys(sg_page(sg));
 		sg_dma_len(sg) = len;
+		sg_mask |= len;
 
 		rem -= len;
 	}
@@ -72,7 +74,7 @@ static int fake_get_pages(struct drm_i915_gem_object *obj)
 
 	obj->mm.madv = I915_MADV_DONTNEED;
 
-	__i915_gem_object_set_pages(obj, pages);
+	__i915_gem_object_set_pages(obj, pages, sg_mask);
 
 	return 0;
 #undef GFP
-- 
2.13.5

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

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

* [PATCH 07/23] drm/i915: introduce vm set_pages/clear_pages
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (5 preceding siblings ...)
  2017-08-21 18:34 ` [PATCH 06/23] drm/i915: introduce page_size members Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-08-21 18:34 ` [PATCH 08/23] drm/i915: align the vma start to the largest gtt page size Matthew Auld
                   ` (17 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

Move the setting/clearing of the vma->pages to a vm operation. Doing so
neatens things up a little, but more importantly gives us a sane place
to also set/clear the vma->pages_sizes, which we introduce later in
preparation for supporting huge-pages.

v2: remove redundant vma->pages check

v3: GEM_BUG_ON(vma->pages) following i915_vma_remove

Suggested-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c       | 70 +++++++++++++++++++------------
 drivers/gpu/drm/i915/i915_gem_gtt.h       |  2 +
 drivers/gpu/drm/i915/i915_vma.c           | 27 +++++++-----
 drivers/gpu/drm/i915/selftests/mock_gtt.c | 11 ++---
 4 files changed, 66 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 0f7399801398..fa4b5349c982 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -205,8 +205,6 @@ static int ppgtt_bind_vma(struct i915_vma *vma,
 			return ret;
 	}
 
-	vma->pages = vma->obj->mm.pages;
-
 	/* Currently applicable only to VLV */
 	pte_flags = 0;
 	if (vma->obj->gt_ro)
@@ -222,6 +220,26 @@ static void ppgtt_unbind_vma(struct i915_vma *vma)
 	vma->vm->clear_range(vma->vm, vma->node.start, vma->size);
 }
 
+static int ppgtt_set_pages(struct i915_vma *vma)
+{
+	GEM_BUG_ON(vma->pages);
+
+	vma->pages = vma->obj->mm.pages;
+
+	return 0;
+}
+
+static void clear_pages(struct i915_vma *vma)
+{
+	GEM_BUG_ON(!vma->pages);
+
+	if (vma->pages != vma->obj->mm.pages) {
+		sg_free_table(vma->pages);
+		kfree(vma->pages);
+	}
+	vma->pages = NULL;
+}
+
 static gen8_pte_t gen8_pte_encode(dma_addr_t addr,
 				  enum i915_cache_level level)
 {
@@ -1385,6 +1403,8 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
 	ppgtt->base.cleanup = gen8_ppgtt_cleanup;
 	ppgtt->base.unbind_vma = ppgtt_unbind_vma;
 	ppgtt->base.bind_vma = ppgtt_bind_vma;
+	ppgtt->base.set_pages = ppgtt_set_pages;
+	ppgtt->base.clear_pages = clear_pages;
 	ppgtt->debug_dump = gen8_dump_ppgtt;
 
 	return 0;
@@ -1827,6 +1847,8 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
 	ppgtt->base.insert_entries = gen6_ppgtt_insert_entries;
 	ppgtt->base.unbind_vma = ppgtt_unbind_vma;
 	ppgtt->base.bind_vma = ppgtt_bind_vma;
+	ppgtt->base.set_pages = ppgtt_set_pages;
+	ppgtt->base.clear_pages = clear_pages;
 	ppgtt->base.cleanup = gen6_ppgtt_cleanup;
 	ppgtt->debug_dump = gen6_dump_ppgtt;
 
@@ -2338,12 +2360,6 @@ static int ggtt_bind_vma(struct i915_vma *vma,
 	struct drm_i915_gem_object *obj = vma->obj;
 	u32 pte_flags;
 
-	if (unlikely(!vma->pages)) {
-		int ret = i915_get_ggtt_vma_pages(vma);
-		if (ret)
-			return ret;
-	}
-
 	/* Currently applicable only to VLV */
 	pte_flags = 0;
 	if (obj->gt_ro)
@@ -2380,12 +2396,6 @@ static int aliasing_gtt_bind_vma(struct i915_vma *vma,
 	u32 pte_flags;
 	int ret;
 
-	if (unlikely(!vma->pages)) {
-		ret = i915_get_ggtt_vma_pages(vma);
-		if (ret)
-			return ret;
-	}
-
 	/* Currently applicable only to VLV */
 	pte_flags = 0;
 	if (vma->obj->gt_ro)
@@ -2400,7 +2410,7 @@ static int aliasing_gtt_bind_vma(struct i915_vma *vma,
 							     vma->node.start,
 							     vma->size);
 			if (ret)
-				goto err_pages;
+				return ret;
 		}
 
 		appgtt->base.insert_entries(&appgtt->base, vma, cache_level,
@@ -2414,17 +2424,6 @@ static int aliasing_gtt_bind_vma(struct i915_vma *vma,
 	}
 
 	return 0;
-
-err_pages:
-	if (!(vma->flags & (I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND))) {
-		if (vma->pages != vma->obj->mm.pages) {
-			GEM_BUG_ON(!vma->pages);
-			sg_free_table(vma->pages);
-			kfree(vma->pages);
-		}
-		vma->pages = NULL;
-	}
-	return ret;
 }
 
 static void aliasing_gtt_unbind_vma(struct i915_vma *vma)
@@ -2462,6 +2461,19 @@ void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj,
 	dma_unmap_sg(kdev, pages->sgl, pages->nents, PCI_DMA_BIDIRECTIONAL);
 }
 
+static int ggtt_set_pages(struct i915_vma *vma)
+{
+	int ret;
+
+	GEM_BUG_ON(vma->pages);
+
+	ret = i915_get_ggtt_vma_pages(vma);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static void i915_gtt_color_adjust(const struct drm_mm_node *node,
 				  unsigned long color,
 				  u64 *start,
@@ -2884,6 +2896,8 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
 	ggtt->base.cleanup = gen6_gmch_remove;
 	ggtt->base.bind_vma = ggtt_bind_vma;
 	ggtt->base.unbind_vma = ggtt_unbind_vma;
+	ggtt->base.set_pages = ggtt_set_pages;
+	ggtt->base.clear_pages = clear_pages;
 	ggtt->base.insert_page = gen8_ggtt_insert_page;
 	ggtt->base.clear_range = nop_clear_range;
 	if (!USES_FULL_PPGTT(dev_priv) || intel_scanout_needs_vtd_wa(dev_priv))
@@ -2940,6 +2954,8 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt)
 	ggtt->base.insert_entries = gen6_ggtt_insert_entries;
 	ggtt->base.bind_vma = ggtt_bind_vma;
 	ggtt->base.unbind_vma = ggtt_unbind_vma;
+	ggtt->base.set_pages = ggtt_set_pages;
+	ggtt->base.clear_pages = clear_pages;
 	ggtt->base.cleanup = gen6_gmch_remove;
 
 	ggtt->invalidate = gen6_ggtt_invalidate;
@@ -2985,6 +3001,8 @@ static int i915_gmch_probe(struct i915_ggtt *ggtt)
 	ggtt->base.clear_range = i915_ggtt_clear_range;
 	ggtt->base.bind_vma = ggtt_bind_vma;
 	ggtt->base.unbind_vma = ggtt_unbind_vma;
+	ggtt->base.set_pages = ggtt_set_pages;
+	ggtt->base.clear_pages = clear_pages;
 	ggtt->base.cleanup = i915_gmch_remove;
 
 	ggtt->invalidate = gmch_ggtt_invalidate;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 4c2f7d7c1e7d..57738a61ea6e 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -330,6 +330,8 @@ struct i915_address_space {
 	int (*bind_vma)(struct i915_vma *vma,
 			enum i915_cache_level cache_level,
 			u32 flags);
+	int (*set_pages)(struct i915_vma *vma);
+	void (*clear_pages)(struct i915_vma *vma);
 
 	I915_SELFTEST_DECLARE(struct fault_attr fault_attr);
 };
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 02d1a5eacb00..49bf49571e47 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -266,6 +266,8 @@ int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
 	if (bind_flags == 0)
 		return 0;
 
+	GEM_BUG_ON(!vma->pages);
+
 	trace_i915_vma_bind(vma, bind_flags);
 	ret = vma->vm->bind_vma(vma, cache_level, bind_flags);
 	if (ret)
@@ -471,25 +473,31 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
 	if (ret)
 		return ret;
 
+	GEM_BUG_ON(vma->pages);
+
+	ret = vma->vm->set_pages(vma);
+	if (ret)
+		goto err_unpin;
+
 	if (flags & PIN_OFFSET_FIXED) {
 		u64 offset = flags & PIN_OFFSET_MASK;
 		if (!IS_ALIGNED(offset, alignment) ||
 		    range_overflows(offset, size, end)) {
 			ret = -EINVAL;
-			goto err_unpin;
+			goto err_clear;
 		}
 
 		ret = i915_gem_gtt_reserve(vma->vm, &vma->node,
 					   size, offset, obj->cache_level,
 					   flags);
 		if (ret)
-			goto err_unpin;
+			goto err_clear;
 	} else {
 		ret = i915_gem_gtt_insert(vma->vm, &vma->node,
 					  size, alignment, obj->cache_level,
 					  start, end, flags);
 		if (ret)
-			goto err_unpin;
+			goto err_clear;
 
 		GEM_BUG_ON(vma->node.start < start);
 		GEM_BUG_ON(vma->node.start + vma->node.size > end);
@@ -504,6 +512,8 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
 
 	return 0;
 
+err_clear:
+	vma->vm->clear_pages(vma);
 err_unpin:
 	i915_gem_object_unpin_pages(obj);
 	return ret;
@@ -517,6 +527,8 @@ i915_vma_remove(struct i915_vma *vma)
 	GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
 	GEM_BUG_ON(vma->flags & (I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND));
 
+	vma->vm->clear_pages(vma);
+
 	drm_mm_remove_node(&vma->node);
 	list_move_tail(&vma->vm_link, &vma->vm->unbound_list);
 
@@ -569,8 +581,8 @@ int __i915_vma_do_pin(struct i915_vma *vma,
 
 err_remove:
 	if ((bound & I915_VMA_BIND_MASK) == 0) {
-		GEM_BUG_ON(vma->pages);
 		i915_vma_remove(vma);
+		GEM_BUG_ON(vma->pages);
 	}
 err_unpin:
 	__i915_vma_unpin(vma);
@@ -695,13 +707,6 @@ int i915_vma_unbind(struct i915_vma *vma)
 	}
 	vma->flags &= ~(I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND);
 
-	if (vma->pages != obj->mm.pages) {
-		GEM_BUG_ON(!vma->pages);
-		sg_free_table(vma->pages);
-		kfree(vma->pages);
-	}
-	vma->pages = NULL;
-
 	i915_vma_remove(vma);
 
 destroy:
diff --git a/drivers/gpu/drm/i915/selftests/mock_gtt.c b/drivers/gpu/drm/i915/selftests/mock_gtt.c
index f2118cf535a0..336e1afb250f 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gtt.c
@@ -43,7 +43,6 @@ static int mock_bind_ppgtt(struct i915_vma *vma,
 			   u32 flags)
 {
 	GEM_BUG_ON(flags & I915_VMA_GLOBAL_BIND);
-	vma->pages = vma->obj->mm.pages;
 	vma->flags |= I915_VMA_LOCAL_BIND;
 	return 0;
 }
@@ -84,6 +83,8 @@ mock_ppgtt(struct drm_i915_private *i915,
 	ppgtt->base.insert_entries = mock_insert_entries;
 	ppgtt->base.bind_vma = mock_bind_ppgtt;
 	ppgtt->base.unbind_vma = mock_unbind_ppgtt;
+	ppgtt->base.set_pages = ppgtt_set_pages;
+	ppgtt->base.clear_pages = clear_pages;
 	ppgtt->base.cleanup = mock_cleanup;
 
 	return ppgtt;
@@ -93,12 +94,6 @@ static int mock_bind_ggtt(struct i915_vma *vma,
 			  enum i915_cache_level cache_level,
 			  u32 flags)
 {
-	int err;
-
-	err = i915_get_ggtt_vma_pages(vma);
-	if (err)
-		return err;
-
 	vma->flags |= I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND;
 	return 0;
 }
@@ -124,6 +119,8 @@ void mock_init_ggtt(struct drm_i915_private *i915)
 	ggtt->base.insert_entries = mock_insert_entries;
 	ggtt->base.bind_vma = mock_bind_ggtt;
 	ggtt->base.unbind_vma = mock_unbind_ggtt;
+	ggtt->base.set_pages = ggtt_set_pages;
+	ggtt->base.clear_pages = clear_pages;
 	ggtt->base.cleanup = mock_cleanup;
 
 	i915_address_space_init(&ggtt->base, i915, "global");
-- 
2.13.5

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

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

* [PATCH 08/23] drm/i915: align the vma start to the largest gtt page size
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (6 preceding siblings ...)
  2017-08-21 18:34 ` [PATCH 07/23] drm/i915: introduce vm set_pages/clear_pages Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-08-21 18:34 ` [PATCH 09/23] drm/i915: align 64K objects to 2M Matthew Auld
                   ` (16 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

For the 48b PPGTT try to align the vma start address to the required
page size boundary to guarantee we use said page size in the gtt. If we
are dealing with multiple page sizes, we can't guarantee anything and
just align to the largest. For soft pinning and objects which need to be
tightly packed into the lower 32bits we don't force any alignment.

v2: various improvements suggested by Chris

v3: use set_pages and better placement of page_sizes

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c |  8 ++++++++
 drivers/gpu/drm/i915/i915_vma.c     | 12 ++++++++++++
 drivers/gpu/drm/i915/i915_vma.h     |  1 +
 3 files changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index fa4b5349c982..f8052721df03 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -226,6 +226,9 @@ static int ppgtt_set_pages(struct i915_vma *vma)
 
 	vma->pages = vma->obj->mm.pages;
 
+	vma->page_sizes.phys = vma->obj->mm.page_sizes.phys;
+	vma->page_sizes.sg = vma->obj->mm.page_sizes.sg;
+
 	return 0;
 }
 
@@ -238,6 +241,8 @@ static void clear_pages(struct i915_vma *vma)
 		kfree(vma->pages);
 	}
 	vma->pages = NULL;
+
+	memset(&vma->page_sizes, 0, sizeof(struct i915_page_sizes));
 }
 
 static gen8_pte_t gen8_pte_encode(dma_addr_t addr,
@@ -2471,6 +2476,9 @@ static int ggtt_set_pages(struct i915_vma *vma)
 	if (ret)
 		return ret;
 
+	vma->page_sizes.phys = vma->obj->mm.page_sizes.phys;
+	vma->page_sizes.sg = vma->obj->mm.page_sizes.sg;
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 49bf49571e47..102c2f184486 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -493,6 +493,18 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
 		if (ret)
 			goto err_clear;
 	} else {
+		/* We only support huge gtt pages through the 48b PPGTT,
+		 * however we also don't want to force any alignment for
+		 * objects which need to be tightly packed into the low 32bits.
+		 */
+		if (end > (1ULL << 32) &&
+		    vma->page_sizes.sg > I915_GTT_PAGE_SIZE) {
+			u64 page_alignment =
+				rounddown_pow_of_two(vma->page_sizes.sg);
+
+			alignment = max(alignment, page_alignment);
+		}
+
 		ret = i915_gem_gtt_insert(vma->vm, &vma->node,
 					  size, alignment, obj->cache_level,
 					  start, end, flags);
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 1fd61e88cfd0..6958198734b5 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -55,6 +55,7 @@ struct i915_vma {
 	void __iomem *iomap;
 	u64 size;
 	u64 display_alignment;
+	struct i915_page_sizes page_sizes;
 
 	u32 fence_size;
 	u32 fence_alignment;
-- 
2.13.5

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

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

* [PATCH 09/23] drm/i915: align 64K objects to 2M
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (7 preceding siblings ...)
  2017-08-21 18:34 ` [PATCH 08/23] drm/i915: align the vma start to the largest gtt page size Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-08-21 18:34 ` [PATCH 10/23] drm/i915: enable IPS bit for 64K pages Matthew Auld
                   ` (15 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

We can't mix 64K and 4K pte's in the same page-table, so for now we
align 64K objects to 2M to avoid any potential mixing. This is
potentially wasteful but in reality shouldn't be too bad since this only
applies to the virtual address space of a 48b PPGTT.

v2: don't separate logically connected ops

Suggested-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_vma.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 102c2f184486..b97843fe6338 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -500,9 +500,17 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
 		if (end > (1ULL << 32) &&
 		    vma->page_sizes.sg > I915_GTT_PAGE_SIZE) {
 			u64 page_alignment =
-				rounddown_pow_of_two(vma->page_sizes.sg);
+				rounddown_pow_of_two(vma->page_sizes.sg |
+						     I915_GTT_PAGE_SIZE_2M);
 
 			alignment = max(alignment, page_alignment);
+
+			/* We can't mix 64K and 4K PTEs in the same page-table (2M
+			 * block), and so to avoid the ugliness and complexity of
+			 * coloring we opt for just aligning 64K objects to 2M.
+			 */
+			if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K)
+				size = round_up(size, I915_GTT_PAGE_SIZE_2M);
 		}
 
 		ret = i915_gem_gtt_insert(vma->vm, &vma->node,
-- 
2.13.5

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

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

* [PATCH 10/23] drm/i915: enable IPS bit for 64K pages
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (8 preceding siblings ...)
  2017-08-21 18:34 ` [PATCH 09/23] drm/i915: align 64K objects to 2M Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-08-21 18:34 ` [PATCH 11/23] drm/i915: disable GTT cache for 2M/1G pages Matthew Auld
                   ` (14 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

Before we can enable 64K pages through the IPS bit, we must first enable
it through MMIO, otherwise the page-walker will simply ignore it.

v2: add comment mentioning that 64K is BDW+

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem.c | 16 ++++++++++++++++
 drivers/gpu/drm/i915/i915_reg.h |  3 +++
 2 files changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index af3b9cfcc1fe..12c365c69edf 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4773,6 +4773,22 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv)
 		}
 	}
 
+	/* To support 64K PTEs we need to first enable the use of the
+	 * Intermediate-Page-Size(IPS) bit of the PDE field via some magical
+	 * mmio, otherwise the page-walker will simply ignore the IPS bit. This
+	 * shouldn't be needed after GEN10.
+	 *
+	 * 64K pages were first introduced from BDW+, although technically they
+	 * only *work* from gen9+. For pre-BDW we instead have the option for
+	 * 32K pages, but we don't currently have any support for it in our
+	 * driver.
+	 */
+	if (HAS_PAGE_SIZE(dev_priv, I915_GTT_PAGE_SIZE_64K) &&
+	    INTEL_GEN(dev_priv) <= 10)
+		I915_WRITE(GEN8_GAMW_ECO_DEV_RW_IA,
+			   I915_READ(GEN8_GAMW_ECO_DEV_RW_IA) |
+			   GAMW_ECO_ENABLE_64K_IPS_FIELD);
+
 	i915_gem_init_swizzling(dev_priv);
 
 	/*
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index d4ecb1905ad8..767952aef2ab 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2371,6 +2371,9 @@ enum i915_power_well_id {
 #define GEN9_GAMT_ECO_REG_RW_IA _MMIO(0x4ab0)
 #define   GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS	(1<<18)
 
+#define GEN8_GAMW_ECO_DEV_RW_IA _MMIO(0x4080)
+#define   GAMW_ECO_ENABLE_64K_IPS_FIELD 0xF
+
 #define GAMT_CHKN_BIT_REG	_MMIO(0x4ab8)
 #define   GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING	(1<<28)
 
-- 
2.13.5

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

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

* [PATCH 11/23] drm/i915: disable GTT cache for 2M/1G pages
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (9 preceding siblings ...)
  2017-08-21 18:34 ` [PATCH 10/23] drm/i915: enable IPS bit for 64K pages Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-08-21 18:34 ` [PATCH 12/23] drm/i915: support 1G pages for the 48b PPGTT Matthew Auld
                   ` (13 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

When SW enables the use of 2M/1G pages, it must disable the GTT cache.

v2: don't disable for Cherryview which doesn't even support 48b PPGTT!

v3: explicitly check that the system does support 2M/1G pages

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/intel_pm.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 68187bcfded4..282cac14dfda 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -8354,10 +8354,13 @@ static void broadwell_init_clock_gating(struct drm_i915_private *dev_priv)
 
 	/*
 	 * WaGttCachingOffByDefault:bdw
-	 * GTT cache may not work with big pages, so if those
-	 * are ever enabled GTT cache may need to be disabled.
+	 * The GTT cache must be disabled if the system is planning to use
+	 * 2M/1G pages.
 	 */
-	I915_WRITE(HSW_GTT_CACHE_EN, GTT_CACHE_EN_ALL);
+	I915_WRITE(HSW_GTT_CACHE_EN,
+		   HAS_PAGE_SIZE(dev_priv,
+				 I915_GTT_PAGE_SIZE_2M |
+				 I915_GTT_PAGE_SIZE_1G) ? 0 : GTT_CACHE_EN_ALL);
 
 	/* WaKVMNotificationOnConfigChange:bdw */
 	I915_WRITE(CHICKEN_PAR2_1, I915_READ(CHICKEN_PAR2_1)
-- 
2.13.5

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

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

* [PATCH 12/23] drm/i915: support 1G pages for the 48b PPGTT
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (10 preceding siblings ...)
  2017-08-21 18:34 ` [PATCH 11/23] drm/i915: disable GTT cache for 2M/1G pages Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-08-21 18:34 ` [PATCH 13/23] drm/i915: support 2M " Matthew Auld
                   ` (12 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

Support inserting 1G gtt pages into the 48b PPGTT.

v2: sanity check sg->length against page_size

v3: don't recalculate rem on each loop
    whitespace breakup

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 78 +++++++++++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/i915_gem_gtt.h |  2 +
 2 files changed, 76 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index f8052721df03..de727bb5d4eb 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -950,6 +950,71 @@ static void gen8_ppgtt_insert_3lvl(struct i915_address_space *vm,
 				      cache_level);
 }
 
+static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
+					   struct i915_page_directory_pointer **pdps,
+					   struct sgt_dma *iter,
+					   enum i915_cache_level cache_level)
+{
+	const gen8_pte_t pte_encode = gen8_pte_encode(0, cache_level);
+	u64 start = vma->node.start;
+	dma_addr_t rem = iter->sg->length;
+
+	do {
+		struct gen8_insert_pte idx = gen8_insert_pte(start);
+		struct i915_page_directory_pointer *pdp = pdps[idx.pml4e];
+		struct i915_page_directory *pd = pdp->page_directory[idx.pdpe];
+		unsigned int page_size;
+		gen8_pte_t encode = pte_encode;
+		gen8_pte_t *vaddr;
+		u16 index, max;
+
+		if (unlikely(vma->page_sizes.sg & I915_GTT_PAGE_SIZE_1G) &&
+		    IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_1G) &&
+		    rem >= I915_GTT_PAGE_SIZE_1G && !(idx.pte | idx.pde)) {
+			index = idx.pdpe;
+			max = GEN8_PML4ES_PER_PML4;
+			page_size = I915_GTT_PAGE_SIZE_1G;
+
+			encode |= GEN8_PDPE_PS_1G;
+
+			vaddr = kmap_atomic_px(pdp);
+		} else {
+			struct i915_page_table *pt = pd->page_table[idx.pde];
+
+			index = idx.pte;
+			max = GEN8_PTES;
+			page_size = I915_GTT_PAGE_SIZE;
+
+			vaddr = kmap_atomic_px(pt);
+		}
+
+		do {
+			GEM_BUG_ON(iter->sg->length < page_size);
+			vaddr[index++] = encode | iter->dma;
+
+			start += page_size;
+			iter->dma += page_size;
+			rem -= page_size;
+			if (iter->dma >= iter->max) {
+				iter->sg = __sg_next(iter->sg);
+				if (!iter->sg)
+					break;
+
+				rem = iter->sg->length;
+				iter->dma = sg_dma_address(iter->sg);
+				iter->max = iter->dma + rem;
+
+				if (unlikely(!IS_ALIGNED(iter->dma, page_size)))
+					break;
+			}
+
+		} while (rem >= page_size && index < max);
+
+		kunmap_atomic(vaddr);
+
+	} while (iter->sg);
+}
+
 static void gen8_ppgtt_insert_4lvl(struct i915_address_space *vm,
 				   struct i915_vma *vma,
 				   enum i915_cache_level cache_level,
@@ -962,11 +1027,16 @@ static void gen8_ppgtt_insert_4lvl(struct i915_address_space *vm,
 		.max = iter.dma + iter.sg->length,
 	};
 	struct i915_page_directory_pointer **pdps = ppgtt->pml4.pdps;
-	struct gen8_insert_pte idx = gen8_insert_pte(vma->node.start);
 
-	while (gen8_ppgtt_insert_pte_entries(ppgtt, pdps[idx.pml4e++], &iter,
-					     &idx, cache_level))
-		GEM_BUG_ON(idx.pml4e >= GEN8_PML4ES_PER_PML4);
+	if (vma->page_sizes.sg > I915_GTT_PAGE_SIZE) {
+		gen8_ppgtt_insert_huge_entries(vma, pdps, &iter, cache_level);
+	} else {
+		struct gen8_insert_pte idx = gen8_insert_pte(vma->node.start);
+
+		while (gen8_ppgtt_insert_pte_entries(ppgtt, pdps[idx.pml4e++],
+						     &iter, &idx, cache_level))
+			GEM_BUG_ON(idx.pml4e >= GEN8_PML4ES_PER_PML4);
+	}
 }
 
 static void gen8_free_page_tables(struct i915_address_space *vm,
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 57738a61ea6e..e46f05f0cfd9 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -149,6 +149,8 @@ typedef u64 gen8_ppgtt_pml4e_t;
 #define GEN8_PPAT_ELLC_OVERRIDE		(0<<2)
 #define GEN8_PPAT(i, x)			((u64)(x) << ((i) * 8))
 
+#define GEN8_PDPE_PS_1G  BIT(7)
+
 struct sg_table;
 
 struct intel_rotation_info {
-- 
2.13.5

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

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

* [PATCH 13/23] drm/i915: support 2M pages for the 48b PPGTT
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (11 preceding siblings ...)
  2017-08-21 18:34 ` [PATCH 12/23] drm/i915: support 1G pages for the 48b PPGTT Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-08-21 18:34 ` [PATCH 14/23] drm/i915: add support for 64K scratch page Matthew Auld
                   ` (11 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

Support inserting 2M pages into the 48b PPGTT.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 10 ++++++++++
 drivers/gpu/drm/i915/i915_gem_gtt.h |  2 ++
 2 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index de727bb5d4eb..135d179c7b0b 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -978,6 +978,16 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
 			encode |= GEN8_PDPE_PS_1G;
 
 			vaddr = kmap_atomic_px(pdp);
+		} else if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_2M &&
+			   IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_2M) &&
+			   rem >= I915_GTT_PAGE_SIZE_2M && !idx.pte) {
+			index = idx.pde;
+			max = I915_PDES;
+			page_size = I915_GTT_PAGE_SIZE_2M;
+
+			encode |= GEN8_PDE_PS_2M;
+
+			vaddr = kmap_atomic_px(pd);
 		} else {
 			struct i915_page_table *pt = pd->page_table[idx.pde];
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index e46f05f0cfd9..aa4488637fc9 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -149,6 +149,8 @@ typedef u64 gen8_ppgtt_pml4e_t;
 #define GEN8_PPAT_ELLC_OVERRIDE		(0<<2)
 #define GEN8_PPAT(i, x)			((u64)(x) << ((i) * 8))
 
+#define GEN8_PDE_PS_2M   BIT(7)
+
 #define GEN8_PDPE_PS_1G  BIT(7)
 
 struct sg_table;
-- 
2.13.5

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

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

* [PATCH 14/23] drm/i915: add support for 64K scratch page
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (12 preceding siblings ...)
  2017-08-21 18:34 ` [PATCH 13/23] drm/i915: support 2M " Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-08-21 18:34 ` [PATCH 15/23] drm/i915: support 64K pages for the 48b PPGTT Matthew Auld
                   ` (10 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

Before we can fully enable 64K pages, we need to first support a 64K
scratch page if we intend to support the case where we have object sizes
< 2M, since any scratch PTE must also point to a 64K region.  Without
this our 64K usage is limited to objects which completely fill the
page-table, and therefore don't need any scratch.

v2: add reminder about why 48b PPGTT

Reported-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 61 +++++++++++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/i915_gem_gtt.h |  1 +
 2 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 135d179c7b0b..1200afa38bb1 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -475,12 +475,69 @@ static void fill_page_dma_32(struct i915_address_space *vm,
 static int
 setup_scratch_page(struct i915_address_space *vm, gfp_t gfp)
 {
-	return __setup_page_dma(vm, &vm->scratch_page, gfp | __GFP_ZERO);
+	struct page *page = NULL;
+	dma_addr_t addr;
+	int order;
+
+	/* In order to utilize 64K pages for an object with a size < 2M, we will
+	 * need to support a 64K scratch page, given that every 16th entry for a
+	 * page-table operating in 64K mode must point to a properly aligned 64K
+	 * region, including any PTEs which happen to point to scratch.
+	 *
+	 * This is only relevant for the 48b PPGTT where we support
+	 * huge-gtt-pages, see also i915_vma_insert().
+	 */
+	if (i915_vm_is_48bit(vm) &&
+	    HAS_PAGE_SIZE(vm->i915, I915_GTT_PAGE_SIZE_64K)) {
+		order = get_order(I915_GTT_PAGE_SIZE_64K);
+		page = alloc_pages(gfp | __GFP_ZERO, order);
+		if (page) {
+			addr = dma_map_page(vm->dma, page, 0,
+					    I915_GTT_PAGE_SIZE_64K,
+					    PCI_DMA_BIDIRECTIONAL);
+			if (unlikely(dma_mapping_error(vm->dma, addr))) {
+				__free_pages(page, order);
+				page = NULL;
+			}
+
+			if (!IS_ALIGNED(addr, I915_GTT_PAGE_SIZE_64K)) {
+				dma_unmap_page(vm->dma, addr,
+					       I915_GTT_PAGE_SIZE_64K,
+					       PCI_DMA_BIDIRECTIONAL);
+				__free_pages(page, order);
+				page = NULL;
+			}
+		}
+	}
+
+	if (!page) {
+		order = 0;
+		page = alloc_page(gfp | __GFP_ZERO);
+		if (unlikely(!page))
+			return -ENOMEM;
+
+		addr = dma_map_page(vm->dma, page, 0, PAGE_SIZE,
+				    PCI_DMA_BIDIRECTIONAL);
+		if (unlikely(dma_mapping_error(vm->dma, addr))) {
+			__free_page(page);
+			return -ENOMEM;
+		}
+	}
+
+	vm->scratch_page.page = page;
+	vm->scratch_page.daddr = addr;
+	vm->scratch_page.order = order;
+
+	return 0;
 }
 
 static void cleanup_scratch_page(struct i915_address_space *vm)
 {
-	cleanup_page_dma(vm, &vm->scratch_page);
+	struct i915_page_dma *p = &vm->scratch_page;
+
+	dma_unmap_page(vm->dma, p->daddr, BIT(p->order) << PAGE_SHIFT,
+		       PCI_DMA_BIDIRECTIONAL);
+	__free_pages(p->page, p->order);
 }
 
 static struct i915_page_table *alloc_pt(struct i915_address_space *vm)
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index aa4488637fc9..356fec26e8c9 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -212,6 +212,7 @@ struct i915_vma;
 
 struct i915_page_dma {
 	struct page *page;
+	int order;
 	union {
 		dma_addr_t daddr;
 
-- 
2.13.5

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

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

* [PATCH 15/23] drm/i915: support 64K pages for the 48b PPGTT
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (13 preceding siblings ...)
  2017-08-21 18:34 ` [PATCH 14/23] drm/i915: add support for 64K scratch page Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-08-21 18:34 ` [PATCH 16/23] drm/i915: accurate page size tracking for the ppgtt Matthew Auld
                   ` (9 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

Support inserting 64K pages into the 48b PPGTT.

v2: check for 64K scratch

v3: we should only have to re-adjust maybe_64K at every sg interval

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 30 ++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_gtt.h |  7 +++++++
 2 files changed, 37 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 1200afa38bb1..48250ecabbf4 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1021,6 +1021,7 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
 		struct i915_page_directory_pointer *pdp = pdps[idx.pml4e];
 		struct i915_page_directory *pd = pdp->page_directory[idx.pdpe];
 		unsigned int page_size;
+		bool maybe_64K = false;
 		gen8_pte_t encode = pte_encode;
 		gen8_pte_t *vaddr;
 		u16 index, max;
@@ -1052,6 +1053,13 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
 			max = GEN8_PTES;
 			page_size = I915_GTT_PAGE_SIZE;
 
+			if (!index &&
+			    vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K &&
+			    IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_64K) &&
+			    (IS_ALIGNED(rem, I915_GTT_PAGE_SIZE_64K) ||
+			     rem >= (max - index) << PAGE_SHIFT))
+				maybe_64K = true;
+
 			vaddr = kmap_atomic_px(pt);
 		}
 
@@ -1071,6 +1079,12 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
 				iter->dma = sg_dma_address(iter->sg);
 				iter->max = iter->dma + rem;
 
+				if (maybe_64K && index < max &&
+				    !(IS_ALIGNED(iter->dma, I915_GTT_PAGE_SIZE_64K) &&
+				      (IS_ALIGNED(rem, I915_GTT_PAGE_SIZE_64K) ||
+				       rem >= (max - index) << PAGE_SHIFT)))
+					maybe_64K = false;
+
 				if (unlikely(!IS_ALIGNED(iter->dma, page_size)))
 					break;
 			}
@@ -1079,6 +1093,22 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
 
 		kunmap_atomic(vaddr);
 
+		/* Is it safe to mark the 2M block as 64K? -- Either we have
+		 * filled whole page-table with 64K entries, or filled part of
+		 * it and have reached the end of the sg table and we have
+		 * enough padding.
+		 */
+		if (maybe_64K &&
+		    (index == max ||
+		     (i915_vm_has_scratch_64K(vma->vm) &&
+		      !iter->sg && IS_ALIGNED(vma->node.start +
+					      vma->node.size,
+					      I915_GTT_PAGE_SIZE_2M)))) {
+			vaddr = kmap_atomic_px(pd);
+			vaddr[idx.pde] |= GEN8_PDE_IPS_64K;
+			kunmap_atomic(vaddr);
+		}
+
 	} while (iter->sg);
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 356fec26e8c9..22b8fd233f30 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -149,6 +149,7 @@ typedef u64 gen8_ppgtt_pml4e_t;
 #define GEN8_PPAT_ELLC_OVERRIDE		(0<<2)
 #define GEN8_PPAT(i, x)			((u64)(x) << ((i) * 8))
 
+#define GEN8_PDE_IPS_64K BIT(11)
 #define GEN8_PDE_PS_2M   BIT(7)
 
 #define GEN8_PDPE_PS_1G  BIT(7)
@@ -349,6 +350,12 @@ i915_vm_is_48bit(const struct i915_address_space *vm)
 	return (vm->total - 1) >> 32;
 }
 
+static inline bool
+i915_vm_has_scratch_64K(struct i915_address_space *vm)
+{
+	return vm->scratch_page.order == get_order(I915_GTT_PAGE_SIZE_64K);
+}
+
 /* The Graphics Translation Table is the way in which GEN hardware translates a
  * Graphics Virtual Address into a Physical Address. In addition to the normal
  * collateral associated with any va->pa translations GEN hardware also has a
-- 
2.13.5

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

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

* [PATCH 16/23] drm/i915: accurate page size tracking for the ppgtt
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (14 preceding siblings ...)
  2017-08-21 18:34 ` [PATCH 15/23] drm/i915: support 64K pages for the 48b PPGTT Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-08-21 18:34 ` [PATCH 17/23] drm/i915/debugfs: include some gtt page size metrics Matthew Auld
                   ` (8 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

Now that we support multiple page sizes for the ppgtt, it would be
useful to track the real usage for debugging purposes.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c    | 11 +++++++++++
 drivers/gpu/drm/i915/i915_gem_object.h | 10 ++++++++++
 2 files changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 48250ecabbf4..71f32c2e83cc 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1005,6 +1005,8 @@ static void gen8_ppgtt_insert_3lvl(struct i915_address_space *vm,
 
 	gen8_ppgtt_insert_pte_entries(ppgtt, &ppgtt->pdp, &iter, &idx,
 				      cache_level);
+
+	vma->page_sizes.gtt = I915_GTT_PAGE_SIZE;
 }
 
 static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
@@ -1107,8 +1109,11 @@ static void gen8_ppgtt_insert_huge_entries(struct i915_vma *vma,
 			vaddr = kmap_atomic_px(pd);
 			vaddr[idx.pde] |= GEN8_PDE_IPS_64K;
 			kunmap_atomic(vaddr);
+			page_size = I915_GTT_PAGE_SIZE_64K;
 		}
 
+		vma->page_sizes.gtt |= page_size;
+
 	} while (iter->sg);
 }
 
@@ -1133,6 +1138,8 @@ static void gen8_ppgtt_insert_4lvl(struct i915_address_space *vm,
 		while (gen8_ppgtt_insert_pte_entries(ppgtt, pdps[idx.pml4e++],
 						     &iter, &idx, cache_level))
 			GEM_BUG_ON(idx.pml4e >= GEN8_PML4ES_PER_PML4);
+
+		vma->page_sizes.gtt = I915_GTT_PAGE_SIZE;
 	}
 }
 
@@ -1851,6 +1858,8 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
 		}
 	} while (1);
 	kunmap_atomic(vaddr);
+
+	vma->page_sizes.gtt = I915_GTT_PAGE_SIZE;
 }
 
 static int gen6_alloc_va_range(struct i915_address_space *vm,
@@ -2541,6 +2550,8 @@ static int ggtt_bind_vma(struct i915_vma *vma,
 	vma->vm->insert_entries(vma->vm, vma, cache_level, pte_flags);
 	intel_runtime_pm_put(i915);
 
+	vma->page_sizes.gtt = I915_GTT_PAGE_SIZE;
+
 	/*
 	 * Without aliasing PPGTT there's no difference between
 	 * GLOBAL/LOCAL_BIND, it's all the same ptes. Hence unconditionally
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h
index 110672952a1c..e4e6dd93889d 100644
--- a/drivers/gpu/drm/i915/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/i915_gem_object.h
@@ -169,6 +169,7 @@ struct drm_i915_gem_object {
 		struct sg_table *pages;
 		void *mapping;
 
+		/* TODO: whack some of this into the error state */
 		struct i915_page_sizes {
 			/**
 			 * The sg mask of the pages sg_table. i.e the mask of
@@ -184,6 +185,15 @@ struct drm_i915_gem_object {
 			 * to use opportunistically.
 			 */
 			unsigned int sg;
+
+			/**
+			 * The actual gtt page size usage. Since we can have
+			 * multiple vma associated with this object we need to
+			 * prevent any trampling of state, hence a copy of this
+			 * struct also lives in each vma, therefore the gtt
+			 * value here should only be read/write through the vma.
+			 */
+			unsigned int gtt;
 		} page_sizes;
 
 		struct i915_gem_object_page_iter {
-- 
2.13.5

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

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

* [PATCH 17/23] drm/i915/debugfs: include some gtt page size metrics
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (15 preceding siblings ...)
  2017-08-21 18:34 ` [PATCH 16/23] drm/i915: accurate page size tracking for the ppgtt Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-08-21 18:34 ` [PATCH 18/23] drm/i915/selftests: huge page tests Matthew Auld
                   ` (7 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

Good to know, mostly for debugging purposes.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 42 +++++++++++++++++++++++++++++++++----
 1 file changed, 38 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 48572b157222..a59c71531ed7 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -117,6 +117,26 @@ static u64 i915_gem_obj_total_ggtt_size(struct drm_i915_gem_object *obj)
 	return size;
 }
 
+static const char *stringify_page_sizes(unsigned int page_sizes)
+{
+	switch (page_sizes) {
+	case I915_GTT_PAGE_SIZE_4K:
+		return "4K";
+	case I915_GTT_PAGE_SIZE_64K:
+		return "64K";
+	case I915_GTT_PAGE_SIZE_2M:
+		return "2M";
+	case I915_GTT_PAGE_SIZE_1G:
+		return "1G";
+	default:
+		/* mixed-mode? */
+		if (page_sizes)
+			return "M";
+
+		return "";
+	}
+}
+
 static void
 describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 {
@@ -154,9 +174,10 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 		if (!drm_mm_node_allocated(&vma->node))
 			continue;
 
-		seq_printf(m, " (%sgtt offset: %08llx, size: %08llx",
+		seq_printf(m, " (%sgtt offset: %08llx, size: %08llx, pages: %s",
 			   i915_vma_is_ggtt(vma) ? "g" : "pp",
-			   vma->node.start, vma->node.size);
+			   vma->node.start, vma->node.size,
+			   stringify_page_sizes(vma->page_sizes.gtt));
 		if (i915_vma_is_ggtt(vma)) {
 			switch (vma->ggtt_view.type) {
 			case I915_GGTT_VIEW_NORMAL:
@@ -401,8 +422,8 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
 	struct drm_device *dev = &dev_priv->drm;
 	struct i915_ggtt *ggtt = &dev_priv->ggtt;
-	u32 count, mapped_count, purgeable_count, dpy_count;
-	u64 size, mapped_size, purgeable_size, dpy_size;
+	u32 count, mapped_count, purgeable_count, dpy_count, huge_count;
+	u64 size, mapped_size, purgeable_size, dpy_size, huge_size;
 	struct drm_i915_gem_object *obj;
 	struct drm_file *file;
 	int ret;
@@ -418,6 +439,7 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
 	size = count = 0;
 	mapped_size = mapped_count = 0;
 	purgeable_size = purgeable_count = 0;
+	huge_size = huge_count = 0;
 	list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_link) {
 		size += obj->base.size;
 		++count;
@@ -431,6 +453,11 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
 			mapped_count++;
 			mapped_size += obj->base.size;
 		}
+
+		if (obj->mm.page_sizes.sg > I915_GTT_PAGE_SIZE) {
+			huge_count++;
+			huge_size += obj->base.size;
+		}
 	}
 	seq_printf(m, "%u unbound objects, %llu bytes\n", count, size);
 
@@ -453,6 +480,11 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
 			mapped_count++;
 			mapped_size += obj->base.size;
 		}
+
+		if (obj->mm.page_sizes.sg > I915_GTT_PAGE_SIZE) {
+			huge_count++;
+			huge_size += obj->base.size;
+		}
 	}
 	seq_printf(m, "%u bound objects, %llu bytes\n",
 		   count, size);
@@ -460,6 +492,8 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
 		   purgeable_count, purgeable_size);
 	seq_printf(m, "%u mapped objects, %llu bytes\n",
 		   mapped_count, mapped_size);
+	seq_printf(m, "%u huge-paged objects, %llu bytes\n",
+		   huge_count, huge_size);
 	seq_printf(m, "%u display objects (pinned), %llu bytes\n",
 		   dpy_count, dpy_size);
 
-- 
2.13.5

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

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

* [PATCH 18/23] drm/i915/selftests: huge page tests
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (16 preceding siblings ...)
  2017-08-21 18:34 ` [PATCH 17/23] drm/i915/debugfs: include some gtt page size metrics Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-08-24 17:56   ` kbuild test robot
  2017-08-21 18:34 ` [PATCH 19/23] drm/i915/selftests: mix huge pages Matthew Auld
                   ` (6 subsequent siblings)
  24 siblings, 1 reply; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

v2: mock test page support configurations and add MI_STORE_DWORD test

v3: run all mockable huge page tests on all platforms via the mock_device

v4: add pin_update regression test
    various improvements suggested by Chris

v5: fix issues reported by kbuild
    test single sg spanning multiple page sizes
    don't explode when running the live-tests through the appgtt

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem.c                    |    1 +
 drivers/gpu/drm/i915/selftests/huge_pages.c        | 1310 ++++++++++++++++++++
 .../gpu/drm/i915/selftests/i915_live_selftests.h   |    1 +
 .../gpu/drm/i915/selftests/i915_mock_selftests.h   |    1 +
 4 files changed, 1313 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/selftests/huge_pages.c

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 12c365c69edf..eb2c8d97d441 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -5443,6 +5443,7 @@ int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align)
 #include "selftests/scatterlist.c"
 #include "selftests/mock_gem_device.c"
 #include "selftests/huge_gem_object.c"
+#include "selftests/huge_pages.c"
 #include "selftests/i915_gem_object.c"
 #include "selftests/i915_gem_coherency.c"
 #endif
diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c
new file mode 100644
index 000000000000..e39d09e1b424
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/huge_pages.c
@@ -0,0 +1,1310 @@
+/*
+ * Copyright © 2017 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.
+ *
+ */
+
+#include "../i915_selftest.h"
+
+#include <linux/prime_numbers.h>
+
+#include "mock_drm.h"
+
+static const unsigned int page_sizes[] = {
+	I915_GTT_PAGE_SIZE_1G,
+	I915_GTT_PAGE_SIZE_2M,
+	I915_GTT_PAGE_SIZE_64K,
+	I915_GTT_PAGE_SIZE_4K,
+};
+
+static unsigned int get_largest_page_size(struct drm_i915_private *i915,
+					  size_t rem)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(page_sizes); ++i) {
+		unsigned int page_size = page_sizes[i];
+
+		if (HAS_PAGE_SIZE(i915, page_size) && rem >= page_size)
+			return page_size;
+	}
+
+	return 0;
+}
+
+static int fake_get_huge_pages(struct drm_i915_gem_object *obj)
+{
+#define GFP (GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY)
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+	size_t max_len = rounddown_pow_of_two(UINT_MAX);
+	struct sg_table *st;
+	struct scatterlist *sg;
+	unsigned int sg_mask = 0;
+	size_t rem;
+
+	st = kmalloc(sizeof(*st), GFP);
+	if (!st)
+		return -ENOMEM;
+
+	if (sg_alloc_table(st, obj->base.size >> PAGE_SHIFT, GFP)) {
+		kfree(st);
+		return -ENOMEM;
+	}
+
+	/* Use optimal page sized chunks to fill in the sg table */
+	rem = obj->base.size;
+	sg = st->sgl;
+	st->nents = 0;
+	do {
+		unsigned int page_size = get_largest_page_size(i915, rem);
+		unsigned int len = min(page_size * (rem / page_size), max_len);
+
+		GEM_BUG_ON(!page_size);
+
+		sg->offset = 0;
+		sg->length = len;
+		sg_dma_len(sg) = len;
+		sg_dma_address(sg) = page_size;
+
+		sg_mask |= len;
+
+		st->nents++;
+
+		rem -= len;
+		if (!rem) {
+			sg_mark_end(sg);
+			break;
+		}
+
+		sg = sg_next(sg);
+	} while (1);
+
+	obj->mm.madv = I915_MADV_DONTNEED;
+
+	__i915_gem_object_set_pages(obj, st, sg_mask);
+
+	return 0;
+}
+
+static int fake_get_huge_pages_single(struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+	struct sg_table *st;
+	struct scatterlist *sg;
+	unsigned int page_size;
+
+	st = kmalloc(sizeof(*st), GFP);
+	if (!st)
+		return -ENOMEM;
+
+	if (sg_alloc_table(st, 1, GFP)) {
+		kfree(st);
+		return -ENOMEM;
+	}
+
+	sg = st->sgl;
+	st->nents = 1;
+
+	page_size = get_largest_page_size(i915, obj->base.size);
+
+	GEM_BUG_ON(!page_size);
+
+	sg->offset = 0;
+	sg->length = obj->base.size;
+	sg_dma_len(sg) = obj->base.size;
+	sg_dma_address(sg) = page_size;
+
+	obj->mm.madv = I915_MADV_DONTNEED;
+
+	__i915_gem_object_set_pages(obj, st, sg->length);
+
+	return 0;
+#undef GFP
+}
+
+static void fake_free_huge_pages(struct drm_i915_gem_object *obj,
+				 struct sg_table *pages)
+{
+	sg_free_table(pages);
+	kfree(pages);
+}
+
+static void fake_put_huge_pages(struct drm_i915_gem_object *obj,
+				struct sg_table *pages)
+{
+	fake_free_huge_pages(obj, pages);
+	obj->mm.dirty = false;
+	obj->mm.madv = I915_MADV_WILLNEED;
+}
+
+static const struct drm_i915_gem_object_ops fake_ops = {
+	.flags = I915_GEM_OBJECT_IS_SHRINKABLE,
+	.get_pages = fake_get_huge_pages,
+	.put_pages = fake_put_huge_pages,
+};
+
+static const struct drm_i915_gem_object_ops fake_ops_single = {
+	.flags = I915_GEM_OBJECT_IS_SHRINKABLE,
+	.get_pages = fake_get_huge_pages_single,
+	.put_pages = fake_put_huge_pages,
+};
+
+static struct drm_i915_gem_object *
+fake_huge_pages_object(struct drm_i915_private *i915, u64 size, bool single)
+{
+	struct drm_i915_gem_object *obj;
+
+	GEM_BUG_ON(!size);
+	GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_PAGE_SIZE));
+
+	if (size >> PAGE_SHIFT > UINT_MAX)
+		return ERR_PTR(-E2BIG);
+
+	if (overflows_type(size, obj->base.size))
+		return ERR_PTR(-E2BIG);
+
+	obj = i915_gem_object_alloc(i915);
+	if (!obj)
+		return ERR_PTR(-ENOMEM);
+
+	drm_gem_private_object_init(&i915->drm, &obj->base, size);
+
+	if (single)
+		i915_gem_object_init(obj, &fake_ops_single);
+	else
+		i915_gem_object_init(obj, &fake_ops);
+
+	obj->base.write_domain = I915_GEM_DOMAIN_CPU;
+	obj->base.read_domains = I915_GEM_DOMAIN_CPU;
+	obj->cache_level = I915_CACHE_NONE;
+
+	return obj;
+}
+
+static int igt_mock_exhaust_device_supported_pages(void *arg)
+{
+	struct i915_hw_ppgtt *ppgtt = arg;
+	struct drm_i915_private *i915 = ppgtt->base.i915;
+	unsigned int saved_mask = INTEL_INFO(i915)->page_size_mask;
+	struct drm_i915_gem_object *obj;
+	int i, j, single;
+	int err;
+
+	/* Sanity check creating objects with every valid page support
+	 * combination for our mock device.
+	 */
+
+	for (i = 1; i < BIT(ARRAY_SIZE(page_sizes)); i++) {
+		unsigned int combination = 0;
+		struct i915_vma *vma;
+
+		for (j = 0; j < ARRAY_SIZE(page_sizes); j++) {
+			if (i & BIT(j))
+				combination |= page_sizes[j];
+		}
+
+		mkwrite_device_info(i915)->page_size_mask = combination;
+
+		for (single = 0; single <= 1; ++single) {
+			obj = fake_huge_pages_object(i915, combination, !!single);
+			if (IS_ERR(obj)) {
+				err = PTR_ERR(obj);
+				goto out_device;
+			}
+
+			GEM_BUG_ON(obj->base.size != combination);
+
+			err = i915_gem_object_pin_pages(obj);
+			if (err)
+				goto out_put;
+
+			GEM_BUG_ON(obj->mm.page_sizes.sg != combination);
+
+			vma = i915_vma_instance(obj, &ppgtt->base, NULL);
+			if (IS_ERR(vma)) {
+				err = PTR_ERR(vma);
+				goto out_unpin;
+			}
+
+			err = i915_vma_pin(vma, 0, 0, PIN_USER);
+			if (err) {
+				i915_vma_close(vma);
+				goto out_unpin;
+			}
+
+			GEM_BUG_ON(obj->mm.page_sizes.gtt);
+			GEM_BUG_ON(!vma->page_sizes.sg);
+			GEM_BUG_ON(!vma->page_sizes.phys);
+
+			GEM_BUG_ON(vma->page_sizes.gtt & ~combination);
+
+			i915_vma_unpin(vma);
+			i915_vma_close(vma);
+
+			i915_gem_object_unpin_pages(obj);
+			i915_gem_object_put(obj);
+		}
+	}
+
+	goto out_device;
+
+out_unpin:
+	i915_gem_object_unpin_pages(obj);
+out_put:
+	i915_gem_object_put(obj);
+out_device:
+	mkwrite_device_info(i915)->page_size_mask = saved_mask;
+
+	return err;
+}
+
+static int igt_mock_ppgtt_misaligned_dma(void *arg)
+{
+	struct i915_hw_ppgtt *ppgtt = arg;
+	struct drm_i915_private *i915 = ppgtt->base.i915;
+	unsigned long supported = INTEL_INFO(i915)->page_size_mask;
+	struct drm_i915_gem_object *obj;
+	int bit;
+	int err;
+
+	/* Sanity check dma misalignment for huge pages -- the dma addresses we
+	 * insert into the paging structures need to always respect the page
+	 * size alignment.
+	 */
+
+	bit = ilog2(I915_GTT_PAGE_SIZE_64K);
+
+	for_each_set_bit_from(bit, &supported, BITS_PER_LONG) {
+		IGT_TIMEOUT(end_time);
+		unsigned int page_size = BIT(bit);
+		unsigned int flags = PIN_USER | PIN_OFFSET_FIXED;
+		struct i915_vma *vma;
+		unsigned int offset;
+		unsigned int size =
+			round_up(page_size, I915_GTT_PAGE_SIZE_2M) << 1;
+
+		obj = fake_huge_pages_object(i915, size, true);
+		if (IS_ERR(obj))
+			return PTR_ERR(obj);
+
+		GEM_BUG_ON(obj->base.size != size);
+
+		err = i915_gem_object_pin_pages(obj);
+		if (err)
+			goto out_put;
+
+		GEM_BUG_ON(!(obj->mm.page_sizes.sg & page_size));
+
+		/* Force the page size for this object */
+		obj->mm.page_sizes.sg = page_size;
+
+		vma = i915_vma_instance(obj, &ppgtt->base, NULL);
+		if (IS_ERR(vma)) {
+			err = PTR_ERR(vma);
+			goto out_unpin;
+		}
+
+		err = i915_vma_pin(vma, 0, 0, flags);
+		if (err) {
+			i915_vma_close(vma);
+			goto out_unpin;
+		}
+
+		GEM_BUG_ON(vma->page_sizes.gtt != page_size);
+
+		i915_vma_unpin(vma);
+		err = i915_vma_unbind(vma);
+		if (err) {
+			i915_vma_close(vma);
+			goto out_unpin;
+		}
+
+		/* Try all the other valid offsets until the next
+		 * boundary -- should always fall back to using 4K
+		 * pages.
+		 */
+		for (offset = 4096; offset < page_size; offset += 4096) {
+			err = i915_vma_pin(vma, 0, 0, flags | offset);
+			if (err) {
+				i915_vma_close(vma);
+				goto out_unpin;
+			}
+
+			GEM_BUG_ON(vma->page_sizes.gtt !=
+				   I915_GTT_PAGE_SIZE_4K);
+
+			i915_vma_unpin(vma);
+			err = i915_vma_unbind(vma);
+			if (err) {
+				i915_vma_close(vma);
+				goto out_unpin;
+			}
+
+			if (igt_timeout(end_time,
+					"%s timed out at offset %x with page-size %x\n",
+					__func__, offset, page_size))
+				break;
+		}
+
+		i915_vma_close(vma);
+
+		i915_gem_object_unpin_pages(obj);
+		i915_gem_object_put(obj);
+	}
+
+	return 0;
+
+out_unpin:
+	i915_gem_object_unpin_pages(obj);
+out_put:
+	i915_gem_object_put(obj);
+
+	return err;
+}
+
+static void close_object_list(struct list_head *objects,
+			      struct i915_hw_ppgtt *ppgtt)
+{
+	struct drm_i915_gem_object *obj, *on;
+
+	list_for_each_entry_safe(obj, on, objects, st_link) {
+		struct i915_vma *vma;
+
+		vma = i915_vma_instance(obj, &ppgtt->base, NULL);
+		if (!IS_ERR(vma))
+			i915_vma_close(vma);
+
+		list_del(&obj->st_link);
+		i915_gem_object_unpin_pages(obj);
+		i915_gem_object_put(obj);
+	}
+}
+
+static int igt_mock_ppgtt_huge_fill(void *arg)
+{
+	struct i915_hw_ppgtt *ppgtt = arg;
+	struct drm_i915_private *i915 = ppgtt->base.i915;
+	unsigned long max_pages = ppgtt->base.total >> PAGE_SHIFT;
+	unsigned long page_num;
+	bool single = false;
+	LIST_HEAD(objects);
+	IGT_TIMEOUT(end_time);
+	int err;
+
+	for_each_prime_number_from(page_num, 1, max_pages) {
+		struct drm_i915_gem_object *obj;
+		size_t size = page_num << PAGE_SHIFT;
+		struct i915_vma *vma;
+		unsigned int expected_gtt = 0;
+		int i;
+
+		obj = fake_huge_pages_object(i915, size, single);
+		if (IS_ERR(obj)) {
+			err = PTR_ERR(obj);
+			break;
+		}
+
+		GEM_BUG_ON(obj->base.size != size);
+
+		err = i915_gem_object_pin_pages(obj);
+		if (err) {
+			i915_gem_object_put(obj);
+			break;
+		}
+
+		list_add(&obj->st_link, &objects);
+
+		GEM_BUG_ON(!obj->mm.page_sizes.sg);
+
+		vma = i915_vma_instance(obj, &ppgtt->base, NULL);
+		if (IS_ERR(vma)) {
+			err = PTR_ERR(vma);
+			break;
+		}
+
+		err = i915_vma_pin(vma, 0, 0, PIN_USER);
+		if (err)
+			break;
+
+		GEM_BUG_ON(obj->mm.page_sizes.gtt);
+		GEM_BUG_ON(!vma->page_sizes.sg);
+		GEM_BUG_ON(!vma->page_sizes.phys);
+
+		/* Figure out the expected gtt page size knowing that we go from
+		 * largest to smallest page size sg chunks, and that we align to
+		 * the largest page size.
+		 */
+		for (i = 0; i < ARRAY_SIZE(page_sizes); ++i) {
+			unsigned int page_size = page_sizes[i];
+
+			if (HAS_PAGE_SIZE(i915, page_size) &&
+			    size >= page_size) {
+				expected_gtt |= page_size;
+				size &= page_size-1;
+			}
+		}
+
+		GEM_BUG_ON(!expected_gtt);
+		GEM_BUG_ON(size);
+
+		if (expected_gtt & I915_GTT_PAGE_SIZE_4K)
+			expected_gtt &= ~I915_GTT_PAGE_SIZE_64K;
+
+		if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K) {
+			GEM_BUG_ON(!IS_ALIGNED(vma->node.start,
+					       I915_GTT_PAGE_SIZE_2M));
+			GEM_BUG_ON(!IS_ALIGNED(vma->node.size,
+					       I915_GTT_PAGE_SIZE_2M));
+		}
+
+		i915_vma_unpin(vma);
+
+		if (vma->page_sizes.gtt != expected_gtt) {
+			pr_err("gtt=%u, expected=%u, size=%zd, single=%s\n",
+			       vma->page_sizes.gtt, expected_gtt,
+			       obj->base.size, yesno(!!single));
+			err = -EINVAL;
+			break;
+		}
+
+		if (igt_timeout(end_time,
+				"%s timed out at size %zd\n",
+				__func__, obj->base.size))
+			break;
+
+		single = !single;
+	}
+
+	close_object_list(&objects, ppgtt);
+
+	if (err == -ENOMEM || err == -ENOSPC)
+		err = 0;
+
+	return err;
+}
+
+static int igt_mock_ppgtt_64K(void *arg)
+{
+	struct i915_hw_ppgtt *ppgtt = arg;
+	struct drm_i915_private *i915 = ppgtt->base.i915;
+	struct drm_i915_gem_object *obj;
+	const struct object_info {
+		unsigned int size;
+		unsigned int gtt;
+		unsigned int offset;
+	} objects[] = {
+		/* Cases with forced padding/alignment */
+		{
+			.size = SZ_64K,
+			.gtt = I915_GTT_PAGE_SIZE_64K,
+			.offset = 0,
+		},
+		{
+			.size = SZ_64K + SZ_4K,
+			.gtt = I915_GTT_PAGE_SIZE_4K,
+			.offset = 0,
+		},
+		{
+			.size = SZ_64K - SZ_4K,
+			.gtt = I915_GTT_PAGE_SIZE_4K,
+			.offset = 0,
+		},
+		{
+			.size = SZ_2M,
+			.gtt = I915_GTT_PAGE_SIZE_64K,
+			.offset = 0,
+		},
+		{
+			.size = SZ_2M - SZ_4K,
+			.gtt = I915_GTT_PAGE_SIZE_4K,
+			.offset = 0,
+		},
+		{
+			.size = SZ_2M + SZ_4K,
+			.gtt = I915_GTT_PAGE_SIZE_64K | I915_GTT_PAGE_SIZE_4K,
+			.offset = 0,
+		},
+		{
+			.size = SZ_2M + SZ_64K,
+			.gtt = I915_GTT_PAGE_SIZE_64K,
+			.offset = 0,
+		},
+		{
+			.size = SZ_2M - SZ_64K,
+			.gtt = I915_GTT_PAGE_SIZE_64K,
+			.offset = 0,
+		},
+		/* Try without any forced padding/alignment */
+		{
+			.size = SZ_64K,
+			.offset = SZ_2M,
+			.gtt = I915_GTT_PAGE_SIZE_4K,
+		},
+		{
+			.size = SZ_128K,
+			.offset = SZ_2M - SZ_64K,
+			.gtt = I915_GTT_PAGE_SIZE_4K,
+		},
+	};
+	struct i915_vma *vma;
+	int i, single;
+	int err;
+
+	/* Sanity check some of the trickiness with 64K pages -- either we can
+	 * safely mark the whole page-table(2M block) as 64K, or we have to
+	 * always fallback to 4K.
+	 */
+
+	if (!HAS_PAGE_SIZE(i915, I915_GTT_PAGE_SIZE_64K))
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(objects); ++i) {
+		unsigned int size = objects[i].size;
+		unsigned int expected_gtt = objects[i].gtt;
+		unsigned int offset = objects[i].offset;
+		unsigned int flags = PIN_USER;
+
+		for (single = 0; single <= 1; single++) {
+			obj = fake_huge_pages_object(i915, size, !!single);
+			if (IS_ERR(obj))
+				return PTR_ERR(obj);
+
+			err = i915_gem_object_pin_pages(obj);
+			if (err)
+				goto out_put;
+
+			GEM_BUG_ON(!obj->mm.page_sizes.sg);
+
+			/* Disable 2M pages -- We only want to use 64K/4K pages
+			 * for this test.
+			 */
+			obj->mm.page_sizes.sg &= ~I915_GTT_PAGE_SIZE_2M;
+
+			vma = i915_vma_instance(obj, &ppgtt->base, NULL);
+			if (IS_ERR(vma)) {
+				err = PTR_ERR(vma);
+				goto out_unpin;
+			}
+
+			if (offset)
+				flags |= PIN_OFFSET_FIXED | offset;
+
+			err = i915_vma_pin(vma, 0, 0, flags);
+			if (err) {
+				i915_vma_close(vma);
+				goto out_unpin;
+			}
+
+			GEM_BUG_ON(obj->mm.page_sizes.gtt);
+			GEM_BUG_ON(!vma->page_sizes.sg);
+			GEM_BUG_ON(!vma->page_sizes.phys);
+
+			if (!offset && vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K) {
+				GEM_BUG_ON(!IS_ALIGNED(vma->node.start,
+							I915_GTT_PAGE_SIZE_2M));
+				GEM_BUG_ON(!IS_ALIGNED(vma->node.size,
+							I915_GTT_PAGE_SIZE_2M));
+			}
+
+			if (vma->page_sizes.gtt != expected_gtt) {
+				pr_err("gtt=%u, expected=%u, i=%d, single=%s\n",
+				       vma->page_sizes.gtt, expected_gtt, i,
+				       yesno(!!single));
+				err = -EINVAL;
+				goto out_vma;
+			}
+
+			i915_vma_unpin(vma);
+			i915_vma_close(vma);
+
+			i915_gem_object_unpin_pages(obj);
+			i915_gem_object_put(obj);
+		}
+	}
+
+	return 0;
+
+out_vma:
+	i915_vma_unpin(vma);
+	i915_vma_close(vma);
+out_unpin:
+	i915_gem_object_unpin_pages(obj);
+out_put:
+	i915_gem_object_put(obj);
+
+	return err;
+}
+
+static struct i915_vma *
+gpu_write_dw(struct i915_vma *vma, u64 offset, u32 val)
+{
+	struct drm_i915_private *i915 = to_i915(vma->obj->base.dev);
+	const int gen = INTEL_GEN(vma->vm->i915);
+	unsigned int count = vma->size >> PAGE_SHIFT;
+	struct drm_i915_gem_object *obj;
+	struct i915_vma *batch;
+	unsigned int size;
+	u32 *cmd;
+	int n;
+	int err;
+
+	size = 1 + 4 * count * sizeof(u32);
+	size = round_up(size, PAGE_SIZE);
+	obj = i915_gem_object_create_internal(i915, size);
+	if (IS_ERR(obj))
+		return ERR_CAST(obj);
+
+	cmd = i915_gem_object_pin_map(obj, I915_MAP_WB);
+	if (IS_ERR(cmd)) {
+		err = PTR_ERR(cmd);
+		goto err;
+	}
+
+	offset += vma->node.start;
+
+	for (n = 0; n < count; n++) {
+		if (gen >= 8) {
+			*cmd++ = MI_STORE_DWORD_IMM_GEN4;
+			*cmd++ = lower_32_bits(offset);
+			*cmd++ = upper_32_bits(offset);
+			*cmd++ = val;
+		} else if (gen >= 4) {
+			*cmd++ = MI_STORE_DWORD_IMM_GEN4 |
+				(gen < 6 ? 1 << 22 : 0);
+			*cmd++ = 0;
+			*cmd++ = offset;
+			*cmd++ = val;
+		} else {
+			*cmd++ = MI_STORE_DWORD_IMM | 1 << 22;
+			*cmd++ = offset;
+			*cmd++ = val;
+		}
+
+		offset += PAGE_SIZE;
+	}
+
+	*cmd = MI_BATCH_BUFFER_END;
+
+	i915_gem_object_unpin_map(obj);
+
+	err = i915_gem_object_set_to_gtt_domain(obj, false);
+	if (err)
+		goto err;
+
+	batch = i915_vma_instance(obj, vma->vm, NULL);
+	if (IS_ERR(batch)) {
+		err = PTR_ERR(batch);
+		goto err;
+	}
+
+	err = i915_vma_pin(batch, 0, 0, PIN_USER);
+	if (err)
+		goto err;
+
+	return batch;
+
+err:
+	i915_gem_object_put(obj);
+
+	return ERR_PTR(err);
+}
+
+static int gpu_write(struct i915_vma *vma,
+		     struct i915_gem_context *ctx,
+		     u32 dword,
+		     u32 value)
+{
+	struct drm_i915_private *i915 = to_i915(vma->obj->base.dev);
+	struct drm_i915_gem_request *rq;
+	struct i915_vma *batch;
+	int flags = 0;
+	int err;
+
+	GEM_BUG_ON(!intel_engine_can_store_dword(i915->engine[RCS]));
+
+	err = i915_gem_object_set_to_gtt_domain(vma->obj, true);
+	if (err)
+		return err;
+
+	rq = i915_gem_request_alloc(i915->engine[RCS], ctx);
+	if (IS_ERR(rq))
+		return PTR_ERR(rq);
+
+	batch = gpu_write_dw(vma, dword * sizeof(u32), value);
+	if (IS_ERR(batch)) {
+		err = PTR_ERR(batch);
+		goto err_request;
+	}
+
+	i915_vma_move_to_active(batch, rq, 0);
+	i915_gem_object_set_active_reference(batch->obj);
+	i915_vma_unpin(batch);
+	i915_vma_close(batch);
+
+	err = rq->engine->emit_flush(rq, EMIT_INVALIDATE);
+	if (err)
+		goto err_request;
+
+	err = i915_switch_context(rq);
+	if (err)
+		goto err_request;
+
+	err = rq->engine->emit_bb_start(rq,
+			batch->node.start, batch->node.size,
+			flags);
+	if (err)
+		goto err_request;
+
+	i915_vma_move_to_active(vma, rq, 0);
+
+	reservation_object_lock(vma->resv, NULL);
+	reservation_object_add_excl_fence(vma->resv, &rq->fence);
+	reservation_object_unlock(vma->resv);
+
+err_request:
+	__i915_add_request(rq, err == 0);
+
+	return err;
+}
+
+static int unmap_mapping(struct drm_i915_gem_object *obj)
+{
+	void *ptr;
+	int err;
+
+	err = mutex_lock_interruptible(&obj->mm.lock);
+	if (err)
+		return err;
+
+	ptr = page_mask_bits(obj->mm.mapping);
+	if (ptr) {
+		if (is_vmalloc_addr(ptr))
+			vunmap(ptr);
+		else
+			kunmap(kmap_to_page(ptr));
+
+		obj->mm.mapping = NULL;
+	}
+
+	mutex_unlock(&obj->mm.lock);
+
+	return 0;
+}
+
+#define DWORDS_PER_PAGE (PAGE_SIZE/sizeof(u32))
+
+static int cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val)
+{
+	enum i915_map_type level;
+	int err;
+
+	for (level = I915_MAP_WB; level <= I915_MAP_WC; level++) {
+		u32 *map, offset;
+
+		if (level == I915_MAP_WB)
+			err = i915_gem_object_set_to_cpu_domain(obj, false);
+		else
+			err = i915_gem_object_set_to_wc_domain(obj, false);
+		if (err)
+			return err;
+
+		unmap_mapping(obj);
+		map = i915_gem_object_pin_map(obj, level);
+		if (IS_ERR(map))
+			return PTR_ERR(map);
+
+		for (offset = dword; offset < obj->base.size/sizeof(u32);
+		     offset += DWORDS_PER_PAGE) {
+			if (map[offset] != val) {
+				pr_err("map[%u] = %u, expected %u\n",
+				       offset, map[offset], val);
+				err = -EINVAL;
+				goto out_close;
+			}
+		}
+
+		i915_gem_object_unpin_map(obj);
+	}
+
+	return 0;
+
+out_close:
+	i915_gem_object_unpin_map(obj);
+
+	return err;
+}
+
+static int igt_write_huge(struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+	unsigned long supported = INTEL_INFO(i915)->page_size_mask;
+	struct i915_gem_context *ctx = i915->kernel_context;
+	struct i915_address_space *vm = ctx->ppgtt ? &ctx->ppgtt->base : &i915->ggtt.base;
+	unsigned int flags = PIN_USER | PIN_OFFSET_FIXED;
+	struct i915_vma *vma;
+	int bit, last;
+	int err;
+
+	GEM_BUG_ON(obj->base.size != SZ_2M);
+
+	err = i915_gem_object_pin_pages(obj);
+	if (err)
+		return err;
+
+	/* We want to run the test even if the platform doesn't support huge gtt
+	 * pages -- our only requirement is that we were able to allocate a
+	 * "huge-page".
+	 */
+	if (obj->mm.page_sizes.phys < I915_GTT_PAGE_SIZE_2M) {
+		pr_info("Unable to allocate huge-page, finishing test early\n");
+		goto out_unpin;
+	}
+
+	vma = i915_vma_instance(obj, vm, NULL);
+	if (IS_ERR(vma)) {
+		err = PTR_ERR(vma);
+		goto out_unpin;
+	}
+
+	last = ilog2(I915_GTT_PAGE_SIZE_2M);
+
+	for_each_set_bit(bit, &supported, last + 1) {
+		IGT_TIMEOUT(end_time);
+		unsigned int page_size = BIT(bit);
+		u32 max = vm->total / I915_GTT_PAGE_SIZE_2M - 1;
+		u32 num;
+
+		/* Force the page size */
+		vma->page_sizes.sg = obj->mm.page_sizes.sg = page_size;
+
+		/* Try various offsets until we timeout -- we want to avoid
+		 * issues hidden by effectively always using offset = 0.
+		 */
+		for_each_prime_number_from(num, 0, max) {
+			u64 offset = num * I915_GTT_PAGE_SIZE_2M;
+			u32 dword;
+
+			err = i915_vma_unbind(vma);
+			if (err)
+				goto out_close;
+
+			err = i915_vma_pin(vma, 0, 0, flags | offset);
+			if (err) {
+				/* The ggtt may have some pages reserved so
+				 * refrain from erroring out.
+				 */
+				if (err == -ENOSPC && i915_is_ggtt(vm))
+					continue;
+
+				goto out_close;
+			}
+
+			GEM_BUG_ON(obj->mm.page_sizes.gtt);
+			GEM_BUG_ON(vma->page_sizes.sg != page_size);
+			GEM_BUG_ON(!vma->page_sizes.phys);
+
+			if (vma->page_sizes.gtt != page_size) {
+				dma_addr_t addr =
+					i915_gem_object_get_dma_address(obj, 0);
+
+				/* The only valid reason for this to ever fail
+				 * would be if the dma-mapper screwed us over
+				 * when we did the dma_map_sg(), since it has
+				 * the final say over the dma address.
+				 */
+				GEM_BUG_ON(IS_ALIGNED(addr,
+						      I915_GTT_PAGE_SIZE_2M));
+
+				pr_info("dma address misaligned, hobbling on\n");
+			}
+
+			for (dword = 0; dword < DWORDS_PER_PAGE; ++dword) {
+				err = gpu_write(vma, ctx, dword, num + 1);
+				if (err) {
+					pr_err("gpu_write failed with page-size %x\n",
+					       page_size);
+					i915_vma_unpin(vma);
+					goto out_close;
+				}
+
+				err = cpu_check(obj, dword, num + 1);
+				if (err) {
+					pr_err("cpu_check failed with page-size %x\n",
+					       page_size);
+					i915_vma_unpin(vma);
+					goto out_close;
+				}
+			}
+
+			i915_vma_unpin(vma);
+
+			if (num > 0 &&
+			    igt_timeout(end_time,
+					"%s timed out at offset %llx with ps %x\n",
+					__func__, offset, page_size))
+				break;
+		}
+	}
+
+out_close:
+	i915_vma_close(vma);
+out_unpin:
+	i915_gem_object_unpin_pages(obj);
+
+	return err;
+}
+
+static int igt_ppgtt_write_huge(void *arg)
+{
+	struct drm_i915_private *i915 = arg;
+	struct drm_i915_gem_object *obj;
+	int err;
+
+	/* Sanity check that the HW uses huge pages correctly -- ensure that
+	 * our writes land in the right place
+	 */
+
+	if (!intel_engine_can_store_dword(i915->engine[RCS])) {
+		pr_info("store-dword-imm not supported, skipping\n");
+		return 0;
+	}
+
+	/* Try without thp */
+	obj = i915_gem_object_create_internal(i915, SZ_2M);
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
+
+	err = igt_write_huge(obj);
+	i915_gem_object_put(obj);
+	if (err) {
+		pr_err("write-huge failed with internal allocator\n");
+		return err;
+	}
+
+	if (!has_transparent_hugepage()) {
+		pr_info("thp not supported, skipping\n");
+		return 0;
+	}
+
+	/* Try with thp through gemfs */
+	obj = i915_gem_object_create(i915, SZ_2M);
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
+
+	err = igt_write_huge(obj);
+	i915_gem_object_put(obj);
+	if (err)
+		pr_err("write-huge failed with thp\n");
+
+	return err;
+}
+
+static int igt_ppgtt_pin_update(void *arg)
+{
+	struct drm_i915_private *dev_priv = arg;
+	unsigned long supported = INTEL_INFO(dev_priv)->page_size_mask;
+	struct i915_hw_ppgtt *ppgtt = dev_priv->kernel_context->ppgtt;
+	struct drm_i915_gem_object *obj;
+	struct i915_vma *vma;
+	unsigned int flags = PIN_USER | PIN_OFFSET_FIXED;
+	unsigned int needs_flush;
+	int bit, last;
+	u32 *ptr;
+	int err;
+
+	/* Make sure there's no funny business when doing a PIN_UPDATE -- in the
+	 * past we had a subtle issue with being able to incorrectly do multiple
+	 * alloc va ranges on the same object when doing a PIN_UPDATE, which
+	 * resulted in some pretty nasty bugs, though only when using
+	 * huge-gtt-pages.
+	 */
+
+	if (!USES_FULL_48BIT_PPGTT(dev_priv)) {
+		pr_info("48b PPGTT not supported, skipping\n");
+		return 0;
+	}
+
+	bit = ilog2(I915_GTT_PAGE_SIZE_64K);
+	last = ilog2(I915_GTT_PAGE_SIZE_2M);
+
+	for_each_set_bit_from(bit, &supported, last + 1) {
+		unsigned int page_size = BIT(bit);
+
+		obj = i915_gem_object_create_internal(dev_priv, SZ_2M);
+		if (IS_ERR(obj))
+			return PTR_ERR(obj);
+
+		vma = i915_vma_instance(obj, &ppgtt->base, NULL);
+		if (IS_ERR(vma)) {
+			err = PTR_ERR(vma);
+			goto out_put;
+		}
+
+		err = i915_vma_pin(vma, 0, 0, flags);
+		if (err)
+			goto out_close;
+
+		if (vma->page_sizes.sg < page_size) {
+			pr_info("Unable to allocate page-size %x, finishing test early\n",
+				page_size);
+			goto out_unpin;
+		}
+
+		if (vma->page_sizes.gtt != page_size) {
+			dma_addr_t addr = i915_gem_object_get_dma_address(obj, 0);
+
+			/* The only valid reason for this to ever fail would be
+			 * if the dma-mapper screwed us over when we did the
+			 * dma_map_sg(), since it has the final say over the dma
+			 * address.
+			 */
+			GEM_BUG_ON(IS_ALIGNED(addr, page_size));
+
+			pr_info("dma address misaligned, finishing test early\n");
+			goto out_unpin;
+		}
+
+		err = i915_vma_bind(vma, I915_CACHE_NONE, PIN_UPDATE);
+		if (err)
+			goto out_unpin;
+
+		i915_vma_unpin(vma);
+		i915_vma_close(vma);
+
+		i915_gem_object_put(obj);
+	}
+
+	obj = i915_gem_object_create_internal(dev_priv, PAGE_SIZE);
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
+
+	vma = i915_vma_instance(obj, &ppgtt->base, NULL);
+	if (IS_ERR(vma)) {
+		err = PTR_ERR(vma);
+		goto out_put;
+	}
+
+	err = i915_vma_pin(vma, 0, 0, flags);
+	if (err)
+		goto out_close;
+
+	/* Make sure we don't end up with something like where the pde is still
+	 * pointing to the 2M page, and the pt we just filled-in is dangling --
+	 * we can check this by writing to the first page where it would then
+	 * land in the now stale 2M page.
+	 */
+
+	err = gpu_write(vma, dev_priv->kernel_context, 0, 0xdeadbeaf);
+	if (err)
+		goto out_unpin;
+
+	err = i915_gem_obj_prepare_shmem_read(obj, &needs_flush);
+	if (err)
+		goto out_unpin;
+
+	ptr = kmap_atomic(i915_gem_object_get_page(obj, 0));
+	if (needs_flush & CLFLUSH_BEFORE)
+		drm_clflush_virt_range(ptr, PAGE_SIZE);
+
+	if (*ptr != 0xdeadbeaf) {
+		pr_err("ptr = %x, expected %x\n", *ptr, 0xdeadbeaf);
+		err = -EINVAL;
+	}
+
+	kunmap_atomic(ptr);
+
+	i915_gem_obj_finish_shmem_access(obj);
+
+out_unpin:
+	i915_vma_unpin(vma);
+out_close:
+	i915_vma_close(vma);
+out_put:
+	i915_gem_object_put(obj);
+
+	return err;
+}
+
+static int igt_ppgtt_gemfs_huge(void *arg)
+{
+	struct drm_i915_private *i915 = arg;
+	struct i915_gem_context *ctx = i915->kernel_context;
+	struct i915_address_space *vm = ctx->ppgtt ? &ctx->ppgtt->base : &i915->ggtt.base;
+	struct drm_i915_gem_object *obj;
+	const unsigned int object_sizes[] = {
+		I915_GTT_PAGE_SIZE_2M,
+		I915_GTT_PAGE_SIZE_2M + I915_GTT_PAGE_SIZE_4K,
+	};
+	unsigned int flags = PIN_USER;
+	int err;
+	int i;
+
+	/* Sanity check THP through gemfs */
+
+	if (!has_transparent_hugepage()) {
+		pr_info("thp not supported, skipping\n");
+		return 0;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(object_sizes); ++i) {
+		unsigned int size = object_sizes[i];
+		struct i915_vma *vma;
+
+		obj = i915_gem_object_create(i915, size);
+		if (IS_ERR(obj))
+			return PTR_ERR(obj);
+
+		err = i915_gem_object_pin_pages(obj);
+		if (err)
+			goto out_put;
+
+		GEM_BUG_ON(!obj->mm.page_sizes.sg);
+
+		if (obj->mm.page_sizes.phys < I915_GTT_PAGE_SIZE_2M) {
+			pr_info("Unable to allocate thp, finishing test early\n");
+			goto out_unpin;
+		}
+
+		vma = i915_vma_instance(obj, vm, NULL);
+		if (IS_ERR(vma)) {
+			err = PTR_ERR(vma);
+			goto out_unpin;
+		}
+
+		err = i915_vma_pin(vma, 0, 0, flags);
+		if (err) {
+			i915_vma_close(vma);
+			goto out_unpin;
+		}
+
+		GEM_BUG_ON(obj->mm.page_sizes.gtt);
+		GEM_BUG_ON(!vma->page_sizes.sg);
+		GEM_BUG_ON(!vma->page_sizes.phys);
+
+		if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_2M) {
+			if (vma->page_sizes.gtt != size) {
+				dma_addr_t addr =
+					i915_gem_object_get_dma_address(obj, 0);
+
+				/* The only valid reason for this to ever fail
+				 * would be if the dma-mapper screwed us over
+				 * when we did the dma_map_sg(), since it has
+				 * the final say over the dma address.
+				 */
+				GEM_BUG_ON(IS_ALIGNED(addr,
+						      I915_GTT_PAGE_SIZE_2M));
+				pr_info("dma address unaligned\n");
+			}
+
+			GEM_BUG_ON(!IS_ALIGNED(vma->node.start,
+					       I915_GTT_PAGE_SIZE_2M));
+		}
+
+		if (vma->page_sizes.sg & I915_GTT_PAGE_SIZE_64K) {
+			GEM_BUG_ON(!IS_ALIGNED(vma->node.size,
+					       I915_GTT_PAGE_SIZE_2M));
+		}
+
+		i915_vma_unpin(vma);
+		i915_vma_close(vma);
+
+		i915_gem_object_unpin_pages(obj);
+		i915_gem_object_put(obj);
+	}
+
+	return 0;
+
+out_unpin:
+	i915_gem_object_unpin_pages(obj);
+out_put:
+	i915_gem_object_put(obj);
+
+	return err;
+}
+
+int i915_gem_huge_page_mock_selftests(void)
+{
+	static const struct i915_subtest tests[] = {
+		SUBTEST(igt_mock_exhaust_device_supported_pages),
+		SUBTEST(igt_mock_ppgtt_misaligned_dma),
+		SUBTEST(igt_mock_ppgtt_huge_fill),
+		SUBTEST(igt_mock_ppgtt_64K),
+	};
+	int saved_ppgtt = i915.enable_ppgtt;
+	struct drm_i915_private *dev_priv;
+	struct pci_dev *pdev;
+	struct i915_hw_ppgtt *ppgtt;
+	int err;
+
+	dev_priv = mock_gem_device();
+	if (!dev_priv)
+		return -ENOMEM;
+
+	/* Pretend to be a device which supports the 48b PPGTT */
+	i915.enable_ppgtt = 3;
+
+	pdev = dev_priv->drm.pdev;
+	dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(39));
+
+	mutex_lock(&dev_priv->drm.struct_mutex);
+	ppgtt = i915_ppgtt_create(dev_priv, ERR_PTR(-ENODEV), "mock");
+	if (IS_ERR(ppgtt)) {
+		err = PTR_ERR(ppgtt);
+		goto out_unlock;
+	}
+
+	GEM_BUG_ON(!i915_vm_is_48bit(&ppgtt->base));
+
+	err = i915_subtests(tests, ppgtt);
+
+	i915_ppgtt_close(&ppgtt->base);
+	i915_ppgtt_put(ppgtt);
+
+out_unlock:
+	mutex_unlock(&dev_priv->drm.struct_mutex);
+
+	i915.enable_ppgtt = saved_ppgtt;
+
+	drm_dev_unref(&dev_priv->drm);
+
+	return err;
+}
+
+int i915_gem_huge_page_live_selftests(struct drm_i915_private *dev_priv)
+{
+	static const struct i915_subtest tests[] = {
+		SUBTEST(igt_ppgtt_gemfs_huge),
+		SUBTEST(igt_ppgtt_pin_update),
+		SUBTEST(igt_ppgtt_write_huge),
+	};
+	int err;
+
+	if (!USES_PPGTT(dev_priv)) {
+		pr_info("PPGTT not supported, skipping live-selftests\n");
+		return 0;
+	}
+
+	mutex_lock(&dev_priv->drm.struct_mutex);
+	err = i915_subtests(tests, dev_priv);
+	mutex_unlock(&dev_priv->drm.struct_mutex);
+
+	return err;
+}
diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
index 18b174d855ca..64acd7eccc5c 100644
--- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
@@ -15,5 +15,6 @@ selftest(objects, i915_gem_object_live_selftests)
 selftest(dmabuf, i915_gem_dmabuf_live_selftests)
 selftest(coherency, i915_gem_coherency_live_selftests)
 selftest(gtt, i915_gem_gtt_live_selftests)
+selftest(hugepages, i915_gem_huge_page_live_selftests)
 selftest(contexts, i915_gem_context_live_selftests)
 selftest(hangcheck, intel_hangcheck_live_selftests)
diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
index fc74687501ba..9961b44f76ed 100644
--- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
@@ -21,3 +21,4 @@ selftest(dmabuf, i915_gem_dmabuf_mock_selftests)
 selftest(vma, i915_vma_mock_selftests)
 selftest(evict, i915_gem_evict_mock_selftests)
 selftest(gtt, i915_gem_gtt_mock_selftests)
+selftest(hugepages, i915_gem_huge_page_mock_selftests)
-- 
2.13.5

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

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

* [PATCH 19/23] drm/i915/selftests: mix huge pages
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (17 preceding siblings ...)
  2017-08-21 18:34 ` [PATCH 18/23] drm/i915/selftests: huge page tests Matthew Auld
@ 2017-08-21 18:34 ` Matthew Auld
  2017-08-21 18:35 ` [PATCH 20/23] drm/i915: disable platform support for vGPU huge gtt pages Matthew Auld
                   ` (5 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:34 UTC (permalink / raw)
  To: intel-gfx

Try to mix sg page sizes for 4K, 64K and 2M pages.

v2: s/BIT(x) >> 12/BIT(x) >> PAGE_SHIFT/

Suggested-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/selftests/scatterlist.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/scatterlist.c b/drivers/gpu/drm/i915/selftests/scatterlist.c
index 1cc5d2931753..cd6d2a16071f 100644
--- a/drivers/gpu/drm/i915/selftests/scatterlist.c
+++ b/drivers/gpu/drm/i915/selftests/scatterlist.c
@@ -189,6 +189,20 @@ static unsigned int random(unsigned long n,
 	return 1 + (prandom_u32_state(rnd) % 1024);
 }
 
+static unsigned int random_page_size_pages(unsigned long n,
+					   unsigned long count,
+					   struct rnd_state *rnd)
+{
+	/* 4K, 64K, 2M */
+	static unsigned int page_count[] = {
+		BIT(12) >> PAGE_SHIFT,
+		BIT(16) >> PAGE_SHIFT,
+		BIT(21) >> PAGE_SHIFT,
+	};
+
+	return page_count[(prandom_u32_state(rnd) % 3)];
+}
+
 static inline bool page_contiguous(struct page *first,
 				   struct page *last,
 				   unsigned long npages)
@@ -252,6 +266,7 @@ static const npages_fn_t npages_funcs[] = {
 	grow,
 	shrink,
 	random,
+	random_page_size_pages,
 	NULL,
 };
 
-- 
2.13.5

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

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

* [PATCH 20/23] drm/i915: disable platform support for vGPU huge gtt pages
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (18 preceding siblings ...)
  2017-08-21 18:34 ` [PATCH 19/23] drm/i915/selftests: mix huge pages Matthew Auld
@ 2017-08-21 18:35 ` Matthew Auld
  2017-08-21 18:35 ` [PATCH 21/23] drm/i915: enable platform support for 64K pages Matthew Auld
                   ` (4 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:35 UTC (permalink / raw)
  To: intel-gfx

Currently gvt gtt handling doesn't support huge page entries, so disable
for now.

v2: remove useless 48b PPGTT check

Suggested-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Zhenyu Wang <zhenyuw@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index eb2c8d97d441..53f8242a9ece 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4849,6 +4849,14 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
 
 	mutex_lock(&dev_priv->drm.struct_mutex);
 
+	/* We need to fallback to 4K pages since gvt gtt handling doesn't
+	 * support huge page entries - we will need to check either hypervisor
+	 * mm can support huge guest page or just do emulation in gvt.
+	 */
+	if (intel_vgpu_active(dev_priv))
+		mkwrite_device_info(dev_priv)->page_size_mask =
+			I915_GTT_PAGE_SIZE_4K;
+
 	dev_priv->mm.unordered_timeline = dma_fence_context_alloc(1);
 
 	if (!i915.enable_execlists) {
-- 
2.13.5

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

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

* [PATCH 21/23] drm/i915: enable platform support for 64K pages
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (19 preceding siblings ...)
  2017-08-21 18:35 ` [PATCH 20/23] drm/i915: disable platform support for vGPU huge gtt pages Matthew Auld
@ 2017-08-21 18:35 ` Matthew Auld
  2017-08-21 18:35 ` [PATCH 22/23] drm/i915: enable platform support for 2M pages Matthew Auld
                   ` (3 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:35 UTC (permalink / raw)
  To: intel-gfx

For gen9+ enable platform level support for 64K pages. Also enable for
mock testing.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_pci.c                  | 3 ++-
 drivers/gpu/drm/i915/selftests/mock_gem_device.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index b07fabf1cd4f..c453ef752ee9 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -364,7 +364,8 @@ static const struct intel_device_info intel_cherryview_info = {
 };
 
 #define GEN9_DEFAULT_PAGE_SIZES \
-	.page_size_mask = I915_GTT_PAGE_SIZE_4K
+	.page_size_mask = I915_GTT_PAGE_SIZE_4K | \
+			  I915_GTT_PAGE_SIZE_64K
 
 #define SKL_PLATFORM \
 	BDW_FEATURES, \
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index 39acab2396b2..ffc4548c47ee 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -170,7 +170,8 @@ struct drm_i915_private *mock_gem_device(void)
 	mkwrite_device_info(i915)->gen = -1;
 
 	mkwrite_device_info(i915)->page_size_mask =
-		I915_GTT_PAGE_SIZE_4K;
+		I915_GTT_PAGE_SIZE_4K |
+		I915_GTT_PAGE_SIZE_64K;
 
 	spin_lock_init(&i915->mm.object_stat_lock);
 	mock_uncore_init(i915);
-- 
2.13.5

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

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

* [PATCH 22/23] drm/i915: enable platform support for 2M pages
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (20 preceding siblings ...)
  2017-08-21 18:35 ` [PATCH 21/23] drm/i915: enable platform support for 64K pages Matthew Auld
@ 2017-08-21 18:35 ` Matthew Auld
  2017-08-21 18:35 ` [PATCH 23/23] drm/i915: enable platform support for 1G pages Matthew Auld
                   ` (2 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:35 UTC (permalink / raw)
  To: intel-gfx

For gen8+ platforms which support the 48b PPGTT, enable platform level
support for 2M pages. Also enable for mock testing.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_pci.c                  | 6 ++++--
 drivers/gpu/drm/i915/selftests/mock_gem_device.c | 3 ++-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index c453ef752ee9..0b1699c574a5 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -319,7 +319,8 @@ static const struct intel_device_info intel_haswell_info = {
 #define BDW_FEATURES \
 	HSW_FEATURES, \
 	BDW_COLORS, \
-	GEN_DEFAULT_PAGE_SIZES, \
+	.page_size_mask = I915_GTT_PAGE_SIZE_4K | \
+			  I915_GTT_PAGE_SIZE_2M, \
 	.has_logical_ring_contexts = 1, \
 	.has_full_48bit_ppgtt = 1, \
 	.has_64bit_reloc = 1, \
@@ -365,7 +366,8 @@ static const struct intel_device_info intel_cherryview_info = {
 
 #define GEN9_DEFAULT_PAGE_SIZES \
 	.page_size_mask = I915_GTT_PAGE_SIZE_4K | \
-			  I915_GTT_PAGE_SIZE_64K
+			  I915_GTT_PAGE_SIZE_64K | \
+			  I915_GTT_PAGE_SIZE_2M
 
 #define SKL_PLATFORM \
 	BDW_FEATURES, \
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index ffc4548c47ee..e8e0dd9743f4 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -171,7 +171,8 @@ struct drm_i915_private *mock_gem_device(void)
 
 	mkwrite_device_info(i915)->page_size_mask =
 		I915_GTT_PAGE_SIZE_4K |
-		I915_GTT_PAGE_SIZE_64K;
+		I915_GTT_PAGE_SIZE_64K |
+		I915_GTT_PAGE_SIZE_2M;
 
 	spin_lock_init(&i915->mm.object_stat_lock);
 	mock_uncore_init(i915);
-- 
2.13.5

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

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

* [PATCH 23/23] drm/i915: enable platform support for 1G pages
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (21 preceding siblings ...)
  2017-08-21 18:35 ` [PATCH 22/23] drm/i915: enable platform support for 2M pages Matthew Auld
@ 2017-08-21 18:35 ` Matthew Auld
  2017-08-21 18:54 ` ✓ Fi.CI.BAT: success for huge gtt pages (rev7) Patchwork
  2017-08-22 14:21 ` [PATCH 00/23] huge gtt pages Chris Wilson
  24 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-21 18:35 UTC (permalink / raw)
  To: intel-gfx

For gen8+ enable platforms which support the 48b PPGTT, enable support
for 1G pages. Also enable for mock testing.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_pci.c                  | 6 ++++--
 drivers/gpu/drm/i915/selftests/mock_gem_device.c | 3 ++-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 0b1699c574a5..f01e23d3ac28 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -320,7 +320,8 @@ static const struct intel_device_info intel_haswell_info = {
 	HSW_FEATURES, \
 	BDW_COLORS, \
 	.page_size_mask = I915_GTT_PAGE_SIZE_4K | \
-			  I915_GTT_PAGE_SIZE_2M, \
+			  I915_GTT_PAGE_SIZE_2M | \
+			  I915_GTT_PAGE_SIZE_1G, \
 	.has_logical_ring_contexts = 1, \
 	.has_full_48bit_ppgtt = 1, \
 	.has_64bit_reloc = 1, \
@@ -367,7 +368,8 @@ static const struct intel_device_info intel_cherryview_info = {
 #define GEN9_DEFAULT_PAGE_SIZES \
 	.page_size_mask = I915_GTT_PAGE_SIZE_4K | \
 			  I915_GTT_PAGE_SIZE_64K | \
-			  I915_GTT_PAGE_SIZE_2M
+			  I915_GTT_PAGE_SIZE_2M | \
+			  I915_GTT_PAGE_SIZE_1G
 
 #define SKL_PLATFORM \
 	BDW_FEATURES, \
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index e8e0dd9743f4..4d05ff8ebf0a 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -172,7 +172,8 @@ struct drm_i915_private *mock_gem_device(void)
 	mkwrite_device_info(i915)->page_size_mask =
 		I915_GTT_PAGE_SIZE_4K |
 		I915_GTT_PAGE_SIZE_64K |
-		I915_GTT_PAGE_SIZE_2M;
+		I915_GTT_PAGE_SIZE_2M |
+		I915_GTT_PAGE_SIZE_1G;
 
 	spin_lock_init(&i915->mm.object_stat_lock);
 	mock_uncore_init(i915);
-- 
2.13.5

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

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

* ✓ Fi.CI.BAT: success for huge gtt pages (rev7)
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (22 preceding siblings ...)
  2017-08-21 18:35 ` [PATCH 23/23] drm/i915: enable platform support for 1G pages Matthew Auld
@ 2017-08-21 18:54 ` Patchwork
  2017-08-22 14:21 ` [PATCH 00/23] huge gtt pages Chris Wilson
  24 siblings, 0 replies; 45+ messages in thread
From: Patchwork @ 2017-08-21 18:54 UTC (permalink / raw)
  To: Matthew Auld; +Cc: intel-gfx

== Series Details ==

Series: huge gtt pages (rev7)
URL   : https://patchwork.freedesktop.org/series/25118/
State : success

== Summary ==

Series 25118v7 huge gtt pages
https://patchwork.freedesktop.org/api/1.0/series/25118/revisions/7/mbox/

Test kms_flip:
        Subgroup basic-flip-vs-modeset:
                skip       -> PASS       (fi-skl-x1585l) fdo#101781
Test kms_pipe_crc_basic:
        Subgroup suspend-read-crc-pipe-b:
                pass       -> DMESG-WARN (fi-byt-n2820) fdo#101705
Test drv_module_reload:
        Subgroup basic-reload-inject:
                pass       -> DMESG-WARN (fi-kbl-7260u) fdo#102295

fdo#101781 https://bugs.freedesktop.org/show_bug.cgi?id=101781
fdo#101705 https://bugs.freedesktop.org/show_bug.cgi?id=101705
fdo#102295 https://bugs.freedesktop.org/show_bug.cgi?id=102295

fi-bdw-5557u     total:279  pass:268  dwarn:0   dfail:0   fail:0   skip:11  time:447s
fi-bdw-gvtdvm    total:279  pass:265  dwarn:0   dfail:0   fail:0   skip:14  time:433s
fi-blb-e6850     total:279  pass:224  dwarn:1   dfail:0   fail:0   skip:54  time:355s
fi-bsw-n3050     total:279  pass:243  dwarn:0   dfail:0   fail:0   skip:36  time:553s
fi-bwr-2160      total:279  pass:184  dwarn:0   dfail:0   fail:0   skip:95  time:249s
fi-bxt-j4205     total:279  pass:260  dwarn:0   dfail:0   fail:0   skip:19  time:518s
fi-byt-j1900     total:279  pass:254  dwarn:1   dfail:0   fail:0   skip:24  time:520s
fi-byt-n2820     total:279  pass:250  dwarn:1   dfail:0   fail:0   skip:28  time:523s
fi-elk-e7500     total:279  pass:230  dwarn:0   dfail:0   fail:0   skip:49  time:439s
fi-glk-2a        total:279  pass:260  dwarn:0   dfail:0   fail:0   skip:19  time:617s
fi-hsw-4770      total:279  pass:263  dwarn:0   dfail:0   fail:0   skip:16  time:455s
fi-hsw-4770r     total:279  pass:263  dwarn:0   dfail:0   fail:0   skip:16  time:425s
fi-ilk-650       total:279  pass:229  dwarn:0   dfail:0   fail:0   skip:50  time:421s
fi-ivb-3520m     total:279  pass:261  dwarn:0   dfail:0   fail:0   skip:18  time:508s
fi-ivb-3770      total:279  pass:261  dwarn:0   dfail:0   fail:0   skip:18  time:474s
fi-kbl-7260u     total:279  pass:267  dwarn:2   dfail:0   fail:0   skip:10  time:489s
fi-kbl-7500u     total:279  pass:261  dwarn:0   dfail:0   fail:0   skip:18  time:477s
fi-kbl-7560u     total:279  pass:269  dwarn:0   dfail:0   fail:0   skip:10  time:597s
fi-kbl-r         total:279  pass:261  dwarn:0   dfail:0   fail:0   skip:18  time:594s
fi-pnv-d510      total:279  pass:223  dwarn:1   dfail:0   fail:0   skip:55  time:533s
fi-skl-6260u     total:279  pass:269  dwarn:0   dfail:0   fail:0   skip:10  time:470s
fi-skl-6700k     total:279  pass:261  dwarn:0   dfail:0   fail:0   skip:18  time:480s
fi-skl-6770hq    total:279  pass:269  dwarn:0   dfail:0   fail:0   skip:10  time:485s
fi-skl-gvtdvm    total:279  pass:266  dwarn:0   dfail:0   fail:0   skip:13  time:435s
fi-skl-x1585l    total:279  pass:269  dwarn:0   dfail:0   fail:0   skip:10  time:500s
fi-snb-2520m     total:279  pass:251  dwarn:0   dfail:0   fail:0   skip:28  time:543s
fi-snb-2600      total:279  pass:250  dwarn:0   dfail:0   fail:0   skip:29  time:409s

dbfb2f62576e1c3550d10398b097589959356db3 drm-tip: 2017y-08m-21d-08h-13m-34s UTC integration manifest
e42487707083 drm/i915: enable platform support for 1G pages
9a16a95f7c54 drm/i915: enable platform support for 2M pages
a436bd563365 drm/i915: enable platform support for 64K pages
9b97db259be0 drm/i915: disable platform support for vGPU huge gtt pages
b9ac999f423a drm/i915/selftests: mix huge pages
66e0f07b65ff drm/i915/selftests: huge page tests
dd58e251fbde drm/i915/debugfs: include some gtt page size metrics
1710b08b8cbc drm/i915: accurate page size tracking for the ppgtt
3a17c296ff20 drm/i915: support 64K pages for the 48b PPGTT
a4856662336e drm/i915: add support for 64K scratch page
89cad69c8be6 drm/i915: support 2M pages for the 48b PPGTT
04fafa0de141 drm/i915: support 1G pages for the 48b PPGTT
4ec4bc844e24 drm/i915: disable GTT cache for 2M/1G pages
e9b745a09c1b drm/i915: enable IPS bit for 64K pages
6a23ff76542d drm/i915: align 64K objects to 2M
311d247b9a75 drm/i915: align the vma start to the largest gtt page size
0b72e347eb95 drm/i915: introduce vm set_pages/clear_pages
cdfe208ba4ee drm/i915: introduce page_size members
e9659e6791ee drm/i915: push set_pages down to the callers
57beca1b09c8 drm/i915: introduce page_size_mask to dev_info
171f291bde14 drm/i915/gemfs: enable THP
889245d5c73c drm/i915: introduce simple gemfs
722294bbe5f0 mm/shmem: introduce shmem_file_setup_with_mnt

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_5452/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 00/23] huge gtt pages
  2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
                   ` (23 preceding siblings ...)
  2017-08-21 18:54 ` ✓ Fi.CI.BAT: success for huge gtt pages (rev7) Patchwork
@ 2017-08-22 14:21 ` Chris Wilson
  2017-08-22 14:23   ` Chris Wilson
  24 siblings, 1 reply; 45+ messages in thread
From: Chris Wilson @ 2017-08-22 14:21 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Matthew Auld (2017-08-21 19:34:40)
> Some more improvements as per Chris' comments.
> 
> Matthew Auld (23):
>   mm/shmem: introduce shmem_file_setup_with_mnt
>   drm/i915: introduce simple gemfs
>   drm/i915/gemfs: enable THP
>   drm/i915: introduce page_size_mask to dev_info
>   drm/i915: push set_pages down to the callers
>   drm/i915: introduce page_size members
>   drm/i915: introduce vm set_pages/clear_pages
>   drm/i915: align the vma start to the largest gtt page size
>   drm/i915: align 64K objects to 2M
>   drm/i915: enable IPS bit for 64K pages
>   drm/i915: disable GTT cache for 2M/1G pages
>   drm/i915: support 1G pages for the 48b PPGTT
>   drm/i915: support 2M pages for the 48b PPGTT
>   drm/i915: add support for 64K scratch page
>   drm/i915: support 64K pages for the 48b PPGTT
>   drm/i915: accurate page size tracking for the ppgtt
>   drm/i915/debugfs: include some gtt page size metrics
>   drm/i915/selftests: huge page tests
>   drm/i915/selftests: mix huge pages
>   drm/i915: disable platform support for vGPU huge gtt pages
>   drm/i915: enable platform support for 64K pages
>   drm/i915: enable platform support for 2M pages
>   drm/i915: enable platform support for 1G pages

Ok, looking good. I keep pushing off the selftest review, sorry. I did
start going through it and felt that it could do with a lot more
permutations of pages sizes within an object to try and exercise the
different boundaries and levels. Everything else looks excellent, I just
haven't yet put together my list of questions for the st...
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 00/23] huge gtt pages
  2017-08-22 14:21 ` [PATCH 00/23] huge gtt pages Chris Wilson
@ 2017-08-22 14:23   ` Chris Wilson
  2017-08-22 15:23     ` Matthew Auld
  0 siblings, 1 reply; 45+ messages in thread
From: Chris Wilson @ 2017-08-22 14:23 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

Quoting Chris Wilson (2017-08-22 15:21:10)
> Quoting Matthew Auld (2017-08-21 19:34:40)
> > Some more improvements as per Chris' comments.
> > 
> > Matthew Auld (23):
> >   mm/shmem: introduce shmem_file_setup_with_mnt
> >   drm/i915: introduce simple gemfs
> >   drm/i915/gemfs: enable THP
> >   drm/i915: introduce page_size_mask to dev_info
> >   drm/i915: push set_pages down to the callers
> >   drm/i915: introduce page_size members
> >   drm/i915: introduce vm set_pages/clear_pages
> >   drm/i915: align the vma start to the largest gtt page size
> >   drm/i915: align 64K objects to 2M
> >   drm/i915: enable IPS bit for 64K pages
> >   drm/i915: disable GTT cache for 2M/1G pages
> >   drm/i915: support 1G pages for the 48b PPGTT
> >   drm/i915: support 2M pages for the 48b PPGTT
> >   drm/i915: add support for 64K scratch page
> >   drm/i915: support 64K pages for the 48b PPGTT
> >   drm/i915: accurate page size tracking for the ppgtt
> >   drm/i915/debugfs: include some gtt page size metrics
> >   drm/i915/selftests: huge page tests
> >   drm/i915/selftests: mix huge pages
> >   drm/i915: disable platform support for vGPU huge gtt pages
> >   drm/i915: enable platform support for 64K pages
> >   drm/i915: enable platform support for 2M pages
> >   drm/i915: enable platform support for 1G pages
> 
> Ok, looking good. I keep pushing off the selftest review, sorry. I did
> start going through it and felt that it could do with a lot more
> permutations of pages sizes within an object to try and exercise the
> different boundaries and levels. Everything else looks excellent, I just
> haven't yet put together my list of questions for the st...

And the other pencilled in suggestion I have is that you grab the
THP/memfd work and put together a userptr igt that can allocate and
utilize huge pages. For that we will need a I915_PARAM to report the
supported pages sizes (and then have to mask that against the THP
supported pages sizes).
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 00/23] huge gtt pages
  2017-08-22 14:23   ` Chris Wilson
@ 2017-08-22 15:23     ` Matthew Auld
  0 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-22 15:23 UTC (permalink / raw)
  To: Chris Wilson; +Cc: Intel Graphics Development, Matthew Auld

On 22 August 2017 at 15:23, Chris Wilson <chris@chris-wilson.co.uk> wrote:
> Quoting Chris Wilson (2017-08-22 15:21:10)
>> Quoting Matthew Auld (2017-08-21 19:34:40)
>> > Some more improvements as per Chris' comments.
>> >
>> > Matthew Auld (23):
>> >   mm/shmem: introduce shmem_file_setup_with_mnt
>> >   drm/i915: introduce simple gemfs
>> >   drm/i915/gemfs: enable THP
>> >   drm/i915: introduce page_size_mask to dev_info
>> >   drm/i915: push set_pages down to the callers
>> >   drm/i915: introduce page_size members
>> >   drm/i915: introduce vm set_pages/clear_pages
>> >   drm/i915: align the vma start to the largest gtt page size
>> >   drm/i915: align 64K objects to 2M
>> >   drm/i915: enable IPS bit for 64K pages
>> >   drm/i915: disable GTT cache for 2M/1G pages
>> >   drm/i915: support 1G pages for the 48b PPGTT
>> >   drm/i915: support 2M pages for the 48b PPGTT
>> >   drm/i915: add support for 64K scratch page
>> >   drm/i915: support 64K pages for the 48b PPGTT
>> >   drm/i915: accurate page size tracking for the ppgtt
>> >   drm/i915/debugfs: include some gtt page size metrics
>> >   drm/i915/selftests: huge page tests
>> >   drm/i915/selftests: mix huge pages
>> >   drm/i915: disable platform support for vGPU huge gtt pages
>> >   drm/i915: enable platform support for 64K pages
>> >   drm/i915: enable platform support for 2M pages
>> >   drm/i915: enable platform support for 1G pages
>>
>> Ok, looking good. I keep pushing off the selftest review, sorry. I did
>> start going through it and felt that it could do with a lot more
>> permutations of pages sizes within an object to try and exercise the
>> different boundaries and levels.

Fair enough, I'll try to come up with something better.

> And the other pencilled in suggestion I have is that you grab the
> THP/memfd work and put together a userptr igt that can allocate and
> utilize huge pages. For that we will need a I915_PARAM to report the
> supported pages sizes (and then have to mask that against the THP
> supported pages sizes).

Yup, on my TODO.

> -Chris
> _______________________________________________
> 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

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

* Re: [PATCH 01/23] mm/shmem: introduce shmem_file_setup_with_mnt
  2017-08-21 18:34 ` [PATCH 01/23] mm/shmem: introduce shmem_file_setup_with_mnt Matthew Auld
@ 2017-08-23  9:31   ` Joonas Lahtinen
  2017-08-23 22:34       ` Andrew Morton
  0 siblings, 1 reply; 45+ messages in thread
From: Joonas Lahtinen @ 2017-08-23  9:31 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Matthew Auld, intel-gfx, Chris Wilson, Dave Hansen,
	Kirill A . Shutemov, Hugh Dickins, linux-mm

Hi Andrew,

This patch has been floating around for a while now Acked and without
further comments. It is blocking us from merging huge page support to
drm/i915.

Would you mind merging it, or prodding the right people to get it in?

Regards, Joonas

On Mon, 2017-08-21 at 19:34 +0100, Matthew Auld wrote:
> We are planning to use our own tmpfs mnt in i915 in place of the
> shm_mnt, such that we can control the mount options, in particular
> huge=, which we require to support huge-gtt-pages. So rather than roll
> our own version of __shmem_file_setup, it would be preferred if we could
> just give shmem our mnt, and let it do the rest.
> 
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Dave Hansen <dave.hansen@intel.com>
> Cc: Kirill A. Shutemov <kirill@shutemov.name>
> Cc: Hugh Dickins <hughd@google.com>
> Cc: linux-mm@kvack.org
> Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> ---
>  include/linux/shmem_fs.h |  2 ++
>  mm/shmem.c               | 30 ++++++++++++++++++++++--------
>  2 files changed, 24 insertions(+), 8 deletions(-)
> 
> diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
> index a7d6bd2a918f..27de676f0b63 100644
> --- a/include/linux/shmem_fs.h
> +++ b/include/linux/shmem_fs.h
> @@ -53,6 +53,8 @@ extern struct file *shmem_file_setup(const char *name,
>  					loff_t size, unsigned long flags);
>  extern struct file *shmem_kernel_file_setup(const char *name, loff_t size,
>  					    unsigned long flags);
> +extern struct file *shmem_file_setup_with_mnt(struct vfsmount *mnt,
> +		const char *name, loff_t size, unsigned long flags);
>  extern int shmem_zero_setup(struct vm_area_struct *);
>  extern unsigned long shmem_get_unmapped_area(struct file *, unsigned long addr,
>  		unsigned long len, unsigned long pgoff, unsigned long flags);
> diff --git a/mm/shmem.c b/mm/shmem.c
> index 6540e5982444..0975e65ea61c 100644
> --- a/mm/shmem.c
> +++ b/mm/shmem.c
> @@ -4141,7 +4141,7 @@ static const struct dentry_operations anon_ops = {
>  	.d_dname = simple_dname
>  };
>  
> -static struct file *__shmem_file_setup(const char *name, loff_t size,
> +static struct file *__shmem_file_setup(struct vfsmount *mnt, const char *name, loff_t size,
>  				       unsigned long flags, unsigned int i_flags)
>  {
>  	struct file *res;
> @@ -4150,8 +4150,8 @@ static struct file *__shmem_file_setup(const char *name, loff_t size,
>  	struct super_block *sb;
>  	struct qstr this;
>  
> -	if (IS_ERR(shm_mnt))
> -		return ERR_CAST(shm_mnt);
> +	if (IS_ERR(mnt))
> +		return ERR_CAST(mnt);
>  
>  	if (size < 0 || size > MAX_LFS_FILESIZE)
>  		return ERR_PTR(-EINVAL);
> @@ -4163,8 +4163,8 @@ static struct file *__shmem_file_setup(const char *name, loff_t size,
>  	this.name = name;
>  	this.len = strlen(name);
>  	this.hash = 0; /* will go */
> -	sb = shm_mnt->mnt_sb;
> -	path.mnt = mntget(shm_mnt);
> +	sb = mnt->mnt_sb;
> +	path.mnt = mntget(mnt);
>  	path.dentry = d_alloc_pseudo(sb, &this);
>  	if (!path.dentry)
>  		goto put_memory;
> @@ -4209,7 +4209,7 @@ static struct file *__shmem_file_setup(const char *name, loff_t size,
>   */
>  struct file *shmem_kernel_file_setup(const char *name, loff_t size, unsigned long flags)
>  {
> -	return __shmem_file_setup(name, size, flags, S_PRIVATE);
> +	return __shmem_file_setup(shm_mnt, name, size, flags, S_PRIVATE);
>  }
>  
>  /**
> @@ -4220,11 +4220,25 @@ struct file *shmem_kernel_file_setup(const char *name, loff_t size, unsigned lon
>   */
>  struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags)
>  {
> -	return __shmem_file_setup(name, size, flags, 0);
> +	return __shmem_file_setup(shm_mnt, name, size, flags, 0);
>  }
>  EXPORT_SYMBOL_GPL(shmem_file_setup);
>  
>  /**
> + * shmem_file_setup_with_mnt - get an unlinked file living in tmpfs
> + * @mnt: the tmpfs mount where the file will be created
> + * @name: name for dentry (to be seen in /proc/<pid>/maps
> + * @size: size to be set for the file
> + * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size
> + */
> +struct file *shmem_file_setup_with_mnt(struct vfsmount *mnt, const char *name,
> +				       loff_t size, unsigned long flags)
> +{
> +	return __shmem_file_setup(mnt, name, size, flags, 0);
> +}
> +EXPORT_SYMBOL_GPL(shmem_file_setup_with_mnt);
> +
> +/**
>   * shmem_zero_setup - setup a shared anonymous mapping
>   * @vma: the vma to be mmapped is prepared by do_mmap_pgoff
>   */
> @@ -4239,7 +4253,7 @@ int shmem_zero_setup(struct vm_area_struct *vma)
>  	 * accessible to the user through its mapping, use S_PRIVATE flag to
>  	 * bypass file security, in the same way as shmem_kernel_file_setup().
>  	 */
> -	file = __shmem_file_setup("dev/zero", size, vma->vm_flags, S_PRIVATE);
> +	file = shmem_kernel_file_setup("dev/zero", size, vma->vm_flags);
>  	if (IS_ERR(file))
>  		return PTR_ERR(file);
>  
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 01/23] mm/shmem: introduce shmem_file_setup_with_mnt
  2017-08-23  9:31   ` Joonas Lahtinen
@ 2017-08-23 22:34       ` Andrew Morton
  0 siblings, 0 replies; 45+ messages in thread
From: Andrew Morton @ 2017-08-23 22:34 UTC (permalink / raw)
  To: Joonas Lahtinen
  Cc: Matthew Auld, intel-gfx, Chris Wilson, Dave Hansen,
	Kirill A . Shutemov, Hugh Dickins, linux-mm

On Wed, 23 Aug 2017 12:31:28 +0300 Joonas Lahtinen <joonas.lahtinen@linux.intel.com> wrote:

> This patch has been floating around for a while now Acked and without
> further comments. It is blocking us from merging huge page support to
> drm/i915.
> 
> Would you mind merging it, or prodding the right people to get it in?
> 
> Regards, Joonas
> 
> On Mon, 2017-08-21 at 19:34 +0100, Matthew Auld wrote:
> > We are planning to use our own tmpfs mnt in i915 in place of the
> > shm_mnt, such that we can control the mount options, in particular
> > huge=, which we require to support huge-gtt-pages. So rather than roll
> > our own version of __shmem_file_setup, it would be preferred if we could
> > just give shmem our mnt, and let it do the rest.

hm, it's a bit odd.  I'm having trouble locating the code which handles
huge=within_size (and any other options?).  What other approaches were
considered?  Was it not feasible to add i915-specific mount options to
mm/shmem.c (for example?).

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 01/23] mm/shmem: introduce shmem_file_setup_with_mnt
@ 2017-08-23 22:34       ` Andrew Morton
  0 siblings, 0 replies; 45+ messages in thread
From: Andrew Morton @ 2017-08-23 22:34 UTC (permalink / raw)
  To: Joonas Lahtinen
  Cc: linux-mm, intel-gfx, Hugh Dickins, Dave Hansen, Matthew Auld,
	Kirill A . Shutemov

On Wed, 23 Aug 2017 12:31:28 +0300 Joonas Lahtinen <joonas.lahtinen@linux.intel.com> wrote:

> This patch has been floating around for a while now Acked and without
> further comments. It is blocking us from merging huge page support to
> drm/i915.
> 
> Would you mind merging it, or prodding the right people to get it in?
> 
> Regards, Joonas
> 
> On Mon, 2017-08-21 at 19:34 +0100, Matthew Auld wrote:
> > We are planning to use our own tmpfs mnt in i915 in place of the
> > shm_mnt, such that we can control the mount options, in particular
> > huge=, which we require to support huge-gtt-pages. So rather than roll
> > our own version of __shmem_file_setup, it would be preferred if we could
> > just give shmem our mnt, and let it do the rest.

hm, it's a bit odd.  I'm having trouble locating the code which handles
huge=within_size (and any other options?).  What other approaches were
considered?  Was it not feasible to add i915-specific mount options to
mm/shmem.c (for example?).

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

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

* Re: [Intel-gfx] [PATCH 01/23] mm/shmem: introduce shmem_file_setup_with_mnt
  2017-08-23 22:34       ` Andrew Morton
@ 2017-08-24 12:04         ` Matthew Auld
  -1 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-24 12:04 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Joonas Lahtinen, linux-mm, Intel Graphics Development,
	Hugh Dickins, Dave Hansen, Matthew Auld, Kirill A . Shutemov

On 23 August 2017 at 23:34, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Wed, 23 Aug 2017 12:31:28 +0300 Joonas Lahtinen <joonas.lahtinen@linux.intel.com> wrote:
>
>> This patch has been floating around for a while now Acked and without
>> further comments. It is blocking us from merging huge page support to
>> drm/i915.
>>
>> Would you mind merging it, or prodding the right people to get it in?
>>
>> Regards, Joonas
>>
>> On Mon, 2017-08-21 at 19:34 +0100, Matthew Auld wrote:
>> > We are planning to use our own tmpfs mnt in i915 in place of the
>> > shm_mnt, such that we can control the mount options, in particular
>> > huge=, which we require to support huge-gtt-pages. So rather than roll
>> > our own version of __shmem_file_setup, it would be preferred if we could
>> > just give shmem our mnt, and let it do the rest.
>
> hm, it's a bit odd.  I'm having trouble locating the code which handles
> huge=within_size (and any other options?).

See here https://patchwork.freedesktop.org/patch/172771/, currently we
only care about huge=within_size.

> What other approaches were considered?

We also tried https://patchwork.freedesktop.org/patch/156528/, where
it was suggested that we mount our own tmpfs instance.

Following from that we now have our own tmps mnt mounted with
huge=within_size. With this patch we avoid having to roll our own
__shmem_file_setup like in
https://patchwork.freedesktop.org/patch/163024/.

> Was it not feasible to add i915-specific mount options to
> mm/shmem.c (for example?).

Hmm, I think within_size should suffice for our needs.

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

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 01/23] mm/shmem: introduce shmem_file_setup_with_mnt
@ 2017-08-24 12:04         ` Matthew Auld
  0 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-08-24 12:04 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Dave Hansen, Intel Graphics Development, Hugh Dickins, linux-mm,
	Matthew Auld, Kirill A . Shutemov

On 23 August 2017 at 23:34, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Wed, 23 Aug 2017 12:31:28 +0300 Joonas Lahtinen <joonas.lahtinen@linux.intel.com> wrote:
>
>> This patch has been floating around for a while now Acked and without
>> further comments. It is blocking us from merging huge page support to
>> drm/i915.
>>
>> Would you mind merging it, or prodding the right people to get it in?
>>
>> Regards, Joonas
>>
>> On Mon, 2017-08-21 at 19:34 +0100, Matthew Auld wrote:
>> > We are planning to use our own tmpfs mnt in i915 in place of the
>> > shm_mnt, such that we can control the mount options, in particular
>> > huge=, which we require to support huge-gtt-pages. So rather than roll
>> > our own version of __shmem_file_setup, it would be preferred if we could
>> > just give shmem our mnt, and let it do the rest.
>
> hm, it's a bit odd.  I'm having trouble locating the code which handles
> huge=within_size (and any other options?).

See here https://patchwork.freedesktop.org/patch/172771/, currently we
only care about huge=within_size.

> What other approaches were considered?

We also tried https://patchwork.freedesktop.org/patch/156528/, where
it was suggested that we mount our own tmpfs instance.

Following from that we now have our own tmps mnt mounted with
huge=within_size. With this patch we avoid having to roll our own
__shmem_file_setup like in
https://patchwork.freedesktop.org/patch/163024/.

> Was it not feasible to add i915-specific mount options to
> mm/shmem.c (for example?).

Hmm, I think within_size should suffice for our needs.

>
> _______________________________________________
> 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

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

* Re: [PATCH 18/23] drm/i915/selftests: huge page tests
  2017-08-21 18:34 ` [PATCH 18/23] drm/i915/selftests: huge page tests Matthew Auld
@ 2017-08-24 17:56   ` kbuild test robot
  2017-08-28 14:36     ` Chris Wilson
  0 siblings, 1 reply; 45+ messages in thread
From: kbuild test robot @ 2017-08-24 17:56 UTC (permalink / raw)
  To: Matthew Auld; +Cc: intel-gfx, kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3938 bytes --]

Hi Matthew,

[auto build test ERROR on mmotm/master]
[cannot apply to drm-intel/for-linux-next linus/master v4.13-rc6 next-20170824]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Matthew-Auld/huge-gtt-pages/20170825-005243
base:   git://git.cmpxchg.org/linux-mmotm.git master
config: i386-randconfig-x075-201734 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   In file included from include/uapi/linux/stddef.h:1:0,
                    from include/linux/stddef.h:4,
                    from include/uapi/linux/posix_types.h:4,
                    from include/uapi/linux/types.h:13,
                    from include/linux/types.h:5,
                    from include/linux/list.h:4,
                    from include/linux/agp_backend.h:33,
                    from include/drm/drmP.h:35,
                    from drivers/gpu//drm/i915/i915_gem.c:28:
   drivers/gpu//drm/i915/selftests/huge_pages.c: In function 'gpu_write':
>> drivers/gpu//drm/i915/selftests/huge_pages.c:741:14: error: implicit declaration of function 'intel_engine_can_store_dword' [-Werror=implicit-function-declaration]
     GEM_BUG_ON(!intel_engine_can_store_dword(i915->engine[RCS]));
                 ^
   include/linux/compiler.h:175:42: note: in definition of macro 'unlikely'
    # define unlikely(x) __builtin_expect(!!(x), 0)
                                             ^
   drivers/gpu//drm/i915/i915_gem.h:31:26: note: in expansion of macro 'BUG_ON'
    #define GEM_BUG_ON(expr) BUG_ON(expr)
                             ^~~~~~
   drivers/gpu//drm/i915/selftests/huge_pages.c:741:2: note: in expansion of macro 'GEM_BUG_ON'
     GEM_BUG_ON(!intel_engine_can_store_dword(i915->engine[RCS]));
     ^~~~~~~~~~
   cc1: all warnings being treated as errors

vim +/intel_engine_can_store_dword +741 drivers/gpu//drm/i915/selftests/huge_pages.c

   729	
   730	static int gpu_write(struct i915_vma *vma,
   731			     struct i915_gem_context *ctx,
   732			     u32 dword,
   733			     u32 value)
   734	{
   735		struct drm_i915_private *i915 = to_i915(vma->obj->base.dev);
   736		struct drm_i915_gem_request *rq;
   737		struct i915_vma *batch;
   738		int flags = 0;
   739		int err;
   740	
 > 741		GEM_BUG_ON(!intel_engine_can_store_dword(i915->engine[RCS]));
   742	
   743		err = i915_gem_object_set_to_gtt_domain(vma->obj, true);
   744		if (err)
   745			return err;
   746	
   747		rq = i915_gem_request_alloc(i915->engine[RCS], ctx);
   748		if (IS_ERR(rq))
   749			return PTR_ERR(rq);
   750	
   751		batch = gpu_write_dw(vma, dword * sizeof(u32), value);
   752		if (IS_ERR(batch)) {
   753			err = PTR_ERR(batch);
   754			goto err_request;
   755		}
   756	
   757		i915_vma_move_to_active(batch, rq, 0);
   758		i915_gem_object_set_active_reference(batch->obj);
   759		i915_vma_unpin(batch);
   760		i915_vma_close(batch);
   761	
   762		err = rq->engine->emit_flush(rq, EMIT_INVALIDATE);
   763		if (err)
   764			goto err_request;
   765	
   766		err = i915_switch_context(rq);
   767		if (err)
   768			goto err_request;
   769	
   770		err = rq->engine->emit_bb_start(rq,
   771				batch->node.start, batch->node.size,
   772				flags);
   773		if (err)
   774			goto err_request;
   775	
   776		i915_vma_move_to_active(vma, rq, 0);
   777	
   778		reservation_object_lock(vma->resv, NULL);
   779		reservation_object_add_excl_fence(vma->resv, &rq->fence);
   780		reservation_object_unlock(vma->resv);
   781	
   782	err_request:
   783		__i915_add_request(rq, err == 0);
   784	
   785		return err;
   786	}
   787	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 31223 bytes --]

[-- Attachment #3: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [Intel-gfx] [PATCH 01/23] mm/shmem: introduce shmem_file_setup_with_mnt
  2017-08-24 12:04         ` Matthew Auld
@ 2017-08-25 20:49           ` Andrew Morton
  -1 siblings, 0 replies; 45+ messages in thread
From: Andrew Morton @ 2017-08-25 20:49 UTC (permalink / raw)
  To: Matthew Auld
  Cc: Joonas Lahtinen, linux-mm, Intel Graphics Development,
	Hugh Dickins, Dave Hansen, Matthew Auld, Kirill A . Shutemov

On Thu, 24 Aug 2017 13:04:09 +0100 Matthew Auld <matthew.william.auld@gmail.com> wrote:

> On 23 August 2017 at 23:34, Andrew Morton <akpm@linux-foundation.org> wrote:
> > On Wed, 23 Aug 2017 12:31:28 +0300 Joonas Lahtinen <joonas.lahtinen@linux.intel.com> wrote:
> >
> >> This patch has been floating around for a while now Acked and without
> >> further comments. It is blocking us from merging huge page support to
> >> drm/i915.
> >>
> >> Would you mind merging it, or prodding the right people to get it in?
> >>
> >> Regards, Joonas
> >>
> >> On Mon, 2017-08-21 at 19:34 +0100, Matthew Auld wrote:
> >> > We are planning to use our own tmpfs mnt in i915 in place of the
> >> > shm_mnt, such that we can control the mount options, in particular
> >> > huge=, which we require to support huge-gtt-pages. So rather than roll
> >> > our own version of __shmem_file_setup, it would be preferred if we could
> >> > just give shmem our mnt, and let it do the rest.
> >
> > hm, it's a bit odd.  I'm having trouble locating the code which handles
> > huge=within_size (and any other options?).
> 
> See here https://patchwork.freedesktop.org/patch/172771/, currently we
> only care about huge=within_size.
> 
> > What other approaches were considered?
> 
> We also tried https://patchwork.freedesktop.org/patch/156528/, where
> it was suggested that we mount our own tmpfs instance.
> 
> Following from that we now have our own tmps mnt mounted with
> huge=within_size. With this patch we avoid having to roll our own
> __shmem_file_setup like in
> https://patchwork.freedesktop.org/patch/163024/.
> 
> > Was it not feasible to add i915-specific mount options to
> > mm/shmem.c (for example?).
> 
> Hmm, I think within_size should suffice for our needs.

hm, ok, well, unless someone can think of something cleaner, please add
my ack and include it in the appropriate drm tree.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 01/23] mm/shmem: introduce shmem_file_setup_with_mnt
@ 2017-08-25 20:49           ` Andrew Morton
  0 siblings, 0 replies; 45+ messages in thread
From: Andrew Morton @ 2017-08-25 20:49 UTC (permalink / raw)
  To: Matthew Auld
  Cc: Dave Hansen, Intel Graphics Development, Hugh Dickins, linux-mm,
	Matthew Auld, Kirill A . Shutemov

On Thu, 24 Aug 2017 13:04:09 +0100 Matthew Auld <matthew.william.auld@gmail.com> wrote:

> On 23 August 2017 at 23:34, Andrew Morton <akpm@linux-foundation.org> wrote:
> > On Wed, 23 Aug 2017 12:31:28 +0300 Joonas Lahtinen <joonas.lahtinen@linux.intel.com> wrote:
> >
> >> This patch has been floating around for a while now Acked and without
> >> further comments. It is blocking us from merging huge page support to
> >> drm/i915.
> >>
> >> Would you mind merging it, or prodding the right people to get it in?
> >>
> >> Regards, Joonas
> >>
> >> On Mon, 2017-08-21 at 19:34 +0100, Matthew Auld wrote:
> >> > We are planning to use our own tmpfs mnt in i915 in place of the
> >> > shm_mnt, such that we can control the mount options, in particular
> >> > huge=, which we require to support huge-gtt-pages. So rather than roll
> >> > our own version of __shmem_file_setup, it would be preferred if we could
> >> > just give shmem our mnt, and let it do the rest.
> >
> > hm, it's a bit odd.  I'm having trouble locating the code which handles
> > huge=within_size (and any other options?).
> 
> See here https://patchwork.freedesktop.org/patch/172771/, currently we
> only care about huge=within_size.
> 
> > What other approaches were considered?
> 
> We also tried https://patchwork.freedesktop.org/patch/156528/, where
> it was suggested that we mount our own tmpfs instance.
> 
> Following from that we now have our own tmps mnt mounted with
> huge=within_size. With this patch we avoid having to roll our own
> __shmem_file_setup like in
> https://patchwork.freedesktop.org/patch/163024/.
> 
> > Was it not feasible to add i915-specific mount options to
> > mm/shmem.c (for example?).
> 
> Hmm, I think within_size should suffice for our needs.

hm, ok, well, unless someone can think of something cleaner, please add
my ack and include it in the appropriate drm tree.

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

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

* Re: [PATCH 18/23] drm/i915/selftests: huge page tests
  2017-08-24 17:56   ` kbuild test robot
@ 2017-08-28 14:36     ` Chris Wilson
  0 siblings, 0 replies; 45+ messages in thread
From: Chris Wilson @ 2017-08-28 14:36 UTC (permalink / raw)
  To: Matthew Auld; +Cc: intel-gfx, kbuild-all

Excuse the piggy-backing, the original never arrived!

+static int cpu_check(struct drm_i915_gem_object *obj, u32 dword, u32 val)
+{
+	enum i915_map_type level;
+	int err;
+
+	for (level = I915_MAP_WB; level <= I915_MAP_WC; level++) {
+		u32 *map, offset;
+
+		if (level == I915_MAP_WB)
+			err = i915_gem_object_set_to_cpu_domain(obj, false);
+		else
+			err = i915_gem_object_set_to_wc_domain(obj, false);
+		if (err)
+			return err;
+
+		unmap_mapping(obj);
+		map = i915_gem_object_pin_map(obj, level);
+		if (IS_ERR(map))
+			return PTR_ERR(map);
+
+		for (offset = dword; offset < obj->base.size/sizeof(u32);
+		     offset += DWORDS_PER_PAGE) {
+			if (map[offset] != val) {
+				pr_err("map[%u] = %u, expected %u\n",
+				       offset, map[offset], val);
+				err = -EINVAL;
+				goto out_close;
+			}
+		}
+
+		i915_gem_object_unpin_map(obj);
+	}
+
+	return 0;
+
+out_close:
+	i915_gem_object_unpin_map(obj);
+
+	return err;
+}

We are testing the GTT layout, so we only need a single CPU check. Using
WC is going to be terrible in performance, and we really don't need to
vmap the whole thing either as we are just reading one dword per page.
Just a kmap and clflush (with a wait_for_rendering) is going to be a lot
quicker.

+static struct i915_vma *
+gpu_write_dw(struct i915_vma *vma, u64 offset, u32 val)
+{
+	struct drm_i915_private *i915 = to_i915(vma->obj->base.dev);
+	const int gen = INTEL_GEN(vma->vm->i915);
+	unsigned int count = vma->size >> PAGE_SHIFT;
+	struct drm_i915_gem_object *obj;
+	struct i915_vma *batch;
+	unsigned int size;
+	u32 *cmd;
+	int n;
+	int err;
+
+	size = 1 + 4 * count * sizeof(u32);

Should be (1 + 4 * count) * sizeof(u32); Likelihood of it mattering, 0.

+static int gpu_write(struct i915_vma *vma,
+		     struct i915_gem_context *ctx,
+		     u32 dword,
+		     u32 value)
+{
...
+	err = rq->engine->emit_bb_start(rq,
+			batch->node.start, batch->node.size,
+			flags);
+	if (err)
+		goto err_request;
+
+	i915_vma_move_to_active(vma, rq, 0);

Should pass EXEC_OBJECT_WRITE. 

+	reservation_object_lock(vma->resv, NULL);
+	reservation_object_add_excl_fence(vma->resv, &rq->fence);
+	reservation_object_unlock(vma->resv);

And remind me to finish moving this export to i915_vma_move_to_active(),
just need to be sure that we can't create any dependency loops.

+
+err_request:
+	__i915_add_request(rq, err == 0);
+
+	return err;
+}

+static int igt_write_huge(struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+	unsigned long supported = INTEL_INFO(i915)->page_size_mask;
+	struct i915_gem_context *ctx = i915->kernel_context;
+	struct i915_address_space *vm = ctx->ppgtt ? &ctx->ppgtt->base : &i915->ggtt.base;
+	unsigned int flags = PIN_USER | PIN_OFFSET_FIXED;
+	struct i915_vma *vma;
+	int bit, last;
+	int err;
+
+	GEM_BUG_ON(obj->base.size != SZ_2M);
+
+	err = i915_gem_object_pin_pages(obj);
+	if (err)
+		return err;
+
+	/* We want to run the test even if the platform doesn't support huge gtt
+	 * pages -- our only requirement is that we were able to allocate a
+	 * "huge-page".
+	 */
+	if (obj->mm.page_sizes.phys < I915_GTT_PAGE_SIZE_2M) {
+		pr_info("Unable to allocate huge-page, finishing test early\n");
+		goto out_unpin;
+	}
+
+	vma = i915_vma_instance(obj, vm, NULL);
+	if (IS_ERR(vma)) {
+		err = PTR_ERR(vma);
+		goto out_unpin;
+	}
+
+	last = ilog2(I915_GTT_PAGE_SIZE_2M);
+
+	for_each_set_bit(bit, &supported, last + 1) {
+		IGT_TIMEOUT(end_time);
+		unsigned int page_size = BIT(bit);
+		u32 max = vm->total / I915_GTT_PAGE_SIZE_2M - 1;
+		u32 num;
+
+		/* Force the page size */
+		vma->page_sizes.sg = obj->mm.page_sizes.sg = page_size;
+
+		/* Try various offsets until we timeout -- we want to avoid
+		 * issues hidden by effectively always using offset = 0.
+		 */
+		for_each_prime_number_from(num, 0, max) {
...
+
+			for (dword = 0; dword < DWORDS_PER_PAGE; ++dword) {

We want to focus on the GTT testing, so checking every offset in the page
is less important than checking the various GTT offsets.

If you use dword = offset_in_page(num) / 4 (rather than the loop), we will
maintain the good checking that a write into a different page through the
GTT ends up where we expect, whilst exercising different cachelines on each
pass (and so be able to check 1024 times more GTT offsets).

+				err = gpu_write(vma, ctx, dword, num + 1);
+				if (err) {
+					pr_err("gpu_write failed with page-size %x\n",
+					       page_size);
+					i915_vma_unpin(vma);
+					goto out_close;
+				}


It looks like there is still a preponderance of GEM_BUG_ON -- these
should only be used for test bugs, we do want to clearly report errors
in the driver without oopsing. That also means we need a lot of pr_*()
giving all the vital information we need.

I'm still missing live testing that mixes page sizes within an object,
or at least I couldn't see ones that quell my qualms over how we
populate the GTT (with the goal of late optimisations). A sketch I have
in my head is that we stitch together our objects using alloc_huge_page
given a permutation mask. Basically, I want to know that 1G, 1G + 4K,
4K + 1G, 1G, 64K*32, 64K*31+16*4K etc all work.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 01/23] mm/shmem: introduce shmem_file_setup_with_mnt
  2017-08-25 20:49           ` Andrew Morton
@ 2017-08-29 14:09             ` Joonas Lahtinen
  -1 siblings, 0 replies; 45+ messages in thread
From: Joonas Lahtinen @ 2017-08-29 14:09 UTC (permalink / raw)
  To: Andrew Morton, Matthew Auld, Chris Wilson
  Cc: linux-mm, Intel Graphics Development, Hugh Dickins, Dave Hansen,
	Matthew Auld, Kirill A . Shutemov

On Fri, 2017-08-25 at 13:49 -0700, Andrew Morton wrote:
> On Thu, 24 Aug 2017 13:04:09 +0100 Matthew Auld <matthew.william.auld@gmail.com> wrote:
> 
> > On 23 August 2017 at 23:34, Andrew Morton <akpm@linux-foundation.org> wrote:
> > > On Wed, 23 Aug 2017 12:31:28 +0300 Joonas Lahtinen <joonas.lahtinen@linux.intel.com> wrote:
> > > 
> > > > This patch has been floating around for a while now Acked and without
> > > > further comments. It is blocking us from merging huge page support to
> > > > drm/i915.
> > > > 
> > > > Would you mind merging it, or prodding the right people to get it in?
> > > > 
> > > > Regards, Joonas
> > > > 
> > > > On Mon, 2017-08-21 at 19:34 +0100, Matthew Auld wrote:
> > > > > We are planning to use our own tmpfs mnt in i915 in place of the
> > > > > shm_mnt, such that we can control the mount options, in particular
> > > > > huge=, which we require to support huge-gtt-pages. So rather than roll
> > > > > our own version of __shmem_file_setup, it would be preferred if we could
> > > > > just give shmem our mnt, and let it do the rest.
> > > 
> > > hm, it's a bit odd.  I'm having trouble locating the code which handles
> > > huge=within_size (and any other options?).
> > 
> > See here https://patchwork.freedesktop.org/patch/172771/, currently we
> > only care about huge=within_size.
> > 
> > > What other approaches were considered?
> > 
> > We also tried https://patchwork.freedesktop.org/patch/156528/, where
> > it was suggested that we mount our own tmpfs instance.
> > 
> > Following from that we now have our own tmps mnt mounted with
> > huge=within_size. With this patch we avoid having to roll our own
> > __shmem_file_setup like in
> > https://patchwork.freedesktop.org/patch/163024/.
> > 
> > > Was it not feasible to add i915-specific mount options to
> > > mm/shmem.c (for example?).
> > 
> > Hmm, I think within_size should suffice for our needs.
> 
> hm, ok, well, unless someone can think of something cleaner, please add
> my ack and include it in the appropriate drm tree.

Thanks, I will do that. It'll first get incorporated into drm-tip (
https://cgit.freedesktop.org/drm-tip) once the kselftests are finalized
(now that we know we're not facing third rewrite for core MM
dependency). And eventually into drm-next through a pull request to
Dave Airlie.

Regards, Joonas
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 01/23] mm/shmem: introduce shmem_file_setup_with_mnt
@ 2017-08-29 14:09             ` Joonas Lahtinen
  0 siblings, 0 replies; 45+ messages in thread
From: Joonas Lahtinen @ 2017-08-29 14:09 UTC (permalink / raw)
  To: Andrew Morton, Matthew Auld, Chris Wilson
  Cc: Dave Hansen, Intel Graphics Development, Hugh Dickins, linux-mm,
	Matthew Auld, Kirill A . Shutemov

On Fri, 2017-08-25 at 13:49 -0700, Andrew Morton wrote:
> On Thu, 24 Aug 2017 13:04:09 +0100 Matthew Auld <matthew.william.auld@gmail.com> wrote:
> 
> > On 23 August 2017 at 23:34, Andrew Morton <akpm@linux-foundation.org> wrote:
> > > On Wed, 23 Aug 2017 12:31:28 +0300 Joonas Lahtinen <joonas.lahtinen@linux.intel.com> wrote:
> > > 
> > > > This patch has been floating around for a while now Acked and without
> > > > further comments. It is blocking us from merging huge page support to
> > > > drm/i915.
> > > > 
> > > > Would you mind merging it, or prodding the right people to get it in?
> > > > 
> > > > Regards, Joonas
> > > > 
> > > > On Mon, 2017-08-21 at 19:34 +0100, Matthew Auld wrote:
> > > > > We are planning to use our own tmpfs mnt in i915 in place of the
> > > > > shm_mnt, such that we can control the mount options, in particular
> > > > > huge=, which we require to support huge-gtt-pages. So rather than roll
> > > > > our own version of __shmem_file_setup, it would be preferred if we could
> > > > > just give shmem our mnt, and let it do the rest.
> > > 
> > > hm, it's a bit odd.  I'm having trouble locating the code which handles
> > > huge=within_size (and any other options?).
> > 
> > See here https://patchwork.freedesktop.org/patch/172771/, currently we
> > only care about huge=within_size.
> > 
> > > What other approaches were considered?
> > 
> > We also tried https://patchwork.freedesktop.org/patch/156528/, where
> > it was suggested that we mount our own tmpfs instance.
> > 
> > Following from that we now have our own tmps mnt mounted with
> > huge=within_size. With this patch we avoid having to roll our own
> > __shmem_file_setup like in
> > https://patchwork.freedesktop.org/patch/163024/.
> > 
> > > Was it not feasible to add i915-specific mount options to
> > > mm/shmem.c (for example?).
> > 
> > Hmm, I think within_size should suffice for our needs.
> 
> hm, ok, well, unless someone can think of something cleaner, please add
> my ack and include it in the appropriate drm tree.

Thanks, I will do that. It'll first get incorporated into drm-tip (
https://cgit.freedesktop.org/drm-tip) once the kselftests are finalized
(now that we know we're not facing third rewrite for core MM
dependency). And eventually into drm-next through a pull request to
Dave Airlie.

Regards, Joonas
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 02/23] drm/i915: introduce simple gemfs
  2017-08-21 18:34   ` Matthew Auld
  (?)
@ 2017-08-29 14:33   ` Joonas Lahtinen
  -1 siblings, 0 replies; 45+ messages in thread
From: Joonas Lahtinen @ 2017-08-29 14:33 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx
  Cc: Chris Wilson, Dave Hansen, Kirill A . Shutemov, Hugh Dickins, linux-mm

On Mon, 2017-08-21 at 19:34 +0100, Matthew Auld wrote:
> Not a fully blown gemfs, just our very own tmpfs kernel mount. Doing so
> moves us away from the shmemfs shm_mnt, and gives us the much needed
> flexibility to do things like set our own mount options, namely huge=
> which should allow us to enable the use of transparent-huge-pages for
> our shmem backed objects.
> 
> v2: various improvements suggested by Joonas
> 
> v3: move gemfs instance to i915.mm and simplify now that we have
> file_setup_with_mnt
> 
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Dave Hansen <dave.hansen@intel.com>
> Cc: Kirill A. Shutemov <kirill@shutemov.name>
> Cc: Hugh Dickins <hughd@google.com>
> Cc: linux-mm@kvack.org

<SNIP>

> @@ -4288,6 +4289,25 @@ static const struct drm_i915_gem_object_ops i915_gem_object_ops = {
>  	.pwrite = i915_gem_object_pwrite_gtt,
>  };
>  
> +static int i915_gem_object_create_shmem(struct drm_device *dev,
> +					struct drm_gem_object *obj,
> +					size_t size)
> +{
> +	struct drm_i915_private *i915 = to_i915(dev);
> +	struct file *filp;
> +
> +	drm_gem_private_object_init(dev, obj, size);
> +
> +	filp = shmem_file_setup_with_mnt(i915->mm.gemfs, "i915", size,
> +					 VM_NORESERVE);

Can you double-check that /proc/meminfo is unaffected by this change?
If we stop appearing under "Shemem:" we maybe need to maybe highlight
this somewhere (at least in commit message).

<SNIP>

> +int i915_gemfs_init(struct drm_i915_private *i915)
> +{
> +	struct file_system_type *type;
> +	struct vfsmount *gemfs;
> +
> +	type = get_fs_type("tmpfs");
> +	if (!type)
> +		return -ENODEV;
> +
> +	gemfs = kern_mount(type);
> +	if (IS_ERR(gemfs))
> +		return PTR_ERR(gemfs);

By occasionally checking that "i915->mm.gemfs" might be NULL, could we
continue without our own gemfs mount and just lose the additional
features? Or is it not worth the hassle?

Anyway, this is:

Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>

Regards, Joonas
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

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

* Re: [PATCH 05/23] drm/i915: push set_pages down to the callers
  2017-08-21 18:34 ` [PATCH 05/23] drm/i915: push set_pages down to the callers Matthew Auld
@ 2017-08-29 14:44   ` Joonas Lahtinen
  0 siblings, 0 replies; 45+ messages in thread
From: Joonas Lahtinen @ 2017-08-29 14:44 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

On Mon, 2017-08-21 at 19:34 +0100, Matthew Auld wrote:
> Each backend is now responsible for calling __i915_gem_object_set_pages
> upon successfully gathering its backing storage. This eliminates the
> inconsistency between the async and sync paths, which stands out even
> more when we start throwing around an sg_mask in a later patch.
> 
> Suggested-by: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>

<SNIP>

> @@ -2485,12 +2490,10 @@ static int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
>  		return -EFAULT;
>  	}
>  
> -	pages = obj->ops->get_pages(obj);
> -	if (unlikely(IS_ERR(pages)))
> -		return PTR_ERR(pages);
> +	ret = obj->ops->get_pages(obj);
> +	GEM_BUG_ON(ret == 0 && IS_ERR_OR_NULL(obj->mm.pages));

!ret should be equally readable. Especially if you call the variable
"err".

Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>

Regards, Joonas
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/23] drm/i915/gemfs: enable THP
  2017-08-21 18:34 ` [PATCH 03/23] drm/i915/gemfs: enable THP Matthew Auld
@ 2017-08-29 14:49   ` Joonas Lahtinen
  2017-09-04 12:09     ` Matthew Auld
  0 siblings, 1 reply; 45+ messages in thread
From: Joonas Lahtinen @ 2017-08-29 14:49 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

On Mon, 2017-08-21 at 19:34 +0100, Matthew Auld wrote:
> Enable transparent-huge-pages through gemfs by mounting with
> huge=within_size.
> 
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>

<SNIP>

> +++ b/drivers/gpu/drm/i915/i915_gemfs.c
> @@ -24,6 +24,7 @@
>  
>  #include <linux/fs.h>
>  #include <linux/mount.h>
> +#include <linux/pagemap.h>
>  
>  #include "i915_drv.h"
>  #include "i915_gemfs.h"
> @@ -41,6 +42,20 @@ int i915_gemfs_init(struct drm_i915_private *i915)
>  	if (IS_ERR(gemfs))
>  		return PTR_ERR(gemfs);
>  
> +	if (has_transparent_hugepage()) {
> +		struct super_block *sb = gemfs->mnt_sb;
> +		char options[] = "huge=within_size";

char const options[] ?

> +		int flags = 0;
> +
> +		/* We don't consider failure to remount fatal, since this should
> +		 * only ever attempt to modify the mount options of the sb, and
> +		 * so should always leave us with a working mount upon failure.
> +		 * Hence decoupling this from the actual kern_mount is probably
> +		 * advisable.
> +		 */
> +		WARN_ON(sb->s_op->remount_fs(sb, &flags, options));

Not to have too many fallback paths, would it make sense for any error
in setting up gemfs to result in NULL gemfs and fallback to tmpfs?

With the string constified, this is:

Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>

Regards, Joonas
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/23] drm/i915/gemfs: enable THP
  2017-08-29 14:49   ` Joonas Lahtinen
@ 2017-09-04 12:09     ` Matthew Auld
  0 siblings, 0 replies; 45+ messages in thread
From: Matthew Auld @ 2017-09-04 12:09 UTC (permalink / raw)
  To: Joonas Lahtinen; +Cc: Intel Graphics Development, Matthew Auld

On 29 August 2017 at 15:49, Joonas Lahtinen
<joonas.lahtinen@linux.intel.com> wrote:
> On Mon, 2017-08-21 at 19:34 +0100, Matthew Auld wrote:
>> Enable transparent-huge-pages through gemfs by mounting with
>> huge=within_size.
>>
>> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
>> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>
> <SNIP>
>
>> +++ b/drivers/gpu/drm/i915/i915_gemfs.c
>> @@ -24,6 +24,7 @@
>>
>>  #include <linux/fs.h>
>>  #include <linux/mount.h>
>> +#include <linux/pagemap.h>
>>
>>  #include "i915_drv.h"
>>  #include "i915_gemfs.h"
>> @@ -41,6 +42,20 @@ int i915_gemfs_init(struct drm_i915_private *i915)
>>       if (IS_ERR(gemfs))
>>               return PTR_ERR(gemfs);
>>
>> +     if (has_transparent_hugepage()) {
>> +             struct super_block *sb = gemfs->mnt_sb;
>> +             char options[] = "huge=within_size";
>
> char const options[] ?

remount_fs expects char *data, and shmem_parse_options() may try to modify data.

>
>> +             int flags = 0;
>> +
>> +             /* We don't consider failure to remount fatal, since this should
>> +              * only ever attempt to modify the mount options of the sb, and
>> +              * so should always leave us with a working mount upon failure.
>> +              * Hence decoupling this from the actual kern_mount is probably
>> +              * advisable.
>> +              */
>> +             WARN_ON(sb->s_op->remount_fs(sb, &flags, options));
>
> Not to have too many fallback paths, would it make sense for any error
> in setting up gemfs to result in NULL gemfs and fallback to tmpfs?

Okay, will do.

>
> With the string constified, this is:
>
> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
>
> Regards, Joonas
> --
> Joonas Lahtinen
> Open Source Technology Center
> Intel Corporation
> _______________________________________________
> 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

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

* Re: [PATCH 06/23] drm/i915: introduce page_size members
  2017-08-21 18:34 ` [PATCH 06/23] drm/i915: introduce page_size members Matthew Auld
@ 2017-09-05  9:25   ` Joonas Lahtinen
  0 siblings, 0 replies; 45+ messages in thread
From: Joonas Lahtinen @ 2017-09-05  9:25 UTC (permalink / raw)
  To: Matthew Auld, intel-gfx

On Mon, 2017-08-21 at 19:34 +0100, Matthew Auld wrote:
> In preparation for supporting huge gtt pages for the ppgtt, we introduce
> page size members for gem objects.  We fill in the page sizes by
> scanning the sg table.
> 
> v2: pass the sg_mask to set_pages
> 
> v3: calculate the sg_mask inline with populating the sg_table where
> possible, and pass to set_pages along with the pages.
> 
> Signed-off-by: Matthew Auld <matthew.auld@intel.com>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Daniel Vetter <daniel@ffwll.ch>

<SNIP>

> @@ -2477,6 +2490,18 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
>  		__i915_gem_object_pin_pages(obj);
>  		obj->mm.quirked = true;
>  	}
> +
> +	GEM_BUG_ON(!sg_mask);

You can drop this extra newline.

> +
> +	obj->mm.page_sizes.phys = sg_mask;
> +
> +	obj->mm.page_sizes.sg = 0;

Maybe worthy a comment here that any higher multiple of supported page
sizes can be filled with current page size.

> +	for_each_set_bit(bit, &supported_page_sizes, BITS_PER_LONG) {
> +		if (obj->mm.page_sizes.phys & ~0u << bit)
> +			obj->mm.page_sizes.sg |= BIT(bit);

'i' might make this less confusing to read as BIT(i).

> +	}
> +
> +	GEM_BUG_ON(!HAS_PAGE_SIZE(i915, obj->mm.page_sizes.sg));

This usage makes me think we should call the macro HAS_PAGE_SIZES()?

> @@ -259,13 +259,19 @@ struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
>  static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
>  {
>  	struct sg_table *pages;
> +	struct scatterlist *sg;
> +	unsigned int sg_mask = 0;

As we are alternating between "unsigned long" and "unsigned int" for
the page size masks, make sure sparse is not complaining.

> +	int n;
>  
>  	pages = dma_buf_map_attachment(obj->base.import_attach,
>  				       DMA_BIDIRECTIONAL);
>  	if (IS_ERR(pages))
>  		return PTR_ERR(pages);
>  
> -	__i915_gem_object_set_pages(obj, pages);

Chris will like you if you do it here;

	sg_mask = 0;
> +	for_each_sg(pages->sgl, sg, pages->nents, n)
> +		sg_mask |= sg->length;
> +
> +	__i915_gem_object_set_pages(obj, pages, sg_mask);
>  
>  	return 0;
>  }

<SNIP>

> @@ -75,6 +76,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
>  	}
>  
>  create_st:
> +	sg_mask = 0;

Maybe move this just before the loop, too.

>  	st = kmalloc(sizeof(*st), GFP_KERNEL);
>  	if (!st)
>  		return -ENOMEM;
> @@ -104,6 +106,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
>  		} while (1);
>  
>  		sg_set_page(sg, page, PAGE_SIZE << order, 0);
> +		sg_mask |= PAGE_SIZE << order;
>  		st->nents++;
>  
>  		npages -= 1 << order;

<SNIP>

> +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
> @@ -422,12 +423,17 @@ st_set_pages(struct sg_table **st, struct page **pvec, int num_pages)
>  
>  		for_each_sg((*st)->sgl, sg, num_pages, n)
>  			sg_set_page(sg, pvec[n], PAGE_SIZE, 0);
> +
> +		*sg_mask = PAGE_SIZE;

This strictly assigns.

>  	} else {
>  		ret = sg_alloc_table_from_pages(*st, pvec, num_pages,
>  						0, num_pages << PAGE_SHIFT,
>  						GFP_KERNEL);
>  		if (ret)
>  			goto err;
> +
> +		for_each_sg((*st)->sgl, sg, num_pages, n)
> +			*sg_mask |= sg->length;

This appends and assumes input is zero. Maybe zero before the loop?

With above fixed, this is:

Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>

Regards, Joonas
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2017-09-05  9:25 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-21 18:34 [PATCH 00/23] huge gtt pages Matthew Auld
2017-08-21 18:34 ` [PATCH 01/23] mm/shmem: introduce shmem_file_setup_with_mnt Matthew Auld
2017-08-23  9:31   ` Joonas Lahtinen
2017-08-23 22:34     ` Andrew Morton
2017-08-23 22:34       ` Andrew Morton
2017-08-24 12:04       ` [Intel-gfx] " Matthew Auld
2017-08-24 12:04         ` Matthew Auld
2017-08-25 20:49         ` [Intel-gfx] " Andrew Morton
2017-08-25 20:49           ` Andrew Morton
2017-08-29 14:09           ` [Intel-gfx] " Joonas Lahtinen
2017-08-29 14:09             ` Joonas Lahtinen
2017-08-21 18:34 ` [PATCH 02/23] drm/i915: introduce simple gemfs Matthew Auld
2017-08-21 18:34   ` Matthew Auld
2017-08-29 14:33   ` Joonas Lahtinen
2017-08-21 18:34 ` [PATCH 03/23] drm/i915/gemfs: enable THP Matthew Auld
2017-08-29 14:49   ` Joonas Lahtinen
2017-09-04 12:09     ` Matthew Auld
2017-08-21 18:34 ` [PATCH 04/23] drm/i915: introduce page_size_mask to dev_info Matthew Auld
2017-08-21 18:34 ` [PATCH 05/23] drm/i915: push set_pages down to the callers Matthew Auld
2017-08-29 14:44   ` Joonas Lahtinen
2017-08-21 18:34 ` [PATCH 06/23] drm/i915: introduce page_size members Matthew Auld
2017-09-05  9:25   ` Joonas Lahtinen
2017-08-21 18:34 ` [PATCH 07/23] drm/i915: introduce vm set_pages/clear_pages Matthew Auld
2017-08-21 18:34 ` [PATCH 08/23] drm/i915: align the vma start to the largest gtt page size Matthew Auld
2017-08-21 18:34 ` [PATCH 09/23] drm/i915: align 64K objects to 2M Matthew Auld
2017-08-21 18:34 ` [PATCH 10/23] drm/i915: enable IPS bit for 64K pages Matthew Auld
2017-08-21 18:34 ` [PATCH 11/23] drm/i915: disable GTT cache for 2M/1G pages Matthew Auld
2017-08-21 18:34 ` [PATCH 12/23] drm/i915: support 1G pages for the 48b PPGTT Matthew Auld
2017-08-21 18:34 ` [PATCH 13/23] drm/i915: support 2M " Matthew Auld
2017-08-21 18:34 ` [PATCH 14/23] drm/i915: add support for 64K scratch page Matthew Auld
2017-08-21 18:34 ` [PATCH 15/23] drm/i915: support 64K pages for the 48b PPGTT Matthew Auld
2017-08-21 18:34 ` [PATCH 16/23] drm/i915: accurate page size tracking for the ppgtt Matthew Auld
2017-08-21 18:34 ` [PATCH 17/23] drm/i915/debugfs: include some gtt page size metrics Matthew Auld
2017-08-21 18:34 ` [PATCH 18/23] drm/i915/selftests: huge page tests Matthew Auld
2017-08-24 17:56   ` kbuild test robot
2017-08-28 14:36     ` Chris Wilson
2017-08-21 18:34 ` [PATCH 19/23] drm/i915/selftests: mix huge pages Matthew Auld
2017-08-21 18:35 ` [PATCH 20/23] drm/i915: disable platform support for vGPU huge gtt pages Matthew Auld
2017-08-21 18:35 ` [PATCH 21/23] drm/i915: enable platform support for 64K pages Matthew Auld
2017-08-21 18:35 ` [PATCH 22/23] drm/i915: enable platform support for 2M pages Matthew Auld
2017-08-21 18:35 ` [PATCH 23/23] drm/i915: enable platform support for 1G pages Matthew Auld
2017-08-21 18:54 ` ✓ Fi.CI.BAT: success for huge gtt pages (rev7) Patchwork
2017-08-22 14:21 ` [PATCH 00/23] huge gtt pages Chris Wilson
2017-08-22 14:23   ` Chris Wilson
2017-08-22 15:23     ` Matthew Auld

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.