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-devel

[Xen-devel] [PATCH] xmalloc: return unused full pages on multi-page allo

To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] xmalloc: return unused full pages on multi-page allocations
From: "Jan Beulich" <JBeulich@xxxxxxxx>
Date: Thu, 13 Oct 2011 08:27:50 +0100
Delivery-date: Thu, 13 Oct 2011 00:28:37 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Certain (boot time) allocations are relatively large (particularly when
building with high NR_CPUS), but can also happen to be pretty far away
from a power-of-two size. Utilize the page allocator's (other than
Linux'es) capability of allowing to return space from higher-order
allocations in smaller pieces to return the unused parts immediately.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>

--- a/xen/common/xmalloc_tlsf.c
+++ b/xen/common/xmalloc_tlsf.c
@@ -527,13 +527,21 @@ static void xmalloc_pool_put(void *p)
 static void *xmalloc_whole_pages(unsigned long size)
 {
     struct bhdr *b;
-    unsigned int pageorder = get_order_from_bytes(size + BHDR_OVERHEAD);
+    unsigned int i, pageorder = get_order_from_bytes(size + BHDR_OVERHEAD);
+    char *p;
 
     b = alloc_xenheap_pages(pageorder, 0);
     if ( b == NULL )
         return NULL;
 
-    b->size = (1 << (pageorder + PAGE_SHIFT));
+    b->size = PAGE_ALIGN(size + BHDR_OVERHEAD);
+    for ( p = (char *)b + b->size, i = 0; i < pageorder; ++i )
+        if ( (unsigned long)p & (PAGE_SIZE << i) )
+        {
+            free_xenheap_pages(p, i);
+            p += PAGE_SIZE << i;
+        }
+
     return (void *)b->ptr.buffer;
 }
 
@@ -611,7 +619,20 @@ void xfree(void *p)
     }
 
     if ( b->size >= PAGE_SIZE )
-        free_xenheap_pages((void *)b, get_order_from_bytes(b->size));
+    {
+        unsigned int i, order = get_order_from_bytes(b->size);
+
+        BUG_ON((unsigned long)b & ((PAGE_SIZE << order) - 1));
+        for ( i = 0; ; ++i )
+        {
+            if ( !(b->size & (PAGE_SIZE << i)) )
+                continue;
+            b->size -= PAGE_SIZE << i;
+            free_xenheap_pages((void *)b + b->size, i);
+            if ( i + 1 >= order )
+                break;
+        }
+    }
     else
         xmem_pool_free(p, xenpool);
 }




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

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