linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* add a not device managed memremap_pages v2
@ 2019-08-16  6:54 Christoph Hellwig
  2019-08-16  6:54 ` [PATCH 1/4] resource: add a not device managed request_free_mem_region variant Christoph Hellwig
                   ` (6 more replies)
  0 siblings, 7 replies; 18+ messages in thread
From: Christoph Hellwig @ 2019-08-16  6:54 UTC (permalink / raw)
  To: Dan Williams, Jason Gunthorpe
  Cc: Bharata B Rao, Andrew Morton, linux-mm, linux-kernel, linux-nvdimm

Hi Dan and Jason,

Bharata has been working on secure page management for kvmppc guests,
and one I thing I noticed is that he had to fake up a struct device
just so that it could be passed to the devm_memremap_pages
instrastructure for device private memory.

This series adds non-device managed versions of the
devm_request_free_mem_region and devm_memremap_pages functions for
his use case.

Changes since v1:
 - don't overload devm_request_free_mem_region
 - export the memremap_pages and munmap_pages as kvmppc can be a module


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

* [PATCH 1/4] resource: add a not device managed request_free_mem_region variant
  2019-08-16  6:54 add a not device managed memremap_pages v2 Christoph Hellwig
@ 2019-08-16  6:54 ` Christoph Hellwig
  2019-08-16 21:01   ` Andrew Morton
  2019-08-16  6:54 ` [PATCH 2/4] memremap: remove the dev field in struct dev_pagemap Christoph Hellwig
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Christoph Hellwig @ 2019-08-16  6:54 UTC (permalink / raw)
  To: Dan Williams, Jason Gunthorpe
  Cc: Bharata B Rao, Andrew Morton, linux-mm, linux-kernel, linux-nvdimm

Just add a simple macro that passes a NULL dev argument to
dev_request_free_mem_region, and call request_mem_region in the
function for that particular case.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 include/linux/ioport.h |  2 ++
 kernel/resource.c      | 45 +++++++++++++++++++++++++++++-------------
 2 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 5b6a7121c9f0..7bddddfc76d6 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -297,6 +297,8 @@ static inline bool resource_overlaps(struct resource *r1, struct resource *r2)
 
 struct resource *devm_request_free_mem_region(struct device *dev,
 		struct resource *base, unsigned long size);
+struct resource *request_free_mem_region(struct resource *base,
+		unsigned long size, const char *name);
 
 #endif /* __ASSEMBLY__ */
 #endif	/* _LINUX_IOPORT_H */
diff --git a/kernel/resource.c b/kernel/resource.c
index 7ea4306503c5..74877e9d90ca 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -1644,19 +1644,8 @@ void resource_list_free(struct list_head *head)
 EXPORT_SYMBOL(resource_list_free);
 
 #ifdef CONFIG_DEVICE_PRIVATE
-/**
- * devm_request_free_mem_region - find free region for device private memory
- *
- * @dev: device struct to bind the resource to
- * @size: size in bytes of the device memory to add
- * @base: resource tree to look in
- *
- * This function tries to find an empty range of physical address big enough to
- * contain the new resource, so that it can later be hotplugged as ZONE_DEVICE
- * memory, which in turn allocates struct pages.
- */
-struct resource *devm_request_free_mem_region(struct device *dev,
-		struct resource *base, unsigned long size)
+static struct resource *__request_free_mem_region(struct device *dev,
+		struct resource *base, unsigned long size, const char *name)
 {
 	resource_size_t end, addr;
 	struct resource *res;
@@ -1670,7 +1659,10 @@ struct resource *devm_request_free_mem_region(struct device *dev,
 				REGION_DISJOINT)
 			continue;
 
-		res = devm_request_mem_region(dev, addr, size, dev_name(dev));
+		if (dev)
+			res = devm_request_mem_region(dev, addr, size, name);
+		else
+			res = request_mem_region(addr, size, name);
 		if (!res)
 			return ERR_PTR(-ENOMEM);
 		res->desc = IORES_DESC_DEVICE_PRIVATE_MEMORY;
@@ -1679,7 +1671,32 @@ struct resource *devm_request_free_mem_region(struct device *dev,
 
 	return ERR_PTR(-ERANGE);
 }
+
+/**
+ * devm_request_free_mem_region - find free region for device private memory
+ *
+ * @dev: device struct to bind the resource to
+ * @size: size in bytes of the device memory to add
+ * @base: resource tree to look in
+ *
+ * This function tries to find an empty range of physical address big enough to
+ * contain the new resource, so that it can later be hotplugged as ZONE_DEVICE
+ * memory, which in turn allocates struct pages.
+ */
+struct resource *devm_request_free_mem_region(struct device *dev,
+		struct resource *base, unsigned long size)
+{
+	return __request_free_mem_region(dev, base, size, dev_name(dev));
+}
 EXPORT_SYMBOL_GPL(devm_request_free_mem_region);
+
+struct resource *request_free_mem_region(struct resource *base,
+		unsigned long size, const char *name)
+{
+	return __request_free_mem_region(NULL, base, size, name);
+}
+EXPORT_SYMBOL_GPL(request_free_mem_region);
+
 #endif /* CONFIG_DEVICE_PRIVATE */
 
 static int __init strict_iomem(char *str)
-- 
2.20.1



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

* [PATCH 2/4] memremap: remove the dev field in struct dev_pagemap
  2019-08-16  6:54 add a not device managed memremap_pages v2 Christoph Hellwig
  2019-08-16  6:54 ` [PATCH 1/4] resource: add a not device managed request_free_mem_region variant Christoph Hellwig
