[PATCH] Unallocate function for memory regions created by allocate_empty_lowmem_region

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] Unallocate function for memory regions created by allocate_empty_lowmem_region

Ross C Mcilroy
[PATCH] Unallocate function for memory regions created by allocate_empty_lowmem_region

Hi,

This patch provides a function which allows a domain to reclaim memory used by the allocate_empty_lowmem_region.  It should allow a module to reclaim any memory which was released to Xen for foreign grant table access.


Thanks

Ross



# HG changeset patch
# User [hidden email]
# Node ID a05f92511a995c6ad48e5d508260edc756d4f327
# Parent  7c05931c1d0b82babd600b7e3e712fc06b899ed9
Functions to allow unallocation of memory regions created by allocate_empty_lowmem_region

Signed-of-by: Ross McIlroy <[hidden email]>

diff -r 7c05931c1d0b -r a05f92511a99 linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c        Thu Aug 18 13:26:50 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c        Mon Aug 22 09:50:48 2005
@@ -452,7 +452,50 @@
        return vstart;
 }

+int unallocate_empty_lowmem_region(unsigned long vstart,
+                                   unsigned long pages)
+{
+       unsigned long *pfn_array;
+       unsigned long  i;
+       unsigned int   order = get_order(pages*PAGE_SIZE);
+       int err;
+
+       if (vstart == 0)
+               return -EINVAL;
+
+       pfn_array = vmalloc((1<<order) * sizeof(*pfn_array));
+       BUG_ON(pfn_array == NULL);
+
+       if (err = balloon_get_pages(pfn_array, 1 << order)) {
+               vfree(pfn_array);
+               return err;
+       }
+
+       for (i = 0; i < (1<<order); i++) {
+#ifdef CONFIG_X86_64
+               xen_l1_entry_update(pfn_array[i],
+                                   (__pa(vstart)>>PAGE_SHIFT)+i);
+#else
+               BUG_ON(HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE),
+                      __pte_ma((pfn_array[i]<<PAGE_SHIFT)|__PAGE_KERNEL), 0));
+#endif
+               xen_machphys_update(pfn_array[i],
+                                   (__pa(vstart)>>PAGE_SHIFT)+i);
+               phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] =
+                       pfn_array[i];
+       }
+
+       flush_tlb_all();
+
+       vfree(pfn_array);
+
+       free_pages(vstart, order);
+
+       return 0;
+}
+
 EXPORT_SYMBOL(allocate_empty_lowmem_region);
+EXPORT_SYMBOL(unallocate_empty_lowmem_region);

 /*
  * Local variables:
diff -r 7c05931c1d0b -r a05f92511a99 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Thu Aug 18 13:26:50 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Mon Aug 22 09:50:48 2005
@@ -467,5 +467,23 @@
     schedule_work(&balloon_worker);
 }

+int balloon_get_pages(unsigned long *mfn_list, unsigned long nr_mfns)
+{
+    unsigned long flags;
+
+    balloon_lock(flags);
+    if ( HYPERVISOR_dom_mem_op(MEMOP_increase_reservation,
+                               mfn_list, nr_mfns, 0) != nr_mfns ) {
+        WPRINTK("Unable to get memory pages from Balloon Driver");
+       balloon_unlock(flags);
+       return -ENOMEM;
+    }
+    current_pages += nr_mfns; /* non-atomic update */
+    balloon_unlock(flags);
+
+    schedule_work(&balloon_worker);
+}
+
 EXPORT_SYMBOL(balloon_update_driver_allowance);
 EXPORT_SYMBOL(balloon_put_pages);
+EXPORT_SYMBOL(balloon_get_pages);
diff -r 7c05931c1d0b -r a05f92511a99 linux-2.6-xen-sparse/include/asm-xen/balloon.h
--- a/linux-2.6-xen-sparse/include/asm-xen/balloon.h    Thu Aug 18 13:26:50 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/balloon.h    Mon Aug 22 09:50:48 2005
@@ -40,6 +40,9 @@
 /* Give up unmapped pages to the balloon driver. */
 extern void balloon_put_pages(unsigned long *mfn_list, unsigned long nr_mfns);

+/* Get an unmapped pages from the balloon driver. */
+extern int balloon_get_pages(unsigned long *mfn_list, unsigned long nr_mfns);
+
 /*
  * Prevent the balloon driver from changing the memory reservation during
  * a driver critical region.
diff -r 7c05931c1d0b -r a05f92511a99 linux-2.6-xen-sparse/include/asm-xen/hypervisor.h
--- a/linux-2.6-xen-sparse/include/asm-xen/hypervisor.h Thu Aug 18 13:26:50 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/hypervisor.h Mon Aug 22 09:50:48 2005
@@ -142,6 +142,9 @@
 /* Allocate a contiguous empty region of low memory. Return virtual start. */
 unsigned long allocate_empty_lowmem_region(unsigned long pages);

+/* Unallocate a contiguous empty region of low memory which was previously
+ * allocated by allocate_empty_lowmem_region */
+int unallocate_empty_lowmem_region(unsigned long vstart, unsigned long pages);
 #include <asm/hypercall.h>

 #if defined(CONFIG_X86_64)


_______________________________________________
Xen-devel mailing list
[hidden email]
http://lists.xensource.com/xen-devel
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] Unallocate function for memory regions created by allocate_empty_lowmem_region

Keir Fraser

On 22 Aug 2005, at 11:09, Ross C Mcilroy wrote:

> Hi,
>
>  This patch provides a function which allows a domain to reclaim
> memory used by the allocate_empty_lowmem_region.  It should allow a
> module to reclaim any memory which was released to Xen for foreign
> grant table access.

This could be implemented much more simply. Add a balloon interface
function balloon_dealloc_empty_page_range(struct page *page, long
nr_pfns).

This function can simply iterate over the page range,
balloon_append()ing each page. Then kick the balloon worker thread and
you're done!

Call that balloon function direct from your driver(s) (ie., don't
bother defining a wrapper function in mm/hypervsior.c).
alloc_lowmem_region will probably also get moved to the balloon driver
at some point.

  -- Keir


_______________________________________________
Xen-devel mailing list
[hidden email]
http://lists.xensource.com/xen-devel