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] RE: [PATCH 2/6] Change the boot allocator function to suppor

To: Keir Fraser <keir.fraser@xxxxxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxxxx>, Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] RE: [PATCH 2/6] Change the boot allocator function to support memory add
From: "Jiang, Yunhong" <yunhong.jiang@xxxxxxxxx>
Date: Sun, 28 Jun 2009 21:24:37 +0800
Accept-language: en-US
Acceptlanguage: en-US
Cc:
Delivery-date: Sun, 28 Jun 2009 06:25:21 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <C66CFB70.E563%keir.fraser@xxxxxxxxxxxxx>
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>
References: <E2263E4A5B2284449EEBD0AAB751098402CCF824CF@xxxxxxxxxxxxxxxxxxxxxxxxxxxx> <C66CFB70.E563%keir.fraser@xxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: Acn30qSePbAyG89HR16wSczYgDMjIQAAzbqgAAIDDVA=
Thread-topic: [PATCH 2/6] Change the boot allocator function to support memory add

>-----Original Message-----
>From: Keir Fraser [mailto:keir.fraser@xxxxxxxxxxxxx]
>Sent: 2009年6月28日 17:50
>To: Jiang, Yunhong; Jan Beulich; Tim Deegan;
>xen-devel@xxxxxxxxxxxxxxxxxxx
>Subject: Re: [PATCH 2/6] Change the boot allocator function to
>support memory add
>
>On 28/06/2009 10:27, "Jiang, Yunhong" <yunhong.jiang@xxxxxxxxx> wrote:
>
>> This patch extend the boot allocator to support memory add.
>>
>> We take different method for boot allocator bitmap for 32/64
>system. In x32 ,
>> we allocate 512K bitmap to support the whole 16G memory. In
>x86_64, we don't
>> change the allocation when system bootup, instead, we try to
>remap the
>> allocator bitmap to some pre-defined virtual address if
>hot-add happen.
>>
>> We also add several API to allocate the handle boot page
>from some range.
>
>The undelrying implementation ideas may be okay, but calling these
>extensions to the 'boot allocator' makes no sense. The boot
>allocator only
>exists during boot. The fact that the bitmap it uses persists
>beyond boot is
>an implementation detail. Perhaps you just need to change the

So can I understand the allocator bitmap (i.e. those for map_free/map_call) as 
something not just about boot allocator, but for generic bitmap to remember the 
page allocation status?
Maybe we can just using one bit in page_info to indicate if page is allocated 
in future?

>name of your
>new allocator interface functions to something more suitable.

So how about rename arch_extend_boot_allocator() to 
"arch_extend_allocation_bitmap" and extend_boot_allocator to 
"extend_állocation_bitmap". Below is updated patch, please have a look. If it 
is ok, I will update the patchset for it.

Change the boot allocator

diff -r 6ba6134f282c xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Sun Jun 28 05:27:44 2009 +0800
+++ b/xen/arch/x86/mm.c Sun Jun 28 05:28:46 2009 +0800
@@ -155,7 +155,7 @@ struct domain *dom_xen, *dom_io;

 /* Frame table and its size in pages. */
 struct page_info *__read_mostly frame_table;
-unsigned long max_page;
+unsigned long max_page, max_boot_page;
 unsigned long total_pages;

 #define PAGE_CACHE_ATTRS (_PAGE_PAT|_PAGE_PCD|_PAGE_PWT)
@@ -207,6 +207,130 @@ void __init init_frametable(void)

     memset(frame_table, 0, nr_pages << PAGE_SHIFT);
 }