@ 2019-08-16  6:54 ` Christoph Hellwig
  2019-08-16  6:54 ` [PATCH 3/4] memremap: don't use a separate devm action for devmap_managed_enable_get Christoph Hellwig
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 18+ messages in thread
From: Christoph Hellwig @ 2019-08-16  6:54 UTC (permalink / raw)
  To: Dan Williams, Jason Gunthorpe
  Cc: Bharata B Rao, Andrew Morton, linux-mm, linux-kernel, linux-nvdimm

The dev field in struct dev_pagemap is only used to print dev_name in
two places, which are at best nice to have.  Just remove the field
and thus the name in those two messages.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 include/linux/memremap.h | 1 -
 mm/memremap.c            | 6 +-----
 mm/page_alloc.c          | 2 +-
 3 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/include/linux/memremap.h b/include/linux/memremap.h
index f8a5b2a19945..8f0013e18e14 100644
--- a/include/linux/memremap.h
+++ b/include/linux/memremap.h
@@ -109,7 +109,6 @@ struct dev_pagemap {
 	struct percpu_ref *ref;
 	struct percpu_ref internal_ref;
 	struct completion done;
-	struct device *dev;
 	enum memory_type type;
 	unsigned int flags;
 	u64 pci_p2pdma_bus_offset;
diff --git a/mm/memremap.c b/mm/memremap.c
index 86432650f829..416b4129acbb 100644
--- a/mm/memremap.c
+++ b/mm/memremap.c
@@ -102,7 +102,6 @@ static void dev_pagemap_cleanup(struct dev_pagemap *pgmap)
 static void devm_memremap_pages_release(void *data)
 {
 	struct dev_pagemap *pgmap = data;
-	struct device *dev = pgmap->dev;
 	struct resource *res = &pgmap->res;
 	unsigned long pfn;
 	int nid;
@@ -129,8 +128,7 @@ static void devm_memremap_pages_release(void *data)
 
 	untrack_pfn(NULL, PHYS_PFN(res->start), resource_size(res));
 	pgmap_array_delete(res);
-	dev_WARN_ONCE(dev, pgmap->altmap.alloc,
-		      "%s: failed to free all reserved pages\n", __func__);
+	WARN_ONCE(pgmap->altmap.alloc, "failed to free all reserved pages\n");
 }
 
 static void dev_pagemap_percpu_release(struct percpu_ref *ref)
@@ -251,8 +249,6 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
 		goto err_array;
 	}
 
-	pgmap->dev = dev;
-
 	error = xa_err(xa_store_range(&pgmap_array, PHYS_PFN(res->start),
 				PHYS_PFN(res->end), pgmap, GFP_KERNEL));
 	if (error)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 272c6de1bf4e..b39baa2b1faf 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5982,7 +5982,7 @@ void __ref memmap_init_zone_device(struct zone *zone,
 		}
 	}
 
-	pr_info("%s initialised, %lu pages in %ums\n", dev_name(pgmap->dev),
+	pr_info("%s initialised %lu pages in %ums\n", __func__,
 		size, jiffies_to_msecs(jiffies - start));
 }
 
-- 
2.20.1



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

* [PATCH 3/4] memremap: don't use a separate devm action for devmap_managed_enable_get
  2019-08-16  6:54 add a not device managed memremap_pages v2 Christoph Hellwig
  2019-08-16  6:54 ` [PATCH 1/4] resource: add a not device managed request_free_mem_region variant Christoph Hellwig
  2019-08-16  6:54 ` [PATCH 2/4] memremap: remove the dev field in struct dev_pagemap Christoph Hellwig
@ 2019-08-16  6:54 ` Christoph Hellwig
  2019-08-16  6:54 ` [PATCH 4/4] memremap: provide a not device managed memremap_pages Christoph Hellwig
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 18+ messages in thread
From: Christoph Hellwig @ 2019-08-16  6:54 UTC (permalink / raw)
  To: Dan Williams, Jason Gunthorpe
  Cc: Bharata B Rao, Andrew Morton, linux-mm, linux-kernel, linux-nvdimm

Just clean up for early failures and then piggy back on
devm_memremap_pages_release.  This helps with a pending not device
managed version of devm_memremap_pages.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 mm/memremap.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/mm/memremap.c b/mm/memremap.c
index 416b4129acbb..4e11da4ecab9 100644
--- a/mm/memremap.c
+++ b/mm/memremap.c
@@ -21,13 +21,13 @@ DEFINE_STATIC_KEY_FALSE(devmap_managed_key);
 EXPORT_SYMBOL(devmap_managed_key);
 static atomic_t devmap_managed_enable;
 
-static void devmap_managed_enable_put(void *data)
+static void devmap_managed_enable_put(void)
 {
 	if (atomic_dec_and_test(&devmap_managed_enable))
 		static_branch_disable(&devmap_managed_key);
 }
 
-static int devmap_managed_enable_get(struct device *dev, struct dev_pagemap *pgmap)
+static int devmap_managed_enable_get(struct dev_pagemap *pgmap)
 {
 	if (!pgmap->ops || !pgmap->ops->page_free) {
 		WARN(1, "Missing page_free method\n");
@@ -36,13 +36,16 @@ static int devmap_managed_enable_get(struct device *dev, struct dev_pagemap *pgm
 
 	if (atomic_inc_return(&devmap_managed_enable) == 1)
 		static_branch_enable(&devmap_managed_key);
-	return devm_add_action_or_reset(dev, devmap_managed_enable_put, NULL);
+	return 0;
 }
 #else
-static int devmap_managed_enable_get(struct device *dev, struct dev_pagemap *pgmap)
+static int devmap_managed_enable_get(struct dev_pagemap *pgmap)
 {
 	return -EINVAL;
 }
+static void devmap_managed_enable_put(void)
+{
+}
 #endif /* CONFIG_DEV_PAGEMAP_OPS */
 
 static void pgmap_array_delete(struct resource *res)
@@ -129,6 +132,7 @@ static void devm_memremap_pages_release(void *data)
 	untrack_pfn(NULL, PHYS_PFN(res->start), resource_size(res));
 	pgmap_array_delete(res);
 	WARN_ONCE(pgmap->altmap.alloc, "failed to free all reserved pages\n");
+	devmap_managed_enable_put();
 }
 
 static void dev_pagemap_percpu_release(struct percpu_ref *ref)
@@ -218,7 +222,7 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
 	}
 
 	if (need_devmap_managed) {
-		error = devmap_managed_enable_get(dev, pgmap);
+		error = devmap_managed_enable_get(pgmap);
 		if (error)
 			return ERR_PTR(error);
 	}
@@ -327,6 +331,7 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
  err_array:
 	dev_pagemap_kill(pgmap);
 	dev_pagemap_cleanup(pgmap);
+	devmap_managed_enable_put();
 	return ERR_PTR(error);
 }
 EXPORT_SYMBOL_GPL(devm_memremap_pages);
-- 
2.20.1



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

* [PATCH 4/4] memremap: provide a not device managed memremap_pages
  2019-08-16  6:54 add a not device managed memremap_pages v2 Christoph Hellwig
                   ` (2 preceding siblings ...)
  2019-08-16  6:54 ` [PATCH 3/4] memremap: don't use a separate devm action for devmap_managed_enable_get Christoph Hellwig
