public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] xen/xenbus: Support multiple grants ring with 64KB page
@ 2015-10-13 16:50 Julien Grall
  2015-10-13 16:50 ` [PATCH 1/3] xen/xenbus: Rename *RING_PAGE* to *RING_GRANT* Julien Grall
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Julien Grall @ 2015-10-13 16:50 UTC (permalink / raw)
  To: xen-devel
  Cc: linux-kernel, Julien Grall, Boris Ostrovsky, David Vrabel,
	Konrad Rzeszutek Wilk, Roger Pau Monné, Stefano Stabellini

Hi all,

The support of multiple grants ring was left aside for 64KB page. This series
aims to fix it.

It's based on xentip/for-linus-4.4.

Sincelerely yours,

Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: "Roger Pau Monné" <roger.pau@citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

Julien Grall (3):
  xen/xenbus: Rename *RING_PAGE* to *RING_GRANT*
  xen/grant-table: Add an helper to iterate over a specific number of
    grants
  xenbus: Support multiple grants ring with 64KB

 drivers/block/xen-blkback/blkback.c |   8 +--
 drivers/block/xen-blkback/xenbus.c  |   2 +-
 drivers/block/xen-blkfront.c        |  10 +--
 drivers/xen/grant-table.c           |  22 +++++++
 drivers/xen/xenbus/xenbus_client.c  | 121 +++++++++++++++++++++++++-----------
 include/xen/grant_table.h           |   6 ++
 include/xen/xenbus.h                |   4 +-
 7 files changed, 124 insertions(+), 49 deletions(-)

-- 
2.1.4


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

* [PATCH 1/3] xen/xenbus: Rename *RING_PAGE* to *RING_GRANT*
  2015-10-13 16:50 [PATCH 0/3] xen/xenbus: Support multiple grants ring with 64KB page Julien Grall
@ 2015-10-13 16:50 ` Julien Grall
  2015-10-13 16:50 ` [PATCH 2/3] xen/grant-table: Add an helper to iterate over a specific number of grants Julien Grall
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Julien Grall @ 2015-10-13 16:50 UTC (permalink / raw)
  To: xen-devel
  Cc: linux-kernel, Julien Grall, Konrad Rzeszutek Wilk,
	Roger Pau Monné, Boris Ostrovsky, David Vrabel,
	Stefano Stabellini

Linux may use a different page size than the size of grant. So make
clear that the order is actually in number of grant.

Signed-off-by: Julien Grall <julien.grall@citrix.com>

---
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: "Roger Pau Monné" <roger.pau@citrix.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 drivers/block/xen-blkback/blkback.c |  8 ++++----
 drivers/block/xen-blkback/xenbus.c  |  2 +-
 drivers/block/xen-blkfront.c        | 10 +++++-----
 drivers/xen/xenbus/xenbus_client.c  | 34 +++++++++++++++++-----------------
 include/xen/xenbus.h                |  4 ++--
 5 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index 809634c..f909994 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -87,7 +87,7 @@ MODULE_PARM_DESC(max_persistent_grants,
  * Maximum order of pages to be used for the shared ring between front and
  * backend, 4KB page granularity is used.
  */
-unsigned int xen_blkif_max_ring_order = XENBUS_MAX_RING_PAGE_ORDER;
+unsigned int xen_blkif_max_ring_order = XENBUS_MAX_RING_GRANT_ORDER;
 module_param_named(max_ring_page_order, xen_blkif_max_ring_order, int, S_IRUGO);
 MODULE_PARM_DESC(max_ring_page_order, "Maximum order of pages to be used for the shared ring");
 /*
@@ -1446,10 +1446,10 @@ static int __init xen_blkif_init(void)
 	if (!xen_domain())
 		return -ENODEV;
 
-	if (xen_blkif_max_ring_order > XENBUS_MAX_RING_PAGE_ORDER) {
+	if (xen_blkif_max_ring_order > XENBUS_MAX_RING_GRANT_ORDER) {
 		pr_info("Invalid max_ring_order (%d), will use default max: %d.\n",
-			xen_blkif_max_ring_order, XENBUS_MAX_RING_PAGE_ORDER);
-		xen_blkif_max_ring_order = XENBUS_MAX_RING_PAGE_ORDER;
+			xen_blkif_max_ring_order, XENBUS_MAX_RING_GRANT_ORDER);
+		xen_blkif_max_ring_order = XENBUS_MAX_RING_GRANT_ORDER;
 	}
 
 	rc = xen_blkif_interface_init();
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index edd27e4..cde8ccd 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -827,7 +827,7 @@ again:
 static int connect_ring(struct backend_info *be)
 {
 	struct xenbus_device *dev = be->dev;
-	unsigned int ring_ref[XENBUS_MAX_RING_PAGES];
+	unsigned int ring_ref[XENBUS_MAX_RING_GRANTS];
 	unsigned int evtchn, nr_grefs, ring_page_order;
 	unsigned int pers_grants;
 	char protocol[64] = "";
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 43cda94..3ea948c 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -111,7 +111,7 @@ MODULE_PARM_DESC(max_ring_page_order, "Maximum order of pages to be used for the
 	__CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * (info)->nr_ring_pages)
 
 #define BLK_MAX_RING_SIZE	\
-	__CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * XENBUS_MAX_RING_PAGES)
+	__CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * XENBUS_MAX_RING_GRANTS)
 
 /*
  * ring-ref%i i=(-1UL) would take 11 characters + 'ring-ref' is 8, so 19
@@ -133,7 +133,7 @@ struct blkfront_info
 	int vdevice;
 	blkif_vdev_t handle;
 	enum blkif_state connected;
-	int ring_ref[XENBUS_MAX_RING_PAGES];
+	int ring_ref[XENBUS_MAX_RING_GRANTS];
 	unsigned int nr_ring_pages;
 	struct blkif_front_ring ring;
 	unsigned int evtchn, irq;
@@ -1412,7 +1412,7 @@ static int setup_blkring(struct xenbus_device *dev,
 	struct blkif_sring *sring;
 	int err, i;
 	unsigned long ring_size = info->nr_ring_pages * XEN_PAGE_SIZE;
-	grant_ref_t gref[XENBUS_MAX_RING_PAGES];
+	grant_ref_t gref[XENBUS_MAX_RING_GRANTS];
 
 	for (i = 0; i < info->nr_ring_pages; i++)
 		info->ring_ref[i] = GRANT_INVALID_REF;
@@ -2283,9 +2283,9 @@ static int __init xlblk_init(void)
 	if (!xen_domain())
 		return -ENODEV;
 
-	if (xen_blkif_max_ring_order > XENBUS_MAX_RING_PAGE_ORDER) {
+	if (xen_blkif_max_ring_order > XENBUS_MAX_RING_GRANT_ORDER) {
 		pr_info("Invalid max_ring_order (%d), will use default max: %d.\n",
-			xen_blkif_max_ring_order, XENBUS_MAX_RING_PAGE_ORDER);
+			xen_blkif_max_ring_order, XENBUS_MAX_RING_GRANT_ORDER);
 		xen_blkif_max_ring_order = 0;
 	}
 
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index 42abee3..b776433 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -56,11 +56,11 @@ struct xenbus_map_node {
 			struct vm_struct *area;
 		} pv;
 		struct {
-			struct page *pages[XENBUS_MAX_RING_PAGES];
+			struct page *pages[XENBUS_MAX_RING_GRANTS];
 			void *addr;
 		} hvm;
 	};
-	grant_handle_t handles[XENBUS_MAX_RING_PAGES];
+	grant_handle_t handles[XENBUS_MAX_RING_GRANTS];
 	unsigned int   nr_handles;
 };
 
@@ -479,12 +479,12 @@ static int __xenbus_map_ring(struct xenbus_device *dev,
 			     unsigned int flags,
 			     bool *leaked)
 {
-	struct gnttab_map_grant_ref map[XENBUS_MAX_RING_PAGES];
-	struct gnttab_unmap_grant_ref unmap[XENBUS_MAX_RING_PAGES];
+	struct gnttab_map_grant_ref map[XENBUS_MAX_RING_GRANTS];
+	struct gnttab_unmap_grant_ref unmap[XENBUS_MAX_RING_GRANTS];
 	int i, j;
 	int err = GNTST_okay;
 
-	if (nr_grefs > XENBUS_MAX_RING_PAGES)
+	if (nr_grefs > XENBUS_MAX_RING_GRANTS)
 		return -EINVAL;
 
 	for (i = 0; i < nr_grefs; i++) {
@@ -540,15 +540,15 @@ static int xenbus_map_ring_valloc_pv(struct xenbus_device *dev,
 {
 	struct xenbus_map_node *node;
 	struct vm_struct *area;
-	pte_t *ptes[XENBUS_MAX_RING_PAGES];
-	phys_addr_t phys_addrs[XENBUS_MAX_RING_PAGES];
+	pte_t *ptes[XENBUS_MAX_RING_GRANTS];
+	phys_addr_t phys_addrs[XENBUS_MAX_RING_GRANTS];
 	int err = GNTST_okay;
 	int i;
 	bool leaked;
 
 	*vaddr = NULL;
 
-	if (nr_grefs > XENBUS_MAX_RING_PAGES)
+	if (nr_grefs > XENBUS_MAX_RING_GRANTS)
 		return -EINVAL;
 
 	node = kzalloc(sizeof(*node), GFP_KERNEL);
@@ -602,10 +602,10 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev,
 	void *addr;
 	bool leaked = false;
 	/* Why do we need two arrays? See comment of __xenbus_map_ring */
-	phys_addr_t phys_addrs[XENBUS_MAX_RING_PAGES];
-	unsigned long addrs[XENBUS_MAX_RING_PAGES];
+	phys_addr_t phys_addrs[XENBUS_MAX_RING_GRANTS];
+	unsigned long addrs[XENBUS_MAX_RING_GRANTS];
 
-	if (nr_grefs > XENBUS_MAX_RING_PAGES)
+	if (nr_grefs > XENBUS_MAX_RING_GRANTS)
 		return -EINVAL;
 
 	*vaddr = NULL;
@@ -686,10 +686,10 @@ int xenbus_map_ring(struct xenbus_device *dev, grant_ref_t *gnt_refs,
 		    unsigned int nr_grefs, grant_handle_t *handles,
 		    unsigned long *vaddrs, bool *leaked)
 {
-	phys_addr_t phys_addrs[XENBUS_MAX_RING_PAGES];
+	phys_addr_t phys_addrs[XENBUS_MAX_RING_GRANTS];
 	int i;
 
-	if (nr_grefs > XENBUS_MAX_RING_PAGES)
+	if (nr_grefs > XENBUS_MAX_RING_GRANTS)
 		return -EINVAL;
 
 	for (i = 0; i < nr_grefs; i++)
@@ -722,7 +722,7 @@ EXPORT_SYMBOL_GPL(xenbus_unmap_ring_vfree);
 static int xenbus_unmap_ring_vfree_pv(struct xenbus_device *dev, void *vaddr)
 {
 	struct xenbus_map_node *node;
-	struct gnttab_unmap_grant_ref unmap[XENBUS_MAX_RING_PAGES];
+	struct gnttab_unmap_grant_ref unmap[XENBUS_MAX_RING_GRANTS];
 	unsigned int level;
 	int i;
 	bool leaked = false;
@@ -787,7 +787,7 @@ static int xenbus_unmap_ring_vfree_hvm(struct xenbus_device *dev, void *vaddr)
 	int rv;
 	struct xenbus_map_node *node;
 	void *addr;
-	unsigned long addrs[XENBUS_MAX_RING_PAGES];
+	unsigned long addrs[XENBUS_MAX_RING_GRANTS];
 	int i;
 
 	spin_lock(&xenbus_valloc_lock);
@@ -840,11 +840,11 @@ int xenbus_unmap_ring(struct xenbus_device *dev,
 		      grant_handle_t *handles, unsigned int nr_handles,
 		      unsigned long *vaddrs)
 {
-	struct gnttab_unmap_grant_ref unmap[XENBUS_MAX_RING_PAGES];
+	struct gnttab_unmap_grant_ref unmap[XENBUS_MAX_RING_GRANTS];
 	int i;
 	int err;
 
-	if (nr_handles > XENBUS_MAX_RING_PAGES)
+	if (nr_handles > XENBUS_MAX_RING_GRANTS)
 		return -EINVAL;
 
 	for (i = 0; i < nr_handles; i++)
diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h
index 289c0b5..32b944b 100644
--- a/include/xen/xenbus.h
+++ b/include/xen/xenbus.h
@@ -46,8 +46,8 @@
 #include <xen/interface/io/xenbus.h>
 #include <xen/interface/io/xs_wire.h>
 
-#define XENBUS_MAX_RING_PAGE_ORDER 4
-#define XENBUS_MAX_RING_PAGES      (1U << XENBUS_MAX_RING_PAGE_ORDER)
+#define XENBUS_MAX_RING_GRANT_ORDER 4
+#define XENBUS_MAX_RING_GRANTS      (1U << XENBUS_MAX_RING_GRANT_ORDER)
 #define INVALID_GRANT_HANDLE       (~0U)
 
 /* Register callback to watch this node. */
-- 
2.1.4


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

* [PATCH 2/3] xen/grant-table: Add an helper to iterate over a specific number of grants
  2015-10-13 16:50 [PATCH 0/3] xen/xenbus: Support multiple grants ring with 64KB page Julien Grall
  2015-10-13 16:50 ` [PATCH 1/3] xen/xenbus: Rename *RING_PAGE* to *RING_GRANT* Julien Grall