+
+#if defined(__x86_64__)
+static int boot_alloc_remapped = 0;
+static unsigned long mapped_pages = 0;
+
+#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
+
+/*
+ * Extend the boot allocator bitmap and initialize the free/alloc state.
+ * It avoid copy original bitmap through splitting super page mapping into
+ * singer page mapping.
+ * It also use pages between start_pfn/end_pfn as page table page
+ */
+int arch_extend_allocation_bitmap(unsigned long start_pfn,
+                                  unsigned long end_pfn)
+{
+    unsigned long n_size, n_pages, i, s_map_pfn, e_map_pfn;
+
+    if ( (start_pfn > end_pfn) || (start_pfn < max_page) )
+        return -EINVAL;
+
+    if (!boot_alloc_remapped)
+    {
+        unsigned long map_start, map_end, map_end_pfn;
+        unsigned long offset, o_start, o_end, o_size;
+
+        o_start = virt_to_maddr(alloc_bitmap);
+
+        o_size  = max_page / 8;
+        o_size += sizeof(unsigned long);
+        o_size  = round_pgup(o_size);
+        o_end = o_start + o_size;
+
+        map_start = o_start & ~((1UL << L2_PAGETABLE_SHIFT) -1UL);
+        map_end = o_end & ~((1UL << L2_PAGETABLE_SHIFT) -1UL);
+        map_end_pfn = map_end >> PAGE_SHIFT;
+
+        map_pages_to_xen(BOOTALLOC_VIRT_START, map_start >> PAGE_SHIFT,
+                         ((map_end - map_start) >> PAGE_SHIFT) + 1,
+                         PAGE_HYPERVISOR);
+
+        mapped_pages += (map_end - map_start) >> PAGE_SHIFT;
+
+        /*
+         * For pages in the end, it may not be 2M aligned
+         * Try to map them as 4k pages, and add some pages to be 2M aligned
+         * XXX A cleaner way is to make init_boot_allocator 2M aligned, do we
+         * care about those extra pages?
+         */
+        for (i = 0; i < (1UL << PAGETABLE_ORDER); i++)
+        {
+            if (i < (( o_end >> PAGE_SHIFT ) - map_end_pfn))
+                map_pages_to_xen(BOOTALLOC_VIRT_START +
+                                    (mapped_pages << PAGE_SHIFT),
+                                 map_end_pfn + i, 1,
+                                 PAGE_HYPERVISOR);
+            else
+            {
+                struct page_info *pg;
+                pg = alloc_domheap_page(NULL, 0);
+                if (!pg)
+                    return -ENOMEM;
+                map_pages_to_xen(BOOTALLOC_VIRT_START +
+                                    (mapped_pages  << PAGE_SHIFT),
+                                 page_to_mfn(pg), 1, PAGE_HYPERVISOR);
+                /* Mark the new created dummy page as allocated */
+                memset((void *)(BOOTALLOC_VIRT_START + (mapped_pages << 
PAGE_SHIFT)), 0xFFU, 1UL << PAGE_SHIFT);
+            }
+            mapped_pages++;
+        }
+
+        offset = o_start & ((1UL << L2_PAGETABLE_SHIFT) - 1UL);
+
+        alloc_bitmap = (unsigned long *)(BOOTALLOC_VIRT_START + offset);
+        smp_mb();
+        boot_alloc_remapped = 1;
+    }
+
+    n_size = end_pfn / 8;
+    n_size += sizeof(unsigned long);
+    n_size = round_pgup(n_size);
+    n_pages = ((unsigned long)alloc_bitmap + n_size  - BOOTALLOC_VIRT_START) >>
+                PAGE_SHIFT;
+    n_pages += ((1UL << PAGETABLE_ORDER) - 1);
+    n_pages &= ~((1UL << PAGETABLE_ORDER) - 1);
+
+    ASSERT(!(mapped_pages & ((1UL << PAGETABLE_ORDER) -1)) );
+    if ( n_pages <= mapped_pages)
+    {
+        map_free(start_pfn, end_pfn - start_pfn + 1);
+        return start_pfn;
+    }
+
+    s_map_pfn = start_pfn + (1UL << PAGETABLE_ORDER) - 1;
+    s_map_pfn = start_pfn & ~((1UL << PAGETABLE_ORDER) - 1);
+    e_map_pfn = s_map_pfn;
+    for ( i = mapped_pages; i <= n_pages; i += (1UL << PAGETABLE_ORDER) )
+    {
+        map_pages_to_xen(BOOTALLOC_VIRT_START+
+                              (i << PAGE_SHIFT),
+                         s_map_pfn + (i << PAGETABLE_ORDER ),
+                         1UL << PAGETABLE_ORDER,
+                         PAGE_HYPERVISOR);
+        e_map_pfn += (i << PAGETABLE_ORDER);
+    }
+
+    /* All new allocated page are marked as allocated initialy */
+    memset((unsigned char *)(BOOTALLOC_VIRT_START +
+                     (mapped_pages << PAGE_SHIFT)),
+            0xFFU, (n_pages - mapped_pages) << PAGE_SHIFT);
+    mapped_pages = n_pages;
+    map_free(start_pfn, s_map_pfn - start_pfn);
+    map_free(e_map_pfn, end_pfn - e_map_pfn + 1);
+
+    return start_pfn;
+}
+#else
+int arch_extend_allocation_bitmap(unsigned long start_pfn,
+                                  unsigned long end_pfn)
+{
+    map_free(start_pfn, end_pfn - start_pfn + 1);
+       return start_pfn;
+}
+#endif

 void __init arch_init_memory(void)
 {
@@ -4402,8 +4526,6 @@ int ptwr_do_page_fault(struct vcpu *v, u

 void free_xen_pagetable(void *v)
 {
-    extern int early_boot;
-
     if ( early_boot )
         return;

diff -r 6ba6134f282c xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Sun Jun 28 05:27:44 2009 +0800
+++ b/xen/arch/x86/setup.c      Sun Jun 28 05:27:48 2009 +0800
@@ -765,6 +765,9 @@ void __init __start_xen(unsigned long mb
     reserve_e820_ram(&boot_e820, initial_images_base, initial_images_end);

     /* Initialise boot heap. */
+#if defined(CONFIG_X86_32) && defined(CONFIG_MEMORY_HOTPLUG)
+    max_boot_page = 16UL << (30 - PAGE_SHIFT);
+#endif
     allocator_bitmap_end = init_boot_allocator(__pa(&_end));
 #if defined(CONFIG_X86_32)
     xenheap_initial_phys_start = allocator_bitmap_end;
diff -r 6ba6134f282c xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c  Sun Jun 28 05:27:44 2009 +0800
+++ b/xen/arch/x86/x86_32/mm.c  Sun Jun 28 05:27:48 2009 +0800
@@ -42,7 +42,6 @@ static unsigned long mpt_size;

 void *alloc_xen_pagetable(void)
 {
-    extern int early_boot;
     extern unsigned long xenheap_initial_phys_start;
     unsigned long mfn;

diff -r 6ba6134f282c xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c  Sun Jun 28 05:27:44 2009 +0800
+++ b/xen/arch/x86/x86_64/mm.c  Sun Jun 28 05:27:48 2009 +0800
@@ -57,7 +57,6 @@ l2_pgentry_t __attribute__ ((__section__

 void *alloc_xen_pagetable(void)
 {
-    extern int early_boot;
     unsigned long mfn;

     if ( !early_boot )
diff -r 6ba6134f282c xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Sun Jun 28 05:27:44 2009 +0800
+++ b/xen/common/page_alloc.c   Sun Jun 28 07:30:10 2009 +0800
@@ -103,7 +103,7 @@ unsigned long *alloc_bitmap;
  *  *_off == Bit offset within an element of the `alloc_bitmap' array.
  */

-static void map_alloc(unsigned long first_page, unsigned long nr_pages)
+void map_alloc(unsigned long first_page, unsigned long nr_pages)
 {
     unsigned long start_off, end_off, curr_idx, end_idx;

@@ -131,7 +131,7 @@ static void map_alloc(unsigned long firs
     }
 }

-static void map_free(unsigned long first_page, unsigned long nr_pages)
+void map_free(unsigned long first_page, unsigned long nr_pages)
 {
     unsigned long start_off, end_off, curr_idx, end_idx;

@@ -178,15 +178,33 @@ paddr_t __init init_boot_allocator(paddr
      * Allocate space for the allocation bitmap. Include an extra longword
      * of padding for possible overrun in map_alloc and map_free.
      */
-    bitmap_size  = max_page / 8;
+    bitmap_size  = (max_boot_page ? max_boot_page : max_page) / 8;
     bitmap_size += sizeof(unsigned long);
     bitmap_size  = round_pgup(bitmap_size);
     alloc_bitmap = (unsigned long *)maddr_to_virt(bitmap_start);

     /* All allocated by default. */
     memset(alloc_bitmap, ~0, bitmap_size);
+    max_boot_page = max_page;

     return bitmap_start + bitmap_size;
+}
+
+int extend_allocation_bitmap(unsigned long spfn, unsigned long epfn)
+{
+    int rc;
+
+    if (epfn < max_page)
+        return 0;
+
+    rc = arch_extend_allocation_bitmap(spfn, epfn);
+
+    if (rc < 0)
+        return rc;
+
+    max_boot_page = epfn;
+
+    return 0;
 }

 void __init init_boot_pages(paddr_t ps, paddr_t pe)
@@ -235,15 +253,22 @@ void __init init_boot_pages(paddr_t ps,
     }
 }

-unsigned long __init alloc_boot_pages(
-    unsigned long nr_pfns, unsigned long pfn_align)
+/*
+ * allocate nr_pfn with "align" alignement between start ~ end
+ */
+unsigned long alloc_in_allocation_bitmap(unsigned long start, unsigned long 
end,
+                                    unsigned long nr_pfns, unsigned long align)
 {
     unsigned long pg, i;
-
-    /* Search backwards to obtain highest available range. */
-    for ( pg = (max_page - nr_pfns) & ~(pfn_align - 1);
-          pg >= first_valid_mfn;
-          pg = (pg + i - nr_pfns) & ~(pfn_align - 1) )
+    if (start < first_valid_mfn)
+        start = first_valid_mfn;
+
+    if ( (end > max_boot_page) )
+        end = max_boot_page;
+
+    for (pg = (end - nr_pfns) & ~(align - 1);
+         pg >= start;
+         pg = (pg + i - nr_pfns) & ~(align - 1) )
     {
         for ( i = 0; i < nr_pfns; i++ )
             if ( allocated_in_map(pg+i) )
@@ -258,6 +283,11 @@ unsigned long __init alloc_boot_pages(
     return 0;
 }

+unsigned long __init alloc_boot_pages(
+    unsigned long nr_pfns, unsigned long pfn_align)
+{
+    return alloc_in_allocation_bitmap(first_valid_mfn, max_page, nr_pfns, 
pfn_align);
+}


 /*************************
@@ -834,7 +864,7 @@ int query_page_offline(unsigned long mfn
  * latter is not on a MAX_ORDER boundary, then we reserve the page by
  * not freeing it to the buddy allocator.
  */
-static void init_heap_pages(
+void init_heap_pages(
     struct page_info *pg, unsigned long nr_pages)
 {
     unsigned int nid_curr, nid_prev;
@@ -894,15 +924,15 @@ static unsigned long avail_heap_pages(
 }

 #define avail_for_domheap(mfn) !(allocated_in_map(mfn) || is_xen_heap_mfn(mfn))
-void __init end_boot_allocator(void)
+void transfer_pages_to_heap(unsigned long spfn, unsigned long epfn)
 {
     unsigned long i, nr = 0;
     int curr_free, next_free;

     /* Pages that are free now go to the domain sub-allocator. */
-    if ( (curr_free = next_free = avail_for_domheap(first_valid_mfn)) )
-        map_alloc(first_valid_mfn, 1);
-    for ( i = first_valid_mfn; i < max_page; i++ )
+    if ( (curr_free = next_free = avail_for_domheap(spfn)) )
+        map_alloc(spfn, 1);
+    for ( i = spfn; i < epfn; i++ )
     {
         curr_free = next_free;
         next_free = avail_for_domheap(i+1);
@@ -918,6 +948,11 @@ void __init end_boot_allocator(void)
     }
     if ( nr )
         init_heap_pages(mfn_to_page(i - nr), nr);
+}
+
+void __init end_boot_allocator(void)
+{
+    transfer_pages_to_heap(first_valid_mfn, max_page);

     if ( !dma_bitsize && (num_online_nodes() > 1) )
     {
@@ -936,6 +971,7 @@ void __init end_boot_allocator(void)
         printk(" DMA width %u bits", dma_bitsize);
     printk("\n");
 }
+
 #undef avail_for_domheap

 /*
diff -r 6ba6134f282c xen/include/asm-ia64/mm.h
--- a/xen/include/asm-ia64/mm.h Sun Jun 28 05:27:44 2009 +0800
+++ b/xen/include/asm-ia64/mm.h Sun Jun 28 07:35:17 2009 +0800
@@ -274,6 +274,12 @@ static inline int get_page_and_type(stru
     }

     return rc;
+}
+
+int arch_extend_allocation_bitmap(unsigned long start_pfn,
+                                  unsigned long end_pfn)
+{
+    return -ENOSYS;
 }

 #define        set_machinetophys(_mfn, _pfn) do { } while(0);
diff -r 6ba6134f282c xen/include/asm-x86/config.h
--- a/xen/include/asm-x86/config.h      Sun Jun 28 05:27:44 2009 +0800
+++ b/xen/include/asm-x86/config.h      Sun Jun 28 05:27:48 2009 +0800
@@ -162,7 +162,9 @@ extern unsigned int video_mode, video_fl
  *    High read-only compatibility machine-to-phys translation table.
  *  0xffff828c80000000 - 0xffff828cbfffffff [1GB,   2^30 bytes, PML4:261]
  *    Xen text, static data, bss.
- *  0xffff828cc0000000 - 0xffff82ffffffffff [461GB,             PML4:261]
+ *  0xffff828cc0000000 - 0xffff82cfffffffff [1GB,   2^30 bytes,  PML4:261]
+ *    Boot allocator bitmap
+ *  0xffff828cd0000000 - 0xffff82ffffffffff [460GB,             PML4:261]
  *    Reserved for future use.
  *  0xffff830000000000 - 0xffff83ffffffffff [1TB,   2^40 bytes, PML4:262-263]
  *    1:1 direct mapping of all physical memory.
@@ -230,6 +232,9 @@ extern unsigned int video_mode, video_fl
 /* Slot 261: xen text, static data and bss (1GB). */
 #define XEN_VIRT_START          (HIRO_COMPAT_MPT_VIRT_END)
 #define XEN_VIRT_END            (XEN_VIRT_START + (1UL << 30))
+/* Slot 261: Boot allocator bitmap (1GB) */
+#define BOOTALLOC_VIRT_START        XEN_VIRT_END
+#define BOOTALLOC_VIRT_END          (BOOTALLOC_VIRT_START + (1UL << 30))
 /* Slot 262-263: A direct 1:1 mapping of all of physical memory. */
 #define DIRECTMAP_VIRT_START    (PML4_ADDR(262))
 #define DIRECTMAP_VIRT_END      (DIRECTMAP_VIRT_START + PML4_ENTRY_BYTES*2)
diff -r 6ba6134f282c xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h  Sun Jun 28 05:27:44 2009 +0800
+++ b/xen/include/asm-x86/mm.h  Sun Jun 28 05:32:54 2009 +0800
@@ -266,9 +266,13 @@ extern void share_xen_page_with_privileg
     struct page_info *page, int readonly);

 extern struct page_info *frame_table;
-extern unsigned long max_page;
+extern unsigned long max_page, max_boot_page;
 extern unsigned long total_pages;
+
+extern int early_boot;
 void init_frametable(void);
+int arch_extend_allocation_bitmap(unsigned long start_pfn,
+                               unsigned long end_pfn);

 int free_page_type(struct page_info *page, unsigned long type,
                    int preemptible);
diff -r 6ba6134f282c xen/include/xen/mm.h
--- a/xen/include/xen/mm.h      Sun Jun 28 05:27:44 2009 +0800
+++ b/xen/include/xen/mm.h      Sun Jun 28 07:31:43 2009 +0800
@@ -38,10 +38,18 @@ struct page_info;

 /* Boot-time allocator. Turns into generic allocator after bootstrap. */
 paddr_t init_boot_allocator(paddr_t bitmap_start);
+void map_free(unsigned long first_page, unsigned long nr_pages);
+void map_alloc(unsigned long first_page, unsigned long nr_pages);
 void init_boot_pages(paddr_t ps, paddr_t pe);
 unsigned long alloc_boot_pages(
     unsigned long nr_pfns, unsigned long pfn_align);
+unsigned long alloc_in_allocation_bitmap(unsigned long start, unsigned long 
end,
+                               unsigned long nr_pfns, unsigned long align);
+void init_heap_pages(
+    struct page_info *pg, unsigned long nr_pages);
 void end_boot_allocator(void);
+void transfer_pages_to_heap(unsigned long spfn, unsigned long epfn);
+int extend_allocation_bitmap(unsigned long spfn, unsigned long epfn);

 /* Xen suballocator. These functions are interrupt-safe. */
 void init_xenheap_pages(paddr_t ps, paddr_t pe);


Thanks
Yunhong Jiang

>
> -- Keir
>
>
>

Attachment: boot_allocator.patch
Description: boot_allocator.patch

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