@ 2019-08-16  6:54 ` Christoph Hellwig
  2019-08-16 21:00   ` Andrew Morton
  2019-08-16 10:48 ` add a not device managed memremap_pages v2 Bharata B Rao
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Christoph Hellwig @ 2019-08-16  6:54 UTC (permalink / raw)
  To: Dan Williams, Jason Gunthorpe
  Cc: Bharata B Rao, Andrew Morton, linux-mm, linux-kernel, linux-nvdimm

The kvmppc ultravisor code wants a device private memory pool that is
system wide and not attached to a device.  Instead of faking up one
provide a low-level memremap_pages for it.  Note that this function is
not exported, and doesn't have a cleanup routine associated with it to
discourage use from more driver like users.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 include/linux/memremap.h |  2 +
 mm/memremap.c            | 84 +++++++++++++++++++++++++---------------
 2 files changed, 54 insertions(+), 32 deletions(-)

diff --git a/include/linux/memremap.h b/include/linux/memremap.h
index 8f0013e18e14..fb2a0bd826b9 100644
--- a/include/linux/memremap.h
+++ b/include/linux/memremap.h
@@ -123,6 +123,8 @@ static inline struct vmem_altmap *pgmap_altmap(struct dev_pagemap *pgmap)
 }
 
 #ifdef CONFIG_ZONE_DEVICE
+void *memremap_pages(struct dev_pagemap *pgmap, int nid);
+void memunmap_pages(struct dev_pagemap *pgmap);
 void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap);
 void devm_memunmap_pages(struct device *dev, struct dev_pagemap *pgmap);
 struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
diff --git a/mm/memremap.c b/mm/memremap.c
index 4e11da4ecab9..9e163fe367ae 100644
--- a/mm/memremap.c
+++ b/mm/memremap.c
@@ -102,9 +102,8 @@ static void dev_pagemap_cleanup(struct dev_pagemap *pgmap)
 		pgmap->ref = NULL;
 }
 
-static void devm_memremap_pages_release(void *data)
+void memunmap_pages(struct dev_pagemap *pgmap)
 {
-	struct dev_pagemap *pgmap = data;
 	struct resource *res = &pgmap->res;
 	unsigned long pfn;
 	int nid;
@@ -134,6 +133,12 @@ static void devm_memremap_pages_release(void *data)
 	WARN_ONCE(pgmap->altmap.alloc, "failed to free all reserved pages\n");
 	devmap_managed_enable_put();
 }
+EXPORT_SYMBOL_GPL(memunmap_pages);
+
+static void devm_memremap_pages_release(void *data)
+{
+	memunmap_pages(data);
+}
 
 static void dev_pagemap_percpu_release(struct percpu_ref *ref)
 {
@@ -143,27 +148,12 @@ static void dev_pagemap_percpu_release(struct percpu_ref *ref)
 	complete(&pgmap->done);
 }
 
-/**
- * devm_memremap_pages - remap and provide memmap backing for the given resource
- * @dev: hosting device for @res
- * @pgmap: pointer to a struct dev_pagemap
- *
- * Notes:
- * 1/ At a minimum the res and type members of @pgmap must be initialized
- *    by the caller before passing it to this function
- *
- * 2/ The altmap field may optionally be initialized, in which case
- *    PGMAP_ALTMAP_VALID must be set in pgmap->flags.
- *
- * 3/ The ref field may optionally be provided, in which pgmap->ref must be
- *    'live' on entry and will be killed and reaped at
- *    devm_memremap_pages_release() time, or if this routine fails.
- *
- * 4/ res is expected to be a host memory range that could feasibly be
- *    treated as a "System RAM" range, i.e. not a device mmio range, but
- *    this is not enforced.
+/*
+ * Not device managed version of dev_memremap_pages, undone by
+ * memunmap_pages().  Please use dev_memremap_pages if you have a struct
+ * device available.
  */
-void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
+void *memremap_pages(struct dev_pagemap *pgmap, int nid)
 {
 	struct resource *res = &pgmap->res;
 	struct dev_pagemap *conflict_pgmap;
@@ -174,7 +164,7 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
 		.altmap = pgmap_altmap(pgmap),
 	};
 	pgprot_t pgprot = PAGE_KERNEL;
-	int error, nid, is_ram;
+	int error, is_ram;
 	bool need_devmap_managed = true;
 
 	switch (pgmap->type) {
@@ -229,7 +219,7 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
 
 	conflict_pgmap = get_dev_pagemap(PHYS_PFN(res->start), NULL);
 	if (conflict_pgmap) {
-		dev_WARN(dev, "Conflicting mapping in same section\n");
+		WARN(1, "Conflicting mapping in same section\n");
 		put_dev_pagemap(conflict_pgmap);
 		error = -ENOMEM;
 		goto err_array;
@@ -237,7 +227,7 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
 
 	conflict_pgmap = get_dev_pagemap(PHYS_PFN(res->end), NULL);
 	if (conflict_pgmap) {
-		dev_WARN(dev, "Conflicting mapping in same section\n");
+		WARN(1, "Conflicting mapping in same section\n");
 		put_dev_pagemap(conflict_pgmap);
 		error = -ENOMEM;
 		goto err_array;
@@ -258,7 +248,6 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
 	if (error)
 		goto err_array;
 
-	nid = dev_to_node(dev);
 	if (nid < 0)
 		nid = numa_mem_id();
 
@@ -314,12 +303,6 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
 				PHYS_PFN(res->start),
 				PHYS_PFN(resource_size(res)), pgmap);
 	percpu_ref_get_many(pgmap->ref, pfn_end(pgmap) - pfn_first(pgmap));
-
-	error = devm_add_action_or_reset(dev, devm_memremap_pages_release,
-			pgmap);
-	if (error)
-		return ERR_PTR(error);
-
 	return __va(res->start);
 
  err_add_memory:
@@ -334,6 +317,43 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
 	devmap_managed_enable_put();
 	return ERR_PTR(error);
 }
+EXPORT_SYMBOL_GPL(memremap_pages);
+
+/**
+ * devm_memremap_pages - remap and provide memmap backing for the given resource
+ * @dev: hosting device for @res
+ * @pgmap: pointer to a struct dev_pagemap
+ *
+ * Notes:
+ * 1/ At a minimum the res and type members of @pgmap must be initialized
+ *    by the caller before passing it to this function
+ *
+ * 2/ The altmap field may optionally be initialized, in which case
+ *    PGMAP_ALTMAP_VALID must be set in pgmap->flags.
+ *
+ * 3/ The ref field may optionally be provided, in which pgmap->ref must be
+ *    'live' on entry and will be killed and reaped at
+ *    devm_memremap_pages_release() time, or if this routine fails.
+ *
+ * 4/ res is expected to be a host memory range that could feasibly be
+ *    treated as a "System RAM" range, i.e. not a device mmio range, but
+ *    this is not enforced.
+ */
+void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
+{
+	int error;
+	void *ret;
+
+	ret = memremap_pages(pgmap, dev_to_node(dev));
+	if (IS_ERR(ret))
+		return ret;
+
+	error = devm_add_action_or_reset(dev, devm_memremap_pages_release,
+			pgmap);
+	if (error)
+		return ERR_PTR(error);
+	return ret;
+}
 EXPORT_SYMBOL_GPL(devm_memremap_pages);
 
 void devm_memunmap_pages(struct device *dev, struct dev_pagemap *pgmap)
-- 
2.20.1



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

* Re: add a not device managed memremap_pages v2
  2019-08-16  6:54 add a not device managed memremap_pages v2 Christoph Hellwig
                   ` (3 preceding siblings ...)
  2019-08-16  6:54 ` [PATCH 4/4] memremap: provide a not device managed memremap_pages Christoph Hellwig
@ 2019-08-16 10:48 ` Bharata B Rao
  2019-08-16 12:34 ` Jason Gunthorpe
  2019-08-16 23:59 ` Ira Weiny
  6 siblings, 0 replies; 18+ messages in thread
From: Bharata B Rao @ 2019-08-16 10:48 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Dan Williams, Jason Gunthorpe, Andrew Morton, linux-mm,
	linux-kernel, linux-nvdimm

On Fri, Aug 16, 2019 at 08:54:30AM +0200, Christoph Hellwig wrote:
> Hi Dan and Jason,
> 
> Bharata has been working on secure page management for kvmppc guests,
> and one I thing I noticed is that he had to fake up a struct device
> just so that it could be passed to the devm_memremap_pages
> instrastructure for device private memory.
> 
> This series adds non-device managed versions of the
> devm_request_free_mem_region and devm_memremap_pages functions for
> his use case.

Tested this series with my patches that add secure page management
for kvmppc guests. These patches along with migrate_vma-cleanup
series are good-to-have to support secure guests on ultravisor enabled
POWER platforms.

Regards,
Bharata.



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

* Re: add a not device managed memremap_pages v2
  2019-08-16  6:54 add a not device managed memremap_pages v2 Christoph Hellwig
                   ` (4 preceding siblings ...)
  2019-08-16 10:48 ` add a not device managed memremap_pages v2 Bharata B Rao
@ 2019-08-16 12:34 ` Jason Gunthorpe
  2019-08-16 12:36   ` Christoph Hellwig
  2019-08-16 23:59 ` Ira Weiny
  6 siblings, 1 reply; 18+ messages in thread
From: Jason Gunthorpe @ 2019-08-16 12:34 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Dan Williams, Bharata B Rao, Andrew Morton, linux-mm,
	linux-kernel, linux-nvdimm

On Fri, Aug 16, 2019 at 08:54:30AM +0200, Christoph Hellwig wrote:
> Hi Dan and Jason,
> 
> Bharata has been working on secure page management for kvmppc guests,
> and one I thing I noticed is that he had to fake up a struct device
> just so that it could be passed to the devm_memremap_pages
> instrastructure for device private memory.
> 
> This series adds non-device managed versions of the
> devm_request_free_mem_region and devm_memremap_pages functions for
> his use case.
> 
> Changes since v1:
>  - don't overload devm_request_free_mem_region
>  - export the memremap_pages and munmap_pages as kvmppc can be a module

What tree do we want this to go through? Dan are you running a pgmap
tree still? Do we know of any conflicts?

Thanks,
Jason


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

* Re: add a not device managed memremap_pages v2
  2019-08-16 12:34 ` Jason Gunthorpe
@ 2019-08-16 12:36   ` Christoph Hellwig
  2019-08-16 12:40     ` Jason Gunthorpe
  0 siblings, 1 reply; 18+ messages in thread
From: Christoph Hellwig @ 2019-08-16 12:36 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Christoph Hellwig, Dan Williams, Bharata B Rao, Andrew Morton,
	linux-mm, linux-kernel, linux-nvdimm

> > Changes since v1:
> >  - don't overload devm_request_free_mem_region
> >  - export the memremap_pages and munmap_pages as kvmppc can be a module
> 
> What tree do we want this to go through? Dan are you running a pgmap
> tree still? Do we know of any conflicts?

The last changes in this area went through the hmm tree.  There are
now known conflicts, and the kvmppc drivers that needs this already
has a dependency on the hmm tree for the migrate_vma_* changes.


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

* Re: add a not device managed memremap_pages v2
  2019-08-16 12:36   ` Christoph Hellwig
@ 2019-08-16 12:40     ` Jason Gunthorpe
  0 siblings, 0 replies; 18+ messages in thread
From: Jason Gunthorpe @ 2019-08-16 12:40 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Dan Williams, Bharata B Rao, Andrew Morton, linux-mm,
	linux-kernel, linux-nvdimm

On Fri, Aug 16, 2019 at 02:36:07PM +0200, Christoph Hellwig wrote:
> > > Changes since v1:
> > >  - don't overload devm_request_free_mem_region
> > >  - export the memremap_pages and munmap_pages as kvmppc can be a module
> > 
> > What tree do we want this to go through? Dan are you running a pgmap
> > tree still? Do we know of any conflicts?
> 
> The last changes in this area went through the hmm tree.  There are
> now known conflicts, and the kvmppc drivers that needs this already
> has a dependency on the hmm tree for the migrate_vma_* changes.

OK by me, Dan can you ack or review? Thanks

Jason


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

* Re: [PATCH 4/4] memremap: provide a not device managed memremap_pages
  2019-08-16  6:54 ` [PATCH 4/4] memremap: provide a not device managed memremap_pages Christoph Hellwig
@ 2019-08-16 21:00   ` Andrew Morton
  2019-08-18  9:04     ` Christoph Hellwig
  0 siblings, 1 reply; 18+ messages in thread
From: Andrew Morton @ 2019-08-16 21:00 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Dan Williams, Jason Gunthorpe, Bharata B Rao, linux-mm,
	linux-kernel, linux-nvdimm

On Fri, 16 Aug 2019 08:54:34 +0200 Christoph Hellwig <hch@lst.de> wrote:

> The kvmppc ultravisor code wants a device private memory pool that is
> system wide and not attached to a device.  Instead of faking up one
> provide a low-level memremap_pages for it.  Note that this function is
> not exported, and doesn't have a cleanup routine associated with it to
> discourage use from more driver like users.

Confused. Which function is "not exported"?

> +EXPORT_SYMBOL_GPL(memunmap_pages);
> +EXPORT_SYMBOL_GPL(memremap_pages);
>  EXPORT_SYMBOL_GPL(devm_memremap_pages);



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

* Re: [PATCH 1/4] resource: add a not device managed request_free_mem_region variant
  2019-08-16  6:54 ` [PATCH 1/4] resource: add a not device managed request_free_mem_region variant Christoph Hellwig
@ 2019-08-16 21:01   ` Andrew Morton
  2019-08-18  9:03     ` Christoph Hellwig
  0 siblings, 1 reply; 18+ messages in thread
From: Andrew Morton @ 2019-08-16 21:01 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Dan Williams, Jason Gunthorpe, Bharata B Rao, linux-mm,
	linux-kernel, linux-nvdimm

