All of lore.kernel.org
 help / color / mirror / Atom feed
* remove alloc_vm_area
@ 2020-09-18 16:37 ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-18 16:37 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Peter Zijlstra, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Minchan Kim, Nitin Gupta, x86, xen-devel, linux-kernel,
	intel-gfx, dri-devel, linux-mm

Hi Andrew,

this series removes alloc_vm_area, which was left over from the big
vmalloc interface rework.  It is a rather arkane interface, basicaly
the equivalent of get_vm_area + actually faulting in all PTEs in
the allocated area.  It was originally addeds for Xen (which isn't
modular to start with), and then grew users in zsmalloc and i915
which seems to mostly qualify as abuses of the interface, especially
for i915 as a random driver should not set up PTE bits directly.

Note that my laptop doesn't seem to actually exercise the new vmap_pfn
path, so careful review from the i915 maintainers is very welcome.

Also I wonder why zsmalloc is even doing the manual allocation of kernel
virtual address space plus mapping into it.  IMHO zsmalloc should be
using our normal vm_map_ram / vm_unmap_ram interface instead of being so
special, which would also allow building it as a module again for the
virtual mapping case.

Diffstat:
 arch/x86/xen/grant-table.c                |   27 +++++---
 drivers/gpu/drm/i915/Kconfig              |    1 
 drivers/gpu/drm/i915/gem/i915_gem_pages.c |  101 +++++++++++++-----------------
 drivers/gpu/drm/i915/gt/shmem_utils.c     |   90 +++++++++++---------------
 drivers/xen/xenbus/xenbus_client.c        |   30 ++++----
 include/linux/vmalloc.h                   |    6 -
 mm/Kconfig                                |    3 
 mm/nommu.c                                |    7 --
 mm/vmalloc.c                              |   93 +++++++++++++--------------
 mm/zsmalloc.c                             |    2 
 10 files changed, 172 insertions(+), 188 deletions(-)

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

* [Intel-gfx] remove alloc_vm_area
@ 2020-09-18 16:37 ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-18 16:37 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Boris Ostrovsky, Nitin Gupta

Hi Andrew,

this series removes alloc_vm_area, which was left over from the big
vmalloc interface rework.  It is a rather arkane interface, basicaly
the equivalent of get_vm_area + actually faulting in all PTEs in
the allocated area.  It was originally addeds for Xen (which isn't
modular to start with), and then grew users in zsmalloc and i915
which seems to mostly qualify as abuses of the interface, especially
for i915 as a random driver should not set up PTE bits directly.

Note that my laptop doesn't seem to actually exercise the new vmap_pfn
path, so careful review from the i915 maintainers is very welcome.

Also I wonder why zsmalloc is even doing the manual allocation of kernel
virtual address space plus mapping into it.  IMHO zsmalloc should be
using our normal vm_map_ram / vm_unmap_ram interface instead of being so
special, which would also allow building it as a module again for the
virtual mapping case.

Diffstat:
 arch/x86/xen/grant-table.c                |   27 +++++---
 drivers/gpu/drm/i915/Kconfig              |    1 
 drivers/gpu/drm/i915/gem/i915_gem_pages.c |  101 +++++++++++++-----------------
 drivers/gpu/drm/i915/gt/shmem_utils.c     |   90 +++++++++++---------------
 drivers/xen/xenbus/xenbus_client.c        |   30 ++++----
 include/linux/vmalloc.h                   |    6 -
 mm/Kconfig                                |    3 
 mm/nommu.c                                |    7 --
 mm/vmalloc.c                              |   93 +++++++++++++--------------
 mm/zsmalloc.c                             |    2 
 10 files changed, 172 insertions(+), 188 deletions(-)
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 1/6] zsmalloc: switch from alloc_vm_area to get_vm_area
  2020-09-18 16:37 ` [Intel-gfx] " Christoph Hellwig
@ 2020-09-18 16:37   ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-18 16:37 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Peter Zijlstra, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Minchan Kim, Nitin Gupta, x86, xen-devel, linux-kernel,
	intel-gfx, dri-devel, linux-mm

There is no obvious reason why zsmalloc needs to pre-fault the PTEs
given that it later uses map_kernel_range to just like vmap().

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 mm/zsmalloc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index c36fdff9a37131..3e4fe3259612fd 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -1122,7 +1122,7 @@ static inline int __zs_cpu_up(struct mapping_area *area)
 	 */
 	if (area->vm)
 		return 0;
-	area->vm = alloc_vm_area(PAGE_SIZE * 2, NULL);
+	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
 	if (!area->vm)
 		return -ENOMEM;
 	return 0;
-- 
2.28.0


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

* [Intel-gfx] [PATCH 1/6] zsmalloc: switch from alloc_vm_area to get_vm_area
@ 2020-09-18 16:37   ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-18 16:37 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Boris Ostrovsky, Nitin Gupta

There is no obvious reason why zsmalloc needs to pre-fault the PTEs
given that it later uses map_kernel_range to just like vmap().

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 mm/zsmalloc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index c36fdff9a37131..3e4fe3259612fd 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -1122,7 +1122,7 @@ static inline int __zs_cpu_up(struct mapping_area *area)
 	 */
 	if (area->vm)
 		return 0;
-	area->vm = alloc_vm_area(PAGE_SIZE * 2, NULL);
+	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
 	if (!area->vm)
 		return -ENOMEM;
 	return 0;
-- 
2.28.0

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

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

* [PATCH 2/6] mm: add a vmap_pfn function
  2020-09-18 16:37 ` [Intel-gfx] " Christoph Hellwig
@ 2020-09-18 16:37   ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-18 16:37 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Peter Zijlstra, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Minchan Kim, Nitin Gupta, x86, xen-devel, linux-kernel,
	intel-gfx, dri-devel, linux-mm

Add a proper helper to remap PFNs into kernel virtual space so that
drivers don't have to abuse alloc_vm_area and open coded PTE
manipulation for it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 include/linux/vmalloc.h |  1 +
 mm/Kconfig              |  3 +++
 mm/vmalloc.c            | 45 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+)

diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 0221f852a7e1a3..8ecd92a947ee0c 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -121,6 +121,7 @@ extern void vfree_atomic(const void *addr);
 
 extern void *vmap(struct page **pages, unsigned int count,
 			unsigned long flags, pgprot_t prot);
+void *vmap_pfn(unsigned long *pfns, unsigned int count, pgprot_t prot);
 extern void vunmap(const void *addr);
 
 extern int remap_vmalloc_range_partial(struct vm_area_struct *vma,
diff --git a/mm/Kconfig b/mm/Kconfig
index 6c974888f86f97..6fa7ba1199eb1e 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -815,6 +815,9 @@ config DEVICE_PRIVATE
 	  memory; i.e., memory that is only accessible from the device (or
 	  group of devices). You likely also want to select HMM_MIRROR.
 
+config VMAP_PFN
+	bool
+
 config FRAME_VECTOR
 	bool
 
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index be4724b916b3e7..59f2afcf26c312 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2407,6 +2407,51 @@ void *vmap(struct page **pages, unsigned int count,
 }
 EXPORT_SYMBOL(vmap);
 
+#ifdef CONFIG_VMAP_PFN
+struct vmap_pfn_data {
+	unsigned long	*pfns;
+	pgprot_t	prot;
+	unsigned int	idx;
+};
+
+static int vmap_pfn_apply(pte_t *pte, unsigned long addr, void *private)
+{
+	struct vmap_pfn_data *data = private;
+
+	if (WARN_ON_ONCE(pfn_valid(data->pfns[data->idx])))
+		return -EINVAL;
+	*pte = pte_mkspecial(pfn_pte(data->pfns[data->idx++], data->prot));
+	return 0;
+}
+
+/**
+ * vmap_pfn - map an array of PFNs into virtually contiguous space
+ * @pfns: array of PFNs
+ * @count: number of pages to map
+ * @prot: page protection for the mapping
+ *
+ * Maps @count PFNs from @pfns into contiguous kernel virtual space and returns
+ * the start address of the mapping.
+ */
+void *vmap_pfn(unsigned long *pfns, unsigned int count, pgprot_t prot)
+{
+	struct vmap_pfn_data data = { .pfns = pfns, .prot = pgprot_nx(prot) };
+	struct vm_struct *area;
+
+	area = get_vm_area_caller(count * PAGE_SIZE, VM_IOREMAP,
+			__builtin_return_address(0));
+	if (!area)
+		return NULL;
+	if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
+			count * PAGE_SIZE, vmap_pfn_apply, &data)) {
+		free_vm_area(area);
+		return NULL;
+	}
+	return area->addr;
+}
+EXPORT_SYMBOL_GPL(vmap_pfn);
+#endif /* CONFIG_VMAP_PFN */
+
 static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
 				 pgprot_t prot, int node)
 {
-- 
2.28.0


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

* [Intel-gfx] [PATCH 2/6] mm: add a vmap_pfn function
@ 2020-09-18 16:37   ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-18 16:37 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Boris Ostrovsky, Nitin Gupta

Add a proper helper to remap PFNs into kernel virtual space so that
drivers don't have to abuse alloc_vm_area and open coded PTE
manipulation for it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 include/linux/vmalloc.h |  1 +
 mm/Kconfig              |  3 +++
 mm/vmalloc.c            | 45 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+)

diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 0221f852a7e1a3..8ecd92a947ee0c 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -121,6 +121,7 @@ extern void vfree_atomic(const void *addr);
 
 extern void *vmap(struct page **pages, unsigned int count,
 			unsigned long flags, pgprot_t prot);
+void *vmap_pfn(unsigned long *pfns, unsigned int count, pgprot_t prot);
 extern void vunmap(const void *addr);
 
 extern int remap_vmalloc_range_partial(struct vm_area_struct *vma,
diff --git a/mm/Kconfig b/mm/Kconfig
index 6c974888f86f97..6fa7ba1199eb1e 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -815,6 +815,9 @@ config DEVICE_PRIVATE
 	  memory; i.e., memory that is only accessible from the device (or
 	  group of devices). You likely also want to select HMM_MIRROR.
 
+config VMAP_PFN
+	bool
+
 config FRAME_VECTOR
 	bool
 
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index be4724b916b3e7..59f2afcf26c312 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2407,6 +2407,51 @@ void *vmap(struct page **pages, unsigned int count,
 }
 EXPORT_SYMBOL(vmap);
 
+#ifdef CONFIG_VMAP_PFN
+struct vmap_pfn_data {
+	unsigned long	*pfns;
+	pgprot_t	prot;
+	unsigned int	idx;
+};
+
+static int vmap_pfn_apply(pte_t *pte, unsigned long addr, void *private)
+{
+	struct vmap_pfn_data *data = private;
+
+	if (WARN_ON_ONCE(pfn_valid(data->pfns[data->idx])))
+		return -EINVAL;
+	*pte = pte_mkspecial(pfn_pte(data->pfns[data->idx++], data->prot));
+	return 0;
+}
+
+/**
+ * vmap_pfn - map an array of PFNs into virtually contiguous space
+ * @pfns: array of PFNs
+ * @count: number of pages to map
+ * @prot: page protection for the mapping
+ *
+ * Maps @count PFNs from @pfns into contiguous kernel virtual space and returns
+ * the start address of the mapping.
+ */
+void *vmap_pfn(unsigned long *pfns, unsigned int count, pgprot_t prot)
+{
+	struct vmap_pfn_data data = { .pfns = pfns, .prot = pgprot_nx(prot) };
+	struct vm_struct *area;
+
+	area = get_vm_area_caller(count * PAGE_SIZE, VM_IOREMAP,
+			__builtin_return_address(0));
+	if (!area)
+		return NULL;
+	if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
+			count * PAGE_SIZE, vmap_pfn_apply, &data)) {
+		free_vm_area(area);
+		return NULL;
+	}
+	return area->addr;
+}
+EXPORT_SYMBOL_GPL(vmap_pfn);
+#endif /* CONFIG_VMAP_PFN */
+
 static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
 				 pgprot_t prot, int node)
 {
-- 
2.28.0

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

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

* [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
  2020-09-18 16:37 ` [Intel-gfx] " Christoph Hellwig
@ 2020-09-18 16:37   ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-18 16:37 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Peter Zijlstra, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Minchan Kim, Nitin Gupta, x86, xen-devel, linux-kernel,
	intel-gfx, dri-devel, linux-mm

shmem_pin_map somewhat awkwardly reimplements vmap using
alloc_vm_area and manual pte setup.  The only practical difference
is that alloc_vm_area prefeaults the vmalloc area PTEs, which doesn't
seem to be required here (and could be added to vmap using a flag
if actually required).

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/gpu/drm/i915/gt/shmem_utils.c | 90 +++++++++++----------------
 1 file changed, 38 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.c b/drivers/gpu/drm/i915/gt/shmem_utils.c
index 43c7acbdc79dea..77410091597f19 100644
--- a/drivers/gpu/drm/i915/gt/shmem_utils.c
+++ b/drivers/gpu/drm/i915/gt/shmem_utils.c
@@ -49,80 +49,66 @@ struct file *shmem_create_from_object(struct drm_i915_gem_object *obj)
 	return file;
 }
 
-static size_t shmem_npte(struct file *file)
+static size_t shmem_npages(struct file *file)
 {
 	return file->f_mapping->host->i_size >> PAGE_SHIFT;
 }
 
-static void __shmem_unpin_map(struct file *file, void *ptr, size_t n_pte)
-{
-	unsigned long pfn;
-
-	vunmap(ptr);
-
-	for (pfn = 0; pfn < n_pte; pfn++) {
-		struct page *page;
-
-		page = shmem_read_mapping_page_gfp(file->f_mapping, pfn,
-						   GFP_KERNEL);
-		if (!WARN_ON(IS_ERR(page))) {
-			put_page(page);
-			put_page(page);
-		}
-	}
-}
-
 void *shmem_pin_map(struct file *file)
 {
-	const size_t n_pte = shmem_npte(file);
-	pte_t *stack[32], **ptes, **mem;
-	struct vm_struct *area;
-	unsigned long pfn;
-
-	mem = stack;
-	if (n_pte > ARRAY_SIZE(stack)) {
-		mem = kvmalloc_array(n_pte, sizeof(*mem), GFP_KERNEL);
-		if (!mem)
+	const size_t n_pages = shmem_npages(file);
+	struct page **pages, *stack[32];
+	void *vaddr;
+	long i;
+
+	pages = stack;
+	if (n_pages > ARRAY_SIZE(stack)) {
+		pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL);
+		if (!pages)
 			return NULL;
 	}
 
-	area = alloc_vm_area(n_pte << PAGE_SHIFT, mem);
-	if (!area) {
-		if (mem != stack)
-			kvfree(mem);
-		return NULL;
-	}
-
-	ptes = mem;
-	for (pfn = 0; pfn < n_pte; pfn++) {
-		struct page *page;
-
-		page = shmem_read_mapping_page_gfp(file->f_mapping, pfn,
-						   GFP_KERNEL);
-		if (IS_ERR(page))
+	for (i = 0; i < n_pages; i++) {
+		pages[i] = shmem_read_mapping_page_gfp(file->f_mapping, i,
+						       GFP_KERNEL);
+		if (IS_ERR(pages[i]))
 			goto err_page;
-
-		**ptes++ = mk_pte(page,  PAGE_KERNEL);
 	}
 
-	if (mem != stack)
-		kvfree(mem);
+	vaddr = vmap(pages, n_pages, 0, PAGE_KERNEL);
+	if (!vaddr)
+		goto err_page;
 
+	if (pages != stack)
+		kvfree(pages);
 	mapping_set_unevictable(file->f_mapping);
-	return area->addr;
+	return vaddr;
 
 err_page:
-	if (mem != stack)
-		kvfree(mem);
-
-	__shmem_unpin_map(file, area->addr, pfn);
+	while (--i >= 0)
+		put_page(pages[i]);
+	if (pages != stack)
+		kvfree(pages);
 	return NULL;
 }
 
 void shmem_unpin_map(struct file *file, void *ptr)
 {
+	long i = shmem_npages(file);
+
 	mapping_clear_unevictable(file->f_mapping);
-	__shmem_unpin_map(file, ptr, shmem_npte(file));
+	vunmap(ptr);
+
+	for (i = 0; i < shmem_npages(file); i++) {
+		struct page *page;
+
+		page = shmem_read_mapping_page_gfp(file->f_mapping, i,
+						   GFP_KERNEL);
+		if (!WARN_ON(IS_ERR(page))) {
+			put_page(page);
+			put_page(page);
+		}
+	}
 }
 
 static int __shmem_rw(struct file *file, loff_t off,
-- 
2.28.0


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

* [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-18 16:37   ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-18 16:37 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Boris Ostrovsky, Nitin Gupta

shmem_pin_map somewhat awkwardly reimplements vmap using
alloc_vm_area and manual pte setup.  The only practical difference
is that alloc_vm_area prefeaults the vmalloc area PTEs, which doesn't
seem to be required here (and could be added to vmap using a flag
if actually required).

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/gpu/drm/i915/gt/shmem_utils.c | 90 +++++++++++----------------
 1 file changed, 38 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.c b/drivers/gpu/drm/i915/gt/shmem_utils.c
index 43c7acbdc79dea..77410091597f19 100644
--- a/drivers/gpu/drm/i915/gt/shmem_utils.c
+++ b/drivers/gpu/drm/i915/gt/shmem_utils.c
@@ -49,80 +49,66 @@ struct file *shmem_create_from_object(struct drm_i915_gem_object *obj)
 	return file;
 }
 
-static size_t shmem_npte(struct file *file)
+static size_t shmem_npages(struct file *file)
 {
 	return file->f_mapping->host->i_size >> PAGE_SHIFT;
 }
 
-static void __shmem_unpin_map(struct file *file, void *ptr, size_t n_pte)
-{
-	unsigned long pfn;
-
-	vunmap(ptr);
-
-	for (pfn = 0; pfn < n_pte; pfn++) {
-		struct page *page;
-
-		page = shmem_read_mapping_page_gfp(file->f_mapping, pfn,
-						   GFP_KERNEL);
-		if (!WARN_ON(IS_ERR(page))) {
-			put_page(page);
-			put_page(page);
-		}
-	}
-}
-
 void *shmem_pin_map(struct file *file)
 {
-	const size_t n_pte = shmem_npte(file);
-	pte_t *stack[32], **ptes, **mem;
-	struct vm_struct *area;
-	unsigned long pfn;
-
-	mem = stack;
-	if (n_pte > ARRAY_SIZE(stack)) {
-		mem = kvmalloc_array(n_pte, sizeof(*mem), GFP_KERNEL);
-		if (!mem)
+	const size_t n_pages = shmem_npages(file);
+	struct page **pages, *stack[32];
+	void *vaddr;
+	long i;
+
+	pages = stack;
+	if (n_pages > ARRAY_SIZE(stack)) {
+		pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL);
+		if (!pages)
 			return NULL;
 	}
 
-	area = alloc_vm_area(n_pte << PAGE_SHIFT, mem);
-	if (!area) {
-		if (mem != stack)
-			kvfree(mem);
-		return NULL;
-	}
-
-	ptes = mem;
-	for (pfn = 0; pfn < n_pte; pfn++) {
-		struct page *page;
-
-		page = shmem_read_mapping_page_gfp(file->f_mapping, pfn,
-						   GFP_KERNEL);
-		if (IS_ERR(page))
+	for (i = 0; i < n_pages; i++) {
+		pages[i] = shmem_read_mapping_page_gfp(file->f_mapping, i,
+						       GFP_KERNEL);
+		if (IS_ERR(pages[i]))
 			goto err_page;
-
-		**ptes++ = mk_pte(page,  PAGE_KERNEL);
 	}
 
-	if (mem != stack)
-		kvfree(mem);
+	vaddr = vmap(pages, n_pages, 0, PAGE_KERNEL);
+	if (!vaddr)
+		goto err_page;
 
+	if (pages != stack)
+		kvfree(pages);
 	mapping_set_unevictable(file->f_mapping);
-	return area->addr;
+	return vaddr;
 
 err_page:
-	if (mem != stack)
-		kvfree(mem);
-
-	__shmem_unpin_map(file, area->addr, pfn);
+	while (--i >= 0)
+		put_page(pages[i]);
+	if (pages != stack)
+		kvfree(pages);
 	return NULL;
 }
 
 void shmem_unpin_map(struct file *file, void *ptr)
 {
+	long i = shmem_npages(file);
+
 	mapping_clear_unevictable(file->f_mapping);
-	__shmem_unpin_map(file, ptr, shmem_npte(file));
+	vunmap(ptr);
+
+	for (i = 0; i < shmem_npages(file); i++) {
+		struct page *page;
+
+		page = shmem_read_mapping_page_gfp(file->f_mapping, i,
+						   GFP_KERNEL);
+		if (!WARN_ON(IS_ERR(page))) {
+			put_page(page);
+			put_page(page);
+		}
+	}
 }
 
 static int __shmem_rw(struct file *file, loff_t off,
-- 
2.28.0

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

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

* [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map
  2020-09-18 16:37 ` [Intel-gfx] " Christoph Hellwig
@ 2020-09-18 16:37   ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-18 16:37 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Peter Zijlstra, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Minchan Kim, Nitin Gupta, x86, xen-devel, linux-kernel,
	intel-gfx, dri-devel, linux-mm

i915_gem_object_map implements fairly low-level vmap functionality in
a driver.  Split it into two helpers, one for remapping kernel memory
which can use vmap, and one for I/O memory that uses vmap_pfn.

The only practical difference is that alloc_vm_area prefeaults the
vmalloc area PTEs, which doesn't seem to be required here for the
kernel memory case (and could be added to vmap using a flag if actually
required).

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/gpu/drm/i915/Kconfig              |   1 +
 drivers/gpu/drm/i915/gem/i915_gem_pages.c | 101 ++++++++++------------
 2 files changed, 47 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 9afa5c4a6bf006..1e1cb245fca778 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -25,6 +25,7 @@ config DRM_I915
 	select CRC32
 	select SND_HDA_I915 if SND_HDA_CORE
 	select CEC_CORE if CEC_NOTIFIER
+	select VMAP_PFN
 	help
 	  Choose this option if you have a system that has "Intel Graphics
 	  Media Accelerator" or "HD Graphics" integrated graphics,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
index e8a083743e0927..90029ea83aede9 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
@@ -234,50 +234,24 @@ int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
 	return err;
 }
 
-static inline pte_t iomap_pte(resource_size_t base,
-			      dma_addr_t offset,
-			      pgprot_t prot)
-{
-	return pte_mkspecial(pfn_pte((base + offset) >> PAGE_SHIFT, prot));
-}
-
 /* The 'mapping' part of i915_gem_object_pin_map() below */
-static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
+static void *i915_gem_object_map_page(struct drm_i915_gem_object *obj,
 				 enum i915_map_type type)
 {
-	unsigned long n_pte = obj->base.size >> PAGE_SHIFT;
-	struct sg_table *sgt = obj->mm.pages;
-	pte_t *stack[32], **mem;
-	struct vm_struct *area;
+	unsigned long n_pages = obj->base.size >> PAGE_SHIFT, i;
+	struct page *stack[32], **pages = stack, *page;
+	struct sgt_iter iter;
 	pgprot_t pgprot;
-
-	if (!i915_gem_object_has_struct_page(obj) && type != I915_MAP_WC)
-		return NULL;
-
-	/* A single page can always be kmapped */
-	if (n_pte == 1 && type == I915_MAP_WB)
-		return kmap(sg_page(sgt->sgl));
-
-	mem = stack;
-	if (n_pte > ARRAY_SIZE(stack)) {
-		/* Too big for stack -- allocate temporary array instead */
-		mem = kvmalloc_array(n_pte, sizeof(*mem), GFP_KERNEL);
-		if (!mem)
-			return NULL;
-	}
-
-	area = alloc_vm_area(obj->base.size, mem);
-	if (!area) {
-		if (mem != stack)
-			kvfree(mem);
-		return NULL;
-	}
+	void *vaddr;
 
 	switch (type) {
 	default:
 		MISSING_CASE(type);
 		fallthrough;	/* to use PAGE_KERNEL anyway */
 	case I915_MAP_WB:
+		/* A single page can always be kmapped */
+		if (n_pages == 1)
+			return kmap(sg_page(obj->mm.pages->sgl));
 		pgprot = PAGE_KERNEL;
 		break;
 	case I915_MAP_WC:
@@ -285,30 +259,44 @@ static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
 		break;
 	}
 
-	if (i915_gem_object_has_struct_page(obj)) {
-		struct sgt_iter iter;
-		struct page *page;
-		pte_t **ptes = mem;
-
-		for_each_sgt_page(page, iter, sgt)
-			**ptes++ = mk_pte(page, pgprot);
-	} else {
-		resource_size_t iomap;
-		struct sgt_iter iter;
-		pte_t **ptes = mem;
-		dma_addr_t addr;
+	if (n_pages > ARRAY_SIZE(stack)) {
+		/* Too big for stack -- allocate temporary array instead */
+		pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL);
+		if (!pages)
+			return NULL;
+	}
 
-		iomap = obj->mm.region->iomap.base;
-		iomap -= obj->mm.region->region.start;
+	for_each_sgt_page(page, iter, obj->mm.pages)
+		pages[i++] = page;
+	vaddr = vmap(pages, n_pages, 0, pgprot);
+	if (pages != stack)
+		kvfree(pages);
+	return vaddr;
+}
 
-		for_each_sgt_daddr(addr, iter, sgt)
-			**ptes++ = iomap_pte(iomap, addr, pgprot);
+static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj)
+{
+	resource_size_t iomap = obj->mm.region->iomap.base -
+		obj->mm.region->region.start;
+	unsigned long n_pfn = obj->base.size >> PAGE_SHIFT;
+	unsigned long stack[32], *pfns = stack, i;
+	struct sgt_iter iter;
+	dma_addr_t addr;
+	void *vaddr;
+
+	if (n_pfn > ARRAY_SIZE(stack)) {
+		/* Too big for stack -- allocate temporary array instead */
+		pfns = kvmalloc_array(n_pfn, sizeof(*pfns), GFP_KERNEL);
+		if (!pfns)
+			return NULL;
 	}
 
-	if (mem != stack)
-		kvfree(mem);
-
-	return area->addr;
+	for_each_sgt_daddr(addr, iter, obj->mm.pages)
+		pfns[i++] = (iomap + addr) >> PAGE_SHIFT;
+	vaddr = vmap_pfn(pfns, n_pfn, pgprot_writecombine(PAGE_KERNEL_IO));
+	if (pfns != stack)
+		kvfree(pfns);
+	return vaddr;
 }
 
 /* get, pin, and map the pages of the object into kernel space */
@@ -360,7 +348,10 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
 	}
 
 	if (!ptr) {
-		ptr = i915_gem_object_map(obj, type);
+		if (i915_gem_object_has_struct_page(obj))
+			ptr = i915_gem_object_map_page(obj, type);
+		else if (type == I915_MAP_WC)
+			ptr = i915_gem_object_map_pfn(obj);
 		if (!ptr) {
 			err = -ENOMEM;
 			goto err_unpin;
-- 
2.28.0


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

* [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map
@ 2020-09-18 16:37   ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-18 16:37 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Boris Ostrovsky, Nitin Gupta

i915_gem_object_map implements fairly low-level vmap functionality in
a driver.  Split it into two helpers, one for remapping kernel memory
which can use vmap, and one for I/O memory that uses vmap_pfn.

The only practical difference is that alloc_vm_area prefeaults the
vmalloc area PTEs, which doesn't seem to be required here for the
kernel memory case (and could be added to vmap using a flag if actually
required).

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/gpu/drm/i915/Kconfig              |   1 +
 drivers/gpu/drm/i915/gem/i915_gem_pages.c | 101 ++++++++++------------
 2 files changed, 47 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 9afa5c4a6bf006..1e1cb245fca778 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -25,6 +25,7 @@ config DRM_I915
 	select CRC32
 	select SND_HDA_I915 if SND_HDA_CORE
 	select CEC_CORE if CEC_NOTIFIER
+	select VMAP_PFN
 	help
 	  Choose this option if you have a system that has "Intel Graphics
 	  Media Accelerator" or "HD Graphics" integrated graphics,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
index e8a083743e0927..90029ea83aede9 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
@@ -234,50 +234,24 @@ int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
 	return err;
 }
 
-static inline pte_t iomap_pte(resource_size_t base,
-			      dma_addr_t offset,
-			      pgprot_t prot)
-{
-	return pte_mkspecial(pfn_pte((base + offset) >> PAGE_SHIFT, prot));
-}
-
 /* The 'mapping' part of i915_gem_object_pin_map() below */
-static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
+static void *i915_gem_object_map_page(struct drm_i915_gem_object *obj,
 				 enum i915_map_type type)
 {
-	unsigned long n_pte = obj->base.size >> PAGE_SHIFT;
-	struct sg_table *sgt = obj->mm.pages;
-	pte_t *stack[32], **mem;
-	struct vm_struct *area;
+	unsigned long n_pages = obj->base.size >> PAGE_SHIFT, i;
+	struct page *stack[32], **pages = stack, *page;
+	struct sgt_iter iter;
 	pgprot_t pgprot;
-
-	if (!i915_gem_object_has_struct_page(obj) && type != I915_MAP_WC)
-		return NULL;
-
-	/* A single page can always be kmapped */
-	if (n_pte == 1 && type == I915_MAP_WB)
-		return kmap(sg_page(sgt->sgl));
-
-	mem = stack;
-	if (n_pte > ARRAY_SIZE(stack)) {
-		/* Too big for stack -- allocate temporary array instead */
-		mem = kvmalloc_array(n_pte, sizeof(*mem), GFP_KERNEL);
-		if (!mem)
-			return NULL;
-	}
-
-	area = alloc_vm_area(obj->base.size, mem);
-	if (!area) {
-		if (mem != stack)
-			kvfree(mem);
-		return NULL;
-	}
+	void *vaddr;
 
 	switch (type) {
 	default:
 		MISSING_CASE(type);
 		fallthrough;	/* to use PAGE_KERNEL anyway */
 	case I915_MAP_WB:
+		/* A single page can always be kmapped */
+		if (n_pages == 1)
+			return kmap(sg_page(obj->mm.pages->sgl));
 		pgprot = PAGE_KERNEL;
 		break;
 	case I915_MAP_WC:
@@ -285,30 +259,44 @@ static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
 		break;
 	}
 
-	if (i915_gem_object_has_struct_page(obj)) {
-		struct sgt_iter iter;
-		struct page *page;
-		pte_t **ptes = mem;
-
-		for_each_sgt_page(page, iter, sgt)
-			**ptes++ = mk_pte(page, pgprot);
-	} else {
-		resource_size_t iomap;
-		struct sgt_iter iter;
-		pte_t **ptes = mem;
-		dma_addr_t addr;
+	if (n_pages > ARRAY_SIZE(stack)) {
+		/* Too big for stack -- allocate temporary array instead */
+		pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL);
+		if (!pages)
+			return NULL;
+	}
 
-		iomap = obj->mm.region->iomap.base;
-		iomap -= obj->mm.region->region.start;
+	for_each_sgt_page(page, iter, obj->mm.pages)
+		pages[i++] = page;
+	vaddr = vmap(pages, n_pages, 0, pgprot);
+	if (pages != stack)
+		kvfree(pages);
+	return vaddr;
+}
 
-		for_each_sgt_daddr(addr, iter, sgt)
-			**ptes++ = iomap_pte(iomap, addr, pgprot);
+static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj)
+{
+	resource_size_t iomap = obj->mm.region->iomap.base -
+		obj->mm.region->region.start;
+	unsigned long n_pfn = obj->base.size >> PAGE_SHIFT;
+	unsigned long stack[32], *pfns = stack, i;
+	struct sgt_iter iter;
+	dma_addr_t addr;
+	void *vaddr;
+
+	if (n_pfn > ARRAY_SIZE(stack)) {
+		/* Too big for stack -- allocate temporary array instead */
+		pfns = kvmalloc_array(n_pfn, sizeof(*pfns), GFP_KERNEL);
+		if (!pfns)
+			return NULL;
 	}
 
-	if (mem != stack)
-		kvfree(mem);
-
-	return area->addr;
+	for_each_sgt_daddr(addr, iter, obj->mm.pages)
+		pfns[i++] = (iomap + addr) >> PAGE_SHIFT;
+	vaddr = vmap_pfn(pfns, n_pfn, pgprot_writecombine(PAGE_KERNEL_IO));
+	if (pfns != stack)
+		kvfree(pfns);
+	return vaddr;
 }
 
 /* get, pin, and map the pages of the object into kernel space */
@@ -360,7 +348,10 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
 	}
 
 	if (!ptr) {
-		ptr = i915_gem_object_map(obj, type);
+		if (i915_gem_object_has_struct_page(obj))
+			ptr = i915_gem_object_map_page(obj, type);
+		else if (type == I915_MAP_WC)
+			ptr = i915_gem_object_map_pfn(obj);
 		if (!ptr) {
 			err = -ENOMEM;
 			goto err_unpin;
-- 
2.28.0

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

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

* [PATCH 5/6] xen/xenbus: use apply_to_page_range directly in xenbus_map_ring_pv
  2020-09-18 16:37 ` [Intel-gfx] " Christoph Hellwig
@ 2020-09-18 16:37   ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-18 16:37 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Peter Zijlstra, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Minchan Kim, Nitin Gupta, x86, xen-devel, linux-kernel,
	intel-gfx, dri-devel, linux-mm

Replacing alloc_vm_area with get_vm_area_caller + apply_page_range
allows to fill put the phys_addr values directly instead of doing
another loop over all addresses.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/xen/xenbus/xenbus_client.c | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index 2690318ad50f48..fd80e318b99cc7 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -73,16 +73,13 @@ struct map_ring_valloc {
 	struct xenbus_map_node *node;
 
 	/* Why do we need two arrays? See comment of __xenbus_map_ring */
-	union {
-		unsigned long addrs[XENBUS_MAX_RING_GRANTS];
-		pte_t *ptes[XENBUS_MAX_RING_GRANTS];
-	};
+	unsigned long addrs[XENBUS_MAX_RING_GRANTS];
 	phys_addr_t phys_addrs[XENBUS_MAX_RING_GRANTS];
 
 	struct gnttab_map_grant_ref map[XENBUS_MAX_RING_GRANTS];
 	struct gnttab_unmap_grant_ref unmap[XENBUS_MAX_RING_GRANTS];
 
-	unsigned int idx;	/* HVM only. */
+	unsigned int idx;
 };
 
 static DEFINE_SPINLOCK(xenbus_valloc_lock);
@@ -686,6 +683,14 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)
 EXPORT_SYMBOL_GPL(xenbus_unmap_ring_vfree);
 
 #ifdef CONFIG_XEN_PV
+static int map_ring_apply(pte_t *pte, unsigned long addr, void *data)
+{
+	struct map_ring_valloc *info = data;
+
+	info->phys_addrs[info->idx++] = arbitrary_virt_to_machine(pte).maddr;
+	return 0;
+}
+
 static int xenbus_map_ring_pv(struct xenbus_device *dev,
 			      struct map_ring_valloc *info,
 			      grant_ref_t *gnt_refs,
@@ -694,18 +699,15 @@ static int xenbus_map_ring_pv(struct xenbus_device *dev,
 {
 	struct xenbus_map_node *node = info->node;
 	struct vm_struct *area;
-	int err = GNTST_okay;
-	int i;
-	bool leaked;
+	bool leaked = false;
+	int err = -ENOMEM;
 
-	area = alloc_vm_area(XEN_PAGE_SIZE * nr_grefs, info->ptes);
+	area = get_vm_area(XEN_PAGE_SIZE * nr_grefs, VM_IOREMAP);
 	if (!area)
 		return -ENOMEM;
-
-	for (i = 0; i < nr_grefs; i++)
-		info->phys_addrs[i] =
-			arbitrary_virt_to_machine(info->ptes[i]).maddr;
-
+	if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
+				XEN_PAGE_SIZE * nr_grefs, map_ring_apply, info))
+		goto failed;
 	err = __xenbus_map_ring(dev, gnt_refs, nr_grefs, node->handles,
 				info, GNTMAP_host_map | GNTMAP_contains_pte,
 				&leaked);
-- 
2.28.0


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

* [Intel-gfx] [PATCH 5/6] xen/xenbus: use apply_to_page_range directly in xenbus_map_ring_pv
@ 2020-09-18 16:37   ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-18 16:37 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Boris Ostrovsky, Nitin Gupta

Replacing alloc_vm_area with get_vm_area_caller + apply_page_range
allows to fill put the phys_addr values directly instead of doing
another loop over all addresses.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/xen/xenbus/xenbus_client.c | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index 2690318ad50f48..fd80e318b99cc7 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -73,16 +73,13 @@ struct map_ring_valloc {
 	struct xenbus_map_node *node;
 
 	/* Why do we need two arrays? See comment of __xenbus_map_ring */
-	union {
-		unsigned long addrs[XENBUS_MAX_RING_GRANTS];
-		pte_t *ptes[XENBUS_MAX_RING_GRANTS];
-	};
+	unsigned long addrs[XENBUS_MAX_RING_GRANTS];
 	phys_addr_t phys_addrs[XENBUS_MAX_RING_GRANTS];
 
 	struct gnttab_map_grant_ref map[XENBUS_MAX_RING_GRANTS];
 	struct gnttab_unmap_grant_ref unmap[XENBUS_MAX_RING_GRANTS];
 
-	unsigned int idx;	/* HVM only. */
+	unsigned int idx;
 };
 
 static DEFINE_SPINLOCK(xenbus_valloc_lock);
@@ -686,6 +683,14 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)
 EXPORT_SYMBOL_GPL(xenbus_unmap_ring_vfree);
 
 #ifdef CONFIG_XEN_PV
+static int map_ring_apply(pte_t *pte, unsigned long addr, void *data)
+{
+	struct map_ring_valloc *info = data;
+
+	info->phys_addrs[info->idx++] = arbitrary_virt_to_machine(pte).maddr;
+	return 0;
+}
+
 static int xenbus_map_ring_pv(struct xenbus_device *dev,
 			      struct map_ring_valloc *info,
 			      grant_ref_t *gnt_refs,
@@ -694,18 +699,15 @@ static int xenbus_map_ring_pv(struct xenbus_device *dev,
 {
 	struct xenbus_map_node *node = info->node;
 	struct vm_struct *area;
-	int err = GNTST_okay;
-	int i;
-	bool leaked;
+	bool leaked = false;
+	int err = -ENOMEM;
 
-	area = alloc_vm_area(XEN_PAGE_SIZE * nr_grefs, info->ptes);
+	area = get_vm_area(XEN_PAGE_SIZE * nr_grefs, VM_IOREMAP);
 	if (!area)
 		return -ENOMEM;
-
-	for (i = 0; i < nr_grefs; i++)
-		info->phys_addrs[i] =
-			arbitrary_virt_to_machine(info->ptes[i]).maddr;
-
+	if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
+				XEN_PAGE_SIZE * nr_grefs, map_ring_apply, info))
+		goto failed;
 	err = __xenbus_map_ring(dev, gnt_refs, nr_grefs, node->handles,
 				info, GNTMAP_host_map | GNTMAP_contains_pte,
 				&leaked);
-- 
2.28.0

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

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

* [PATCH 6/6] x86/xen: open code alloc_vm_area in arch_gnttab_valloc
  2020-09-18 16:37 ` [Intel-gfx] " Christoph Hellwig
@ 2020-09-18 16:37   ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-18 16:37 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Peter Zijlstra, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Minchan Kim, Nitin Gupta, x86, xen-devel, linux-kernel,
	intel-gfx, dri-devel, linux-mm

Open code alloc_vm_area in the last remaining caller.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/x86/xen/grant-table.c | 27 +++++++++++++++------
 include/linux/vmalloc.h    |  5 +---
 mm/nommu.c                 |  7 ------
 mm/vmalloc.c               | 48 --------------------------------------
 4 files changed, 21 insertions(+), 66 deletions(-)

diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c
index 4988e19598c8a5..ccb377c07c651f 100644
--- a/arch/x86/xen/grant-table.c
+++ b/arch/x86/xen/grant-table.c
@@ -90,19 +90,32 @@ void arch_gnttab_unmap(void *shared, unsigned long nr_gframes)
 	}
 }
 
+static int gnttab_apply(pte_t *pte, unsigned long addr, void *data)
+{
+	pte_t ***p = data;
+
+	**p = pte;
+	(*p)++;
+	return 0;
+}
+
 static int arch_gnttab_valloc(struct gnttab_vm_area *area, unsigned nr_frames)
 {
 	area->ptes = kmalloc_array(nr_frames, sizeof(*area->ptes), GFP_KERNEL);
 	if (area->ptes == NULL)
 		return -ENOMEM;
-
-	area->area = alloc_vm_area(PAGE_SIZE * nr_frames, area->ptes);
-	if (area->area == NULL) {
-		kfree(area->ptes);
-		return -ENOMEM;
-	}
-
+	area->area = get_vm_area(PAGE_SIZE * nr_frames, VM_IOREMAP);
+	if (!area->area)
+		goto out_free_ptes;
+	if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
+			PAGE_SIZE * nr_frames, gnttab_apply, &area->ptes))
+		goto out_free_vm_area;
 	return 0;
+out_free_vm_area:
+	free_vm_area(area->area);
+out_free_ptes:
+	kfree(area->ptes);
+	return -ENOMEM;
 }
 
 static void arch_gnttab_vfree(struct gnttab_vm_area *area)
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 8ecd92a947ee0c..a1a4e2f8163504 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -168,6 +168,7 @@ extern struct vm_struct *__get_vm_area_caller(unsigned long size,
 					unsigned long flags,
 					unsigned long start, unsigned long end,
 					const void *caller);
+void free_vm_area(struct vm_struct *area);
 extern struct vm_struct *remove_vm_area(const void *addr);
 extern struct vm_struct *find_vm_area(const void *addr);
 
@@ -203,10 +204,6 @@ static inline void set_vm_flush_reset_perms(void *addr)
 }
 #endif
 
-/* Allocate/destroy a 'vmalloc' VM area. */
-extern struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes);
-extern void free_vm_area(struct vm_struct *area);
-
 /* for /dev/kmem */
 extern long vread(char *buf, char *addr, unsigned long count);
 extern long vwrite(char *buf, char *addr, unsigned long count);
diff --git a/mm/nommu.c b/mm/nommu.c
index 75a327149af127..9272f30e4c4726 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -354,13 +354,6 @@ void vm_unmap_aliases(void)
 }
 EXPORT_SYMBOL_GPL(vm_unmap_aliases);
 
-struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes)
-{
-	BUG();
-	return NULL;
-}
-EXPORT_SYMBOL_GPL(alloc_vm_area);
-
 void free_vm_area(struct vm_struct *area)
 {
 	BUG();
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 59f2afcf26c312..9f29147deca580 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -3077,54 +3077,6 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
 }
 EXPORT_SYMBOL(remap_vmalloc_range);
 
-static int f(pte_t *pte, unsigned long addr, void *data)
-{
-	pte_t ***p = data;
-
-	if (p) {
-		*(*p) = pte;
-		(*p)++;
-	}
-	return 0;
-}
-
-/**
- * alloc_vm_area - allocate a range of kernel address space
- * @size:	   size of the area
- * @ptes:	   returns the PTEs for the address space
- *
- * Returns:	NULL on failure, vm_struct on success
- *
- * This function reserves a range of kernel address space, and
- * allocates pagetables to map that range.  No actual mappings
- * are created.
- *
- * If @ptes is non-NULL, pointers to the PTEs (in init_mm)
- * allocated for the VM area are returned.
- */
-struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes)
-{
-	struct vm_struct *area;
-
-	area = get_vm_area_caller(size, VM_IOREMAP,
-				__builtin_return_address(0));
-	if (area == NULL)
-		return NULL;
-
-	/*
-	 * This ensures that page tables are constructed for this region
-	 * of kernel virtual address space and mapped into init_mm.
-	 */
-	if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
-				size, f, ptes ? &ptes : NULL)) {
-		free_vm_area(area);
-		return NULL;
-	}
-
-	return area;
-}
-EXPORT_SYMBOL_GPL(alloc_vm_area);
-
 void free_vm_area(struct vm_struct *area)
 {
 	struct vm_struct *ret;
-- 
2.28.0


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

* [Intel-gfx] [PATCH 6/6] x86/xen: open code alloc_vm_area in arch_gnttab_valloc
@ 2020-09-18 16:37   ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-18 16:37 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Boris Ostrovsky, Nitin Gupta

Open code alloc_vm_area in the last remaining caller.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/x86/xen/grant-table.c | 27 +++++++++++++++------
 include/linux/vmalloc.h    |  5 +---
 mm/nommu.c                 |  7 ------
 mm/vmalloc.c               | 48 --------------------------------------
 4 files changed, 21 insertions(+), 66 deletions(-)

diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c
index 4988e19598c8a5..ccb377c07c651f 100644
--- a/arch/x86/xen/grant-table.c
+++ b/arch/x86/xen/grant-table.c
@@ -90,19 +90,32 @@ void arch_gnttab_unmap(void *shared, unsigned long nr_gframes)
 	}
 }
 
+static int gnttab_apply(pte_t *pte, unsigned long addr, void *data)
+{
+	pte_t ***p = data;
+
+	**p = pte;
+	(*p)++;
+	return 0;
+}
+
 static int arch_gnttab_valloc(struct gnttab_vm_area *area, unsigned nr_frames)
 {
 	area->ptes = kmalloc_array(nr_frames, sizeof(*area->ptes), GFP_KERNEL);
 	if (area->ptes == NULL)
 		return -ENOMEM;
-
-	area->area = alloc_vm_area(PAGE_SIZE * nr_frames, area->ptes);
-	if (area->area == NULL) {
-		kfree(area->ptes);
-		return -ENOMEM;
-	}
-
+	area->area = get_vm_area(PAGE_SIZE * nr_frames, VM_IOREMAP);
+	if (!area->area)
+		goto out_free_ptes;
+	if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
+			PAGE_SIZE * nr_frames, gnttab_apply, &area->ptes))
+		goto out_free_vm_area;
 	return 0;
+out_free_vm_area:
+	free_vm_area(area->area);
+out_free_ptes:
+	kfree(area->ptes);
+	return -ENOMEM;
 }
 
 static void arch_gnttab_vfree(struct gnttab_vm_area *area)
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 8ecd92a947ee0c..a1a4e2f8163504 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -168,6 +168,7 @@ extern struct vm_struct *__get_vm_area_caller(unsigned long size,
 					unsigned long flags,
 					unsigned long start, unsigned long end,
 					const void *caller);
+void free_vm_area(struct vm_struct *area);
 extern struct vm_struct *remove_vm_area(const void *addr);
 extern struct vm_struct *find_vm_area(const void *addr);
 
@@ -203,10 +204,6 @@ static inline void set_vm_flush_reset_perms(void *addr)
 }
 #endif
 
-/* Allocate/destroy a 'vmalloc' VM area. */
-extern struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes);
-extern void free_vm_area(struct vm_struct *area);
-
 /* for /dev/kmem */
 extern long vread(char *buf, char *addr, unsigned long count);
 extern long vwrite(char *buf, char *addr, unsigned long count);
diff --git a/mm/nommu.c b/mm/nommu.c
index 75a327149af127..9272f30e4c4726 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -354,13 +354,6 @@ void vm_unmap_aliases(void)
 }
 EXPORT_SYMBOL_GPL(vm_unmap_aliases);
 
-struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes)
-{
-	BUG();
-	return NULL;
-}
-EXPORT_SYMBOL_GPL(alloc_vm_area);
-
 void free_vm_area(struct vm_struct *area)
 {
 	BUG();
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 59f2afcf26c312..9f29147deca580 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -3077,54 +3077,6 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
 }
 EXPORT_SYMBOL(remap_vmalloc_range);
 
-static int f(pte_t *pte, unsigned long addr, void *data)
-{
-	pte_t ***p = data;
-
-	if (p) {
-		*(*p) = pte;
-		(*p)++;
-	}
-	return 0;
-}
-
-/**
- * alloc_vm_area - allocate a range of kernel address space
- * @size:	   size of the area
- * @ptes:	   returns the PTEs for the address space
- *
- * Returns:	NULL on failure, vm_struct on success
- *
- * This function reserves a range of kernel address space, and
- * allocates pagetables to map that range.  No actual mappings
- * are created.
- *
- * If @ptes is non-NULL, pointers to the PTEs (in init_mm)
- * allocated for the VM area are returned.
- */
-struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes)
-{
-	struct vm_struct *area;
-
-	area = get_vm_area_caller(size, VM_IOREMAP,
-				__builtin_return_address(0));
-	if (area == NULL)
-		return NULL;
-
-	/*
-	 * This ensures that page tables are constructed for this region
-	 * of kernel virtual address space and mapped into init_mm.
-	 */
-	if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
-				size, f, ptes ? &ptes : NULL)) {
-		free_vm_area(area);
-		return NULL;
-	}
-
-	return area;
-}
-EXPORT_SYMBOL_GPL(alloc_vm_area);
-
 void free_vm_area(struct vm_struct *area)
 {
 	struct vm_struct *ret;
-- 
2.28.0

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

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

* [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area
  2020-09-18 16:37 ` [Intel-gfx] " Christoph Hellwig
                   ` (6 preceding siblings ...)
  (?)
@ 2020-09-18 17:03 ` Patchwork
  -1 siblings, 0 replies; 85+ messages in thread
From: Patchwork @ 2020-09-18 17:03 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area
URL   : https://patchwork.freedesktop.org/series/81855/
State : failure

== Summary ==

Applying: zsmalloc: switch from alloc_vm_area to get_vm_area
Applying: mm: add a vmap_pfn function
Applying: drm/i915: use vmap in shmem_pin_map
Applying: drm/i915: use vmap in i915_gem_object_map
Using index info to reconstruct a base tree...
M	drivers/gpu/drm/i915/gem/i915_gem_pages.c
Falling back to patching base and 3-way merge...
Auto-merging drivers/gpu/drm/i915/gem/i915_gem_pages.c
CONFLICT (content): Merge conflict in drivers/gpu/drm/i915/gem/i915_gem_pages.c
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0004 drm/i915: use vmap in i915_gem_object_map
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".


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

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

* Re: [PATCH 1/6] zsmalloc: switch from alloc_vm_area to get_vm_area
  2020-09-18 16:37   ` [Intel-gfx] " Christoph Hellwig
  (?)
@ 2020-09-21 17:42     ` Minchan Kim
  -1 siblings, 0 replies; 85+ messages in thread
From: Minchan Kim @ 2020-09-21 17:42 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, Peter Zijlstra, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Nitin Gupta, x86, xen-devel, linux-kernel, intel-gfx, dri-devel,
	linux-mm

On Fri, Sep 18, 2020 at 06:37:19PM +0200, Christoph Hellwig wrote:
> There is no obvious reason why zsmalloc needs to pre-fault the PTEs
> given that it later uses map_kernel_range to just like vmap().

IIRC, the problem was runtime pte popluating needs GFP_KERNEL but
zs_map_object API runs under non-preemtible section.

> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  mm/zsmalloc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
> index c36fdff9a37131..3e4fe3259612fd 100644
> --- a/mm/zsmalloc.c
> +++ b/mm/zsmalloc.c
> @@ -1122,7 +1122,7 @@ static inline int __zs_cpu_up(struct mapping_area *area)
>  	 */
>  	if (area->vm)
>  		return 0;
> -	area->vm = alloc_vm_area(PAGE_SIZE * 2, NULL);
> +	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
>  	if (!area->vm)
>  		return -ENOMEM;
>  	return 0;

I think it shoud work.

diff --git a/mm/memory.c b/mm/memory.c
index 05789aa4af12..6a1e4d854593 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2232,7 +2232,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
 	arch_enter_lazy_mmu_mode();
 
 	do {
-		if (create || !pte_none(*pte)) {
+		if ((create || !pte_none(*pte)) && fn) {
 			err = fn(pte++, addr, data);
 			if (err)
 				break;
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 3e4fe3259612..9ef7daf3d279 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -1116,6 +1116,8 @@ static struct zspage *find_get_zspage(struct size_class *class)
 #ifdef CONFIG_ZSMALLOC_PGTABLE_MAPPING
 static inline int __zs_cpu_up(struct mapping_area *area)
 {
+	int ret;
+
 	/*
 	 * Make sure we don't leak memory if a cpu UP notification
 	 * and zs_init() race and both call zs_cpu_up() on the same cpu
@@ -1125,7 +1127,13 @@ static inline int __zs_cpu_up(struct mapping_area *area)
 	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
 	if (!area->vm)
 		return -ENOMEM;
-	return 0;
+
+	/*
+	 * Populate ptes in advance to avoid pte allocation with GFP_KERNEL
+	 * in non-preemtible context of zs_map_object.
+	 */
+	ret = apply_to_page_range(&init_mm, NULL, PAGE_SIZE * 2, NULL, NULL);
+	return ret;
 }
 
 static inline void __zs_cpu_down(struct mapping_area *area)


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

* Re: [PATCH 1/6] zsmalloc: switch from alloc_vm_area to get_vm_area
@ 2020-09-21 17:42     ` Minchan Kim
  0 siblings, 0 replies; 85+ messages in thread
From: Minchan Kim @ 2020-09-21 17:42 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, Peter Zijlstra, intel-gfx,
	x86, linux-kernel, linux-mm, dri-devel, Rodrigo Vivi, xen-devel,
	Andrew Morton, Boris Ostrovsky, Nitin Gupta

On Fri, Sep 18, 2020 at 06:37:19PM +0200, Christoph Hellwig wrote:
> There is no obvious reason why zsmalloc needs to pre-fault the PTEs
> given that it later uses map_kernel_range to just like vmap().

IIRC, the problem was runtime pte popluating needs GFP_KERNEL but
zs_map_object API runs under non-preemtible section.

> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  mm/zsmalloc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
> index c36fdff9a37131..3e4fe3259612fd 100644
> --- a/mm/zsmalloc.c
> +++ b/mm/zsmalloc.c
> @@ -1122,7 +1122,7 @@ static inline int __zs_cpu_up(struct mapping_area *area)
>  	 */
>  	if (area->vm)
>  		return 0;
> -	area->vm = alloc_vm_area(PAGE_SIZE * 2, NULL);
> +	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
>  	if (!area->vm)
>  		return -ENOMEM;
>  	return 0;

I think it shoud work.

diff --git a/mm/memory.c b/mm/memory.c
index 05789aa4af12..6a1e4d854593 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2232,7 +2232,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
 	arch_enter_lazy_mmu_mode();
 
 	do {
-		if (create || !pte_none(*pte)) {
+		if ((create || !pte_none(*pte)) && fn) {
 			err = fn(pte++, addr, data);
 			if (err)
 				break;
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 3e4fe3259612..9ef7daf3d279 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -1116,6 +1116,8 @@ static struct zspage *find_get_zspage(struct size_class *class)
 #ifdef CONFIG_ZSMALLOC_PGTABLE_MAPPING
 static inline int __zs_cpu_up(struct mapping_area *area)
 {
+	int ret;
+
 	/*
 	 * Make sure we don't leak memory if a cpu UP notification
 	 * and zs_init() race and both call zs_cpu_up() on the same cpu
@@ -1125,7 +1127,13 @@ static inline int __zs_cpu_up(struct mapping_area *area)
 	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
 	if (!area->vm)
 		return -ENOMEM;
-	return 0;
+
+	/*
+	 * Populate ptes in advance to avoid pte allocation with GFP_KERNEL
+	 * in non-preemtible context of zs_map_object.
+	 */
+	ret = apply_to_page_range(&init_mm, NULL, PAGE_SIZE * 2, NULL, NULL);
+	return ret;
 }
 
 static inline void __zs_cpu_down(struct mapping_area *area)

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 1/6] zsmalloc: switch from alloc_vm_area to get_vm_area
@ 2020-09-21 17:42     ` Minchan Kim
  0 siblings, 0 replies; 85+ messages in thread
From: Minchan Kim @ 2020-09-21 17:42 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, Peter Zijlstra, intel-gfx,
	x86, linux-kernel, linux-mm, dri-devel, xen-devel, Andrew Morton,
	Boris Ostrovsky, Nitin Gupta

On Fri, Sep 18, 2020 at 06:37:19PM +0200, Christoph Hellwig wrote:
> There is no obvious reason why zsmalloc needs to pre-fault the PTEs
> given that it later uses map_kernel_range to just like vmap().

IIRC, the problem was runtime pte popluating needs GFP_KERNEL but
zs_map_object API runs under non-preemtible section.

> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  mm/zsmalloc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
> index c36fdff9a37131..3e4fe3259612fd 100644
> --- a/mm/zsmalloc.c
> +++ b/mm/zsmalloc.c
> @@ -1122,7 +1122,7 @@ static inline int __zs_cpu_up(struct mapping_area *area)
>  	 */
>  	if (area->vm)
>  		return 0;
> -	area->vm = alloc_vm_area(PAGE_SIZE * 2, NULL);
> +	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
>  	if (!area->vm)
>  		return -ENOMEM;
>  	return 0;

I think it shoud work.

diff --git a/mm/memory.c b/mm/memory.c
index 05789aa4af12..6a1e4d854593 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2232,7 +2232,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
 	arch_enter_lazy_mmu_mode();
 
 	do {
-		if (create || !pte_none(*pte)) {
+		if ((create || !pte_none(*pte)) && fn) {
 			err = fn(pte++, addr, data);
 			if (err)
 				break;
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 3e4fe3259612..9ef7daf3d279 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -1116,6 +1116,8 @@ static struct zspage *find_get_zspage(struct size_class *class)
 #ifdef CONFIG_ZSMALLOC_PGTABLE_MAPPING
 static inline int __zs_cpu_up(struct mapping_area *area)
 {
+	int ret;
+
 	/*
 	 * Make sure we don't leak memory if a cpu UP notification
 	 * and zs_init() race and both call zs_cpu_up() on the same cpu
@@ -1125,7 +1127,13 @@ static inline int __zs_cpu_up(struct mapping_area *area)
 	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
 	if (!area->vm)
 		return -ENOMEM;
-	return 0;
+
+	/*
+	 * Populate ptes in advance to avoid pte allocation with GFP_KERNEL
+	 * in non-preemtible context of zs_map_object.
+	 */
+	ret = apply_to_page_range(&init_mm, NULL, PAGE_SIZE * 2, NULL, NULL);
+	return ret;
 }
 
 static inline void __zs_cpu_down(struct mapping_area *area)

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

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

* [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area (rev2)
  2020-09-18 16:37 ` [Intel-gfx] " Christoph Hellwig
                   ` (7 preceding siblings ...)
  (?)
@ 2020-09-21 17:50 ` Patchwork
  -1 siblings, 0 replies; 85+ messages in thread
From: Patchwork @ 2020-09-21 17:50 UTC (permalink / raw)
  To: Minchan Kim; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area (rev2)
URL   : https://patchwork.freedesktop.org/series/81855/
State : failure

== Summary ==

Applying: zsmalloc: switch from alloc_vm_area to get_vm_area
error: sha1 information is lacking or useless (mm/memory.c).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0001 zsmalloc: switch from alloc_vm_area to get_vm_area
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".


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

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

* Re: [PATCH 1/6] zsmalloc: switch from alloc_vm_area to get_vm_area
  2020-09-21 17:42     ` Minchan Kim
@ 2020-09-21 18:17       ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-21 18:17 UTC (permalink / raw)
  To: Minchan Kim
  Cc: Christoph Hellwig, Andrew Morton, Peter Zijlstra,
	Boris Ostrovsky, Juergen Gross, Stefano Stabellini, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Nitin Gupta, x86, xen-devel,
	linux-kernel, intel-gfx, dri-devel, linux-mm

On Mon, Sep 21, 2020 at 10:42:56AM -0700, Minchan Kim wrote:
> IIRC, the problem was runtime pte popluating needs GFP_KERNEL but
> zs_map_object API runs under non-preemtible section.

Make sense.

> > -	area->vm = alloc_vm_area(PAGE_SIZE * 2, NULL);
> > +	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
> >  	if (!area->vm)
> >  		return -ENOMEM;
> >  	return 0;
> 
> I think it shoud work.
> 
> diff --git a/mm/memory.c b/mm/memory.c
> index 05789aa4af12..6a1e4d854593 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -2232,7 +2232,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
>  	arch_enter_lazy_mmu_mode();
>  
>  	do {
> -		if (create || !pte_none(*pte)) {
> +		if ((create || !pte_none(*pte)) && fn) {
>  			err = fn(pte++, addr, data);
>  			if (err)
>  				break;
> diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
> index 3e4fe3259612..9ef7daf3d279 100644
> --- a/mm/zsmalloc.c
> +++ b/mm/zsmalloc.c
> @@ -1116,6 +1116,8 @@ static struct zspage *find_get_zspage(struct size_class *class)
>  #ifdef CONFIG_ZSMALLOC_PGTABLE_MAPPING
>  static inline int __zs_cpu_up(struct mapping_area *area)
>  {
> +	int ret;
> +
>  	/*
>  	 * Make sure we don't leak memory if a cpu UP notification
>  	 * and zs_init() race and both call zs_cpu_up() on the same cpu
> @@ -1125,7 +1127,13 @@ static inline int __zs_cpu_up(struct mapping_area *area)
>  	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
>  	if (!area->vm)
>  		return -ENOMEM;
> -	return 0;
> +
> +	/*
> +	 * Populate ptes in advance to avoid pte allocation with GFP_KERNEL
> +	 * in non-preemtible context of zs_map_object.
> +	 */
> +	ret = apply_to_page_range(&init_mm, NULL, PAGE_SIZE * 2, NULL, NULL);
> +	return ret;

I think this needs the addr from the vm area somewhere..

We probaby want to add a trivial helper to prefault an area instead of
the open coded variant.

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

* Re: [Intel-gfx] [PATCH 1/6] zsmalloc: switch from alloc_vm_area to get_vm_area
@ 2020-09-21 18:17       ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-21 18:17 UTC (permalink / raw)
  To: Minchan Kim
  Cc: Juergen Gross, Stefano Stabellini, Peter Zijlstra,
	Boris Ostrovsky, x86, linux-kernel, linux-mm, dri-devel,
	xen-devel, Andrew Morton, intel-gfx, Christoph Hellwig,
	Nitin Gupta

On Mon, Sep 21, 2020 at 10:42:56AM -0700, Minchan Kim wrote:
> IIRC, the problem was runtime pte popluating needs GFP_KERNEL but
> zs_map_object API runs under non-preemtible section.

Make sense.

> > -	area->vm = alloc_vm_area(PAGE_SIZE * 2, NULL);
> > +	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
> >  	if (!area->vm)
> >  		return -ENOMEM;
> >  	return 0;
> 
> I think it shoud work.
> 
> diff --git a/mm/memory.c b/mm/memory.c
> index 05789aa4af12..6a1e4d854593 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -2232,7 +2232,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
>  	arch_enter_lazy_mmu_mode();
>  
>  	do {
> -		if (create || !pte_none(*pte)) {
> +		if ((create || !pte_none(*pte)) && fn) {
>  			err = fn(pte++, addr, data);
>  			if (err)
>  				break;
> diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
> index 3e4fe3259612..9ef7daf3d279 100644
> --- a/mm/zsmalloc.c
> +++ b/mm/zsmalloc.c
> @@ -1116,6 +1116,8 @@ static struct zspage *find_get_zspage(struct size_class *class)
>  #ifdef CONFIG_ZSMALLOC_PGTABLE_MAPPING
>  static inline int __zs_cpu_up(struct mapping_area *area)
>  {
> +	int ret;
> +
>  	/*
>  	 * Make sure we don't leak memory if a cpu UP notification
>  	 * and zs_init() race and both call zs_cpu_up() on the same cpu
> @@ -1125,7 +1127,13 @@ static inline int __zs_cpu_up(struct mapping_area *area)
>  	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
>  	if (!area->vm)
>  		return -ENOMEM;
> -	return 0;
> +
> +	/*
> +	 * Populate ptes in advance to avoid pte allocation with GFP_KERNEL
> +	 * in non-preemtible context of zs_map_object.
> +	 */
> +	ret = apply_to_page_range(&init_mm, NULL, PAGE_SIZE * 2, NULL, NULL);
> +	return ret;

I think this needs the addr from the vm area somewhere..

We probaby want to add a trivial helper to prefault an area instead of
the open coded variant.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 1/6] zsmalloc: switch from alloc_vm_area to get_vm_area
  2020-09-21 18:17       ` [Intel-gfx] " Christoph Hellwig
  (?)
@ 2020-09-21 18:42         ` Minchan Kim
  -1 siblings, 0 replies; 85+ messages in thread
From: Minchan Kim @ 2020-09-21 18:42 UTC (permalink / raw)
  To: Christoph Hellwig, Andrew Morton
  Cc: Andrew Morton, Peter Zijlstra, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Nitin Gupta, x86, xen-devel, linux-kernel, intel-gfx, dri-devel,
	linux-mm

On Mon, Sep 21, 2020 at 08:17:08PM +0200, Christoph Hellwig wrote:
> On Mon, Sep 21, 2020 at 10:42:56AM -0700, Minchan Kim wrote:
> > IIRC, the problem was runtime pte popluating needs GFP_KERNEL but
> > zs_map_object API runs under non-preemtible section.
> 
> Make sense.
> 
> > > -	area->vm = alloc_vm_area(PAGE_SIZE * 2, NULL);
> > > +	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
> > >  	if (!area->vm)
> > >  		return -ENOMEM;
> > >  	return 0;
> > 
> > I think it shoud work.
> > 
> > diff --git a/mm/memory.c b/mm/memory.c
> > index 05789aa4af12..6a1e4d854593 100644
> > --- a/mm/memory.c
> > +++ b/mm/memory.c
> > @@ -2232,7 +2232,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
> >  	arch_enter_lazy_mmu_mode();
> >  
> >  	do {
> > -		if (create || !pte_none(*pte)) {
> > +		if ((create || !pte_none(*pte)) && fn) {
> >  			err = fn(pte++, addr, data);
> >  			if (err)
> >  				break;
> > diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
> > index 3e4fe3259612..9ef7daf3d279 100644
> > --- a/mm/zsmalloc.c
> > +++ b/mm/zsmalloc.c
> > @@ -1116,6 +1116,8 @@ static struct zspage *find_get_zspage(struct size_class *class)
> >  #ifdef CONFIG_ZSMALLOC_PGTABLE_MAPPING
> >  static inline int __zs_cpu_up(struct mapping_area *area)
> >  {
> > +	int ret;
> > +
> >  	/*
> >  	 * Make sure we don't leak memory if a cpu UP notification
> >  	 * and zs_init() race and both call zs_cpu_up() on the same cpu
> > @@ -1125,7 +1127,13 @@ static inline int __zs_cpu_up(struct mapping_area *area)
> >  	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
> >  	if (!area->vm)
> >  		return -ENOMEM;
> > -	return 0;
> > +
> > +	/*
> > +	 * Populate ptes in advance to avoid pte allocation with GFP_KERNEL
> > +	 * in non-preemtible context of zs_map_object.
> > +	 */
> > +	ret = apply_to_page_range(&init_mm, NULL, PAGE_SIZE * 2, NULL, NULL);
> > +	return ret;
> 
> I think this needs the addr from the vm area somewhere..

Yeah, let's assign the addres we got get_vm_area.

> 
> We probaby want to add a trivial helper to prefault an area instead of
> the open coded variant.

It seems zsmalloc is only customer the function so let's have the helper
when we see another customer.

If we don't have objection, I'd like to ask to Andrew fold this up.

---
 mm/memory.c   | 2 +-
 mm/zsmalloc.c | 8 +++++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/mm/memory.c b/mm/memory.c
index 05789aa4af12..6a1e4d854593 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2232,7 +2232,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
 	arch_enter_lazy_mmu_mode();
 
 	do {
-		if (create || !pte_none(*pte)) {
+		if ((create || !pte_none(*pte)) && fn) {
 			err = fn(pte++, addr, data);
 			if (err)
 				break;
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 3e4fe3259612..918c7b019b3d 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -1125,7 +1125,13 @@ static inline int __zs_cpu_up(struct mapping_area *area)
 	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
 	if (!area->vm)
 		return -ENOMEM;
-	return 0;
+
+	/*
+	 * Populate ptes in advance to avoid pte allocation with GFP_KERNEL
+	 * in non-preemtible context of zs_map_object.
+	 */
+	return apply_to_page_range(&init_mm, (unsigned long)area->vm->addr,
+			PAGE_SIZE * 2, NULL, NULL);
 }
 
 static inline void __zs_cpu_down(struct mapping_area *area)
-- 
2.28.0.681.g6f77f65b4e-goog


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

* Re: [PATCH 1/6] zsmalloc: switch from alloc_vm_area to get_vm_area
@ 2020-09-21 18:42         ` Minchan Kim
  0 siblings, 0 replies; 85+ messages in thread
From: Minchan Kim @ 2020-09-21 18:42 UTC (permalink / raw)
  To: Christoph Hellwig, Andrew Morton
  Cc: Juergen Gross, Stefano Stabellini, Peter Zijlstra, intel-gfx,
	x86, linux-kernel, linux-mm, dri-devel, Rodrigo Vivi, xen-devel,
	Andrew Morton, Boris Ostrovsky, Nitin Gupta

On Mon, Sep 21, 2020 at 08:17:08PM +0200, Christoph Hellwig wrote:
> On Mon, Sep 21, 2020 at 10:42:56AM -0700, Minchan Kim wrote:
> > IIRC, the problem was runtime pte popluating needs GFP_KERNEL but
> > zs_map_object API runs under non-preemtible section.
> 
> Make sense.
> 
> > > -	area->vm = alloc_vm_area(PAGE_SIZE * 2, NULL);
> > > +	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
> > >  	if (!area->vm)
> > >  		return -ENOMEM;
> > >  	return 0;
> > 
> > I think it shoud work.
> > 
> > diff --git a/mm/memory.c b/mm/memory.c
> > index 05789aa4af12..6a1e4d854593 100644
> > --- a/mm/memory.c
> > +++ b/mm/memory.c
> > @@ -2232,7 +2232,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
> >  	arch_enter_lazy_mmu_mode();
> >  
> >  	do {
> > -		if (create || !pte_none(*pte)) {
> > +		if ((create || !pte_none(*pte)) && fn) {
> >  			err = fn(pte++, addr, data);
> >  			if (err)
> >  				break;
> > diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
> > index 3e4fe3259612..9ef7daf3d279 100644
> > --- a/mm/zsmalloc.c
> > +++ b/mm/zsmalloc.c
> > @@ -1116,6 +1116,8 @@ static struct zspage *find_get_zspage(struct size_class *class)
> >  #ifdef CONFIG_ZSMALLOC_PGTABLE_MAPPING
> >  static inline int __zs_cpu_up(struct mapping_area *area)
> >  {
> > +	int ret;
> > +
> >  	/*
> >  	 * Make sure we don't leak memory if a cpu UP notification
> >  	 * and zs_init() race and both call zs_cpu_up() on the same cpu
> > @@ -1125,7 +1127,13 @@ static inline int __zs_cpu_up(struct mapping_area *area)
> >  	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
> >  	if (!area->vm)
> >  		return -ENOMEM;
> > -	return 0;
> > +
> > +	/*
> > +	 * Populate ptes in advance to avoid pte allocation with GFP_KERNEL
> > +	 * in non-preemtible context of zs_map_object.
> > +	 */
> > +	ret = apply_to_page_range(&init_mm, NULL, PAGE_SIZE * 2, NULL, NULL);
> > +	return ret;
> 
> I think this needs the addr from the vm area somewhere..

Yeah, let's assign the addres we got get_vm_area.

> 
> We probaby want to add a trivial helper to prefault an area instead of
> the open coded variant.

It seems zsmalloc is only customer the function so let's have the helper
when we see another customer.

If we don't have objection, I'd like to ask to Andrew fold this up.

---
 mm/memory.c   | 2 +-
 mm/zsmalloc.c | 8 +++++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/mm/memory.c b/mm/memory.c
index 05789aa4af12..6a1e4d854593 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2232,7 +2232,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
 	arch_enter_lazy_mmu_mode();
 
 	do {
-		if (create || !pte_none(*pte)) {
+		if ((create || !pte_none(*pte)) && fn) {
 			err = fn(pte++, addr, data);
 			if (err)
 				break;
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 3e4fe3259612..918c7b019b3d 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -1125,7 +1125,13 @@ static inline int __zs_cpu_up(struct mapping_area *area)
 	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
 	if (!area->vm)
 		return -ENOMEM;
-	return 0;
+
+	/*
+	 * Populate ptes in advance to avoid pte allocation with GFP_KERNEL
+	 * in non-preemtible context of zs_map_object.
+	 */
+	return apply_to_page_range(&init_mm, (unsigned long)area->vm->addr,
+			PAGE_SIZE * 2, NULL, NULL);
 }
 
 static inline void __zs_cpu_down(struct mapping_area *area)
-- 
2.28.0.681.g6f77f65b4e-goog

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 1/6] zsmalloc: switch from alloc_vm_area to get_vm_area
@ 2020-09-21 18:42         ` Minchan Kim
  0 siblings, 0 replies; 85+ messages in thread
From: Minchan Kim @ 2020-09-21 18:42 UTC (permalink / raw)
  To: Christoph Hellwig, Andrew Morton
  Cc: Juergen Gross, Stefano Stabellini, Peter Zijlstra, intel-gfx,
	x86, linux-kernel, linux-mm, dri-devel, xen-devel, Andrew Morton,
	Boris Ostrovsky, Nitin Gupta

On Mon, Sep 21, 2020 at 08:17:08PM +0200, Christoph Hellwig wrote:
> On Mon, Sep 21, 2020 at 10:42:56AM -0700, Minchan Kim wrote:
> > IIRC, the problem was runtime pte popluating needs GFP_KERNEL but
> > zs_map_object API runs under non-preemtible section.
> 
> Make sense.
> 
> > > -	area->vm = alloc_vm_area(PAGE_SIZE * 2, NULL);
> > > +	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
> > >  	if (!area->vm)
> > >  		return -ENOMEM;
> > >  	return 0;
> > 
> > I think it shoud work.
> > 
> > diff --git a/mm/memory.c b/mm/memory.c
> > index 05789aa4af12..6a1e4d854593 100644
> > --- a/mm/memory.c
> > +++ b/mm/memory.c
> > @@ -2232,7 +2232,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
> >  	arch_enter_lazy_mmu_mode();
> >  
> >  	do {
> > -		if (create || !pte_none(*pte)) {
> > +		if ((create || !pte_none(*pte)) && fn) {
> >  			err = fn(pte++, addr, data);
> >  			if (err)
> >  				break;
> > diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
> > index 3e4fe3259612..9ef7daf3d279 100644
> > --- a/mm/zsmalloc.c
> > +++ b/mm/zsmalloc.c
> > @@ -1116,6 +1116,8 @@ static struct zspage *find_get_zspage(struct size_class *class)
> >  #ifdef CONFIG_ZSMALLOC_PGTABLE_MAPPING
> >  static inline int __zs_cpu_up(struct mapping_area *area)
> >  {
> > +	int ret;
> > +
> >  	/*
> >  	 * Make sure we don't leak memory if a cpu UP notification
> >  	 * and zs_init() race and both call zs_cpu_up() on the same cpu
> > @@ -1125,7 +1127,13 @@ static inline int __zs_cpu_up(struct mapping_area *area)
> >  	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
> >  	if (!area->vm)
> >  		return -ENOMEM;
> > -	return 0;
> > +
> > +	/*
> > +	 * Populate ptes in advance to avoid pte allocation with GFP_KERNEL
> > +	 * in non-preemtible context of zs_map_object.
> > +	 */
> > +	ret = apply_to_page_range(&init_mm, NULL, PAGE_SIZE * 2, NULL, NULL);
> > +	return ret;
> 
> I think this needs the addr from the vm area somewhere..

Yeah, let's assign the addres we got get_vm_area.

> 
> We probaby want to add a trivial helper to prefault an area instead of
> the open coded variant.

It seems zsmalloc is only customer the function so let's have the helper
when we see another customer.

If we don't have objection, I'd like to ask to Andrew fold this up.

---
 mm/memory.c   | 2 +-
 mm/zsmalloc.c | 8 +++++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/mm/memory.c b/mm/memory.c
index 05789aa4af12..6a1e4d854593 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2232,7 +2232,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
 	arch_enter_lazy_mmu_mode();
 
 	do {
-		if (create || !pte_none(*pte)) {
+		if ((create || !pte_none(*pte)) && fn) {
 			err = fn(pte++, addr, data);
 			if (err)
 				break;
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 3e4fe3259612..918c7b019b3d 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -1125,7 +1125,13 @@ static inline int __zs_cpu_up(struct mapping_area *area)
 	area->vm = get_vm_area(PAGE_SIZE * 2, 0);
 	if (!area->vm)
 		return -ENOMEM;
-	return 0;
+
+	/*
+	 * Populate ptes in advance to avoid pte allocation with GFP_KERNEL
+	 * in non-preemtible context of zs_map_object.
+	 */
+	return apply_to_page_range(&init_mm, (unsigned long)area->vm->addr,
+			PAGE_SIZE * 2, NULL, NULL);
 }
 
 static inline void __zs_cpu_down(struct mapping_area *area)
-- 
2.28.0.681.g6f77f65b4e-goog

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

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

* Re: [PATCH 1/6] zsmalloc: switch from alloc_vm_area to get_vm_area
  2020-09-21 18:42         ` Minchan Kim
@ 2020-09-21 18:43           ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-21 18:43 UTC (permalink / raw)
  To: Minchan Kim
  Cc: Christoph Hellwig, Andrew Morton, Peter Zijlstra,
	Boris Ostrovsky, Juergen Gross, Stefano Stabellini, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Nitin Gupta, x86, xen-devel,
	linux-kernel, intel-gfx, dri-devel, linux-mm

On Mon, Sep 21, 2020 at 11:42:29AM -0700, Minchan Kim wrote:
> It seems zsmalloc is only customer the function so let's have the helper
> when we see another customer.
> 
> If we don't have objection, I'd like to ask to Andrew fold this up.

Fine with me.

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

* Re: [Intel-gfx] [PATCH 1/6] zsmalloc: switch from alloc_vm_area to get_vm_area
@ 2020-09-21 18:43           ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-21 18:43 UTC (permalink / raw)
  To: Minchan Kim
  Cc: Juergen Gross, Stefano Stabellini, Peter Zijlstra,
	Boris Ostrovsky, x86, linux-kernel, linux-mm, dri-devel,
	xen-devel, Andrew Morton, intel-gfx, Christoph Hellwig,
	Nitin Gupta

On Mon, Sep 21, 2020 at 11:42:29AM -0700, Minchan Kim wrote:
> It seems zsmalloc is only customer the function so let's have the helper
> when we see another customer.
> 
> If we don't have objection, I'd like to ask to Andrew fold this up.

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

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

* [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area (rev3)
  2020-09-18 16:37 ` [Intel-gfx] " Christoph Hellwig
                   ` (8 preceding siblings ...)
  (?)
@ 2020-09-21 18:47 ` Patchwork
  -1 siblings, 0 replies; 85+ messages in thread
From: Patchwork @ 2020-09-21 18:47 UTC (permalink / raw)
  To: Minchan Kim; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area (rev3)
URL   : https://patchwork.freedesktop.org/series/81855/
State : failure

== Summary ==

Applying: zsmalloc: switch from alloc_vm_area to get_vm_area
error: sha1 information is lacking or useless (mm/memory.c).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0001 zsmalloc: switch from alloc_vm_area to get_vm_area
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".


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

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

* Re: [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
  2020-09-18 16:37   ` [Intel-gfx] " Christoph Hellwig
  (?)
@ 2020-09-21 19:11     ` Matthew Wilcox
  -1 siblings, 0 replies; 85+ messages in thread
From: Matthew Wilcox @ 2020-09-21 19:11 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, Peter Zijlstra, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Minchan Kim, Nitin Gupta, x86, xen-devel, linux-kernel,
	intel-gfx, dri-devel, linux-mm

On Fri, Sep 18, 2020 at 06:37:21PM +0200, Christoph Hellwig wrote:
>  void shmem_unpin_map(struct file *file, void *ptr)
>  {
> +	long i = shmem_npages(file);
> +
>  	mapping_clear_unevictable(file->f_mapping);
> -	__shmem_unpin_map(file, ptr, shmem_npte(file));
> +	vunmap(ptr);
> +
> +	for (i = 0; i < shmem_npages(file); i++) {
> +		struct page *page;
> +
> +		page = shmem_read_mapping_page_gfp(file->f_mapping, i,
> +						   GFP_KERNEL);
> +		if (!WARN_ON(IS_ERR(page))) {
> +			put_page(page);
> +			put_page(page);
> +		}
> +	}
>  }

This is awkward.  I'd like it if we had a vfree() variant which called
put_page() instead of __free_pages().  I'd like it even more if we
used release_pages() instead of our own loop that called put_page().

Perhaps something like this ...

+++ b/mm/vmalloc.c
@@ -2262,7 +2262,7 @@ static void __vunmap(const void *addr, int deallocate_page
s)
 
        vm_remove_mappings(area, deallocate_pages);
 
-       if (deallocate_pages) {
+       if (deallocate_pages == 1) {
                int i;
 
                for (i = 0; i < area->nr_pages; i++) {
@@ -2271,8 +2271,12 @@ static void __vunmap(const void *addr, int deallocate_pages)
                        BUG_ON(!page);
                        __free_pages(page, 0);
                }
-               atomic_long_sub(area->nr_pages, &nr_vmalloc_pages);
+       } else if (deallocate_pages == 2) {
+               release_pages(area->pages, area->nr_pages);
+       }
 
+       if (deallocate_pages) {
+               atomic_long_sub(area->nr_pages, &nr_vmalloc_pages);
                kvfree(area->pages);
        }
@@ -2369,6 +2373,14 @@ void vunmap(const void *addr)
 }
 EXPORT_SYMBOL(vunmap);
 
+void vunmap_put_pages(const void *addr)
+{
+       BUG_ON(in_interrupt());
+       might_sleep();
+       if (addr)
+               __vunmap(addr, 2);
+}
+
 /**
  * vmap - map an array of pages into virtually contiguous space
  * @pages: array of page pointers

only with kernel-doc and so on.  I bet somebody has a better idea for a name.

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

* Re: [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-21 19:11     ` Matthew Wilcox
  0 siblings, 0 replies; 85+ messages in thread
From: Matthew Wilcox @ 2020-09-21 19:11 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel,
	Rodrigo Vivi, xen-devel, Andrew Morton, Boris Ostrovsky,
	Nitin Gupta

On Fri, Sep 18, 2020 at 06:37:21PM +0200, Christoph Hellwig wrote:
>  void shmem_unpin_map(struct file *file, void *ptr)
>  {
> +	long i = shmem_npages(file);
> +
>  	mapping_clear_unevictable(file->f_mapping);
> -	__shmem_unpin_map(file, ptr, shmem_npte(file));
> +	vunmap(ptr);
> +
> +	for (i = 0; i < shmem_npages(file); i++) {
> +		struct page *page;
> +
> +		page = shmem_read_mapping_page_gfp(file->f_mapping, i,
> +						   GFP_KERNEL);
> +		if (!WARN_ON(IS_ERR(page))) {
> +			put_page(page);
> +			put_page(page);
> +		}
> +	}
>  }

This is awkward.  I'd like it if we had a vfree() variant which called
put_page() instead of __free_pages().  I'd like it even more if we
used release_pages() instead of our own loop that called put_page().

Perhaps something like this ...

+++ b/mm/vmalloc.c
@@ -2262,7 +2262,7 @@ static void __vunmap(const void *addr, int deallocate_page
s)
 
        vm_remove_mappings(area, deallocate_pages);
 
-       if (deallocate_pages) {
+       if (deallocate_pages == 1) {
                int i;
 
                for (i = 0; i < area->nr_pages; i++) {
@@ -2271,8 +2271,12 @@ static void __vunmap(const void *addr, int deallocate_pages)
                        BUG_ON(!page);
                        __free_pages(page, 0);
                }
-               atomic_long_sub(area->nr_pages, &nr_vmalloc_pages);
+       } else if (deallocate_pages == 2) {
+               release_pages(area->pages, area->nr_pages);
+       }
 
+       if (deallocate_pages) {
+               atomic_long_sub(area->nr_pages, &nr_vmalloc_pages);
                kvfree(area->pages);
        }
@@ -2369,6 +2373,14 @@ void vunmap(const void *addr)
 }
 EXPORT_SYMBOL(vunmap);
 
+void vunmap_put_pages(const void *addr)
+{
+       BUG_ON(in_interrupt());
+       might_sleep();
+       if (addr)
+               __vunmap(addr, 2);
+}
+
 /**
  * vmap - map an array of pages into virtually contiguous space
  * @pages: array of page pointers

only with kernel-doc and so on.  I bet somebody has a better idea for a name.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-21 19:11     ` Matthew Wilcox
  0 siblings, 0 replies; 85+ messages in thread
From: Matthew Wilcox @ 2020-09-21 19:11 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Andrew Morton, Boris Ostrovsky, Nitin Gupta

On Fri, Sep 18, 2020 at 06:37:21PM +0200, Christoph Hellwig wrote:
>  void shmem_unpin_map(struct file *file, void *ptr)
>  {
> +	long i = shmem_npages(file);
> +
>  	mapping_clear_unevictable(file->f_mapping);
> -	__shmem_unpin_map(file, ptr, shmem_npte(file));
> +	vunmap(ptr);
> +
> +	for (i = 0; i < shmem_npages(file); i++) {
> +		struct page *page;
> +
> +		page = shmem_read_mapping_page_gfp(file->f_mapping, i,
> +						   GFP_KERNEL);
> +		if (!WARN_ON(IS_ERR(page))) {
> +			put_page(page);
> +			put_page(page);
> +		}
> +	}
>  }

This is awkward.  I'd like it if we had a vfree() variant which called
put_page() instead of __free_pages().  I'd like it even more if we
used release_pages() instead of our own loop that called put_page().

Perhaps something like this ...

+++ b/mm/vmalloc.c
@@ -2262,7 +2262,7 @@ static void __vunmap(const void *addr, int deallocate_page
s)
 
        vm_remove_mappings(area, deallocate_pages);
 
-       if (deallocate_pages) {
+       if (deallocate_pages == 1) {
                int i;
 
                for (i = 0; i < area->nr_pages; i++) {
@@ -2271,8 +2271,12 @@ static void __vunmap(const void *addr, int deallocate_pages)
                        BUG_ON(!page);
                        __free_pages(page, 0);
                }
-               atomic_long_sub(area->nr_pages, &nr_vmalloc_pages);
+       } else if (deallocate_pages == 2) {
+               release_pages(area->pages, area->nr_pages);
+       }
 
+       if (deallocate_pages) {
+               atomic_long_sub(area->nr_pages, &nr_vmalloc_pages);
                kvfree(area->pages);
        }
@@ -2369,6 +2373,14 @@ void vunmap(const void *addr)
 }
 EXPORT_SYMBOL(vunmap);
 
+void vunmap_put_pages(const void *addr)
+{
+       BUG_ON(in_interrupt());
+       might_sleep();
+       if (addr)
+               __vunmap(addr, 2);
+}
+
 /**
  * vmap - map an array of pages into virtually contiguous space
  * @pages: array of page pointers

only with kernel-doc and so on.  I bet somebody has a better idea for a name.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 6/6] x86/xen: open code alloc_vm_area in arch_gnttab_valloc
  2020-09-18 16:37   ` [Intel-gfx] " Christoph Hellwig
  (?)
@ 2020-09-21 20:44     ` boris.ostrovsky
  -1 siblings, 0 replies; 85+ messages in thread
From: boris.ostrovsky @ 2020-09-21 20:44 UTC (permalink / raw)
  To: Christoph Hellwig, Andrew Morton
  Cc: Peter Zijlstra, Juergen Gross, Stefano Stabellini, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Minchan Kim, Nitin Gupta, x86,
	xen-devel, linux-kernel, intel-gfx, dri-devel, linux-mm


On 9/18/20 12:37 PM, Christoph Hellwig wrote:
>  
> +static int gnttab_apply(pte_t *pte, unsigned long addr, void *data)
> +{
> +	pte_t ***p = data;
> +
> +	**p = pte;
> +	(*p)++;
> +	return 0;
> +}
> +
>  static int arch_gnttab_valloc(struct gnttab_vm_area *area, unsigned nr_frames)
>  {
>  	area->ptes = kmalloc_array(nr_frames, sizeof(*area->ptes), GFP_KERNEL);
>  	if (area->ptes == NULL)
>  		return -ENOMEM;
> -
> -	area->area = alloc_vm_area(PAGE_SIZE * nr_frames, area->ptes);
> -	if (area->area == NULL) {
> -		kfree(area->ptes);
> -		return -ENOMEM;
> -	}
> -
> +	area->area = get_vm_area(PAGE_SIZE * nr_frames, VM_IOREMAP);
> +	if (!area->area)
> +		goto out_free_ptes;
> +	if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
> +			PAGE_SIZE * nr_frames, gnttab_apply, &area->ptes))


This will end up incrementing area->ptes pointer. So perhaps something like


pte_t **ptes = area->ptes;

if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
                        PAGE_SIZE * nr_frames, gnttab_apply, &ptes)) {

       ...

}


-boris

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

* Re: [PATCH 6/6] x86/xen: open code alloc_vm_area in arch_gnttab_valloc
@ 2020-09-21 20:44     ` boris.ostrovsky
  0 siblings, 0 replies; 85+ messages in thread
From: boris.ostrovsky @ 2020-09-21 20:44 UTC (permalink / raw)
  To: Christoph Hellwig, Andrew Morton
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel,
	Rodrigo Vivi, xen-devel, Nitin Gupta


On 9/18/20 12:37 PM, Christoph Hellwig wrote:
>  
> +static int gnttab_apply(pte_t *pte, unsigned long addr, void *data)
> +{
> +	pte_t ***p = data;
> +
> +	**p = pte;
> +	(*p)++;
> +	return 0;
> +}
> +
>  static int arch_gnttab_valloc(struct gnttab_vm_area *area, unsigned nr_frames)
>  {
>  	area->ptes = kmalloc_array(nr_frames, sizeof(*area->ptes), GFP_KERNEL);
>  	if (area->ptes == NULL)
>  		return -ENOMEM;
> -
> -	area->area = alloc_vm_area(PAGE_SIZE * nr_frames, area->ptes);
> -	if (area->area == NULL) {
> -		kfree(area->ptes);
> -		return -ENOMEM;
> -	}
> -
> +	area->area = get_vm_area(PAGE_SIZE * nr_frames, VM_IOREMAP);
> +	if (!area->area)
> +		goto out_free_ptes;
> +	if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
> +			PAGE_SIZE * nr_frames, gnttab_apply, &area->ptes))


This will end up incrementing area->ptes pointer. So perhaps something like


pte_t **ptes = area->ptes;

if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
                        PAGE_SIZE * nr_frames, gnttab_apply, &ptes)) {

       ...

}


-boris
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 6/6] x86/xen: open code alloc_vm_area in arch_gnttab_valloc
@ 2020-09-21 20:44     ` boris.ostrovsky
  0 siblings, 0 replies; 85+ messages in thread
From: boris.ostrovsky @ 2020-09-21 20:44 UTC (permalink / raw)
  To: Christoph Hellwig, Andrew Morton
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Nitin Gupta


On 9/18/20 12:37 PM, Christoph Hellwig wrote:
>  
> +static int gnttab_apply(pte_t *pte, unsigned long addr, void *data)
> +{
> +	pte_t ***p = data;
> +
> +	**p = pte;
> +	(*p)++;
> +	return 0;
> +}
> +
>  static int arch_gnttab_valloc(struct gnttab_vm_area *area, unsigned nr_frames)
>  {
>  	area->ptes = kmalloc_array(nr_frames, sizeof(*area->ptes), GFP_KERNEL);
>  	if (area->ptes == NULL)
>  		return -ENOMEM;
> -
> -	area->area = alloc_vm_area(PAGE_SIZE * nr_frames, area->ptes);
> -	if (area->area == NULL) {
> -		kfree(area->ptes);
> -		return -ENOMEM;
> -	}
> -
> +	area->area = get_vm_area(PAGE_SIZE * nr_frames, VM_IOREMAP);
> +	if (!area->area)
> +		goto out_free_ptes;
> +	if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
> +			PAGE_SIZE * nr_frames, gnttab_apply, &area->ptes))


This will end up incrementing area->ptes pointer. So perhaps something like


pte_t **ptes = area->ptes;

if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
                        PAGE_SIZE * nr_frames, gnttab_apply, &ptes)) {

       ...

}


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

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

* Re: [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
  2020-09-21 19:11     ` Matthew Wilcox
@ 2020-09-22  6:22       ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-22  6:22 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Christoph Hellwig, Andrew Morton, Peter Zijlstra,
	Boris Ostrovsky, Juergen Gross, Stefano Stabellini, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Minchan Kim, Nitin Gupta, x86,
	xen-devel, linux-kernel, intel-gfx, dri-devel, linux-mm

On Mon, Sep 21, 2020 at 08:11:57PM +0100, Matthew Wilcox wrote:
> This is awkward.  I'd like it if we had a vfree() variant which called
> put_page() instead of __free_pages().  I'd like it even more if we
> used release_pages() instead of our own loop that called put_page().

Note that we don't need a new vfree variant, we can do this manually if
we want, take a look at kernel/dma/remap.c.  But I thought this code
intentionally doesn't want to do that to avoid locking in the memory
for the pages array.  Maybe the i915 maintainers can clarify.

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-22  6:22       ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-22  6:22 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	Boris Ostrovsky, x86, linux-kernel, Minchan Kim, dri-devel,
	xen-devel, Andrew Morton, intel-gfx, Christoph Hellwig,
	Nitin Gupta

On Mon, Sep 21, 2020 at 08:11:57PM +0100, Matthew Wilcox wrote:
> This is awkward.  I'd like it if we had a vfree() variant which called
> put_page() instead of __free_pages().  I'd like it even more if we
> used release_pages() instead of our own loop that called put_page().

Note that we don't need a new vfree variant, we can do this manually if
we want, take a look at kernel/dma/remap.c.  But I thought this code
intentionally doesn't want to do that to avoid locking in the memory
for the pages array.  Maybe the i915 maintainers can clarify.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
  2020-09-22  6:22       ` [Intel-gfx] " Christoph Hellwig
  (?)
@ 2020-09-22  8:23         ` Tvrtko Ursulin
  -1 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-22  8:23 UTC (permalink / raw)
  To: Christoph Hellwig, Matthew Wilcox
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	Boris Ostrovsky, x86, linux-kernel, Minchan Kim, dri-devel,
	xen-devel, Andrew Morton, intel-gfx, Nitin Gupta, Chris Wilson,
	Matthew Auld


On 22/09/2020 07:22, Christoph Hellwig wrote:
> On Mon, Sep 21, 2020 at 08:11:57PM +0100, Matthew Wilcox wrote:
>> This is awkward.  I'd like it if we had a vfree() variant which called
>> put_page() instead of __free_pages().  I'd like it even more if we
>> used release_pages() instead of our own loop that called put_page().
> 
> Note that we don't need a new vfree variant, we can do this manually if
> we want, take a look at kernel/dma/remap.c.  But I thought this code
> intentionally doesn't want to do that to avoid locking in the memory
> for the pages array.  Maybe the i915 maintainers can clarify.

+ Chris & Matt who were involved with this part of i915.

If I understood this sub-thread correctly, iterating and freeing the 
pages via the vmapped ptes, so no need for a
shmem_read_mapping_page_gfp loop in shmem_unpin_map looks plausible to me.

I did not get the reference to kernel/dma/remap.c though, and also not 
sure how to do the error unwind path in shmem_pin_map at which point the 
allocated vm area hasn't been fully populated yet. Hand-roll the loop 
walking vm area struct in there?

Regards,

Tvrtko

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-22  8:23         ` Tvrtko Ursulin
  0 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-22  8:23 UTC (permalink / raw)
  To: Christoph Hellwig, Matthew Wilcox
  Cc: Juergen Gross, Stefano Stabellini, Minchan Kim, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, dri-devel, Chris Wilson, linux-mm,
	Matthew Auld, xen-devel, Boris Ostrovsky, Andrew Morton,
	Nitin Gupta


On 22/09/2020 07:22, Christoph Hellwig wrote:
> On Mon, Sep 21, 2020 at 08:11:57PM +0100, Matthew Wilcox wrote:
>> This is awkward.  I'd like it if we had a vfree() variant which called
>> put_page() instead of __free_pages().  I'd like it even more if we
>> used release_pages() instead of our own loop that called put_page().
> 
> Note that we don't need a new vfree variant, we can do this manually if
> we want, take a look at kernel/dma/remap.c.  But I thought this code
> intentionally doesn't want to do that to avoid locking in the memory
> for the pages array.  Maybe the i915 maintainers can clarify.

+ Chris & Matt who were involved with this part of i915.

If I understood this sub-thread correctly, iterating and freeing the 
pages via the vmapped ptes, so no need for a
shmem_read_mapping_page_gfp loop in shmem_unpin_map looks plausible to me.

I did not get the reference to kernel/dma/remap.c though, and also not 
sure how to do the error unwind path in shmem_pin_map at which point the 
allocated vm area hasn't been fully populated yet. Hand-roll the loop 
walking vm area struct in there?

Regards,

Tvrtko
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-22  8:23         ` Tvrtko Ursulin
  0 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-22  8:23 UTC (permalink / raw)
  To: Christoph Hellwig, Matthew Wilcox
  Cc: Juergen Gross, Stefano Stabellini, Minchan Kim, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, dri-devel, Chris Wilson, linux-mm,
	Matthew Auld, xen-devel, Boris Ostrovsky, Andrew Morton,
	Nitin Gupta


On 22/09/2020 07:22, Christoph Hellwig wrote:
> On Mon, Sep 21, 2020 at 08:11:57PM +0100, Matthew Wilcox wrote:
>> This is awkward.  I'd like it if we had a vfree() variant which called
>> put_page() instead of __free_pages().  I'd like it even more if we
>> used release_pages() instead of our own loop that called put_page().
> 
> Note that we don't need a new vfree variant, we can do this manually if
> we want, take a look at kernel/dma/remap.c.  But I thought this code
> intentionally doesn't want to do that to avoid locking in the memory
> for the pages array.  Maybe the i915 maintainers can clarify.

+ Chris & Matt who were involved with this part of i915.

If I understood this sub-thread correctly, iterating and freeing the 
pages via the vmapped ptes, so no need for a
shmem_read_mapping_page_gfp loop in shmem_unpin_map looks plausible to me.

I did not get the reference to kernel/dma/remap.c though, and also not 
sure how to do the error unwind path in shmem_pin_map at which point the 
allocated vm area hasn't been fully populated yet. Hand-roll the loop 
walking vm area struct in there?

Regards,

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

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

* Re: [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
  2020-09-22  6:22       ` [Intel-gfx] " Christoph Hellwig
  (?)
@ 2020-09-22 11:21         ` Matthew Wilcox
  -1 siblings, 0 replies; 85+ messages in thread
From: Matthew Wilcox @ 2020-09-22 11:21 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, Peter Zijlstra, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Minchan Kim, Nitin Gupta, x86, xen-devel, linux-kernel,
	intel-gfx, dri-devel, linux-mm

On Tue, Sep 22, 2020 at 08:22:49AM +0200, Christoph Hellwig wrote:
> On Mon, Sep 21, 2020 at 08:11:57PM +0100, Matthew Wilcox wrote:
> > This is awkward.  I'd like it if we had a vfree() variant which called
> > put_page() instead of __free_pages().  I'd like it even more if we
> > used release_pages() instead of our own loop that called put_page().
> 
> Note that we don't need a new vfree variant, we can do this manually if
> we want, take a look at kernel/dma/remap.c.  But I thought this code
> intentionally doesn't want to do that to avoid locking in the memory
> for the pages array.  Maybe the i915 maintainers can clarify.

Actually, vfree() will work today; I cc'd you on a documentation update
to make it clear that this is permitted.

From my current experience with the i915 shmem code, I think that the
i915 maintainers are experts at graphics, and are unfamiliar with the MM.
There are a number of places where they do things the hard way.

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

* Re: [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-22 11:21         ` Matthew Wilcox
  0 siblings, 0 replies; 85+ messages in thread
From: Matthew Wilcox @ 2020-09-22 11:21 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel,
	Rodrigo Vivi, xen-devel, Andrew Morton, Boris Ostrovsky,
	Nitin Gupta

On Tue, Sep 22, 2020 at 08:22:49AM +0200, Christoph Hellwig wrote:
> On Mon, Sep 21, 2020 at 08:11:57PM +0100, Matthew Wilcox wrote:
> > This is awkward.  I'd like it if we had a vfree() variant which called
> > put_page() instead of __free_pages().  I'd like it even more if we
> > used release_pages() instead of our own loop that called put_page().
> 
> Note that we don't need a new vfree variant, we can do this manually if
> we want, take a look at kernel/dma/remap.c.  But I thought this code
> intentionally doesn't want to do that to avoid locking in the memory
> for the pages array.  Maybe the i915 maintainers can clarify.

Actually, vfree() will work today; I cc'd you on a documentation update
to make it clear that this is permitted.

From my current experience with the i915 shmem code, I think that the
i915 maintainers are experts at graphics, and are unfamiliar with the MM.
There are a number of places where they do things the hard way.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-22 11:21         ` Matthew Wilcox
  0 siblings, 0 replies; 85+ messages in thread
From: Matthew Wilcox @ 2020-09-22 11:21 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Andrew Morton, Boris Ostrovsky, Nitin Gupta

On Tue, Sep 22, 2020 at 08:22:49AM +0200, Christoph Hellwig wrote:
> On Mon, Sep 21, 2020 at 08:11:57PM +0100, Matthew Wilcox wrote:
> > This is awkward.  I'd like it if we had a vfree() variant which called
> > put_page() instead of __free_pages().  I'd like it even more if we
> > used release_pages() instead of our own loop that called put_page().
> 
> Note that we don't need a new vfree variant, we can do this manually if
> we want, take a look at kernel/dma/remap.c.  But I thought this code
> intentionally doesn't want to do that to avoid locking in the memory
> for the pages array.  Maybe the i915 maintainers can clarify.

Actually, vfree() will work today; I cc'd you on a documentation update
to make it clear that this is permitted.

From my current experience with the i915 shmem code, I think that the
i915 maintainers are experts at graphics, and are unfamiliar with the MM.
There are a number of places where they do things the hard way.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
  2020-09-22  8:23         ` Tvrtko Ursulin
@ 2020-09-22 14:31           ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-22 14:31 UTC (permalink / raw)
  To: Tvrtko Ursulin
  Cc: Christoph Hellwig, Matthew Wilcox, Juergen Gross,
	Stefano Stabellini, linux-mm, Peter Zijlstra, Boris Ostrovsky,
	x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Andrew Morton, intel-gfx, Nitin Gupta, Chris Wilson,
	Matthew Auld

On Tue, Sep 22, 2020 at 09:23:59AM +0100, Tvrtko Ursulin wrote:
> If I understood this sub-thread correctly, iterating and freeing the pages 
> via the vmapped ptes, so no need for a
> shmem_read_mapping_page_gfp loop in shmem_unpin_map looks plausible to me.
>
> I did not get the reference to kernel/dma/remap.c though,

What I mean is the code in dma_common_find_pages, which returns the
page array for freeing.

>
> and also not sure 
> how to do the error unwind path in shmem_pin_map at which point the 
> allocated vm area hasn't been fully populated yet. Hand-roll the loop 
> walking vm area struct in there?

Yes.  What I originally did (re-created as I didn't save it) would be
something like this:

---
From 5605e77cda246df6dd7ded99ec22cb3f341ef5d5 Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <hch@lst.de>
Date: Wed, 16 Sep 2020 13:54:04 +0200
Subject: drm/i915: use vmap in shmem_pin_map

shmem_pin_map somewhat awkwardly reimplements vmap using
alloc_vm_area and manual pte setup.  The only practical difference
is that alloc_vm_area prefeaults the vmalloc area PTEs, which doesn't
seem to be required here (and could be added to vmap using a flag
if actually required).

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/gpu/drm/i915/gt/shmem_utils.c | 81 +++++++++------------------
 1 file changed, 27 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.c b/drivers/gpu/drm/i915/gt/shmem_utils.c
index 43c7acbdc79dea..7ec6ba4c1065b2 100644
--- a/drivers/gpu/drm/i915/gt/shmem_utils.c
+++ b/drivers/gpu/drm/i915/gt/shmem_utils.c
@@ -49,80 +49,53 @@ struct file *shmem_create_from_object(struct drm_i915_gem_object *obj)
 	return file;
 }
 
-static size_t shmem_npte(struct file *file)
+static size_t shmem_npages(struct file *file)
 {
 	return file->f_mapping->host->i_size >> PAGE_SHIFT;
 }
 
-static void __shmem_unpin_map(struct file *file, void *ptr, size_t n_pte)
-{
-	unsigned long pfn;
-
-	vunmap(ptr);
-
-	for (pfn = 0; pfn < n_pte; pfn++) {
-		struct page *page;
-
-		page = shmem_read_mapping_page_gfp(file->f_mapping, pfn,
-						   GFP_KERNEL);
-		if (!WARN_ON(IS_ERR(page))) {
-			put_page(page);
-			put_page(page);
-		}
-	}
-}
-
 void *shmem_pin_map(struct file *file)
 {
-	const size_t n_pte = shmem_npte(file);
-	pte_t *stack[32], **ptes, **mem;
-	struct vm_struct *area;
-	unsigned long pfn;
-
-	mem = stack;
-	if (n_pte > ARRAY_SIZE(stack)) {
-		mem = kvmalloc_array(n_pte, sizeof(*mem), GFP_KERNEL);
-		if (!mem)
-			return NULL;
-	}
+	size_t n_pages = shmem_npages(file), i;
+	struct page **pages;
+	void *vaddr;
 
-	area = alloc_vm_area(n_pte << PAGE_SHIFT, mem);
-	if (!area) {
-		if (mem != stack)
-			kvfree(mem);
+	pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL);
+	if (!pages)
 		return NULL;
-	}
-
-	ptes = mem;
-	for (pfn = 0; pfn < n_pte; pfn++) {
-		struct page *page;
 
-		page = shmem_read_mapping_page_gfp(file->f_mapping, pfn,
-						   GFP_KERNEL);
-		if (IS_ERR(page))
+	for (i = 0; i < n_pages; i++) {
+		pages[i] = shmem_read_mapping_page_gfp(file->f_mapping, i,
+						       GFP_KERNEL);
+		if (IS_ERR(pages[i]))
 			goto err_page;
-
-		**ptes++ = mk_pte(page,  PAGE_KERNEL);
 	}
 
-	if (mem != stack)
-		kvfree(mem);
-
+	vaddr = vmap(pages, n_pages, 0, PAGE_KERNEL);
+	if (!vaddr)
+		goto err_page;
 	mapping_set_unevictable(file->f_mapping);
-	return area->addr;
-
+	return vaddr;
 err_page:
-	if (mem != stack)
-		kvfree(mem);
-
-	__shmem_unpin_map(file, area->addr, pfn);
+	while (--i >= 0)
+		put_page(pages[i]);
+	kvfree(pages);
 	return NULL;
 }
 
 void shmem_unpin_map(struct file *file, void *ptr)
 {
+	struct vm_struct *area = find_vm_area(ptr);
+	size_t i = shmem_npages(file);
+
+	if (WARN_ON_ONCE(!area || !area->pages))
+		return;
+
 	mapping_clear_unevictable(file->f_mapping);
-	__shmem_unpin_map(file, ptr, shmem_npte(file));
+	for (i = 0; i < shmem_npages(file); i++)
+		put_page(area->pages[i]);
+	kvfree(area->pages);
+	vunmap(ptr);
 }
 
 static int __shmem_rw(struct file *file, loff_t off,
-- 
2.28.0


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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-22 14:31           ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-22 14:31 UTC (permalink / raw)
  To: Tvrtko Ursulin
  Cc: Juergen Gross, Stefano Stabellini, Andrew Morton, Minchan Kim,
	Peter Zijlstra, intel-gfx, x86, linux-kernel, Matthew Wilcox,
	Chris Wilson, linux-mm, dri-devel, xen-devel, Boris Ostrovsky,
	Christoph Hellwig, Nitin Gupta, Matthew Auld

On Tue, Sep 22, 2020 at 09:23:59AM +0100, Tvrtko Ursulin wrote:
> If I understood this sub-thread correctly, iterating and freeing the pages 
> via the vmapped ptes, so no need for a
> shmem_read_mapping_page_gfp loop in shmem_unpin_map looks plausible to me.
>
> I did not get the reference to kernel/dma/remap.c though,

What I mean is the code in dma_common_find_pages, which returns the
page array for freeing.

>
> and also not sure 
> how to do the error unwind path in shmem_pin_map at which point the 
> allocated vm area hasn't been fully populated yet. Hand-roll the loop 
> walking vm area struct in there?

Yes.  What I originally did (re-created as I didn't save it) would be
something like this:

---
From 5605e77cda246df6dd7ded99ec22cb3f341ef5d5 Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <hch@lst.de>
Date: Wed, 16 Sep 2020 13:54:04 +0200
Subject: drm/i915: use vmap in shmem_pin_map

shmem_pin_map somewhat awkwardly reimplements vmap using
alloc_vm_area and manual pte setup.  The only practical difference
is that alloc_vm_area prefeaults the vmalloc area PTEs, which doesn't
seem to be required here (and could be added to vmap using a flag
if actually required).

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/gpu/drm/i915/gt/shmem_utils.c | 81 +++++++++------------------
 1 file changed, 27 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.c b/drivers/gpu/drm/i915/gt/shmem_utils.c
index 43c7acbdc79dea..7ec6ba4c1065b2 100644
--- a/drivers/gpu/drm/i915/gt/shmem_utils.c
+++ b/drivers/gpu/drm/i915/gt/shmem_utils.c
@@ -49,80 +49,53 @@ struct file *shmem_create_from_object(struct drm_i915_gem_object *obj)
 	return file;
 }
 
-static size_t shmem_npte(struct file *file)
+static size_t shmem_npages(struct file *file)
 {
 	return file->f_mapping->host->i_size >> PAGE_SHIFT;
 }
 
-static void __shmem_unpin_map(struct file *file, void *ptr, size_t n_pte)
-{
-	unsigned long pfn;
-
-	vunmap(ptr);
-
-	for (pfn = 0; pfn < n_pte; pfn++) {
-		struct page *page;
-
-		page = shmem_read_mapping_page_gfp(file->f_mapping, pfn,
-						   GFP_KERNEL);
-		if (!WARN_ON(IS_ERR(page))) {
-			put_page(page);
-			put_page(page);
-		}
-	}
-}
-
 void *shmem_pin_map(struct file *file)
 {
-	const size_t n_pte = shmem_npte(file);
-	pte_t *stack[32], **ptes, **mem;
-	struct vm_struct *area;
-	unsigned long pfn;
-
-	mem = stack;
-	if (n_pte > ARRAY_SIZE(stack)) {
-		mem = kvmalloc_array(n_pte, sizeof(*mem), GFP_KERNEL);
-		if (!mem)
-			return NULL;
-	}
+	size_t n_pages = shmem_npages(file), i;
+	struct page **pages;
+	void *vaddr;
 
-	area = alloc_vm_area(n_pte << PAGE_SHIFT, mem);
-	if (!area) {
-		if (mem != stack)
-			kvfree(mem);
+	pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL);
+	if (!pages)
 		return NULL;
-	}
-
-	ptes = mem;
-	for (pfn = 0; pfn < n_pte; pfn++) {
-		struct page *page;
 
-		page = shmem_read_mapping_page_gfp(file->f_mapping, pfn,
-						   GFP_KERNEL);
-		if (IS_ERR(page))
+	for (i = 0; i < n_pages; i++) {
+		pages[i] = shmem_read_mapping_page_gfp(file->f_mapping, i,
+						       GFP_KERNEL);
+		if (IS_ERR(pages[i]))
 			goto err_page;
-
-		**ptes++ = mk_pte(page,  PAGE_KERNEL);
 	}
 
-	if (mem != stack)
-		kvfree(mem);
-
+	vaddr = vmap(pages, n_pages, 0, PAGE_KERNEL);
+	if (!vaddr)
+		goto err_page;
 	mapping_set_unevictable(file->f_mapping);
-	return area->addr;
-
+	return vaddr;
 err_page:
-	if (mem != stack)
-		kvfree(mem);
-
-	__shmem_unpin_map(file, area->addr, pfn);
+	while (--i >= 0)
+		put_page(pages[i]);
+	kvfree(pages);
 	return NULL;
 }
 
 void shmem_unpin_map(struct file *file, void *ptr)
 {
+	struct vm_struct *area = find_vm_area(ptr);
+	size_t i = shmem_npages(file);
+
+	if (WARN_ON_ONCE(!area || !area->pages))
+		return;
+
 	mapping_clear_unevictable(file->f_mapping);
-	__shmem_unpin_map(file, ptr, shmem_npte(file));
+	for (i = 0; i < shmem_npages(file); i++)
+		put_page(area->pages[i]);
+	kvfree(area->pages);
+	vunmap(ptr);
 }
 
 static int __shmem_rw(struct file *file, loff_t off,
-- 
2.28.0

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

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

* Re: [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
  2020-09-22 11:21         ` Matthew Wilcox
@ 2020-09-22 14:39           ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-22 14:39 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Christoph Hellwig, Andrew Morton, Peter Zijlstra,
	Boris Ostrovsky, Juergen Gross, Stefano Stabellini, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Minchan Kim, Nitin Gupta, x86,
	xen-devel, linux-kernel, intel-gfx, dri-devel, linux-mm

On Tue, Sep 22, 2020 at 12:21:44PM +0100, Matthew Wilcox wrote:
> Actually, vfree() will work today; I cc'd you on a documentation update
> to make it clear that this is permitted.

vfree calls __free_pages, the i915 and a lot of other code calls
put_page.  They are mostly the same, but not quite and everytime I
look into that mess I'm more confused than before.

Can someone in the know write sensible documentation on when to use
__free_page(s) vs put_page?

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-22 14:39           ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-22 14:39 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	Boris Ostrovsky, x86, linux-kernel, Minchan Kim, dri-devel,
	xen-devel, Andrew Morton, intel-gfx, Christoph Hellwig,
	Nitin Gupta

On Tue, Sep 22, 2020 at 12:21:44PM +0100, Matthew Wilcox wrote:
> Actually, vfree() will work today; I cc'd you on a documentation update
> to make it clear that this is permitted.

vfree calls __free_pages, the i915 and a lot of other code calls
put_page.  They are mostly the same, but not quite and everytime I
look into that mess I'm more confused than before.

Can someone in the know write sensible documentation on when to use
__free_page(s) vs put_page?
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area (rev4)
  2020-09-18 16:37 ` [Intel-gfx] " Christoph Hellwig
                   ` (9 preceding siblings ...)
  (?)
@ 2020-09-22 14:44 ` Patchwork
  -1 siblings, 0 replies; 85+ messages in thread
From: Patchwork @ 2020-09-22 14:44 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area (rev4)
URL   : https://patchwork.freedesktop.org/series/81855/
State : failure

== Summary ==

Applying: zsmalloc: switch from alloc_vm_area to get_vm_area
error: sha1 information is lacking or useless (mm/memory.c).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0001 zsmalloc: switch from alloc_vm_area to get_vm_area
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".


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

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

* Re: [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
  2020-09-22 14:39           ` [Intel-gfx] " Christoph Hellwig
  (?)
@ 2020-09-22 14:53             ` Matthew Wilcox
  -1 siblings, 0 replies; 85+ messages in thread
From: Matthew Wilcox @ 2020-09-22 14:53 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, Peter Zijlstra, Boris Ostrovsky, Juergen Gross,
	Stefano Stabellini, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Minchan Kim, Nitin Gupta, x86, xen-devel, linux-kernel,
	intel-gfx, dri-devel, linux-mm

On Tue, Sep 22, 2020 at 04:39:06PM +0200, Christoph Hellwig wrote:
> On Tue, Sep 22, 2020 at 12:21:44PM +0100, Matthew Wilcox wrote:
> > Actually, vfree() will work today; I cc'd you on a documentation update
> > to make it clear that this is permitted.
> 
> vfree calls __free_pages, the i915 and a lot of other code calls
> put_page.  They are mostly the same, but not quite and everytime I
> look into that mess I'm more confused than before.
> 
> Can someone in the know write sensible documentation on when to use
> __free_page(s) vs put_page?

I started on that, and then I found a bug that's been lurking for 12
years, so that delayed the documentation somewhat.  The short answer is
that __free_pages() lets you free non-compound high-order pages while
put_page() can only free order-0 and compound pages.

I would really like to overhaul our memory allocation APIs:

current			new
__get_free_page(s)	alloc_page(s)
free_page(s)		free_page(s)
alloc_page(s)		get_free_page(s)
__free_pages		put_page_order

Then put_page() and put_page_order() are more obviously friends.

But I cannot imagine a world in which Linus says yes to that upheaval.
He's previous expressed dislike of the get_free_page() family of APIs,
and thinks all those callers should just use kmalloc().  Maybe we can
make that transition happen, now that kmalloc() aligns larger allocations.

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

* Re: [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-22 14:53             ` Matthew Wilcox
  0 siblings, 0 replies; 85+ messages in thread
From: Matthew Wilcox @ 2020-09-22 14:53 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel,
	Rodrigo Vivi, xen-devel, Andrew Morton, Boris Ostrovsky,
	Nitin Gupta

On Tue, Sep 22, 2020 at 04:39:06PM +0200, Christoph Hellwig wrote:
> On Tue, Sep 22, 2020 at 12:21:44PM +0100, Matthew Wilcox wrote:
> > Actually, vfree() will work today; I cc'd you on a documentation update
> > to make it clear that this is permitted.
> 
> vfree calls __free_pages, the i915 and a lot of other code calls
> put_page.  They are mostly the same, but not quite and everytime I
> look into that mess I'm more confused than before.
> 
> Can someone in the know write sensible documentation on when to use
> __free_page(s) vs put_page?

I started on that, and then I found a bug that's been lurking for 12
years, so that delayed the documentation somewhat.  The short answer is
that __free_pages() lets you free non-compound high-order pages while
put_page() can only free order-0 and compound pages.

I would really like to overhaul our memory allocation APIs:

current			new
__get_free_page(s)	alloc_page(s)
free_page(s)		free_page(s)
alloc_page(s)		get_free_page(s)
__free_pages		put_page_order

Then put_page() and put_page_order() are more obviously friends.

But I cannot imagine a world in which Linus says yes to that upheaval.
He's previous expressed dislike of the get_free_page() family of APIs,
and thinks all those callers should just use kmalloc().  Maybe we can
make that transition happen, now that kmalloc() aligns larger allocations.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-22 14:53             ` Matthew Wilcox
  0 siblings, 0 replies; 85+ messages in thread
From: Matthew Wilcox @ 2020-09-22 14:53 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Andrew Morton, Boris Ostrovsky, Nitin Gupta

On Tue, Sep 22, 2020 at 04:39:06PM +0200, Christoph Hellwig wrote:
> On Tue, Sep 22, 2020 at 12:21:44PM +0100, Matthew Wilcox wrote:
> > Actually, vfree() will work today; I cc'd you on a documentation update
> > to make it clear that this is permitted.
> 
> vfree calls __free_pages, the i915 and a lot of other code calls
> put_page.  They are mostly the same, but not quite and everytime I
> look into that mess I'm more confused than before.
> 
> Can someone in the know write sensible documentation on when to use
> __free_page(s) vs put_page?

I started on that, and then I found a bug that's been lurking for 12
years, so that delayed the documentation somewhat.  The short answer is
that __free_pages() lets you free non-compound high-order pages while
put_page() can only free order-0 and compound pages.

I would really like to overhaul our memory allocation APIs:

current			new
__get_free_page(s)	alloc_page(s)
free_page(s)		free_page(s)
alloc_page(s)		get_free_page(s)
__free_pages		put_page_order

Then put_page() and put_page_order() are more obviously friends.

But I cannot imagine a world in which Linus says yes to that upheaval.
He's previous expressed dislike of the get_free_page() family of APIs,
and thinks all those callers should just use kmalloc().  Maybe we can
make that transition happen, now that kmalloc() aligns larger allocations.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 6/6] x86/xen: open code alloc_vm_area in arch_gnttab_valloc
  2020-09-21 20:44     ` boris.ostrovsky
@ 2020-09-22 14:58       ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-22 14:58 UTC (permalink / raw)
  To: boris.ostrovsky
  Cc: Christoph Hellwig, Andrew Morton, Peter Zijlstra, Juergen Gross,
	Stefano Stabellini, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Minchan Kim, Nitin Gupta, x86, xen-devel, linux-kernel,
	intel-gfx, dri-devel, linux-mm

On Mon, Sep 21, 2020 at 04:44:10PM -0400, boris.ostrovsky@oracle.com wrote:
> This will end up incrementing area->ptes pointer. So perhaps something like
> 
> 
> pte_t **ptes = area->ptes;
> 
> if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
>                         PAGE_SIZE * nr_frames, gnttab_apply, &ptes)) {
> 
>        ...

Yeah.  What do you think of this version?  I think it is a little
cleaner and matches what xenbus does.  At this point it probably should
be split into a Xen and a alloc_vm_area removal patch, though.

---
From 74d6b797e049f72b5e9f63f14da6321c4209a792 Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <hch@lst.de>
Date: Wed, 16 Sep 2020 16:09:42 +0200
Subject: x86/xen: open code alloc_vm_area in arch_gnttab_valloc

Open code alloc_vm_area in the last remaining caller.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/x86/xen/grant-table.c | 27 +++++++++++++++------
 include/linux/vmalloc.h    |  5 +---
 mm/nommu.c                 |  7 ------
 mm/vmalloc.c               | 48 --------------------------------------
 4 files changed, 21 insertions(+), 66 deletions(-)

diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c
index 4988e19598c8a5..1e681bf62561a0 100644
--- a/arch/x86/xen/grant-table.c
+++ b/arch/x86/xen/grant-table.c
@@ -25,6 +25,7 @@
 static struct gnttab_vm_area {
 	struct vm_struct *area;
 	pte_t **ptes;
+	int idx;
 } gnttab_shared_vm_area, gnttab_status_vm_area;
 
 int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
@@ -90,19 +91,31 @@ void arch_gnttab_unmap(void *shared, unsigned long nr_gframes)
 	}
 }
 
+static int gnttab_apply(pte_t *pte, unsigned long addr, void *data)
+{
+	struct gnttab_vm_area *area = data;
+
+	area->ptes[area->idx++] = pte;
+	return 0;
+}
+
 static int arch_gnttab_valloc(struct gnttab_vm_area *area, unsigned nr_frames)
 {
 	area->ptes = kmalloc_array(nr_frames, sizeof(*area->ptes), GFP_KERNEL);
 	if (area->ptes == NULL)
 		return -ENOMEM;
-
-	area->area = alloc_vm_area(PAGE_SIZE * nr_frames, area->ptes);
-	if (area->area == NULL) {
-		kfree(area->ptes);
-		return -ENOMEM;
-	}
-
+	area->area = get_vm_area(PAGE_SIZE * nr_frames, VM_IOREMAP);
+	if (!area->area)
+		goto out_free_ptes;
+	if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
+			PAGE_SIZE * nr_frames, gnttab_apply, area))
+		goto out_free_vm_area;
 	return 0;
+out_free_vm_area:
+	free_vm_area(area->area);
+out_free_ptes:
+	kfree(area->ptes);
+	return -ENOMEM;
 }
 
 static void arch_gnttab_vfree(struct gnttab_vm_area *area)
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 8ecd92a947ee0c..a1a4e2f8163504 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -168,6 +168,7 @@ extern struct vm_struct *__get_vm_area_caller(unsigned long size,
 					unsigned long flags,
 					unsigned long start, unsigned long end,
 					const void *caller);
+void free_vm_area(struct vm_struct *area);
 extern struct vm_struct *remove_vm_area(const void *addr);
 extern struct vm_struct *find_vm_area(const void *addr);
 
@@ -203,10 +204,6 @@ static inline void set_vm_flush_reset_perms(void *addr)
 }
 #endif
 
-/* Allocate/destroy a 'vmalloc' VM area. */
-extern struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes);
-extern void free_vm_area(struct vm_struct *area);
-
 /* for /dev/kmem */
 extern long vread(char *buf, char *addr, unsigned long count);
 extern long vwrite(char *buf, char *addr, unsigned long count);
diff --git a/mm/nommu.c b/mm/nommu.c
index 75a327149af127..9272f30e4c4726 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -354,13 +354,6 @@ void vm_unmap_aliases(void)
 }
 EXPORT_SYMBOL_GPL(vm_unmap_aliases);
 
-struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes)
-{
-	BUG();
-	return NULL;
-}
-EXPORT_SYMBOL_GPL(alloc_vm_area);
-
 void free_vm_area(struct vm_struct *area)
 {
 	BUG();
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 59f2afcf26c312..9f29147deca580 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -3077,54 +3077,6 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
 }
 EXPORT_SYMBOL(remap_vmalloc_range);
 
-static int f(pte_t *pte, unsigned long addr, void *data)
-{
-	pte_t ***p = data;
-
-	if (p) {
-		*(*p) = pte;
-		(*p)++;
-	}
-	return 0;
-}
-
-/**
- * alloc_vm_area - allocate a range of kernel address space
- * @size:	   size of the area
- * @ptes:	   returns the PTEs for the address space
- *
- * Returns:	NULL on failure, vm_struct on success
- *
- * This function reserves a range of kernel address space, and
- * allocates pagetables to map that range.  No actual mappings
- * are created.
- *
- * If @ptes is non-NULL, pointers to the PTEs (in init_mm)
- * allocated for the VM area are returned.
- */
-struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes)
-{
-	struct vm_struct *area;
-
-	area = get_vm_area_caller(size, VM_IOREMAP,
-				__builtin_return_address(0));
-	if (area == NULL)
-		return NULL;
-
-	/*
-	 * This ensures that page tables are constructed for this region
-	 * of kernel virtual address space and mapped into init_mm.
-	 */
-	if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
-				size, f, ptes ? &ptes : NULL)) {
-		free_vm_area(area);
-		return NULL;
-	}
-
-	return area;
-}
-EXPORT_SYMBOL_GPL(alloc_vm_area);
-
 void free_vm_area(struct vm_struct *area)
 {
 	struct vm_struct *ret;
-- 
2.28.0


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

* Re: [Intel-gfx] [PATCH 6/6] x86/xen: open code alloc_vm_area in arch_gnttab_valloc
@ 2020-09-22 14:58       ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-22 14:58 UTC (permalink / raw)
  To: boris.ostrovsky
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Andrew Morton, Christoph Hellwig, Nitin Gupta

On Mon, Sep 21, 2020 at 04:44:10PM -0400, boris.ostrovsky@oracle.com wrote:
> This will end up incrementing area->ptes pointer. So perhaps something like
> 
> 
> pte_t **ptes = area->ptes;
> 
> if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
>                         PAGE_SIZE * nr_frames, gnttab_apply, &ptes)) {
> 
>        ...

Yeah.  What do you think of this version?  I think it is a little
cleaner and matches what xenbus does.  At this point it probably should
be split into a Xen and a alloc_vm_area removal patch, though.

---
From 74d6b797e049f72b5e9f63f14da6321c4209a792 Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <hch@lst.de>
Date: Wed, 16 Sep 2020 16:09:42 +0200
Subject: x86/xen: open code alloc_vm_area in arch_gnttab_valloc

Open code alloc_vm_area in the last remaining caller.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 arch/x86/xen/grant-table.c | 27 +++++++++++++++------
 include/linux/vmalloc.h    |  5 +---
 mm/nommu.c                 |  7 ------
 mm/vmalloc.c               | 48 --------------------------------------
 4 files changed, 21 insertions(+), 66 deletions(-)

diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c
index 4988e19598c8a5..1e681bf62561a0 100644
--- a/arch/x86/xen/grant-table.c
+++ b/arch/x86/xen/grant-table.c
@@ -25,6 +25,7 @@
 static struct gnttab_vm_area {
 	struct vm_struct *area;
 	pte_t **ptes;
+	int idx;
 } gnttab_shared_vm_area, gnttab_status_vm_area;
 
 int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
@@ -90,19 +91,31 @@ void arch_gnttab_unmap(void *shared, unsigned long nr_gframes)
 	}
 }
 
+static int gnttab_apply(pte_t *pte, unsigned long addr, void *data)
+{
+	struct gnttab_vm_area *area = data;
+
+	area->ptes[area->idx++] = pte;
+	return 0;
+}
+
 static int arch_gnttab_valloc(struct gnttab_vm_area *area, unsigned nr_frames)
 {
 	area->ptes = kmalloc_array(nr_frames, sizeof(*area->ptes), GFP_KERNEL);
 	if (area->ptes == NULL)
 		return -ENOMEM;
-
-	area->area = alloc_vm_area(PAGE_SIZE * nr_frames, area->ptes);
-	if (area->area == NULL) {
-		kfree(area->ptes);
-		return -ENOMEM;
-	}
-
+	area->area = get_vm_area(PAGE_SIZE * nr_frames, VM_IOREMAP);
+	if (!area->area)
+		goto out_free_ptes;
+	if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
+			PAGE_SIZE * nr_frames, gnttab_apply, area))
+		goto out_free_vm_area;
 	return 0;
+out_free_vm_area:
+	free_vm_area(area->area);
+out_free_ptes:
+	kfree(area->ptes);
+	return -ENOMEM;
 }
 
 static void arch_gnttab_vfree(struct gnttab_vm_area *area)
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 8ecd92a947ee0c..a1a4e2f8163504 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -168,6 +168,7 @@ extern struct vm_struct *__get_vm_area_caller(unsigned long size,
 					unsigned long flags,
 					unsigned long start, unsigned long end,
 					const void *caller);
+void free_vm_area(struct vm_struct *area);
 extern struct vm_struct *remove_vm_area(const void *addr);
 extern struct vm_struct *find_vm_area(const void *addr);
 
@@ -203,10 +204,6 @@ static inline void set_vm_flush_reset_perms(void *addr)
 }
 #endif
 
-/* Allocate/destroy a 'vmalloc' VM area. */
-extern struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes);
-extern void free_vm_area(struct vm_struct *area);
-
 /* for /dev/kmem */
 extern long vread(char *buf, char *addr, unsigned long count);
 extern long vwrite(char *buf, char *addr, unsigned long count);
diff --git a/mm/nommu.c b/mm/nommu.c
index 75a327149af127..9272f30e4c4726 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -354,13 +354,6 @@ void vm_unmap_aliases(void)
 }
 EXPORT_SYMBOL_GPL(vm_unmap_aliases);
 
-struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes)
-{
-	BUG();
-	return NULL;
-}
-EXPORT_SYMBOL_GPL(alloc_vm_area);
-
 void free_vm_area(struct vm_struct *area)
 {
 	BUG();
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 59f2afcf26c312..9f29147deca580 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -3077,54 +3077,6 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
 }
 EXPORT_SYMBOL(remap_vmalloc_range);
 
-static int f(pte_t *pte, unsigned long addr, void *data)
-{
-	pte_t ***p = data;
-
-	if (p) {
-		*(*p) = pte;
-		(*p)++;
-	}
-	return 0;
-}
-
-/**
- * alloc_vm_area - allocate a range of kernel address space
- * @size:	   size of the area
- * @ptes:	   returns the PTEs for the address space
- *
- * Returns:	NULL on failure, vm_struct on success
- *
- * This function reserves a range of kernel address space, and
- * allocates pagetables to map that range.  No actual mappings
- * are created.
- *
- * If @ptes is non-NULL, pointers to the PTEs (in init_mm)
- * allocated for the VM area are returned.
- */
-struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes)
-{
-	struct vm_struct *area;
-
-	area = get_vm_area_caller(size, VM_IOREMAP,
-				__builtin_return_address(0));
-	if (area == NULL)
-		return NULL;
-
-	/*
-	 * This ensures that page tables are constructed for this region
-	 * of kernel virtual address space and mapped into init_mm.
-	 */
-	if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
-				size, f, ptes ? &ptes : NULL)) {
-		free_vm_area(area);
-		return NULL;
-	}
-
-	return area;
-}
-EXPORT_SYMBOL_GPL(alloc_vm_area);
-
 void free_vm_area(struct vm_struct *area)
 {
 	struct vm_struct *ret;
-- 
2.28.0

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

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

* [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area (rev5)
  2020-09-18 16:37 ` [Intel-gfx] " Christoph Hellwig
                   ` (10 preceding siblings ...)
  (?)
@ 2020-09-22 15:01 ` Patchwork
  -1 siblings, 0 replies; 85+ messages in thread
From: Patchwork @ 2020-09-22 15:01 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area (rev5)
URL   : https://patchwork.freedesktop.org/series/81855/
State : failure

== Summary ==

Applying: zsmalloc: switch from alloc_vm_area to get_vm_area
error: sha1 information is lacking or useless (mm/memory.c).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0001 zsmalloc: switch from alloc_vm_area to get_vm_area
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".


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

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

* Re: [PATCH 6/6] x86/xen: open code alloc_vm_area in arch_gnttab_valloc
  2020-09-22 14:58       ` [Intel-gfx] " Christoph Hellwig
  (?)
@ 2020-09-22 15:24         ` boris.ostrovsky
  -1 siblings, 0 replies; 85+ messages in thread
From: boris.ostrovsky @ 2020-09-22 15:24 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, Peter Zijlstra, Juergen Gross, Stefano Stabellini,
	Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Minchan Kim,
	Nitin Gupta, x86, xen-devel, linux-kernel, intel-gfx, dri-devel,
	linux-mm


On 9/22/20 10:58 AM, Christoph Hellwig wrote:
> On Mon, Sep 21, 2020 at 04:44:10PM -0400, boris.ostrovsky@oracle.com wrote:
>> This will end up incrementing area->ptes pointer. So perhaps something like
>>
>>
>> pte_t **ptes = area->ptes;
>>
>> if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
>>                         PAGE_SIZE * nr_frames, gnttab_apply, &ptes)) {
>>
>>        ...
> Yeah.  What do you think of this version? 


Oh yes, this is way better. This now can actually be read without trying to mentally unwind triple pointers. (You probably want to initialize idx to zero before calling apply_to_page_range(), I am not sure it's guaranteed to be zero).


>  I think it is a little
> cleaner and matches what xenbus does.  At this point it probably should
> be split into a Xen and a alloc_vm_area removal patch, though.


Right.


-boris


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

* Re: [PATCH 6/6] x86/xen: open code alloc_vm_area in arch_gnttab_valloc
@ 2020-09-22 15:24         ` boris.ostrovsky
  0 siblings, 0 replies; 85+ messages in thread
From: boris.ostrovsky @ 2020-09-22 15:24 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel,
	Rodrigo Vivi, xen-devel, Andrew Morton, Nitin Gupta


On 9/22/20 10:58 AM, Christoph Hellwig wrote:
> On Mon, Sep 21, 2020 at 04:44:10PM -0400, boris.ostrovsky@oracle.com wrote:
>> This will end up incrementing area->ptes pointer. So perhaps something like
>>
>>
>> pte_t **ptes = area->ptes;
>>
>> if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
>>                         PAGE_SIZE * nr_frames, gnttab_apply, &ptes)) {
>>
>>        ...
> Yeah.  What do you think of this version? 


Oh yes, this is way better. This now can actually be read without trying to mentally unwind triple pointers. (You probably want to initialize idx to zero before calling apply_to_page_range(), I am not sure it's guaranteed to be zero).


>  I think it is a little
> cleaner and matches what xenbus does.  At this point it probably should
> be split into a Xen and a alloc_vm_area removal patch, though.


Right.


-boris

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 6/6] x86/xen: open code alloc_vm_area in arch_gnttab_valloc
@ 2020-09-22 15:24         ` boris.ostrovsky
  0 siblings, 0 replies; 85+ messages in thread
From: boris.ostrovsky @ 2020-09-22 15:24 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Andrew Morton, Nitin Gupta


On 9/22/20 10:58 AM, Christoph Hellwig wrote:
> On Mon, Sep 21, 2020 at 04:44:10PM -0400, boris.ostrovsky@oracle.com wrote:
>> This will end up incrementing area->ptes pointer. So perhaps something like
>>
>>
>> pte_t **ptes = area->ptes;
>>
>> if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
>>                         PAGE_SIZE * nr_frames, gnttab_apply, &ptes)) {
>>
>>        ...
> Yeah.  What do you think of this version? 


Oh yes, this is way better. This now can actually be read without trying to mentally unwind triple pointers. (You probably want to initialize idx to zero before calling apply_to_page_range(), I am not sure it's guaranteed to be zero).


>  I think it is a little
> cleaner and matches what xenbus does.  At this point it probably should
> be split into a Xen and a alloc_vm_area removal patch, though.


Right.


-boris

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

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

* Re: [PATCH 6/6] x86/xen: open code alloc_vm_area in arch_gnttab_valloc
  2020-09-22 15:24         ` boris.ostrovsky
@ 2020-09-22 15:27           ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-22 15:27 UTC (permalink / raw)
  To: boris.ostrovsky
  Cc: Christoph Hellwig, Andrew Morton, Peter Zijlstra, Juergen Gross,
	Stefano Stabellini, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Minchan Kim, Nitin Gupta, x86, xen-devel, linux-kernel,
	intel-gfx, dri-devel, linux-mm

On Tue, Sep 22, 2020 at 11:24:20AM -0400, boris.ostrovsky@oracle.com wrote:
> 
> On 9/22/20 10:58 AM, Christoph Hellwig wrote:
> > On Mon, Sep 21, 2020 at 04:44:10PM -0400, boris.ostrovsky@oracle.com wrote:
> >> This will end up incrementing area->ptes pointer. So perhaps something like
> >>
> >>
> >> pte_t **ptes = area->ptes;
> >>
> >> if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
> >>                         PAGE_SIZE * nr_frames, gnttab_apply, &ptes)) {
> >>
> >>        ...
> > Yeah.  What do you think of this version? 
> 
> 
> Oh yes, this is way better. This now can actually be read without trying to mentally unwind triple pointers. (You probably want to initialize idx to zero before calling apply_to_page_range(), I am not sure it's guaranteed to be zero).

Both instances are static variables, thus in .bss and initialized.
So unless you insist I don't think we need a manual one.

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

* Re: [Intel-gfx] [PATCH 6/6] x86/xen: open code alloc_vm_area in arch_gnttab_valloc
@ 2020-09-22 15:27           ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-22 15:27 UTC (permalink / raw)
  To: boris.ostrovsky
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Andrew Morton, Christoph Hellwig, Nitin Gupta

On Tue, Sep 22, 2020 at 11:24:20AM -0400, boris.ostrovsky@oracle.com wrote:
> 
> On 9/22/20 10:58 AM, Christoph Hellwig wrote:
> > On Mon, Sep 21, 2020 at 04:44:10PM -0400, boris.ostrovsky@oracle.com wrote:
> >> This will end up incrementing area->ptes pointer. So perhaps something like
> >>
> >>
> >> pte_t **ptes = area->ptes;
> >>
> >> if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
> >>                         PAGE_SIZE * nr_frames, gnttab_apply, &ptes)) {
> >>
> >>        ...
> > Yeah.  What do you think of this version? 
> 
> 
> Oh yes, this is way better. This now can actually be read without trying to mentally unwind triple pointers. (You probably want to initialize idx to zero before calling apply_to_page_range(), I am not sure it's guaranteed to be zero).

Both instances are static variables, thus in .bss and initialized.
So unless you insist I don't think we need a manual one.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 6/6] x86/xen: open code alloc_vm_area in arch_gnttab_valloc
  2020-09-22 15:27           ` [Intel-gfx] " Christoph Hellwig
  (?)
@ 2020-09-22 15:34             ` boris.ostrovsky
  -1 siblings, 0 replies; 85+ messages in thread
From: boris.ostrovsky @ 2020-09-22 15:34 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, Peter Zijlstra, Juergen Gross, Stefano Stabellini,
	Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Minchan Kim,
	Nitin Gupta, x86, xen-devel, linux-kernel, intel-gfx, dri-devel,
	linux-mm


On 9/22/20 11:27 AM, Christoph Hellwig wrote:
> On Tue, Sep 22, 2020 at 11:24:20AM -0400, boris.ostrovsky@oracle.com wrote:
>> On 9/22/20 10:58 AM, Christoph Hellwig wrote:
>>> On Mon, Sep 21, 2020 at 04:44:10PM -0400, boris.ostrovsky@oracle.com wrote:
>>>> This will end up incrementing area->ptes pointer. So perhaps something like
>>>>
>>>>
>>>> pte_t **ptes = area->ptes;
>>>>
>>>> if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
>>>>                         PAGE_SIZE * nr_frames, gnttab_apply, &ptes)) {
>>>>
>>>>        ...
>>> Yeah.  What do you think of this version? 
>>
>> Oh yes, this is way better. This now can actually be read without trying to mentally unwind triple pointers. (You probably want to initialize idx to zero before calling apply_to_page_range(), I am not sure it's guaranteed to be zero).
> Both instances are static variables, thus in .bss and initialized.
> So unless you insist I don't think we need a manual one.


Yes, you are right. (I thought perhaps this code could be called more than once but no, it can't).


-boris


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

* Re: [PATCH 6/6] x86/xen: open code alloc_vm_area in arch_gnttab_valloc
@ 2020-09-22 15:34             ` boris.ostrovsky
  0 siblings, 0 replies; 85+ messages in thread
From: boris.ostrovsky @ 2020-09-22 15:34 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel,
	Rodrigo Vivi, xen-devel, Andrew Morton, Nitin Gupta


On 9/22/20 11:27 AM, Christoph Hellwig wrote:
> On Tue, Sep 22, 2020 at 11:24:20AM -0400, boris.ostrovsky@oracle.com wrote:
>> On 9/22/20 10:58 AM, Christoph Hellwig wrote:
>>> On Mon, Sep 21, 2020 at 04:44:10PM -0400, boris.ostrovsky@oracle.com wrote:
>>>> This will end up incrementing area->ptes pointer. So perhaps something like
>>>>
>>>>
>>>> pte_t **ptes = area->ptes;
>>>>
>>>> if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
>>>>                         PAGE_SIZE * nr_frames, gnttab_apply, &ptes)) {
>>>>
>>>>        ...
>>> Yeah.  What do you think of this version? 
>>
>> Oh yes, this is way better. This now can actually be read without trying to mentally unwind triple pointers. (You probably want to initialize idx to zero before calling apply_to_page_range(), I am not sure it's guaranteed to be zero).
> Both instances are static variables, thus in .bss and initialized.
> So unless you insist I don't think we need a manual one.


Yes, you are right. (I thought perhaps this code could be called more than once but no, it can't).


-boris

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 6/6] x86/xen: open code alloc_vm_area in arch_gnttab_valloc
@ 2020-09-22 15:34             ` boris.ostrovsky
  0 siblings, 0 replies; 85+ messages in thread
From: boris.ostrovsky @ 2020-09-22 15:34 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Andrew Morton, Nitin Gupta


On 9/22/20 11:27 AM, Christoph Hellwig wrote:
> On Tue, Sep 22, 2020 at 11:24:20AM -0400, boris.ostrovsky@oracle.com wrote:
>> On 9/22/20 10:58 AM, Christoph Hellwig wrote:
>>> On Mon, Sep 21, 2020 at 04:44:10PM -0400, boris.ostrovsky@oracle.com wrote:
>>>> This will end up incrementing area->ptes pointer. So perhaps something like
>>>>
>>>>
>>>> pte_t **ptes = area->ptes;
>>>>
>>>> if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
>>>>                         PAGE_SIZE * nr_frames, gnttab_apply, &ptes)) {
>>>>
>>>>        ...
>>> Yeah.  What do you think of this version? 
>>
>> Oh yes, this is way better. This now can actually be read without trying to mentally unwind triple pointers. (You probably want to initialize idx to zero before calling apply_to_page_range(), I am not sure it's guaranteed to be zero).
> Both instances are static variables, thus in .bss and initialized.
> So unless you insist I don't think we need a manual one.


Yes, you are right. (I thought perhaps this code could be called more than once but no, it can't).


-boris

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

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
  2020-09-22 14:31           ` Christoph Hellwig
  (?)
@ 2020-09-22 16:13             ` Tvrtko Ursulin
  -1 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-22 16:13 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Matthew Wilcox, Juergen Gross, Stefano Stabellini, linux-mm,
	Peter Zijlstra, Boris Ostrovsky, x86, linux-kernel, Minchan Kim,
	dri-devel, xen-devel, Andrew Morton, intel-gfx, Nitin Gupta,
	Chris Wilson, Matthew Auld


On 22/09/2020 15:31, Christoph Hellwig wrote:
> On Tue, Sep 22, 2020 at 09:23:59AM +0100, Tvrtko Ursulin wrote:
>> If I understood this sub-thread correctly, iterating and freeing the pages
>> via the vmapped ptes, so no need for a
>> shmem_read_mapping_page_gfp loop in shmem_unpin_map looks plausible to me.
>>
>> I did not get the reference to kernel/dma/remap.c though,
> 
> What I mean is the code in dma_common_find_pages, which returns the
> page array for freeing.

Got it.

>> and also not sure
>> how to do the error unwind path in shmem_pin_map at which point the
>> allocated vm area hasn't been fully populated yet. Hand-roll the loop
>> walking vm area struct in there?
> 
> Yes.  What I originally did (re-created as I didn't save it) would be
> something like this:
> 
> ---
>>From 5605e77cda246df6dd7ded99ec22cb3f341ef5d5 Mon Sep 17 00:00:00 2001
> From: Christoph Hellwig <hch@lst.de>
> Date: Wed, 16 Sep 2020 13:54:04 +0200
> Subject: drm/i915: use vmap in shmem_pin_map
> 
> shmem_pin_map somewhat awkwardly reimplements vmap using
> alloc_vm_area and manual pte setup.  The only practical difference
> is that alloc_vm_area prefeaults the vmalloc area PTEs, which doesn't
> seem to be required here (and could be added to vmap using a flag
> if actually required).
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   drivers/gpu/drm/i915/gt/shmem_utils.c | 81 +++++++++------------------
>   1 file changed, 27 insertions(+), 54 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.c b/drivers/gpu/drm/i915/gt/shmem_utils.c
> index 43c7acbdc79dea..7ec6ba4c1065b2 100644
> --- a/drivers/gpu/drm/i915/gt/shmem_utils.c
> +++ b/drivers/gpu/drm/i915/gt/shmem_utils.c
> @@ -49,80 +49,53 @@ struct file *shmem_create_from_object(struct drm_i915_gem_object *obj)
>   	return file;
>   }
>   
> -static size_t shmem_npte(struct file *file)
> +static size_t shmem_npages(struct file *file)
>   {
>   	return file->f_mapping->host->i_size >> PAGE_SHIFT;
>   }
>   
> -static void __shmem_unpin_map(struct file *file, void *ptr, size_t n_pte)
> -{
> -	unsigned long pfn;
> -
> -	vunmap(ptr);
> -
> -	for (pfn = 0; pfn < n_pte; pfn++) {
> -		struct page *page;
> -
> -		page = shmem_read_mapping_page_gfp(file->f_mapping, pfn,
> -						   GFP_KERNEL);
> -		if (!WARN_ON(IS_ERR(page))) {
> -			put_page(page);
> -			put_page(page);
> -		}
> -	}
> -}
> -
>   void *shmem_pin_map(struct file *file)
>   {
> -	const size_t n_pte = shmem_npte(file);
> -	pte_t *stack[32], **ptes, **mem;

Chris can comment how much he'd miss the 32 page stack shortcut.

> -	struct vm_struct *area;
> -	unsigned long pfn;
> -
> -	mem = stack;
> -	if (n_pte > ARRAY_SIZE(stack)) {
> -		mem = kvmalloc_array(n_pte, sizeof(*mem), GFP_KERNEL);
> -		if (!mem)
> -			return NULL;
> -	}
> +	size_t n_pages = shmem_npages(file), i;
> +	struct page **pages;
> +	void *vaddr;
>   
> -	area = alloc_vm_area(n_pte << PAGE_SHIFT, mem);
> -	if (!area) {
> -		if (mem != stack)
> -			kvfree(mem);
> +	pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL);
> +	if (!pages)
>   		return NULL;
> -	}
> -
> -	ptes = mem;
> -	for (pfn = 0; pfn < n_pte; pfn++) {
> -		struct page *page;
>   
> -		page = shmem_read_mapping_page_gfp(file->f_mapping, pfn,
> -						   GFP_KERNEL);
> -		if (IS_ERR(page))
> +	for (i = 0; i < n_pages; i++) {
> +		pages[i] = shmem_read_mapping_page_gfp(file->f_mapping, i,
> +						       GFP_KERNEL);
> +		if (IS_ERR(pages[i]))
>   			goto err_page;
> -
> -		**ptes++ = mk_pte(page,  PAGE_KERNEL);
>   	}
>   
> -	if (mem != stack)
> -		kvfree(mem);
> -
> +	vaddr = vmap(pages, n_pages, 0, PAGE_KERNEL);
> +	if (!vaddr)
> +		goto err_page;
>   	mapping_set_unevictable(file->f_mapping);
> -	return area->addr;
> -
> +	return vaddr;

Is there something in vmap() preventing us from freeing the pages array 
here? I can't spot anything that is holding on to the pointer. Or it was 
just a sketch before you realized we could walk the vm_area?

Also, I may be totally misunderstanding something, but I think you need 
to assign area->pages manually so shmem_unpin_map can access it below.

>   err_page:
> -	if (mem != stack)
> -		kvfree(mem);
> -
> -	__shmem_unpin_map(file, area->addr, pfn);
> +	while (--i >= 0)
> +		put_page(pages[i]);
> +	kvfree(pages);
>   	return NULL;
>   }
>   
>   void shmem_unpin_map(struct file *file, void *ptr)
>   {
> +	struct vm_struct *area = find_vm_area(ptr);
> +	size_t i = shmem_npages(file);
> +
> +	if (WARN_ON_ONCE(!area || !area->pages))
> +		return;
> +
>   	mapping_clear_unevictable(file->f_mapping);
> -	__shmem_unpin_map(file, ptr, shmem_npte(file));
> +	for (i = 0; i < shmem_npages(file); i++)
> +		put_page(area->pages[i]);
> +	kvfree(area->pages);
> +	vunmap(ptr);

Is the verdict from mm experts that we can't use vfree due __free_pages 
vs put_page differences?

Could we get from ptes to pages, so that we don't have to keep the 
area->pages array allocated for the duration of the pin?

Regards,

Tvrtko

>   }
>   
>   static int __shmem_rw(struct file *file, loff_t off,
> 


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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-22 16:13             ` Tvrtko Ursulin
  0 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-22 16:13 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, Minchan Kim, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Matthew Wilcox, Chris Wilson,
	linux-mm, dri-devel, xen-devel, Boris Ostrovsky, Andrew Morton,
	Nitin Gupta, Matthew Auld


On 22/09/2020 15:31, Christoph Hellwig wrote:
> On Tue, Sep 22, 2020 at 09:23:59AM +0100, Tvrtko Ursulin wrote:
>> If I understood this sub-thread correctly, iterating and freeing the pages
>> via the vmapped ptes, so no need for a
>> shmem_read_mapping_page_gfp loop in shmem_unpin_map looks plausible to me.
>>
>> I did not get the reference to kernel/dma/remap.c though,
> 
> What I mean is the code in dma_common_find_pages, which returns the
> page array for freeing.

Got it.

>> and also not sure
>> how to do the error unwind path in shmem_pin_map at which point the
>> allocated vm area hasn't been fully populated yet. Hand-roll the loop
>> walking vm area struct in there?
> 
> Yes.  What I originally did (re-created as I didn't save it) would be
> something like this:
> 
> ---
>>From 5605e77cda246df6dd7ded99ec22cb3f341ef5d5 Mon Sep 17 00:00:00 2001
> From: Christoph Hellwig <hch@lst.de>
> Date: Wed, 16 Sep 2020 13:54:04 +0200
> Subject: drm/i915: use vmap in shmem_pin_map
> 
> shmem_pin_map somewhat awkwardly reimplements vmap using
> alloc_vm_area and manual pte setup.  The only practical difference
> is that alloc_vm_area prefeaults the vmalloc area PTEs, which doesn't
> seem to be required here (and could be added to vmap using a flag
> if actually required).
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   drivers/gpu/drm/i915/gt/shmem_utils.c | 81 +++++++++------------------
>   1 file changed, 27 insertions(+), 54 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.c b/drivers/gpu/drm/i915/gt/shmem_utils.c
> index 43c7acbdc79dea..7ec6ba4c1065b2 100644
> --- a/drivers/gpu/drm/i915/gt/shmem_utils.c
> +++ b/drivers/gpu/drm/i915/gt/shmem_utils.c
> @@ -49,80 +49,53 @@ struct file *shmem_create_from_object(struct drm_i915_gem_object *obj)
>   	return file;
>   }
>   
> -static size_t shmem_npte(struct file *file)
> +static size_t shmem_npages(struct file *file)
>   {
>   	return file->f_mapping->host->i_size >> PAGE_SHIFT;
>   }
>   
> -static void __shmem_unpin_map(struct file *file, void *ptr, size_t n_pte)
> -{
> -	unsigned long pfn;
> -
> -	vunmap(ptr);
> -
> -	for (pfn = 0; pfn < n_pte; pfn++) {
> -		struct page *page;
> -
> -		page = shmem_read_mapping_page_gfp(file->f_mapping, pfn,
> -						   GFP_KERNEL);
> -		if (!WARN_ON(IS_ERR(page))) {
> -			put_page(page);
> -			put_page(page);
> -		}
> -	}
> -}
> -
>   void *shmem_pin_map(struct file *file)
>   {
> -	const size_t n_pte = shmem_npte(file);
> -	pte_t *stack[32], **ptes, **mem;

Chris can comment how much he'd miss the 32 page stack shortcut.

> -	struct vm_struct *area;
> -	unsigned long pfn;
> -
> -	mem = stack;
> -	if (n_pte > ARRAY_SIZE(stack)) {
> -		mem = kvmalloc_array(n_pte, sizeof(*mem), GFP_KERNEL);
> -		if (!mem)
> -			return NULL;
> -	}
> +	size_t n_pages = shmem_npages(file), i;
> +	struct page **pages;
> +	void *vaddr;
>   
> -	area = alloc_vm_area(n_pte << PAGE_SHIFT, mem);
> -	if (!area) {
> -		if (mem != stack)
> -			kvfree(mem);
> +	pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL);
> +	if (!pages)
>   		return NULL;
> -	}
> -
> -	ptes = mem;
> -	for (pfn = 0; pfn < n_pte; pfn++) {
> -		struct page *page;
>   
> -		page = shmem_read_mapping_page_gfp(file->f_mapping, pfn,
> -						   GFP_KERNEL);
> -		if (IS_ERR(page))
> +	for (i = 0; i < n_pages; i++) {
> +		pages[i] = shmem_read_mapping_page_gfp(file->f_mapping, i,
> +						       GFP_KERNEL);
> +		if (IS_ERR(pages[i]))
>   			goto err_page;
> -
> -		**ptes++ = mk_pte(page,  PAGE_KERNEL);
>   	}
>   
> -	if (mem != stack)
> -		kvfree(mem);
> -
> +	vaddr = vmap(pages, n_pages, 0, PAGE_KERNEL);
> +	if (!vaddr)
> +		goto err_page;
>   	mapping_set_unevictable(file->f_mapping);
> -	return area->addr;
> -
> +	return vaddr;

Is there something in vmap() preventing us from freeing the pages array 
here? I can't spot anything that is holding on to the pointer. Or it was 
just a sketch before you realized we could walk the vm_area?

Also, I may be totally misunderstanding something, but I think you need 
to assign area->pages manually so shmem_unpin_map can access it below.

>   err_page:
> -	if (mem != stack)
> -		kvfree(mem);
> -
> -	__shmem_unpin_map(file, area->addr, pfn);
> +	while (--i >= 0)
> +		put_page(pages[i]);
> +	kvfree(pages);
>   	return NULL;
>   }
>   
>   void shmem_unpin_map(struct file *file, void *ptr)
>   {
> +	struct vm_struct *area = find_vm_area(ptr);
> +	size_t i = shmem_npages(file);
> +
> +	if (WARN_ON_ONCE(!area || !area->pages))
> +		return;
> +
>   	mapping_clear_unevictable(file->f_mapping);
> -	__shmem_unpin_map(file, ptr, shmem_npte(file));
> +	for (i = 0; i < shmem_npages(file); i++)
> +		put_page(area->pages[i]);
> +	kvfree(area->pages);
> +	vunmap(ptr);

Is the verdict from mm experts that we can't use vfree due __free_pages 
vs put_page differences?

Could we get from ptes to pages, so that we don't have to keep the 
area->pages array allocated for the duration of the pin?

Regards,

Tvrtko

>   }
>   
>   static int __shmem_rw(struct file *file, loff_t off,
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-22 16:13             ` Tvrtko Ursulin
  0 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-22 16:13 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, Minchan Kim, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Matthew Wilcox, Chris Wilson,
	linux-mm, dri-devel, xen-devel, Boris Ostrovsky, Andrew Morton,
	Nitin Gupta, Matthew Auld


On 22/09/2020 15:31, Christoph Hellwig wrote:
> On Tue, Sep 22, 2020 at 09:23:59AM +0100, Tvrtko Ursulin wrote:
>> If I understood this sub-thread correctly, iterating and freeing the pages
>> via the vmapped ptes, so no need for a
>> shmem_read_mapping_page_gfp loop in shmem_unpin_map looks plausible to me.
>>
>> I did not get the reference to kernel/dma/remap.c though,
> 
> What I mean is the code in dma_common_find_pages, which returns the
> page array for freeing.

Got it.

>> and also not sure
>> how to do the error unwind path in shmem_pin_map at which point the
>> allocated vm area hasn't been fully populated yet. Hand-roll the loop
>> walking vm area struct in there?
> 
> Yes.  What I originally did (re-created as I didn't save it) would be
> something like this:
> 
> ---
>>From 5605e77cda246df6dd7ded99ec22cb3f341ef5d5 Mon Sep 17 00:00:00 2001
> From: Christoph Hellwig <hch@lst.de>
> Date: Wed, 16 Sep 2020 13:54:04 +0200
> Subject: drm/i915: use vmap in shmem_pin_map
> 
> shmem_pin_map somewhat awkwardly reimplements vmap using
> alloc_vm_area and manual pte setup.  The only practical difference
> is that alloc_vm_area prefeaults the vmalloc area PTEs, which doesn't
> seem to be required here (and could be added to vmap using a flag
> if actually required).
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   drivers/gpu/drm/i915/gt/shmem_utils.c | 81 +++++++++------------------
>   1 file changed, 27 insertions(+), 54 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.c b/drivers/gpu/drm/i915/gt/shmem_utils.c
> index 43c7acbdc79dea..7ec6ba4c1065b2 100644
> --- a/drivers/gpu/drm/i915/gt/shmem_utils.c
> +++ b/drivers/gpu/drm/i915/gt/shmem_utils.c
> @@ -49,80 +49,53 @@ struct file *shmem_create_from_object(struct drm_i915_gem_object *obj)
>   	return file;
>   }
>   
> -static size_t shmem_npte(struct file *file)
> +static size_t shmem_npages(struct file *file)
>   {
>   	return file->f_mapping->host->i_size >> PAGE_SHIFT;
>   }
>   
> -static void __shmem_unpin_map(struct file *file, void *ptr, size_t n_pte)
> -{
> -	unsigned long pfn;
> -
> -	vunmap(ptr);
> -
> -	for (pfn = 0; pfn < n_pte; pfn++) {
> -		struct page *page;
> -
> -		page = shmem_read_mapping_page_gfp(file->f_mapping, pfn,
> -						   GFP_KERNEL);
> -		if (!WARN_ON(IS_ERR(page))) {
> -			put_page(page);
> -			put_page(page);
> -		}
> -	}
> -}
> -
>   void *shmem_pin_map(struct file *file)
>   {
> -	const size_t n_pte = shmem_npte(file);
> -	pte_t *stack[32], **ptes, **mem;

Chris can comment how much he'd miss the 32 page stack shortcut.

> -	struct vm_struct *area;
> -	unsigned long pfn;
> -
> -	mem = stack;
> -	if (n_pte > ARRAY_SIZE(stack)) {
> -		mem = kvmalloc_array(n_pte, sizeof(*mem), GFP_KERNEL);
> -		if (!mem)
> -			return NULL;
> -	}
> +	size_t n_pages = shmem_npages(file), i;
> +	struct page **pages;
> +	void *vaddr;
>   
> -	area = alloc_vm_area(n_pte << PAGE_SHIFT, mem);
> -	if (!area) {
> -		if (mem != stack)
> -			kvfree(mem);
> +	pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL);
> +	if (!pages)
>   		return NULL;
> -	}
> -
> -	ptes = mem;
> -	for (pfn = 0; pfn < n_pte; pfn++) {
> -		struct page *page;
>   
> -		page = shmem_read_mapping_page_gfp(file->f_mapping, pfn,
> -						   GFP_KERNEL);
> -		if (IS_ERR(page))
> +	for (i = 0; i < n_pages; i++) {
> +		pages[i] = shmem_read_mapping_page_gfp(file->f_mapping, i,
> +						       GFP_KERNEL);
> +		if (IS_ERR(pages[i]))
>   			goto err_page;
> -
> -		**ptes++ = mk_pte(page,  PAGE_KERNEL);
>   	}
>   
> -	if (mem != stack)
> -		kvfree(mem);
> -
> +	vaddr = vmap(pages, n_pages, 0, PAGE_KERNEL);
> +	if (!vaddr)
> +		goto err_page;
>   	mapping_set_unevictable(file->f_mapping);
> -	return area->addr;
> -
> +	return vaddr;

Is there something in vmap() preventing us from freeing the pages array 
here? I can't spot anything that is holding on to the pointer. Or it was 
just a sketch before you realized we could walk the vm_area?

Also, I may be totally misunderstanding something, but I think you need 
to assign area->pages manually so shmem_unpin_map can access it below.

>   err_page:
> -	if (mem != stack)
> -		kvfree(mem);
> -
> -	__shmem_unpin_map(file, area->addr, pfn);
> +	while (--i >= 0)
> +		put_page(pages[i]);
> +	kvfree(pages);
>   	return NULL;
>   }
>   
>   void shmem_unpin_map(struct file *file, void *ptr)
>   {
> +	struct vm_struct *area = find_vm_area(ptr);
> +	size_t i = shmem_npages(file);
> +
> +	if (WARN_ON_ONCE(!area || !area->pages))
> +		return;
> +
>   	mapping_clear_unevictable(file->f_mapping);
> -	__shmem_unpin_map(file, ptr, shmem_npte(file));
> +	for (i = 0; i < shmem_npages(file); i++)
> +		put_page(area->pages[i]);
> +	kvfree(area->pages);
> +	vunmap(ptr);

Is the verdict from mm experts that we can't use vfree due __free_pages 
vs put_page differences?

Could we get from ptes to pages, so that we don't have to keep the 
area->pages array allocated for the duration of the pin?

Regards,

Tvrtko

>   }
>   
>   static int __shmem_rw(struct file *file, loff_t off,
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
  2020-09-22 16:13             ` Tvrtko Ursulin
@ 2020-09-22 16:33               ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-22 16:33 UTC (permalink / raw)
  To: Tvrtko Ursulin
  Cc: Christoph Hellwig, Matthew Wilcox, Juergen Gross,
	Stefano Stabellini, linux-mm, Peter Zijlstra, Boris Ostrovsky,
	x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Andrew Morton, intel-gfx, Nitin Gupta, Chris Wilson,
	Matthew Auld

On Tue, Sep 22, 2020 at 05:13:45PM +0100, Tvrtko Ursulin wrote:
>>   void *shmem_pin_map(struct file *file)
>>   {
>> -	const size_t n_pte = shmem_npte(file);
>> -	pte_t *stack[32], **ptes, **mem;
>
> Chris can comment how much he'd miss the 32 page stack shortcut.

I'd like to see a profile that claim that kmalloc matters in a
path that does a vmap and reads pages through the page cache.
Especially when the kmalloc saves doing another page cache lookup
on the free side.

> Is there something in vmap() preventing us from freeing the pages array 
> here? I can't spot anything that is holding on to the pointer. Or it was 
> just a sketch before you realized we could walk the vm_area?
>
> Also, I may be totally misunderstanding something, but I think you need to 
> assign area->pages manually so shmem_unpin_map can access it below.

We need area->pages to hold the pages for the free side.  That being
said the patch I posted is broken because it never assigned to that.
As said it was a sketch.  This is the patch I just rebooted into on
my Laptop:

http://git.infradead.org/users/hch/misc.git/commitdiff/048522dfa26b6667adfb0371ff530dc263abe829

it needs extra prep patches from the series:

http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/alloc_vm_area

>>   	mapping_clear_unevictable(file->f_mapping);
>> -	__shmem_unpin_map(file, ptr, shmem_npte(file));
>> +	for (i = 0; i < shmem_npages(file); i++)
>> +		put_page(area->pages[i]);
>> +	kvfree(area->pages);
>> +	vunmap(ptr);
>
> Is the verdict from mm experts that we can't use vfree due __free_pages vs 
> put_page differences?

Switched to vfree now.

> Could we get from ptes to pages, so that we don't have to keep the 
> area->pages array allocated for the duration of the pin?

We could do vmalloc_to_page, but that is fairly expensive (not as bad
as reading from the page cache..).  Are you really worried about the
allocation?

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-22 16:33               ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-22 16:33 UTC (permalink / raw)
  To: Tvrtko Ursulin
  Cc: Juergen Gross, Stefano Stabellini, Andrew Morton, Minchan Kim,
	Peter Zijlstra, intel-gfx, x86, linux-kernel, Matthew Wilcox,
	Chris Wilson, linux-mm, dri-devel, xen-devel, Boris Ostrovsky,
	Christoph Hellwig, Nitin Gupta, Matthew Auld

On Tue, Sep 22, 2020 at 05:13:45PM +0100, Tvrtko Ursulin wrote:
>>   void *shmem_pin_map(struct file *file)
>>   {
>> -	const size_t n_pte = shmem_npte(file);
>> -	pte_t *stack[32], **ptes, **mem;
>
> Chris can comment how much he'd miss the 32 page stack shortcut.

I'd like to see a profile that claim that kmalloc matters in a
path that does a vmap and reads pages through the page cache.
Especially when the kmalloc saves doing another page cache lookup
on the free side.

> Is there something in vmap() preventing us from freeing the pages array 
> here? I can't spot anything that is holding on to the pointer. Or it was 
> just a sketch before you realized we could walk the vm_area?
>
> Also, I may be totally misunderstanding something, but I think you need to 
> assign area->pages manually so shmem_unpin_map can access it below.

We need area->pages to hold the pages for the free side.  That being
said the patch I posted is broken because it never assigned to that.
As said it was a sketch.  This is the patch I just rebooted into on
my Laptop:

http://git.infradead.org/users/hch/misc.git/commitdiff/048522dfa26b6667adfb0371ff530dc263abe829

it needs extra prep patches from the series:

http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/alloc_vm_area

>>   	mapping_clear_unevictable(file->f_mapping);
>> -	__shmem_unpin_map(file, ptr, shmem_npte(file));
>> +	for (i = 0; i < shmem_npages(file); i++)
>> +		put_page(area->pages[i]);
>> +	kvfree(area->pages);
>> +	vunmap(ptr);
>
> Is the verdict from mm experts that we can't use vfree due __free_pages vs 
> put_page differences?

Switched to vfree now.

> Could we get from ptes to pages, so that we don't have to keep the 
> area->pages array allocated for the duration of the pin?

We could do vmalloc_to_page, but that is fairly expensive (not as bad
as reading from the page cache..).  Are you really worried about the
allocation?
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
  2020-09-22 16:33               ` Christoph Hellwig
  (?)
@ 2020-09-22 17:04                 ` Tvrtko Ursulin
  -1 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-22 17:04 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Matthew Wilcox, Juergen Gross, Stefano Stabellini, linux-mm,
	Peter Zijlstra, Boris Ostrovsky, x86, linux-kernel, Minchan Kim,
	dri-devel, xen-devel, Andrew Morton, intel-gfx, Nitin Gupta,
	Chris Wilson, Matthew Auld


On 22/09/2020 17:33, Christoph Hellwig wrote:
> On Tue, Sep 22, 2020 at 05:13:45PM +0100, Tvrtko Ursulin wrote:
>>>    void *shmem_pin_map(struct file *file)
>>>    {
>>> -	const size_t n_pte = shmem_npte(file);
>>> -	pte_t *stack[32], **ptes, **mem;
>>
>> Chris can comment how much he'd miss the 32 page stack shortcut.
> 
> I'd like to see a profile that claim that kmalloc matters in a
> path that does a vmap and reads pages through the page cache.
> Especially when the kmalloc saves doing another page cache lookup
> on the free side.

Only reason I can come up with now is if mapping side is on a latency 
sensitive path, while un-mapping is lazy/delayed so can be more costly. 
Then fast map and extra cost on unmap may make sense.

It more applies to the other i915 patch, which implements a much more 
used API, but whether or not we can demonstrate any difference in the 
perf profiles I couldn't tell you without trying to collect some.

>> Is there something in vmap() preventing us from freeing the pages array
>> here? I can't spot anything that is holding on to the pointer. Or it was
>> just a sketch before you realized we could walk the vm_area?
>>
>> Also, I may be totally misunderstanding something, but I think you need to
>> assign area->pages manually so shmem_unpin_map can access it below.
> 
> We need area->pages to hold the pages for the free side.  That being
> said the patch I posted is broken because it never assigned to that.
> As said it was a sketch.  This is the patch I just rebooted into on
> my Laptop:
> 
> http://git.infradead.org/users/hch/misc.git/commitdiff/048522dfa26b6667adfb0371ff530dc263abe829
> 
> it needs extra prep patches from the series:
> 
> http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/alloc_vm_area
> 
>>>    	mapping_clear_unevictable(file->f_mapping);
>>> -	__shmem_unpin_map(file, ptr, shmem_npte(file));
>>> +	for (i = 0; i < shmem_npages(file); i++)
>>> +		put_page(area->pages[i]);
>>> +	kvfree(area->pages);
>>> +	vunmap(ptr);
>>
>> Is the verdict from mm experts that we can't use vfree due __free_pages vs
>> put_page differences?
> 
> Switched to vfree now.
> 
>> Could we get from ptes to pages, so that we don't have to keep the
>> area->pages array allocated for the duration of the pin?
> 
> We could do vmalloc_to_page, but that is fairly expensive (not as bad
> as reading from the page cache..).  Are you really worried about the
> allocation?

Not so much given how we don't even use shmem_pin_map outside selftests.

If we start using it I expect it will be for tiny objects anyway. Only 
if they end up being pinned for the lifetime of the driver, it may be a 
pointless waste of memory compared to the downsides of vmalloc_to_page. 
But we can revisit this particular edge case optimization if the need 
arises.

I'll look at your other i915 patch tomorrow.

Regards,

Tvrtko


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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-22 17:04                 ` Tvrtko Ursulin
  0 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-22 17:04 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, Minchan Kim, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Matthew Wilcox, Chris Wilson,
	linux-mm, dri-devel, xen-devel, Boris Ostrovsky, Andrew Morton,
	Nitin Gupta, Matthew Auld


On 22/09/2020 17:33, Christoph Hellwig wrote:
> On Tue, Sep 22, 2020 at 05:13:45PM +0100, Tvrtko Ursulin wrote:
>>>    void *shmem_pin_map(struct file *file)
>>>    {
>>> -	const size_t n_pte = shmem_npte(file);
>>> -	pte_t *stack[32], **ptes, **mem;
>>
>> Chris can comment how much he'd miss the 32 page stack shortcut.
> 
> I'd like to see a profile that claim that kmalloc matters in a
> path that does a vmap and reads pages through the page cache.
> Especially when the kmalloc saves doing another page cache lookup
> on the free side.

Only reason I can come up with now is if mapping side is on a latency 
sensitive path, while un-mapping is lazy/delayed so can be more costly. 
Then fast map and extra cost on unmap may make sense.

It more applies to the other i915 patch, which implements a much more 
used API, but whether or not we can demonstrate any difference in the 
perf profiles I couldn't tell you without trying to collect some.

>> Is there something in vmap() preventing us from freeing the pages array
>> here? I can't spot anything that is holding on to the pointer. Or it was
>> just a sketch before you realized we could walk the vm_area?
>>
>> Also, I may be totally misunderstanding something, but I think you need to
>> assign area->pages manually so shmem_unpin_map can access it below.
> 
> We need area->pages to hold the pages for the free side.  That being
> said the patch I posted is broken because it never assigned to that.
> As said it was a sketch.  This is the patch I just rebooted into on
> my Laptop:
> 
> http://git.infradead.org/users/hch/misc.git/commitdiff/048522dfa26b6667adfb0371ff530dc263abe829
> 
> it needs extra prep patches from the series:
> 
> http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/alloc_vm_area
> 
>>>    	mapping_clear_unevictable(file->f_mapping);
>>> -	__shmem_unpin_map(file, ptr, shmem_npte(file));
>>> +	for (i = 0; i < shmem_npages(file); i++)
>>> +		put_page(area->pages[i]);
>>> +	kvfree(area->pages);
>>> +	vunmap(ptr);
>>
>> Is the verdict from mm experts that we can't use vfree due __free_pages vs
>> put_page differences?
> 
> Switched to vfree now.
> 
>> Could we get from ptes to pages, so that we don't have to keep the
>> area->pages array allocated for the duration of the pin?
> 
> We could do vmalloc_to_page, but that is fairly expensive (not as bad
> as reading from the page cache..).  Are you really worried about the
> allocation?

Not so much given how we don't even use shmem_pin_map outside selftests.

If we start using it I expect it will be for tiny objects anyway. Only 
if they end up being pinned for the lifetime of the driver, it may be a 
pointless waste of memory compared to the downsides of vmalloc_to_page. 
But we can revisit this particular edge case optimization if the need 
arises.

I'll look at your other i915 patch tomorrow.

Regards,

Tvrtko
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-22 17:04                 ` Tvrtko Ursulin
  0 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-22 17:04 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, Minchan Kim, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Matthew Wilcox, Chris Wilson,
	linux-mm, dri-devel, xen-devel, Boris Ostrovsky, Andrew Morton,
	Nitin Gupta, Matthew Auld


On 22/09/2020 17:33, Christoph Hellwig wrote:
> On Tue, Sep 22, 2020 at 05:13:45PM +0100, Tvrtko Ursulin wrote:
>>>    void *shmem_pin_map(struct file *file)
>>>    {
>>> -	const size_t n_pte = shmem_npte(file);
>>> -	pte_t *stack[32], **ptes, **mem;
>>
>> Chris can comment how much he'd miss the 32 page stack shortcut.
> 
> I'd like to see a profile that claim that kmalloc matters in a
> path that does a vmap and reads pages through the page cache.
> Especially when the kmalloc saves doing another page cache lookup
> on the free side.

Only reason I can come up with now is if mapping side is on a latency 
sensitive path, while un-mapping is lazy/delayed so can be more costly. 
Then fast map and extra cost on unmap may make sense.

It more applies to the other i915 patch, which implements a much more 
used API, but whether or not we can demonstrate any difference in the 
perf profiles I couldn't tell you without trying to collect some.

>> Is there something in vmap() preventing us from freeing the pages array
>> here? I can't spot anything that is holding on to the pointer. Or it was
>> just a sketch before you realized we could walk the vm_area?
>>
>> Also, I may be totally misunderstanding something, but I think you need to
>> assign area->pages manually so shmem_unpin_map can access it below.
> 
> We need area->pages to hold the pages for the free side.  That being
> said the patch I posted is broken because it never assigned to that.
> As said it was a sketch.  This is the patch I just rebooted into on
> my Laptop:
> 
> http://git.infradead.org/users/hch/misc.git/commitdiff/048522dfa26b6667adfb0371ff530dc263abe829
> 
> it needs extra prep patches from the series:
> 
> http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/alloc_vm_area
> 
>>>    	mapping_clear_unevictable(file->f_mapping);
>>> -	__shmem_unpin_map(file, ptr, shmem_npte(file));
>>> +	for (i = 0; i < shmem_npages(file); i++)
>>> +		put_page(area->pages[i]);
>>> +	kvfree(area->pages);
>>> +	vunmap(ptr);
>>
>> Is the verdict from mm experts that we can't use vfree due __free_pages vs
>> put_page differences?
> 
> Switched to vfree now.
> 
>> Could we get from ptes to pages, so that we don't have to keep the
>> area->pages array allocated for the duration of the pin?
> 
> We could do vmalloc_to_page, but that is fairly expensive (not as bad
> as reading from the page cache..).  Are you really worried about the
> allocation?

Not so much given how we don't even use shmem_pin_map outside selftests.

If we start using it I expect it will be for tiny objects anyway. Only 
if they end up being pinned for the lifetime of the driver, it may be a 
pointless waste of memory compared to the downsides of vmalloc_to_page. 
But we can revisit this particular edge case optimization if the need 
arises.

I'll look at your other i915 patch tomorrow.

Regards,

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

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
  2020-09-22 17:04                 ` Tvrtko Ursulin
@ 2020-09-23  6:11                   ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-23  6:11 UTC (permalink / raw)
  To: Tvrtko Ursulin
  Cc: Christoph Hellwig, Matthew Wilcox, Juergen Gross,
	Stefano Stabellini, linux-mm, Peter Zijlstra, Boris Ostrovsky,
	x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Andrew Morton, intel-gfx, Nitin Gupta, Chris Wilson,
	Matthew Auld

On Tue, Sep 22, 2020 at 06:04:37PM +0100, Tvrtko Ursulin wrote:
> Only reason I can come up with now is if mapping side is on a latency 
> sensitive path, while un-mapping is lazy/delayed so can be more costly. 
> Then fast map and extra cost on unmap may make sense.

In general yes.  But compared to the overall operations a small kmalloc
is in the noise, so I'd really like to see numbers.

> It more applies to the other i915 patch, which implements a much more used 
> API, but whether or not we can demonstrate any difference in the perf 
> profiles I couldn't tell you without trying to collect some.

The other patch keeps the stack, as avoiding it would not simplify the
code as significantly.  I still doubt it is all that useful, though.


>> We could do vmalloc_to_page, but that is fairly expensive (not as bad
>> as reading from the page cache..).  Are you really worried about the
>> allocation?
>
> Not so much given how we don't even use shmem_pin_map outside selftests.
>
> If we start using it I expect it will be for tiny objects anyway. Only if 
> they end up being pinned for the lifetime of the driver, it may be a 
> pointless waste of memory compared to the downsides of vmalloc_to_page. But 
> we can revisit this particular edge case optimization if the need arises.

For tiny object we could either look into using kmap, or in fact
ensure the shmem files aren't in highmem, in which case you could
always use single-page mappings without any extra mapping.

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

* Re: [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
@ 2020-09-23  6:11                   ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-23  6:11 UTC (permalink / raw)
  To: Tvrtko Ursulin
  Cc: Juergen Gross, Stefano Stabellini, Andrew Morton, Minchan Kim,
	Peter Zijlstra, intel-gfx, x86, linux-kernel, Matthew Wilcox,
	Chris Wilson, linux-mm, dri-devel, xen-devel, Boris Ostrovsky,
	Christoph Hellwig, Nitin Gupta, Matthew Auld

On Tue, Sep 22, 2020 at 06:04:37PM +0100, Tvrtko Ursulin wrote:
> Only reason I can come up with now is if mapping side is on a latency 
> sensitive path, while un-mapping is lazy/delayed so can be more costly. 
> Then fast map and extra cost on unmap may make sense.

In general yes.  But compared to the overall operations a small kmalloc
is in the noise, so I'd really like to see numbers.

> It more applies to the other i915 patch, which implements a much more used 
> API, but whether or not we can demonstrate any difference in the perf 
> profiles I couldn't tell you without trying to collect some.

The other patch keeps the stack, as avoiding it would not simplify the
code as significantly.  I still doubt it is all that useful, though.


>> We could do vmalloc_to_page, but that is fairly expensive (not as bad
>> as reading from the page cache..).  Are you really worried about the
>> allocation?
>
> Not so much given how we don't even use shmem_pin_map outside selftests.
>
> If we start using it I expect it will be for tiny objects anyway. Only if 
> they end up being pinned for the lifetime of the driver, it may be a 
> pointless waste of memory compared to the downsides of vmalloc_to_page. But 
> we can revisit this particular edge case optimization if the need arises.

For tiny object we could either look into using kmap, or in fact
ensure the shmem files aren't in highmem, in which case you could
always use single-page mappings without any extra mapping.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map
  2020-09-18 16:37   ` [Intel-gfx] " Christoph Hellwig
  (?)
@ 2020-09-23  9:52     ` Tvrtko Ursulin
  -1 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-23  9:52 UTC (permalink / raw)
  To: Christoph Hellwig, Andrew Morton
  Cc: Juergen Gross, Stefano Stabellini, linux-mm, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, Minchan Kim, dri-devel, xen-devel,
	Boris Ostrovsky, Nitin Gupta


On 18/09/2020 17:37, Christoph Hellwig wrote:
> i915_gem_object_map implements fairly low-level vmap functionality in
> a driver.  Split it into two helpers, one for remapping kernel memory
> which can use vmap, and one for I/O memory that uses vmap_pfn.
> 
> The only practical difference is that alloc_vm_area prefeaults the
> vmalloc area PTEs, which doesn't seem to be required here for the
> kernel memory case (and could be added to vmap using a flag if actually
> required).

Patch looks good to me.

Series did not get a CI run from our side because of a different base so 
I don't know if you would like to have a run there? If so you would need 
to rebase against git://anongit.freedesktop.org/drm-tip drm-tip and you 
could even send a series to intel-gfx-trybot@lists.freedesktop.org, 
suppressing cc, to check it out without sending a copy to the real 
mailing list.

Regards,

Tvrtko

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   drivers/gpu/drm/i915/Kconfig              |   1 +
>   drivers/gpu/drm/i915/gem/i915_gem_pages.c | 101 ++++++++++------------
>   2 files changed, 47 insertions(+), 55 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
> index 9afa5c4a6bf006..1e1cb245fca778 100644
> --- a/drivers/gpu/drm/i915/Kconfig
> +++ b/drivers/gpu/drm/i915/Kconfig
> @@ -25,6 +25,7 @@ config DRM_I915
>   	select CRC32
>   	select SND_HDA_I915 if SND_HDA_CORE
>   	select CEC_CORE if CEC_NOTIFIER
> +	select VMAP_PFN
>   	help
>   	  Choose this option if you have a system that has "Intel Graphics
>   	  Media Accelerator" or "HD Graphics" integrated graphics,
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> index e8a083743e0927..90029ea83aede9 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> @@ -234,50 +234,24 @@ int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
>   	return err;
>   }
>   
> -static inline pte_t iomap_pte(resource_size_t base,
> -			      dma_addr_t offset,
> -			      pgprot_t prot)
> -{
> -	return pte_mkspecial(pfn_pte((base + offset) >> PAGE_SHIFT, prot));
> -}
> -
>   /* The 'mapping' part of i915_gem_object_pin_map() below */
> -static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
> +static void *i915_gem_object_map_page(struct drm_i915_gem_object *obj,
>   				 enum i915_map_type type)
>   {
> -	unsigned long n_pte = obj->base.size >> PAGE_SHIFT;
> -	struct sg_table *sgt = obj->mm.pages;
> -	pte_t *stack[32], **mem;
> -	struct vm_struct *area;
> +	unsigned long n_pages = obj->base.size >> PAGE_SHIFT, i;
> +	struct page *stack[32], **pages = stack, *page;
> +	struct sgt_iter iter;
>   	pgprot_t pgprot;
> -
> -	if (!i915_gem_object_has_struct_page(obj) && type != I915_MAP_WC)
> -		return NULL;
> -
> -	/* A single page can always be kmapped */
> -	if (n_pte == 1 && type == I915_MAP_WB)
> -		return kmap(sg_page(sgt->sgl));
> -
> -	mem = stack;
> -	if (n_pte > ARRAY_SIZE(stack)) {
> -		/* Too big for stack -- allocate temporary array instead */
> -		mem = kvmalloc_array(n_pte, sizeof(*mem), GFP_KERNEL);
> -		if (!mem)
> -			return NULL;
> -	}
> -
> -	area = alloc_vm_area(obj->base.size, mem);
> -	if (!area) {
> -		if (mem != stack)
> -			kvfree(mem);
> -		return NULL;
> -	}
> +	void *vaddr;
>   
>   	switch (type) {
>   	default:
>   		MISSING_CASE(type);
>   		fallthrough;	/* to use PAGE_KERNEL anyway */
>   	case I915_MAP_WB:
> +		/* A single page can always be kmapped */
> +		if (n_pages == 1)
> +			return kmap(sg_page(obj->mm.pages->sgl));
>   		pgprot = PAGE_KERNEL;
>   		break;
>   	case I915_MAP_WC:
> @@ -285,30 +259,44 @@ static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
>   		break;
>   	}
>   
> -	if (i915_gem_object_has_struct_page(obj)) {
> -		struct sgt_iter iter;
> -		struct page *page;
> -		pte_t **ptes = mem;
> -
> -		for_each_sgt_page(page, iter, sgt)
> -			**ptes++ = mk_pte(page, pgprot);
> -	} else {
> -		resource_size_t iomap;
> -		struct sgt_iter iter;
> -		pte_t **ptes = mem;
> -		dma_addr_t addr;
> +	if (n_pages > ARRAY_SIZE(stack)) {
> +		/* Too big for stack -- allocate temporary array instead */
> +		pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL);
> +		if (!pages)
> +			return NULL;
> +	}
>   
> -		iomap = obj->mm.region->iomap.base;
> -		iomap -= obj->mm.region->region.start;
> +	for_each_sgt_page(page, iter, obj->mm.pages)
> +		pages[i++] = page;
> +	vaddr = vmap(pages, n_pages, 0, pgprot);
> +	if (pages != stack)
> +		kvfree(pages);
> +	return vaddr;
> +}
>   
> -		for_each_sgt_daddr(addr, iter, sgt)
> -			**ptes++ = iomap_pte(iomap, addr, pgprot);
> +static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj)
> +{
> +	resource_size_t iomap = obj->mm.region->iomap.base -
> +		obj->mm.region->region.start;
> +	unsigned long n_pfn = obj->base.size >> PAGE_SHIFT;
> +	unsigned long stack[32], *pfns = stack, i;
> +	struct sgt_iter iter;
> +	dma_addr_t addr;
> +	void *vaddr;
> +
> +	if (n_pfn > ARRAY_SIZE(stack)) {
> +		/* Too big for stack -- allocate temporary array instead */
> +		pfns = kvmalloc_array(n_pfn, sizeof(*pfns), GFP_KERNEL);
> +		if (!pfns)
> +			return NULL;
>   	}
>   
> -	if (mem != stack)
> -		kvfree(mem);
> -
> -	return area->addr;
> +	for_each_sgt_daddr(addr, iter, obj->mm.pages)
> +		pfns[i++] = (iomap + addr) >> PAGE_SHIFT;
> +	vaddr = vmap_pfn(pfns, n_pfn, pgprot_writecombine(PAGE_KERNEL_IO));
> +	if (pfns != stack)
> +		kvfree(pfns);
> +	return vaddr;
>   }
>   
>   /* get, pin, and map the pages of the object into kernel space */
> @@ -360,7 +348,10 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
>   	}
>   
>   	if (!ptr) {
> -		ptr = i915_gem_object_map(obj, type);
> +		if (i915_gem_object_has_struct_page(obj))
> +			ptr = i915_gem_object_map_page(obj, type);
> +		else if (type == I915_MAP_WC)
> +			ptr = i915_gem_object_map_pfn(obj);
>   		if (!ptr) {
>   			err = -ENOMEM;
>   			goto err_unpin;
> 

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map
@ 2020-09-23  9:52     ` Tvrtko Ursulin
  0 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-23  9:52 UTC (permalink / raw)
  To: Christoph Hellwig, Andrew Morton
  Cc: Juergen Gross, Stefano Stabellini, Minchan Kim, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, dri-devel, linux-mm, xen-devel,
	Boris Ostrovsky, Nitin Gupta


On 18/09/2020 17:37, Christoph Hellwig wrote:
> i915_gem_object_map implements fairly low-level vmap functionality in
> a driver.  Split it into two helpers, one for remapping kernel memory
> which can use vmap, and one for I/O memory that uses vmap_pfn.
> 
> The only practical difference is that alloc_vm_area prefeaults the
> vmalloc area PTEs, which doesn't seem to be required here for the
> kernel memory case (and could be added to vmap using a flag if actually
> required).

Patch looks good to me.

Series did not get a CI run from our side because of a different base so 
I don't know if you would like to have a run there? If so you would need 
to rebase against git://anongit.freedesktop.org/drm-tip drm-tip and you 
could even send a series to intel-gfx-trybot@lists.freedesktop.org, 
suppressing cc, to check it out without sending a copy to the real 
mailing list.

Regards,

Tvrtko

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   drivers/gpu/drm/i915/Kconfig              |   1 +
>   drivers/gpu/drm/i915/gem/i915_gem_pages.c | 101 ++++++++++------------
>   2 files changed, 47 insertions(+), 55 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
> index 9afa5c4a6bf006..1e1cb245fca778 100644
> --- a/drivers/gpu/drm/i915/Kconfig
> +++ b/drivers/gpu/drm/i915/Kconfig
> @@ -25,6 +25,7 @@ config DRM_I915
>   	select CRC32
>   	select SND_HDA_I915 if SND_HDA_CORE
>   	select CEC_CORE if CEC_NOTIFIER
> +	select VMAP_PFN
>   	help
>   	  Choose this option if you have a system that has "Intel Graphics
>   	  Media Accelerator" or "HD Graphics" integrated graphics,
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> index e8a083743e0927..90029ea83aede9 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> @@ -234,50 +234,24 @@ int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
>   	return err;
>   }
>   
> -static inline pte_t iomap_pte(resource_size_t base,
> -			      dma_addr_t offset,
> -			      pgprot_t prot)
> -{
> -	return pte_mkspecial(pfn_pte((base + offset) >> PAGE_SHIFT, prot));
> -}
> -
>   /* The 'mapping' part of i915_gem_object_pin_map() below */
> -static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
> +static void *i915_gem_object_map_page(struct drm_i915_gem_object *obj,
>   				 enum i915_map_type type)
>   {
> -	unsigned long n_pte = obj->base.size >> PAGE_SHIFT;
> -	struct sg_table *sgt = obj->mm.pages;
> -	pte_t *stack[32], **mem;
> -	struct vm_struct *area;
> +	unsigned long n_pages = obj->base.size >> PAGE_SHIFT, i;
> +	struct page *stack[32], **pages = stack, *page;
> +	struct sgt_iter iter;
>   	pgprot_t pgprot;
> -
> -	if (!i915_gem_object_has_struct_page(obj) && type != I915_MAP_WC)
> -		return NULL;
> -
> -	/* A single page can always be kmapped */
> -	if (n_pte == 1 && type == I915_MAP_WB)
> -		return kmap(sg_page(sgt->sgl));
> -
> -	mem = stack;
> -	if (n_pte > ARRAY_SIZE(stack)) {
> -		/* Too big for stack -- allocate temporary array instead */
> -		mem = kvmalloc_array(n_pte, sizeof(*mem), GFP_KERNEL);
> -		if (!mem)
> -			return NULL;
> -	}
> -
> -	area = alloc_vm_area(obj->base.size, mem);
> -	if (!area) {
> -		if (mem != stack)
> -			kvfree(mem);
> -		return NULL;
> -	}
> +	void *vaddr;
>   
>   	switch (type) {
>   	default:
>   		MISSING_CASE(type);
>   		fallthrough;	/* to use PAGE_KERNEL anyway */
>   	case I915_MAP_WB:
> +		/* A single page can always be kmapped */
> +		if (n_pages == 1)
> +			return kmap(sg_page(obj->mm.pages->sgl));
>   		pgprot = PAGE_KERNEL;
>   		break;
>   	case I915_MAP_WC:
> @@ -285,30 +259,44 @@ static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
>   		break;
>   	}
>   
> -	if (i915_gem_object_has_struct_page(obj)) {
> -		struct sgt_iter iter;
> -		struct page *page;
> -		pte_t **ptes = mem;
> -
> -		for_each_sgt_page(page, iter, sgt)
> -			**ptes++ = mk_pte(page, pgprot);
> -	} else {
> -		resource_size_t iomap;
> -		struct sgt_iter iter;
> -		pte_t **ptes = mem;
> -		dma_addr_t addr;
> +	if (n_pages > ARRAY_SIZE(stack)) {
> +		/* Too big for stack -- allocate temporary array instead */
> +		pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL);
> +		if (!pages)
> +			return NULL;
> +	}
>   
> -		iomap = obj->mm.region->iomap.base;
> -		iomap -= obj->mm.region->region.start;
> +	for_each_sgt_page(page, iter, obj->mm.pages)
> +		pages[i++] = page;
> +	vaddr = vmap(pages, n_pages, 0, pgprot);
> +	if (pages != stack)
> +		kvfree(pages);
> +	return vaddr;
> +}
>   
> -		for_each_sgt_daddr(addr, iter, sgt)
> -			**ptes++ = iomap_pte(iomap, addr, pgprot);
> +static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj)
> +{
> +	resource_size_t iomap = obj->mm.region->iomap.base -
> +		obj->mm.region->region.start;
> +	unsigned long n_pfn = obj->base.size >> PAGE_SHIFT;
> +	unsigned long stack[32], *pfns = stack, i;
> +	struct sgt_iter iter;
> +	dma_addr_t addr;
> +	void *vaddr;
> +
> +	if (n_pfn > ARRAY_SIZE(stack)) {
> +		/* Too big for stack -- allocate temporary array instead */
> +		pfns = kvmalloc_array(n_pfn, sizeof(*pfns), GFP_KERNEL);
> +		if (!pfns)
> +			return NULL;
>   	}
>   
> -	if (mem != stack)
> -		kvfree(mem);
> -
> -	return area->addr;
> +	for_each_sgt_daddr(addr, iter, obj->mm.pages)
> +		pfns[i++] = (iomap + addr) >> PAGE_SHIFT;
> +	vaddr = vmap_pfn(pfns, n_pfn, pgprot_writecombine(PAGE_KERNEL_IO));
> +	if (pfns != stack)
> +		kvfree(pfns);
> +	return vaddr;
>   }
>   
>   /* get, pin, and map the pages of the object into kernel space */
> @@ -360,7 +348,10 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
>   	}
>   
>   	if (!ptr) {
> -		ptr = i915_gem_object_map(obj, type);
> +		if (i915_gem_object_has_struct_page(obj))
> +			ptr = i915_gem_object_map_page(obj, type);
> +		else if (type == I915_MAP_WC)
> +			ptr = i915_gem_object_map_pfn(obj);
>   		if (!ptr) {
>   			err = -ENOMEM;
>   			goto err_unpin;
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map
@ 2020-09-23  9:52     ` Tvrtko Ursulin
  0 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-23  9:52 UTC (permalink / raw)
  To: Christoph Hellwig, Andrew Morton
  Cc: Juergen Gross, Stefano Stabellini, Minchan Kim, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, dri-devel, linux-mm, xen-devel,
	Boris Ostrovsky, Nitin Gupta


On 18/09/2020 17:37, Christoph Hellwig wrote:
> i915_gem_object_map implements fairly low-level vmap functionality in
> a driver.  Split it into two helpers, one for remapping kernel memory
> which can use vmap, and one for I/O memory that uses vmap_pfn.
> 
> The only practical difference is that alloc_vm_area prefeaults the
> vmalloc area PTEs, which doesn't seem to be required here for the
> kernel memory case (and could be added to vmap using a flag if actually
> required).

Patch looks good to me.

Series did not get a CI run from our side because of a different base so 
I don't know if you would like to have a run there? If so you would need 
to rebase against git://anongit.freedesktop.org/drm-tip drm-tip and you 
could even send a series to intel-gfx-trybot@lists.freedesktop.org, 
suppressing cc, to check it out without sending a copy to the real 
mailing list.

Regards,

Tvrtko

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>   drivers/gpu/drm/i915/Kconfig              |   1 +
>   drivers/gpu/drm/i915/gem/i915_gem_pages.c | 101 ++++++++++------------
>   2 files changed, 47 insertions(+), 55 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
> index 9afa5c4a6bf006..1e1cb245fca778 100644
> --- a/drivers/gpu/drm/i915/Kconfig
> +++ b/drivers/gpu/drm/i915/Kconfig
> @@ -25,6 +25,7 @@ config DRM_I915
>   	select CRC32
>   	select SND_HDA_I915 if SND_HDA_CORE
>   	select CEC_CORE if CEC_NOTIFIER
> +	select VMAP_PFN
>   	help
>   	  Choose this option if you have a system that has "Intel Graphics
>   	  Media Accelerator" or "HD Graphics" integrated graphics,
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> index e8a083743e0927..90029ea83aede9 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> @@ -234,50 +234,24 @@ int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
>   	return err;
>   }
>   
> -static inline pte_t iomap_pte(resource_size_t base,
> -			      dma_addr_t offset,
> -			      pgprot_t prot)
> -{
> -	return pte_mkspecial(pfn_pte((base + offset) >> PAGE_SHIFT, prot));
> -}
> -
>   /* The 'mapping' part of i915_gem_object_pin_map() below */
> -static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
> +static void *i915_gem_object_map_page(struct drm_i915_gem_object *obj,
>   				 enum i915_map_type type)
>   {
> -	unsigned long n_pte = obj->base.size >> PAGE_SHIFT;
> -	struct sg_table *sgt = obj->mm.pages;
> -	pte_t *stack[32], **mem;
> -	struct vm_struct *area;
> +	unsigned long n_pages = obj->base.size >> PAGE_SHIFT, i;
> +	struct page *stack[32], **pages = stack, *page;
> +	struct sgt_iter iter;
>   	pgprot_t pgprot;
> -
> -	if (!i915_gem_object_has_struct_page(obj) && type != I915_MAP_WC)
> -		return NULL;
> -
> -	/* A single page can always be kmapped */
> -	if (n_pte == 1 && type == I915_MAP_WB)
> -		return kmap(sg_page(sgt->sgl));
> -
> -	mem = stack;
> -	if (n_pte > ARRAY_SIZE(stack)) {
> -		/* Too big for stack -- allocate temporary array instead */
> -		mem = kvmalloc_array(n_pte, sizeof(*mem), GFP_KERNEL);
> -		if (!mem)
> -			return NULL;
> -	}
> -
> -	area = alloc_vm_area(obj->base.size, mem);
> -	if (!area) {
> -		if (mem != stack)
> -			kvfree(mem);
> -		return NULL;
> -	}
> +	void *vaddr;
>   
>   	switch (type) {
>   	default:
>   		MISSING_CASE(type);
>   		fallthrough;	/* to use PAGE_KERNEL anyway */
>   	case I915_MAP_WB:
> +		/* A single page can always be kmapped */
> +		if (n_pages == 1)
> +			return kmap(sg_page(obj->mm.pages->sgl));
>   		pgprot = PAGE_KERNEL;
>   		break;
>   	case I915_MAP_WC:
> @@ -285,30 +259,44 @@ static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
>   		break;
>   	}
>   
> -	if (i915_gem_object_has_struct_page(obj)) {
> -		struct sgt_iter iter;
> -		struct page *page;
> -		pte_t **ptes = mem;
> -
> -		for_each_sgt_page(page, iter, sgt)
> -			**ptes++ = mk_pte(page, pgprot);
> -	} else {
> -		resource_size_t iomap;
> -		struct sgt_iter iter;
> -		pte_t **ptes = mem;
> -		dma_addr_t addr;
> +	if (n_pages > ARRAY_SIZE(stack)) {
> +		/* Too big for stack -- allocate temporary array instead */
> +		pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL);
> +		if (!pages)
> +			return NULL;
> +	}
>   
> -		iomap = obj->mm.region->iomap.base;
> -		iomap -= obj->mm.region->region.start;
> +	for_each_sgt_page(page, iter, obj->mm.pages)
> +		pages[i++] = page;
> +	vaddr = vmap(pages, n_pages, 0, pgprot);
> +	if (pages != stack)
> +		kvfree(pages);
> +	return vaddr;
> +}
>   
> -		for_each_sgt_daddr(addr, iter, sgt)
> -			**ptes++ = iomap_pte(iomap, addr, pgprot);
> +static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj)
> +{
> +	resource_size_t iomap = obj->mm.region->iomap.base -
> +		obj->mm.region->region.start;
> +	unsigned long n_pfn = obj->base.size >> PAGE_SHIFT;
> +	unsigned long stack[32], *pfns = stack, i;
> +	struct sgt_iter iter;
> +	dma_addr_t addr;
> +	void *vaddr;
> +
> +	if (n_pfn > ARRAY_SIZE(stack)) {
> +		/* Too big for stack -- allocate temporary array instead */
> +		pfns = kvmalloc_array(n_pfn, sizeof(*pfns), GFP_KERNEL);
> +		if (!pfns)
> +			return NULL;
>   	}
>   
> -	if (mem != stack)
> -		kvfree(mem);
> -
> -	return area->addr;
> +	for_each_sgt_daddr(addr, iter, obj->mm.pages)
> +		pfns[i++] = (iomap + addr) >> PAGE_SHIFT;
> +	vaddr = vmap_pfn(pfns, n_pfn, pgprot_writecombine(PAGE_KERNEL_IO));
> +	if (pfns != stack)
> +		kvfree(pfns);
> +	return vaddr;
>   }
>   
>   /* get, pin, and map the pages of the object into kernel space */
> @@ -360,7 +348,10 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
>   	}
>   
>   	if (!ptr) {
> -		ptr = i915_gem_object_map(obj, type);
> +		if (i915_gem_object_has_struct_page(obj))
> +			ptr = i915_gem_object_map_page(obj, type);
> +		else if (type == I915_MAP_WC)
> +			ptr = i915_gem_object_map_pfn(obj);
>   		if (!ptr) {
>   			err = -ENOMEM;
>   			goto err_unpin;
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map
  2020-09-23  9:52     ` Tvrtko Ursulin
@ 2020-09-23 13:41       ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-23 13:41 UTC (permalink / raw)
  To: Tvrtko Ursulin
  Cc: Christoph Hellwig, Andrew Morton, Juergen Gross,
	Stefano Stabellini, linux-mm, Peter Zijlstra, intel-gfx, x86,
	linux-kernel, Minchan Kim, dri-devel, xen-devel, Boris Ostrovsky,
	Nitin Gupta

On Wed, Sep 23, 2020 at 10:52:33AM +0100, Tvrtko Ursulin wrote:
>
> On 18/09/2020 17:37, Christoph Hellwig wrote:
>> i915_gem_object_map implements fairly low-level vmap functionality in
>> a driver.  Split it into two helpers, one for remapping kernel memory
>> which can use vmap, and one for I/O memory that uses vmap_pfn.
>>
>> The only practical difference is that alloc_vm_area prefeaults the
>> vmalloc area PTEs, which doesn't seem to be required here for the
>> kernel memory case (and could be added to vmap using a flag if actually
>> required).
>
> Patch looks good to me.
>
> Series did not get a CI run from our side because of a different base so I 
> don't know if you would like to have a run there? If so you would need to 
> rebase against git://anongit.freedesktop.org/drm-tip drm-tip and you could 
> even send a series to intel-gfx-trybot@lists.freedesktop.org, suppressing 
> cc, to check it out without sending a copy to the real mailing list.

It doesn't seem like I can post to any freedesktop list, as I always
get rejection messages.  But I'll happily prepare a branch if one
of you an feed it into your CI.

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map
@ 2020-09-23 13:41       ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-23 13:41 UTC (permalink / raw)
  To: Tvrtko Ursulin
  Cc: Juergen Gross, Stefano Stabellini, Boris Ostrovsky, Minchan Kim,
	Peter Zijlstra, intel-gfx, x86, linux-kernel, dri-devel,
	linux-mm, xen-devel, Andrew Morton, Christoph Hellwig,
	Nitin Gupta

On Wed, Sep 23, 2020 at 10:52:33AM +0100, Tvrtko Ursulin wrote:
>
> On 18/09/2020 17:37, Christoph Hellwig wrote:
>> i915_gem_object_map implements fairly low-level vmap functionality in
>> a driver.  Split it into two helpers, one for remapping kernel memory
>> which can use vmap, and one for I/O memory that uses vmap_pfn.
>>
>> The only practical difference is that alloc_vm_area prefeaults the
>> vmalloc area PTEs, which doesn't seem to be required here for the
>> kernel memory case (and could be added to vmap using a flag if actually
>> required).
>
> Patch looks good to me.
>
> Series did not get a CI run from our side because of a different base so I 
> don't know if you would like to have a run there? If so you would need to 
> rebase against git://anongit.freedesktop.org/drm-tip drm-tip and you could 
> even send a series to intel-gfx-trybot@lists.freedesktop.org, suppressing 
> cc, to check it out without sending a copy to the real mailing list.

It doesn't seem like I can post to any freedesktop list, as I always
get rejection messages.  But I'll happily prepare a branch if one
of you an feed it into your CI.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map
  2020-09-23 13:41       ` Christoph Hellwig
  (?)
@ 2020-09-23 13:58         ` Tvrtko Ursulin
  -1 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-23 13:58 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, Juergen Gross, Stefano Stabellini, linux-mm,
	Peter Zijlstra, intel-gfx, x86, linux-kernel, Minchan Kim,
	dri-devel, xen-devel, Boris Ostrovsky, Nitin Gupta


On 23/09/2020 14:41, Christoph Hellwig wrote:
> On Wed, Sep 23, 2020 at 10:52:33AM +0100, Tvrtko Ursulin wrote:
>>
>> On 18/09/2020 17:37, Christoph Hellwig wrote:
>>> i915_gem_object_map implements fairly low-level vmap functionality in
>>> a driver.  Split it into two helpers, one for remapping kernel memory
>>> which can use vmap, and one for I/O memory that uses vmap_pfn.
>>>
>>> The only practical difference is that alloc_vm_area prefeaults the
>>> vmalloc area PTEs, which doesn't seem to be required here for the
>>> kernel memory case (and could be added to vmap using a flag if actually
>>> required).
>>
>> Patch looks good to me.
>>
>> Series did not get a CI run from our side because of a different base so I
>> don't know if you would like to have a run there? If so you would need to
>> rebase against git://anongit.freedesktop.org/drm-tip drm-tip and you could
>> even send a series to intel-gfx-trybot@lists.freedesktop.org, suppressing
>> cc, to check it out without sending a copy to the real mailing list.
> 
> It doesn't seem like I can post to any freedesktop list, as I always
> get rejection messages.  But I'll happily prepare a branch if one
> of you an feed it into your CI.

That's fine, just ping me and I will forward it for testing, thanks!

Regards,

Tvrtko

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map
@ 2020-09-23 13:58         ` Tvrtko Ursulin
  0 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-23 13:58 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, Minchan Kim, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, dri-devel, linux-mm, xen-devel,
	Andrew Morton, Boris Ostrovsky, Nitin Gupta


On 23/09/2020 14:41, Christoph Hellwig wrote:
> On Wed, Sep 23, 2020 at 10:52:33AM +0100, Tvrtko Ursulin wrote:
>>
>> On 18/09/2020 17:37, Christoph Hellwig wrote:
>>> i915_gem_object_map implements fairly low-level vmap functionality in
>>> a driver.  Split it into two helpers, one for remapping kernel memory
>>> which can use vmap, and one for I/O memory that uses vmap_pfn.
>>>
>>> The only practical difference is that alloc_vm_area prefeaults the
>>> vmalloc area PTEs, which doesn't seem to be required here for the
>>> kernel memory case (and could be added to vmap using a flag if actually
>>> required).
>>
>> Patch looks good to me.
>>
>> Series did not get a CI run from our side because of a different base so I
>> don't know if you would like to have a run there? If so you would need to
>> rebase against git://anongit.freedesktop.org/drm-tip drm-tip and you could
>> even send a series to intel-gfx-trybot@lists.freedesktop.org, suppressing
>> cc, to check it out without sending a copy to the real mailing list.
> 
> It doesn't seem like I can post to any freedesktop list, as I always
> get rejection messages.  But I'll happily prepare a branch if one
> of you an feed it into your CI.

That's fine, just ping me and I will forward it for testing, thanks!

Regards,

Tvrtko
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map
@ 2020-09-23 13:58         ` Tvrtko Ursulin
  0 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-23 13:58 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, Minchan Kim, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, dri-devel, linux-mm, xen-devel,
	Andrew Morton, Boris Ostrovsky, Nitin Gupta


On 23/09/2020 14:41, Christoph Hellwig wrote:
> On Wed, Sep 23, 2020 at 10:52:33AM +0100, Tvrtko Ursulin wrote:
>>
>> On 18/09/2020 17:37, Christoph Hellwig wrote:
>>> i915_gem_object_map implements fairly low-level vmap functionality in
>>> a driver.  Split it into two helpers, one for remapping kernel memory
>>> which can use vmap, and one for I/O memory that uses vmap_pfn.
>>>
>>> The only practical difference is that alloc_vm_area prefeaults the
>>> vmalloc area PTEs, which doesn't seem to be required here for the
>>> kernel memory case (and could be added to vmap using a flag if actually
>>> required).
>>
>> Patch looks good to me.
>>
>> Series did not get a CI run from our side because of a different base so I
>> don't know if you would like to have a run there? If so you would need to
>> rebase against git://anongit.freedesktop.org/drm-tip drm-tip and you could
>> even send a series to intel-gfx-trybot@lists.freedesktop.org, suppressing
>> cc, to check it out without sending a copy to the real mailing list.
> 
> It doesn't seem like I can post to any freedesktop list, as I always
> get rejection messages.  But I'll happily prepare a branch if one
> of you an feed it into your CI.

That's fine, just ping me and I will forward it for testing, thanks!

Regards,

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

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map
  2020-09-23 13:58         ` Tvrtko Ursulin
@ 2020-09-23 14:44           ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-23 14:44 UTC (permalink / raw)
  To: Tvrtko Ursulin
  Cc: Christoph Hellwig, Andrew Morton, Juergen Gross,
	Stefano Stabellini, linux-mm, Peter Zijlstra, intel-gfx, x86,
	linux-kernel, Minchan Kim, dri-devel, xen-devel, Boris Ostrovsky,
	Nitin Gupta

On Wed, Sep 23, 2020 at 02:58:43PM +0100, Tvrtko Ursulin wrote:
>>> Series did not get a CI run from our side because of a different base so I
>>> don't know if you would like to have a run there? If so you would need to
>>> rebase against git://anongit.freedesktop.org/drm-tip drm-tip and you could
>>> even send a series to intel-gfx-trybot@lists.freedesktop.org, suppressing
>>> cc, to check it out without sending a copy to the real mailing list.
>>
>> It doesn't seem like I can post to any freedesktop list, as I always
>> get rejection messages.  But I'll happily prepare a branch if one
>> of you an feed it into your CI.
>
> That's fine, just ping me and I will forward it for testing, thanks!

    git://git.infradead.org/users/hch/misc.git i915-vmap-wip

Gitweb:

    http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/i915-vmap-wip

note that this includes a new commit to clean up one of the recent
commits in the code.

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map
@ 2020-09-23 14:44           ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-23 14:44 UTC (permalink / raw)
  To: Tvrtko Ursulin
  Cc: Juergen Gross, Stefano Stabellini, Boris Ostrovsky, Minchan Kim,
	Peter Zijlstra, intel-gfx, x86, linux-kernel, dri-devel,
	linux-mm, xen-devel, Andrew Morton, Christoph Hellwig,
	Nitin Gupta

On Wed, Sep 23, 2020 at 02:58:43PM +0100, Tvrtko Ursulin wrote:
>>> Series did not get a CI run from our side because of a different base so I
>>> don't know if you would like to have a run there? If so you would need to
>>> rebase against git://anongit.freedesktop.org/drm-tip drm-tip and you could
>>> even send a series to intel-gfx-trybot@lists.freedesktop.org, suppressing
>>> cc, to check it out without sending a copy to the real mailing list.
>>
>> It doesn't seem like I can post to any freedesktop list, as I always
>> get rejection messages.  But I'll happily prepare a branch if one
>> of you an feed it into your CI.
>
> That's fine, just ping me and I will forward it for testing, thanks!

    git://git.infradead.org/users/hch/misc.git i915-vmap-wip

Gitweb:

    http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/i915-vmap-wip

note that this includes a new commit to clean up one of the recent
commits in the code.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map
  2020-09-23 14:44           ` Christoph Hellwig
  (?)
@ 2020-09-24 12:22             ` Tvrtko Ursulin
  -1 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-24 12:22 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Andrew Morton, Juergen Gross, Stefano Stabellini, linux-mm,
	Peter Zijlstra, intel-gfx, x86, linux-kernel, Minchan Kim,
	dri-devel, xen-devel, Boris Ostrovsky, Nitin Gupta


On 23/09/2020 15:44, Christoph Hellwig wrote:
> On Wed, Sep 23, 2020 at 02:58:43PM +0100, Tvrtko Ursulin wrote:
>>>> Series did not get a CI run from our side because of a different base so I
>>>> don't know if you would like to have a run there? If so you would need to
>>>> rebase against git://anongit.freedesktop.org/drm-tip drm-tip and you could
>>>> even send a series to intel-gfx-trybot@lists.freedesktop.org, suppressing
>>>> cc, to check it out without sending a copy to the real mailing list.
>>>
>>> It doesn't seem like I can post to any freedesktop list, as I always
>>> get rejection messages.  But I'll happily prepare a branch if one
>>> of you an feed it into your CI.
>>
>> That's fine, just ping me and I will forward it for testing, thanks!
> 
>      git://git.infradead.org/users/hch/misc.git i915-vmap-wip
> 
> Gitweb:
> 
>      http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/i915-vmap-wip
> 
> note that this includes a new commit to clean up one of the recent
> commits in the code.

CI says series looks good from the i915 perspective (*).

I don't know how will you handle it logistically, but when you have 
final version I am happy to re-read and r-b the i915 patches.


Regards,

Tvrtko

*)
https://patchwork.freedesktop.org/series/82051/

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map
@ 2020-09-24 12:22             ` Tvrtko Ursulin
  0 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-24 12:22 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, Minchan Kim, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, dri-devel, linux-mm, xen-devel,
	Andrew Morton, Boris Ostrovsky, Nitin Gupta


On 23/09/2020 15:44, Christoph Hellwig wrote:
> On Wed, Sep 23, 2020 at 02:58:43PM +0100, Tvrtko Ursulin wrote:
>>>> Series did not get a CI run from our side because of a different base so I
>>>> don't know if you would like to have a run there? If so you would need to
>>>> rebase against git://anongit.freedesktop.org/drm-tip drm-tip and you could
>>>> even send a series to intel-gfx-trybot@lists.freedesktop.org, suppressing
>>>> cc, to check it out without sending a copy to the real mailing list.
>>>
>>> It doesn't seem like I can post to any freedesktop list, as I always
>>> get rejection messages.  But I'll happily prepare a branch if one
>>> of you an feed it into your CI.
>>
>> That's fine, just ping me and I will forward it for testing, thanks!
> 
>      git://git.infradead.org/users/hch/misc.git i915-vmap-wip
> 
> Gitweb:
> 
>      http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/i915-vmap-wip
> 
> note that this includes a new commit to clean up one of the recent
> commits in the code.

CI says series looks good from the i915 perspective (*).

I don't know how will you handle it logistically, but when you have 
final version I am happy to re-read and r-b the i915 patches.


Regards,

Tvrtko

*)
https://patchwork.freedesktop.org/series/82051/
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map
@ 2020-09-24 12:22             ` Tvrtko Ursulin
  0 siblings, 0 replies; 85+ messages in thread
From: Tvrtko Ursulin @ 2020-09-24 12:22 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Juergen Gross, Stefano Stabellini, Minchan Kim, Peter Zijlstra,
	intel-gfx, x86, linux-kernel, dri-devel, linux-mm, xen-devel,
	Andrew Morton, Boris Ostrovsky, Nitin Gupta


On 23/09/2020 15:44, Christoph Hellwig wrote:
> On Wed, Sep 23, 2020 at 02:58:43PM +0100, Tvrtko Ursulin wrote:
>>>> Series did not get a CI run from our side because of a different base so I
>>>> don't know if you would like to have a run there? If so you would need to
>>>> rebase against git://anongit.freedesktop.org/drm-tip drm-tip and you could
>>>> even send a series to intel-gfx-trybot@lists.freedesktop.org, suppressing
>>>> cc, to check it out without sending a copy to the real mailing list.
>>>
>>> It doesn't seem like I can post to any freedesktop list, as I always
>>> get rejection messages.  But I'll happily prepare a branch if one
>>> of you an feed it into your CI.
>>
>> That's fine, just ping me and I will forward it for testing, thanks!
> 
>      git://git.infradead.org/users/hch/misc.git i915-vmap-wip
> 
> Gitweb:
> 
>      http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/i915-vmap-wip
> 
> note that this includes a new commit to clean up one of the recent
> commits in the code.

CI says series looks good from the i915 perspective (*).

I don't know how will you handle it logistically, but when you have 
final version I am happy to re-read and r-b the i915 patches.


Regards,

Tvrtko

*)
https://patchwork.freedesktop.org/series/82051/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map
  2020-09-24 12:22             ` Tvrtko Ursulin
@ 2020-09-24 13:23               ` Christoph Hellwig
  -1 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-24 13:23 UTC (permalink / raw)
  To: Tvrtko Ursulin
  Cc: Christoph Hellwig, Andrew Morton, Juergen Gross,
	Stefano Stabellini, linux-mm, Peter Zijlstra, intel-gfx, x86,
	linux-kernel, Minchan Kim, dri-devel, xen-devel, Boris Ostrovsky,
	Nitin Gupta

On Thu, Sep 24, 2020 at 01:22:35PM +0100, Tvrtko Ursulin wrote:
> CI says series looks good from the i915 perspective (*).
>
> I don't know how will you handle it logistically, but when you have final 
> version I am happy to re-read and r-b the i915 patches.

I'll resend the series later today, and will make sure you are on the
Cc list.

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

* Re: [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map
@ 2020-09-24 13:23               ` Christoph Hellwig
  0 siblings, 0 replies; 85+ messages in thread
From: Christoph Hellwig @ 2020-09-24 13:23 UTC (permalink / raw)
  To: Tvrtko Ursulin
  Cc: Juergen Gross, Stefano Stabellini, Boris Ostrovsky, Minchan Kim,
	Peter Zijlstra, intel-gfx, x86, linux-kernel, dri-devel,
	linux-mm, xen-devel, Andrew Morton, Christoph Hellwig,
	Nitin Gupta

On Thu, Sep 24, 2020 at 01:22:35PM +0100, Tvrtko Ursulin wrote:
> CI says series looks good from the i915 perspective (*).
>
> I don't know how will you handle it logistically, but when you have final 
> version I am happy to re-read and r-b the i915 patches.

I'll resend the series later today, and will make sure you are on the
Cc list.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2020-09-24 13:23 UTC | newest]

Thread overview: 85+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-18 16:37 remove alloc_vm_area Christoph Hellwig
2020-09-18 16:37 ` [Intel-gfx] " Christoph Hellwig
2020-09-18 16:37 ` [PATCH 1/6] zsmalloc: switch from alloc_vm_area to get_vm_area Christoph Hellwig
2020-09-18 16:37   ` [Intel-gfx] " Christoph Hellwig
2020-09-21 17:42   ` Minchan Kim
2020-09-21 17:42     ` [Intel-gfx] " Minchan Kim
2020-09-21 17:42     ` Minchan Kim
2020-09-21 18:17     ` Christoph Hellwig
2020-09-21 18:17       ` [Intel-gfx] " Christoph Hellwig
2020-09-21 18:42       ` Minchan Kim
2020-09-21 18:42         ` [Intel-gfx] " Minchan Kim
2020-09-21 18:42         ` Minchan Kim
2020-09-21 18:43         ` Christoph Hellwig
2020-09-21 18:43           ` [Intel-gfx] " Christoph Hellwig
2020-09-18 16:37 ` [PATCH 2/6] mm: add a vmap_pfn function Christoph Hellwig
2020-09-18 16:37   ` [Intel-gfx] " Christoph Hellwig
2020-09-18 16:37 ` [PATCH 3/6] drm/i915: use vmap in shmem_pin_map Christoph Hellwig
2020-09-18 16:37   ` [Intel-gfx] " Christoph Hellwig
2020-09-21 19:11   ` Matthew Wilcox
2020-09-21 19:11     ` [Intel-gfx] " Matthew Wilcox
2020-09-21 19:11     ` Matthew Wilcox
2020-09-22  6:22     ` Christoph Hellwig
2020-09-22  6:22       ` [Intel-gfx] " Christoph Hellwig
2020-09-22  8:23       ` Tvrtko Ursulin
2020-09-22  8:23         ` Tvrtko Ursulin
2020-09-22  8:23         ` Tvrtko Ursulin
2020-09-22 14:31         ` Christoph Hellwig
2020-09-22 14:31           ` Christoph Hellwig
2020-09-22 16:13           ` Tvrtko Ursulin
2020-09-22 16:13             ` Tvrtko Ursulin
2020-09-22 16:13             ` Tvrtko Ursulin
2020-09-22 16:33             ` Christoph Hellwig
2020-09-22 16:33               ` Christoph Hellwig
2020-09-22 17:04               ` Tvrtko Ursulin
2020-09-22 17:04                 ` Tvrtko Ursulin
2020-09-22 17:04                 ` Tvrtko Ursulin
2020-09-23  6:11                 ` Christoph Hellwig
2020-09-23  6:11                   ` Christoph Hellwig
2020-09-22 11:21       ` Matthew Wilcox
2020-09-22 11:21         ` [Intel-gfx] " Matthew Wilcox
2020-09-22 11:21         ` Matthew Wilcox
2020-09-22 14:39         ` Christoph Hellwig
2020-09-22 14:39           ` [Intel-gfx] " Christoph Hellwig
2020-09-22 14:53           ` Matthew Wilcox
2020-09-22 14:53             ` [Intel-gfx] " Matthew Wilcox
2020-09-22 14:53             ` Matthew Wilcox
2020-09-18 16:37 ` [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map Christoph Hellwig
2020-09-18 16:37   ` [Intel-gfx] " Christoph Hellwig
2020-09-23  9:52   ` Tvrtko Ursulin
2020-09-23  9:52     ` Tvrtko Ursulin
2020-09-23  9:52     ` Tvrtko Ursulin
2020-09-23 13:41     ` Christoph Hellwig
2020-09-23 13:41       ` Christoph Hellwig
2020-09-23 13:58       ` Tvrtko Ursulin
2020-09-23 13:58         ` Tvrtko Ursulin
2020-09-23 13:58         ` Tvrtko Ursulin
2020-09-23 14:44         ` Christoph Hellwig
2020-09-23 14:44           ` Christoph Hellwig
2020-09-24 12:22           ` Tvrtko Ursulin
2020-09-24 12:22             ` Tvrtko Ursulin
2020-09-24 12:22             ` Tvrtko Ursulin
2020-09-24 13:23             ` Christoph Hellwig
2020-09-24 13:23               ` Christoph Hellwig
2020-09-18 16:37 ` [PATCH 5/6] xen/xenbus: use apply_to_page_range directly in xenbus_map_ring_pv Christoph Hellwig
2020-09-18 16:37   ` [Intel-gfx] " Christoph Hellwig
2020-09-18 16:37 ` [PATCH 6/6] x86/xen: open code alloc_vm_area in arch_gnttab_valloc Christoph Hellwig
2020-09-18 16:37   ` [Intel-gfx] " Christoph Hellwig
2020-09-21 20:44   ` boris.ostrovsky
2020-09-21 20:44     ` [Intel-gfx] " boris.ostrovsky
2020-09-21 20:44     ` boris.ostrovsky
2020-09-22 14:58     ` Christoph Hellwig
2020-09-22 14:58       ` [Intel-gfx] " Christoph Hellwig
2020-09-22 15:24       ` boris.ostrovsky
2020-09-22 15:24         ` [Intel-gfx] " boris.ostrovsky
2020-09-22 15:24         ` boris.ostrovsky
2020-09-22 15:27         ` Christoph Hellwig
2020-09-22 15:27           ` [Intel-gfx] " Christoph Hellwig
2020-09-22 15:34           ` boris.ostrovsky
2020-09-22 15:34             ` [Intel-gfx] " boris.ostrovsky
2020-09-22 15:34             ` boris.ostrovsky
2020-09-18 17:03 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area Patchwork
2020-09-21 17:50 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area (rev2) Patchwork
2020-09-21 18:47 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area (rev3) Patchwork
2020-09-22 14:44 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area (rev4) Patchwork
2020-09-22 15:01 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area (rev5) Patchwork

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.