WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-ppc-devel

[XenPPC] [linux-ppc-2.6] [XEN][POWERPC] Use a bitmap to manage the forei

To: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Subject: [XenPPC] [linux-ppc-2.6] [XEN][POWERPC] Use a bitmap to manage the foreign page area
From: Xen patchbot-linux-ppc-2.6 <patchbot-linux-ppc-2.6@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 09 Nov 2006 00:02:45 +0000
Delivery-date: Wed, 08 Nov 2006 16:04:37 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-ppc-devel-request@lists.xensource.com?subject=help>
List-id: Xen PPC development <xen-ppc-devel.lists.xensource.com>
List-post: <mailto:xen-ppc-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-ppc-devel-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
# Node ID 39d3d1cfe7146a6542a7708bace0ab38f11e48b5
# Parent  2a9c6a23cd1292e9ed361e33d640ce84a6fbdb53
[XEN][POWERPC] Use a bitmap to manage the foreign page area

We needed to be able to dispense pages from the foreign map to Xen VIO
back drivers.  I thougth mempool would be an easy way to do this, but
it seems that a bitmap is far easier and simpler to do this with.

Signed-off-by: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
---
 arch/powerpc/platforms/xen/balloon.c |   14 +---
 arch/powerpc/platforms/xen/gnttab.c  |  100 ++++++++++++++++-------------------
 arch/powerpc/platforms/xen/setup.h   |    4 -
 arch/powerpc/platforms/xen/util.c    |    2 
 4 files changed, 55 insertions(+), 65 deletions(-)