On Fri, 16 Aug 2019 08:54:31 +0200 Christoph Hellwig <hch@lst.de> wrote:

> Just add a simple macro that passes a NULL dev argument to
> dev_request_free_mem_region, and call request_mem_region in the
> function for that particular case.

Nit:

> +struct resource *request_free_mem_region(struct resource *base,
> +		unsigned long size, const char *name);

This isn't a macro ;)


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

* Re: add a not device managed memremap_pages v2
  2019-08-16  6:54 add a not device managed memremap_pages v2 Christoph Hellwig
                   ` (5 preceding siblings ...)
  2019-08-16 12:34 ` Jason Gunthorpe
@ 2019-08-16 23:59 ` Ira Weiny
  6 siblings, 0 replies; 18+ messages in thread
From: Ira Weiny @ 2019-08-16 23:59 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Dan Williams, Jason Gunthorpe, linux-mm, Andrew Morton,
	linux-nvdimm, linux-kernel, Bharata B Rao

On Fri, Aug 16, 2019 at 08:54:30AM +0200, Christoph Hellwig wrote:
> Hi Dan and Jason,
> 
> Bharata has been working on secure page management for kvmppc guests,
> and one I thing I noticed is that he had to fake up a struct device
> just so that it could be passed to the devm_memremap_pages
> instrastructure for device private memory.
> 
> This series adds non-device managed versions of the
> devm_request_free_mem_region and devm_memremap_pages functions for
> his use case.
> 
> Changes since v1:
>  - don't overload devm_request_free_mem_region
>  - export the memremap_pages and munmap_pages as kvmppc can be a module

Except for the questions from Andrew this does not look to change anything so:

Reviewed-by: Ira Weiny <ira.weiny@intel.com>

> _______________________________________________
> Linux-nvdimm mailing list
> Linux-nvdimm@lists.01.org
> https://lists.01.org/mailman/listinfo/linux-nvdimm


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

* Re: [PATCH 1/4] resource: add a not device managed request_free_mem_region variant
  2019-08-16 21:01   ` Andrew Morton
@ 2019-08-18  9:03     ` Christoph Hellwig
  0 siblings, 0 replies; 18+ messages in thread
From: Christoph Hellwig @ 2019-08-18  9:03 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Christoph Hellwig, Dan Williams, Jason Gunthorpe, Bharata B Rao,
	linux-mm, linux-kernel, linux-nvdimm

On Fri, Aug 16, 2019 at 02:01:34PM -0700, Andrew Morton wrote:
> On Fri, 16 Aug 2019 08:54:31 +0200 Christoph Hellwig <hch@lst.de> wrote:
> 
> > Just add a simple macro that passes a NULL dev argument to
> > dev_request_free_mem_region, and call request_mem_region in the
> > function for that particular case.
> 
> Nit:
> 
> > +struct resource *request_free_mem_region(struct resource *base,
> > +		unsigned long size, const char *name);
> 
> This isn't a macro ;)

Oops, the changelog needs updating vs the first version of course.


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

* Re: [PATCH 4/4] memremap: provide a not device managed memremap_pages
  2019-08-16 21:00   ` Andrew Morton
@ 2019-08-18  9:04     ` Christoph Hellwig
  0 siblings, 0 replies; 18+ messages in thread
From: Christoph Hellwig @ 2019-08-18  9:04 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Christoph Hellwig, Dan Williams, Jason Gunthorpe, Bharata B Rao,
	linux-mm, linux-kernel, linux-nvdimm

On Fri, Aug 16, 2019 at 02:00:57PM -0700, Andrew Morton wrote:
> On Fri, 16 Aug 2019 08:54:34 +0200 Christoph Hellwig <hch@lst.de> wrote:
> 
> > The kvmppc ultravisor code wants a device private memory pool that is
> > system wide and not attached to a device.  Instead of faking up one
> > provide a low-level memremap_pages for it.  Note that this function is
> > not exported, and doesn't have a cleanup routine associated with it to
> > discourage use from more driver like users.
> 
> Confused. Which function is "not exported"?

Leftover from v1 and dropped now.


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

* Re: [PATCH 1/4] resource: add a not device managed request_free_mem_region variant
  2019-08-20  2:26     ` Christoph Hellwig
@ 2019-08-20  4:38       ` Dan Williams
  0 siblings, 0 replies; 18+ messages in thread
From: Dan Williams @ 2019-08-20  4:38 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Jason Gunthorpe, Bharata B Rao, Andrew Morton, Linux MM,
	Linux Kernel Mailing List, linux-nvdimm, Ira Weiny

On Mon, Aug 19, 2019 at 7:26 PM Christoph Hellwig <hch@lst.de> wrote:
>
> On Mon, Aug 19, 2019 at 06:28:30PM -0700, Dan Williams wrote:
> >
> > Previously we would loudly crash if someone passed NULL to
> > devm_request_free_mem_region(), but now it will silently work and the
> > result will leak. Perhaps this wants a:
>
> We'd still instantly crash due to the dev_name dereference, right?

Whoops, yes.


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

* Re: [PATCH 1/4] resource: add a not device managed request_free_mem_region variant
  2019-08-20  1:28   ` Dan Williams
@ 2019-08-20  2:26     ` Christoph Hellwig
  2019-08-20  4:38       ` Dan Williams
  0 siblings, 1 reply; 18+ messages in thread