@ 2015-10-13 16:50 ` Julien Grall
  2015-10-13 16:50 ` [PATCH 3/3] xenbus: Support multiple grants ring with 64KB Julien Grall
  2015-10-16 14:12 ` [Xen-devel] [PATCH 0/3] xen/xenbus: Support multiple grants ring with 64KB page David Vrabel
  3 siblings, 0 replies; 5+ messages in thread
From: Julien Grall @ 2015-10-13 16:50 UTC (permalink / raw)
  To: xen-devel
  Cc: linux-kernel, Julien Grall, Konrad Rzeszutek Wilk,
	Boris Ostrovsky, David Vrabel, Stefano Stabellini

With the 64KB page granularity support on ARM64, a Linux page may be
split accross multiple grant.

Currently we have the helper gnttab_foreach_grant_in_grant to break a
Linux page based on an offset and a len, but it doesn't fit when we only
have a number of grants in hand.

Introduce a new helper which take an array of Linux page and a number of
grant and will figure out the address of each grant.

Signed-off-by: Julien Grall <julien.grall@citrix.com>

---
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 drivers/xen/grant-table.c | 22 ++++++++++++++++++++++
 include/xen/grant_table.h |  6 ++++++
 2 files changed, 28 insertions(+)

diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 72d6339..c49f79ed 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -802,6 +802,28 @@ void gnttab_foreach_grant_in_range(struct page *page,
 }
 EXPORT_SYMBOL_GPL(gnttab_foreach_grant_in_range);
 
+void gnttab_foreach_grant(struct page **pages,
+			  unsigned int nr_grefs,
+			  xen_grant_fn_t fn,
+			  void *data)
+{
+	unsigned int goffset = 0;
+	unsigned long xen_pfn = 0;
+	unsigned int i;
+
+	for (i = 0; i < nr_grefs; i++) {
+		if ((i % XEN_PFN_PER_PAGE) == 0) {
+			xen_pfn = page_to_xen_pfn(pages[i / XEN_PFN_PER_PAGE]);
+			goffset = 0;
+		}
+
+		fn(pfn_to_gfn(xen_pfn), goffset, XEN_PAGE_SIZE, data);
+
+		goffset += XEN_PAGE_SIZE;
+		xen_pfn++;
+	}
+}
+
 int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
 		    struct gnttab_map_grant_ref *kmap_ops,
 		    struct page **pages, unsigned int count)
diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
index e17a4b3..34b1379 100644
--- a/include/xen/grant_table.h
+++ b/include/xen/grant_table.h
@@ -264,6 +264,12 @@ static inline void gnttab_for_one_grant(struct page *page, unsigned int offset,
 	gnttab_foreach_grant_in_range(page, offset, len, fn, data);
 }
 
+/* Get @nr_grefs grants from an array of page and call fn for each grant */
+void gnttab_foreach_grant(struct page **pages,
+			  unsigned int nr_grefs,
+			  xen_grant_fn_t fn,
+			  void *data);
+
 /* Get the number of grant in a specified region
  *
  * start: Offset from the beginning of the first page
-- 
2.1.4


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

* [PATCH 3/3] xenbus: Support multiple grants ring with 64KB
  2015-10-13 16:50 [PATCH 0/3] xen/xenbus: Support multiple grants ring with 64KB page Julien Grall
  2015-10-13 16:50 ` [PATCH 1/3] xen/xenbus: Rename *RING_PAGE* to *RING_GRANT* Julien Grall
  2015-10-13 16:50 ` [PATCH 2/3] xen/grant-table: Add an helper to iterate over a specific number of grants Julien Grall
@ 2015-10-13 16:50 ` Julien Grall
  2015-10-16 14:12 ` [Xen-devel] [PATCH 0/3] xen/xenbus: Support multiple grants ring with 64KB page David Vrabel
  3 siblings, 0 replies; 5+ messages in thread
From: Julien Grall @ 2015-10-13 16:50 UTC (permalink / raw)
  To: xen-devel
  Cc: linux-kernel, Julien Grall, Konrad Rzeszutek Wilk,
	Boris Ostrovsky, David Vrabel, Stefano Stabellini

The PV ring may use multiple grants and expect them to be mapped
contiguously in the virtual memory.

Although, the current code is relying on a Linux page will be mapped to
a single grant. On build where Linux is using a different page size than
the grant (i.e other than 4KB), the grant will always be mapped on the
first 4KB of each Linux page which make the final ring not contiguous in
the memory.

This can be fixed by mapping multiple grant in a same Linux page.

Signed-off-by: Julien Grall <julien.grall@citrix.com>

---
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: David Vrabel <david.vrabel@citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 drivers/xen/xenbus/xenbus_client.c | 97 ++++++++++++++++++++++++++++----------
 1 file changed, 72 insertions(+), 25 deletions(-)

diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index b776433..056da6e 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -49,6 +49,10 @@
 
 #include "xenbus_probe.h"
 
+#define XENBUS_PAGES(_grants)	(DIV_ROUND_UP(_grants, XEN_PFN_PER_PAGE))
+
+#define XENBUS_MAX_RING_PAGES	(XENBUS_PAGES(XENBUS_MAX_RING_GRANTS))
+
 struct xenbus_map_node {
 	struct list_head next;
 	union {
@@ -56,7 +60,8 @@ struct xenbus_map_node {
 			struct vm_struct *area;
 		} pv;
 		struct {
-			struct page *pages[XENBUS_MAX_RING_GRANTS];
+			struct page *pages[XENBUS_MAX_RING_PAGES];
+			unsigned long addrs[XENBUS_MAX_RING_GRANTS];
 			void *addr;
 		} hvm;
 	};
@@ -591,19 +596,42 @@ failed:
 	return err;
 }
 
+struct map_ring_valloc_hvm
+{
+	unsigned int idx;
+
+	/* Why do we need two arrays? See comment of __xenbus_map_ring */
+	phys_addr_t phys_addrs[XENBUS_MAX_RING_GRANTS];
+	unsigned long addrs[XENBUS_MAX_RING_GRANTS];
+};
+
+static void xenbus_map_ring_setup_grant_hvm(unsigned long gfn,
+					    unsigned int goffset,
+					    unsigned int len,
+					    void *data)
+{
+	struct map_ring_valloc_hvm *info = data;
+	unsigned long vaddr = (unsigned long)gfn_to_virt(gfn);
+
+	info->phys_addrs[info->idx] = vaddr;
+	info->addrs[info->idx] = vaddr;
+
+	info->idx++;
+}
+
 static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev,
 				      grant_ref_t *gnt_ref,
 				      unsigned int nr_grefs,
 				      void **vaddr)
 {
 	struct xenbus_map_node *node;
-	int i;
 	int err;
 	void *addr;
 	bool leaked = false;
-	/* Why do we need two arrays? See comment of __xenbus_map_ring */
-	phys_addr_t phys_addrs[XENBUS_MAX_RING_GRANTS];
-	unsigned long addrs[XENBUS_MAX_RING_GRANTS];
+	struct map_ring_valloc_hvm info = {
+		.idx = 0,
+	};
+	unsigned int nr_pages = XENBUS_PAGES(nr_grefs);
 
 	if (nr_grefs > XENBUS_MAX_RING_GRANTS)
 		return -EINVAL;
@@ -614,24 +642,22 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev,
 	if (!node)
 		return -ENOMEM;
 
-	err = alloc_xenballooned_pages(nr_grefs, node->hvm.pages);
+	err = alloc_xenballooned_pages(nr_pages, node->hvm.pages);
 	if (err)
 		goto out_err;
 
-	for (i = 0; i < nr_grefs; i++) {
-		unsigned long pfn = page_to_pfn(node->hvm.pages[i]);
-		phys_addrs[i] = (unsigned long)pfn_to_kaddr(pfn);
-		addrs[i] = (unsigned long)pfn_to_kaddr(pfn);
-	}
+	gnttab_foreach_grant(node->hvm.pages, nr_grefs,
+			     xenbus_map_ring_setup_grant_hvm,
+			     &info);
 
 	err = __xenbus_map_ring(dev, gnt_ref, nr_grefs, node->handles,
-				phys_addrs, GNTMAP_host_map, &leaked);
+				info.phys_addrs, GNTMAP_host_map, &leaked);
 	node->nr_handles = nr_grefs;
 
 	if (err)
 		goto out_free_ballooned_pages;
 
-	addr = vmap(node->hvm.pages, nr_grefs, VM_MAP | VM_IOREMAP,
+	addr = vmap(node->hvm.pages, nr_pages, VM_MAP | VM_IOREMAP,
 		    PAGE_KERNEL);
 	if (!addr) {
 		err = -ENOMEM;
@@ -649,14 +675,13 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev,
 
  out_xenbus_unmap_ring:
 	if (!leaked)
-		xenbus_unmap_ring(dev, node->handles, node->nr_handles,
-				  addrs);
+		xenbus_unmap_ring(dev, node->handles, nr_grefs, info.addrs);
 	else
 		pr_alert("leaking %p size %u page(s)",
-			 addr, nr_grefs);
+			 addr, nr_pages);
  out_free_ballooned_pages:
 	if (!leaked)
-		free_xenballooned_pages(nr_grefs, node->hvm.pages);
+		free_xenballooned_pages(nr_pages, node->hvm.pages);
  out_err:
 	kfree(node);
 	return err;
@@ -782,13 +807,33 @@ static int xenbus_unmap_ring_vfree_pv(struct xenbus_device *dev, void *vaddr)
 	return err;
 }
 
+struct unmap_ring_vfree_hvm
+{
+	unsigned int idx;
+	unsigned long addrs[XENBUS_MAX_RING_GRANTS];
+};
+
+static void xenbus_unmap_ring_setup_grant_hvm(unsigned long gfn,
+					      unsigned int goffset,
+					      unsigned int len,
+					      void *data)
+{
+	struct unmap_ring_vfree_hvm *info = data;
+
+	info->addrs[info->idx] = (unsigned long)gfn_to_virt(gfn);
+
+	info->idx++;
+}
+
 static int xenbus_unmap_ring_vfree_hvm(struct xenbus_device *dev, void *vaddr)
 {
 	int rv;
 	struct xenbus_map_node *node;
 	void *addr;
-	unsigned long addrs[XENBUS_MAX_RING_GRANTS];
-	int i;
+	struct unmap_ring_vfree_hvm info = {
+		.idx = 0,
+	};
+	unsigned int nr_pages;
 
 	spin_lock(&xenbus_valloc_lock);
 	list_for_each_entry(node, &xenbus_valloc_pages, next) {
@@ -808,18 +853,20 @@ static int xenbus_unmap_ring_vfree_hvm(struct xenbus_device *dev, void *vaddr)
 		return GNTST_bad_virt_addr;
 	}
 
-	for (i = 0; i < node->nr_handles; i++)
-		addrs[i] = (unsigned long)pfn_to_kaddr(page_to_pfn(node->hvm.pages[i]));
+	nr_pages = XENBUS_PAGES(node->nr_handles);
+
+	gnttab_foreach_grant(node->hvm.pages, node->nr_handles,
+			     xenbus_unmap_ring_setup_grant_hvm,
+			     &info);
 
 	rv = xenbus_unmap_ring(dev, node->handles, node->nr_handles,
-			       addrs);
+			       info.addrs);
 	if (!rv) {
 		vunmap(vaddr);
-		free_xenballooned_pages(node->nr_handles, node->hvm.pages);
+		free_xenballooned_pages(nr_pages, node->hvm.pages);
 	}
 	else
-		WARN(1, "Leaking %p, size %u page(s)\n", vaddr,
-		     node->nr_handles);
+		WARN(1, "Leaking %p, size %u page(s)\n", vaddr, nr_pages);
 
 	kfree(node);
 	return rv;
-- 
2.1.4


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

* Re: [Xen-devel] [PATCH 0/3] xen/xenbus: Support multiple grants ring with 64KB page
  2015-10-13 16:50 [PATCH 0/3] xen/xenbus: Support multiple grants ring with 64KB page Julien Grall
                   ` (2 preceding siblings ...)
  2015-10-13 16:50 ` [PATCH 3/3] xenbus: Support multiple grants ring with 64KB Julien Grall
@ 2015-10-16 14:12 ` David Vrabel
  3 siblings, 0 replies; 5+ messages in thread
From: David Vrabel @ 2015-10-16 14:12 UTC (permalink / raw)
  To: Julien Grall, xen-devel
  Cc: Stefano Stabellini, linux-kernel, David Vrabel, Boris Ostrovsky,
	Roger Pau Monné

On 13/10/15 17:50, Julien Grall wrote:
> Hi all,
> 
> The support of multiple grants ring was left aside for 64KB page. This series
> aims to fix it.

Applied to for-linus-4.4, thanks.

David

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

end of thread, other threads:[~2015-10-16 14:12 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-13 16:50 [PATCH 0/3] xen/xenbus: Support multiple grants ring with 64KB page Julien Grall
2015-10-13 16:50 ` [PATCH 1/3] xen/xenbus: Rename *RING_PAGE* to *RING_GRANT* Julien Grall
2015-10-13 16:50 ` [PATCH 2/3] xen/grant-table: Add an helper to iterate over a specific number of grants Julien Grall
2015-10-13 16:50 ` [PATCH 3/3] xenbus: Support multiple grants ring with 64KB Julien Grall
2015-10-16 14:12 ` [Xen-devel] [PATCH 0/3] xen/xenbus: Support multiple grants ring with 64KB page David Vrabel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox