[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 08/10] xen/xenbus: use apply_to_page_range directly in xenbus_map_ring_pv



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@xxxxxx>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>
---
 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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.