From: Christoph Hellwig @ 2019-08-20  2:26 UTC (permalink / raw)
  To: Dan Williams
  Cc: Christoph Hellwig, Jason Gunthorpe, Bharata B Rao, Andrew Morton,
	Linux MM, Linux Kernel Mailing List, linux-nvdimm, Ira Weiny

On Mon, Aug 19, 2019 at 06:28:30PM -0700, Dan Williams wrote:
> 
> Previously we would loudly crash if someone passed NULL to
> devm_request_free_mem_region(), but now it will silently work and the
> result will leak. Perhaps this wants a:

We'd still instantly crash due to the dev_name dereference, right?


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

* Re: [PATCH 1/4] resource: add a not device managed request_free_mem_region variant
  2019-08-18  9:05 ` [PATCH 1/4] resource: add a not device managed request_free_mem_region variant Christoph Hellwig
@ 2019-08-20  1:28   ` Dan Williams
  2019-08-20  2:26     ` Christoph Hellwig
  0 siblings, 1 reply; 18+ messages in thread
From: Dan Williams @ 2019-08-20  1:28 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Jason Gunthorpe, Bharata B Rao, Andrew Morton, Linux MM,
	Linux Kernel Mailing List, linux-nvdimm, Ira Weiny

On Sun, Aug 18, 2019 at 2:10 AM Christoph Hellwig <hch@lst.de> wrote:
>
> Factor out the guts of devm_request_free_mem_region so that we can
> implement both a device managed and a manually release version as
> tiny wrappers around it.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Ira Weiny <ira.weiny@intel.com>
> ---
>  include/linux/ioport.h |  2 ++
>  kernel/resource.c      | 45 +++++++++++++++++++++++++++++-------------
>  2 files changed, 33 insertions(+), 14 deletions(-)
>
> diff --git a/include/linux/ioport.h b/include/linux/ioport.h
> index 5b6a7121c9f0..7bddddfc76d6 100644
> --- a/include/linux/ioport.h
> +++ b/include/linux/ioport.h
> @@ -297,6 +297,8 @@ static inline bool resource_overlaps(struct resource *r1, struct resource *r2)
>
>  struct resource *devm_request_free_mem_region(struct device *dev,
>                 struct resource *base, unsigned long size);
> +struct resource *request_free_mem_region(struct resource *base,
> +               unsigned long size, const char *name);
>
>  #endif /* __ASSEMBLY__ */
>  #endif /* _LINUX_IOPORT_H */
> diff --git a/kernel/resource.c b/kernel/resource.c
> index 7ea4306503c5..74877e9d90ca 100644
> --- a/kernel/resource.c
> +++ b/kernel/resource.c
> @@ -1644,19 +1644,8 @@ void resource_list_free(struct list_head *head)
>  EXPORT_SYMBOL(resource_list_free);
>
>  #ifdef CONFIG_DEVICE_PRIVATE
> -/**
> - * devm_request_free_mem_region - find free region for device private memory
> - *
> - * @dev: device struct to bind the resource to
> - * @size: size in bytes of the device memory to add
> - * @base: resource tree to look in
> - *
> - * This function tries to find an empty range of physical address big enough to
> - * contain the new resource, so that it can later be hotplugged as ZONE_DEVICE
> - * memory, which in turn allocates struct pages.
> - */
> -struct resource *devm_request_free_mem_region(struct device *dev,
> -               struct resource *base, unsigned long size)
> +static struct resource *__request_free_mem_region(struct device *dev,
> +               struct resource *base, unsigned long size, const char *name)
>  {
>         resource_size_t end, addr;
>         struct resource *res;
> @@ -1670,7 +1659,10 @@ struct resource *devm_request_free_mem_region(struct device *dev,
>                                 REGION_DISJOINT)
>                         continue;
>
> -               res = devm_request_mem_region(dev, addr, size, dev_name(dev));
> +               if (dev)
> +                       res = devm_request_mem_region(dev, addr, size, name);
> +               else
> +                       res = request_mem_region(addr, size, name);
>                 if (!res)
>                         return ERR_PTR(-ENOMEM);
>                 res->desc = IORES_DESC_DEVICE_PRIVATE_MEMORY;
> @@ -1679,7 +1671,32 @@ struct resource *devm_request_free_mem_region(struct device *dev,
>
>         return ERR_PTR(-ERANGE);
>  }
> +
> +/**
> + * devm_request_free_mem_region - find free region for device private memory
> + *
> + * @dev: device struct to bind the resource to
> + * @size: size in bytes of the device memory to add
> + * @base: resource tree to look in
> + *
> + * This function tries to find an empty range of physical address big enough to
> + * contain the new resource, so that it can later be hotplugged as ZONE_DEVICE
> + * memory, which in turn allocates struct pages.
> + */
> +struct resource *devm_request_free_mem_region(struct device *dev,
> +               struct resource *base, unsigned long size)
> +{

Previously we would loudly crash if someone passed NULL to
devm_request_free_mem_region(), but now it will silently work and the
result will leak. Perhaps this wants a:

if (!dev)
    return NULL;

...to head off those mistakes?

No major heartburn if you keep it as is, you can add:

Reviewed-by: Dan Williams <dan.j.williams@intel.com>


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

* [PATCH 1/4] resource: add a not device managed request_free_mem_region variant
  2019-08-18  9:05 add a not device managed memremap_pages v3 Christoph Hellwig
@ 2019-08-18  9:05 ` Christoph Hellwig
  2019-08-20  1:28   ` Dan Williams
  0 siblings, 1 reply; 18+ messages in thread
From: Christoph Hellwig @ 2019-08-18  9:05 UTC (permalink / raw)
  To: Dan Williams, Jason Gunthorpe
  Cc: Bharata B Rao, Andrew Morton, linux-mm, linux-kernel,
	linux-nvdimm, Ira Weiny

Factor out the guts of devm_request_free_mem_region so that we can
implement both a device managed and a manually release version as
tiny wrappers around it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
---
 include/linux/ioport.h |  2 ++
 kernel/resource.c      | 45 +++++++++++++++++++++++++++++-------------
 2 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 5b6a7121c9f0..7bddddfc76d6 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -297,6 +297,8 @@ static inline bool resource_overlaps(struct resource *r1, struct resource *r2)
 
 struct resource *devm_request_free_mem_region(struct device *dev,
 		struct resource *base, unsigned long size);
+struct resource *request_free_mem_region(struct resource *base,
+		unsigned long size, const char *name);
 
 #endif /* __ASSEMBLY__ */
 #endif	/* _LINUX_IOPORT_H */
diff --git a/kernel/resource.c b/kernel/resource.c
index 7ea4306503c5..74877e9d90ca 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -1644,19 +1644,8 @@ void resource_list_free(struct list_head *head)
 EXPORT_SYMBOL(resource_list_free);
 
 #ifdef CONFIG_DEVICE_PRIVATE
-/**
- * devm_request_free_mem_region - find free region for device private memory
- *
- * @dev: device struct to bind the resource to
- * @size: size in bytes of the device memory to add
- * @base: resource tree to look in
- *
- * This function tries to find an empty range of physical address big enough to
- * contain the new resource, so that it can later be hotplugged as ZONE_DEVICE
- * memory, which in turn allocates struct pages.
- */
-struct resource *devm_request_free_mem_region(struct device *dev,
-		struct resource *base, unsigned long size)
+static struct resource *__request_free_mem_region(struct device *dev,
+		struct resource *base, unsigned long size, const char *name)
 {
 	resource_size_t end, addr;
 	struct resource *res;
@@ -1670,7 +1659,10 @@ struct resource *devm_request_free_mem_region(struct device *dev,
 				REGION_DISJOINT)
 			continue;
 
-		res = devm_request_mem_region(dev, addr, size, dev_name(dev));
+		if (dev)
+			res = devm_request_mem_region(dev, addr, size, name);
+		else
+			res = request_mem_region(addr, size, name);
 		if (!res)
 			return ERR_PTR(-ENOMEM);
 		res->desc = IORES_DESC_DEVICE_PRIVATE_MEMORY;
@@ -1679,7 +1671,32 @@ struct resource *devm_request_free_mem_region(struct device *dev,
 
 	return ERR_PTR(-ERANGE);
 }
+
+/**
+ * devm_request_free_mem_region - find free region for device private memory
+ *
+ * @dev: device struct to bind the resource to
+ * @size: size in bytes of the device memory to add
+ * @base: resource tree to look in
+ *
+ * This function tries to find an empty range of physical address big enough to
+ * contain the new resource, so that it can later be hotplugged as ZONE_DEVICE
+ * memory, which in turn allocates struct pages.
+ */
+struct resource *devm_request_free_mem_region(struct device *dev,
+		struct resource *base, unsigned long size)
+{
+	return __request_free_mem_region(dev, base, size, dev_name(dev));
+}
 EXPORT_SYMBOL_GPL(devm_request_free_mem_region);
+
+struct resource *request_free_mem_region(struct resource *base,
+		unsigned long size, const char *name)
+{
+	return __request_free_mem_region(NULL, base, size, name);
+}
+EXPORT_SYMBOL_GPL(request_free_mem_region);
+
 #endif /* CONFIG_DEVICE_PRIVATE */
 
 static int __init strict_iomem(char *str)
-- 
2.20.1



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

end of thread, other threads:[~2019-08-20  4:38 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-16  6:54 add a not device managed memremap_pages v2 Christoph Hellwig
2019-08-16  6:54 ` [PATCH 1/4] resource: add a not device managed request_free_mem_region variant Christoph Hellwig
2019-08-16 21:01   ` Andrew Morton
2019-08-18  9:03     ` Christoph Hellwig
2019-08-16  6:54 ` [PATCH 2/4] memremap: remove the dev field in struct dev_pagemap Christoph Hellwig
2019-08-16  6:54 ` [PATCH 3/4] memremap: don't use a separate devm action for devmap_managed_enable_get Christoph Hellwig
2019-08-16  6:54 ` [PATCH 4/4] memremap: provide a not device managed memremap_pages Christoph Hellwig
2019-08-16 21:00   ` Andrew Morton
2019-08-18  9:04     ` Christoph Hellwig
2019-08-16 10:48 ` add a not device managed memremap_pages v2 Bharata B Rao
2019-08-16 12:34 ` Jason Gunthorpe
2019-08-16 12:36   ` Christoph Hellwig
2019-08-16 12:40     ` Jason Gunthorpe
2019-08-16 23:59 ` Ira Weiny
2019-08-18  9:05 add a not device managed memremap_pages v3 Christoph Hellwig
2019-08-18  9:05 ` [PATCH 1/4] resource: add a not device managed request_free_mem_region variant Christoph Hellwig
2019-08-20  1:28   ` Dan Williams
2019-08-20  2:26     ` Christoph Hellwig
2019-08-20  4:38       ` Dan Williams

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).