diff -r 2a9c6a23cd12 -r 39d3d1cfe714 arch/powerpc/platforms/xen/balloon.c
--- a/arch/powerpc/platforms/xen/balloon.c      Fri Nov 03 16:50:22 2006 -0500
+++ b/arch/powerpc/platforms/xen/balloon.c      Wed Nov 08 15:44:19 2006 -0500
@@ -11,22 +11,16 @@ struct page **alloc_empty_pages_and_page
 {
        struct page *page, **pagevec;
        int i;
-       int scrub = 0;
 
        pagevec = kmalloc(sizeof(*pagevec) * nr_pages, GFP_KERNEL);
        if (pagevec == NULL)
                return  NULL;
 
        for (i = 0; i < nr_pages; i++) {
-               page = alloc_grant_page();
+               page = alloc_foreign_page();
                pagevec[i] = page;
-
-               if (scrub) {
-                       void *vaddr;
-
-                       vaddr = page_address(page);
-                       scrub_pages(vaddr, 1);
-               }
+               /* There is no real page backing us yet so it cannot
+                * be scrubbed */
        }
 
        return pagevec;
@@ -40,7 +34,7 @@ void free_empty_pages_and_pagevec(struct
                return;
 
        for (i = 0; i < nr_pages; i++) {
-               free_grant_page(pagevec[i]);
+               free_foreign_page(pagevec[i]);
        }
        
        kfree(pagevec);
diff -r 2a9c6a23cd12 -r 39d3d1cfe714 arch/powerpc/platforms/xen/gnttab.c
--- a/arch/powerpc/platforms/xen/gnttab.c       Fri Nov 03 16:50:22 2006 -0500
+++ b/arch/powerpc/platforms/xen/gnttab.c       Wed Nov 08 15:44:19 2006 -0500
@@ -2,7 +2,6 @@
 #include <linux/config.h>
 #include <linux/vmalloc.h>
 #include <linux/memory_hotplug.h>
-#include <linux/mempool.h>
 #include <xen/gnttab.h>
 #include <asm/hypervisor.h>
 #include <xen/interface/grant_table.h>
@@ -25,8 +24,9 @@
 
 struct address_space xen_foreign_dummy_mapping;
 
-static ulong foreign_map_base;
-static ulong foreign_map_end;
+static ulong foreign_map_pfn;
+static ulong foreign_map_pgs;
+static unsigned long *foreign_map_bitmap;
 
 
 /* hijack _mapcount */
@@ -215,7 +215,9 @@ static void gnttab_post_map_grant_ref(
                        continue;
                }
 
-               BUG_ON(pa < foreign_map_base || pa >= foreign_map_end);
+               BUG_ON(pa < (foreign_map_pfn << PAGE_SHIFT));
+               BUG_ON(pa >= (foreign_map_pfn << PAGE_SHIFT) + 
+                      (foreign_map_pgs << PAGE_SHIFT));
 
                page = virt_to_page(__va(pa));
 
@@ -330,9 +332,7 @@ static ulong find_grant_maps(void)
                panic("foreign-map is 0x%lx, expect 0x%lx\n",
                      gm[0], expect);
 
-       foreign_map_base = 1UL << (gm[0] + PAGE_SHIFT);
-       foreign_map_end = foreign_map_base + (gm[1] << PAGE_SHIFT);
-
+       foreign_map_pfn = 1UL << gm[0];
        return gm[1];
 }
 
@@ -353,40 +353,27 @@ int arch_gnttab_suspend(volatile void __
        return 0;
 }
 
-static mempool_t *grant_pool;
-struct page *alloc_grant_page(void)
-{
-       void *va;
-
-       va = mempool_alloc(grant_pool, GFP_KERNEL);
-
-       return virt_to_page(va);
-}
-
-void free_grant_page(struct page *page)
-{
-       mempool_free(pfn_to_kaddr(page_to_pfn(page)), grant_pool);
-}
-
-static void *gp_alloc(gfp_t gfp_mask, void *pool_data)
-{
-       static ulong count;
-       ulong max = (ulong)pool_data;
-       void *ret = NULL;
-
-       if (count < max) {
-               ulong pfn;
-
-               pfn = (foreign_map_base >> PAGE_SHIFT) + count;
-               ret = pfn_to_kaddr(pfn);
-               ++count;
-       }
-       return ret;
-}
-
-static void gp_free(void *element, void *pool_data)
-{
-       BUG();
+struct page *alloc_foreign_page(void)
+{
+       int bit;
+       do {
+               bit = find_first_zero_bit(foreign_map_bitmap,
+                                         foreign_map_pgs);
+               if (bit >= foreign_map_pgs)
+                       return NULL;
+       } while (test_and_set_bit(bit, foreign_map_bitmap) == 1);
+
+       return pfn_to_page(foreign_map_pfn + bit);
+}
+
+void free_foreign_page(struct page *page)
+{
+       int bit = page_to_pfn(page) - foreign_map_pfn;
+
+       BUG_ON(bit < 0);
+       BUG_ON(bit >= foreign_map_pgs);
+
+       clear_bit(bit, foreign_map_bitmap);
 }
 
 static void setup_grant_area(void)
@@ -400,25 +387,39 @@ static void setup_grant_area(void)
        pgs = find_grant_maps();
        setup_foreign_segment();
 
+       printk("%s: Xen VIO will use a foreign address space of 0x%lx pages\n",
+              __func__, pgs);
+
        /* add pages to the zone */
        nid = 0;
        pgdata = NODE_DATA(nid);
        zone = pgdata->node_zones;
 
-       err = __add_pages(zone, foreign_map_base >> PAGE_SHIFT, pgs);
+       err = __add_pages(zone, foreign_map_pfn, pgs);
 
        if (err < 0) {
                printk(KERN_EMERG "%s: add_pages(0x%lx, 0x%lx) = %d\n",
-                      __func__, foreign_map_base >> PAGE_SHIFT, pgs, err);
+                      __func__, foreign_map_pfn, pgs, err);
                BUG();
        }
 
-       /* create a memory pool to manage these pages */
-       grant_pool = mempool_create(pgs, gp_alloc, gp_free, (void *)pgs);
-       if (grant_pool == NULL) {
-               printk(KERN_EMERG "%s: mempool_create(): failed\n", __func__);
+       /* create a bitmap to manage these pages */
+       foreign_map_bitmap = kmalloc(BITS_TO_LONGS(pgs) * sizeof(long),
+                                    GFP_KERNEL);
+       if (foreign_map_bitmap == NULL) {
+               printk(KERN_EMERG 
+                      "%s: could not allocate foreign_map_bitmap to "
+                      "manage 0x%lx foreign pages\n", __func__, pgs);
                BUG();
        }
+       /* I'm paranoid so make sure we assign the top bits so we
+        * don't give them away */
+       bitmap_fill(&foreign_map_bitmap[BITS_TO_LONGS(pgs) - 1],
+                   BITS_PER_LONG);
+       /* now clear all the real bits */
+       bitmap_zero(foreign_map_bitmap, pgs);
+
+       foreign_map_pgs = pgs;
 }
 
 void *arch_gnttab_map(unsigned long *frames)
@@ -439,8 +440,3 @@ void *arch_gnttab_map(unsigned long *fra
 
        return shared;
 }
-
-int arch_is_foreign_page(struct page *page)
-{
-       return ((page_to_pfn(page) << PAGE_SHIFT) >= foreign_map_base);
-}
diff -r 2a9c6a23cd12 -r 39d3d1cfe714 arch/powerpc/platforms/xen/setup.h
--- a/arch/powerpc/platforms/xen/setup.h        Fri Nov 03 16:50:22 2006 -0500
+++ b/arch/powerpc/platforms/xen/setup.h        Wed Nov 08 15:44:19 2006 -0500
@@ -22,6 +22,6 @@ static inline u64 jiffies_to_ns(unsigned
 
 #define xen_guest_handle(hnd)  ((hnd).p)
 
-extern struct page *alloc_grant_page(void);
-extern void free_grant_page(struct page *page);
+extern struct page *alloc_foreign_page(void);
+extern void free_foreign_page(struct page *page);
 
diff -r 2a9c6a23cd12 -r 39d3d1cfe714 arch/powerpc/platforms/xen/util.c
--- a/arch/powerpc/platforms/xen/util.c Fri Nov 03 16:50:22 2006 -0500
+++ b/arch/powerpc/platforms/xen/util.c Wed Nov 08 15:44:19 2006 -0500
@@ -12,7 +12,7 @@ struct vm_struct *alloc_vm_area(unsigned
        struct vm_struct *area;
        struct page *page;
 
-       page = alloc_grant_page();
+       page = alloc_foreign_page();
        if (page == NULL) {
                BUG();
                return NULL;

_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel

<Prev in Thread] Current Thread [Next in Thread>