]> xenbits.xensource.com Git - people/sstabellini/xen-unstable.git/.git/commitdiff
xen/arm: add colored allocator initialization
authorLuca Miccio <206497@studenti.unimore.it>
Wed, 21 Aug 2019 15:09:56 +0000 (17:09 +0200)
committerLuca Miccio <206497@studenti.unimore.it>
Mon, 6 Jan 2020 13:59:35 +0000 (14:59 +0100)
Initialize colored heap and allocator data structures. It is assumed
that pages are given to the init function is in ascending order. To
ensure that, pages are retrieved from bootmem_regions starting from the
first one.

Signed-off-by: Luca Miccio <206497@studenti.unimore.it>
Signed-off-by: Marco Solieri <marco.solieri@unimore.it>
xen/arch/arm/color_alloc.c
xen/arch/arm/coloring.c
xen/common/page_alloc.c
xen/include/asm-arm/coloring.h

index ede3782eb189caf2a4e1c53605c950e03fb7b8d4..44cc31b1f17dc5605d4252f691b46e62225b984f 100644 (file)
@@ -39,6 +39,7 @@ typedef struct page_list_head color_list;
 static color_list *color_heap;
 static long total_avail_col_pages;
 static u64 col_num_max;
+static bool color_init_state = true;
 
 static DEFINE_SPINLOCK(heap_lock);
 
@@ -204,6 +205,40 @@ void free_col_heap_page(struct page_info *pg)
     page_list_add_order( pg, page_to_head(pg) );
 }
 
+bool init_col_heap_pages(struct page_info *pg, unsigned long nr_pages)
+{
+    int i;
+
+    if ( color_init_state )
+    {
+        col_num_max = get_max_colors();
+        color_heap = xmalloc_array(color_list, col_num_max);
+        BUG_ON(!color_heap);
+
+        for ( i = 0; i < col_num_max; i++ )
+        {
+            C_DEBUG("Init list for color: %u\n", i);
+            INIT_PAGE_LIST_HEAD(&color_heap[i]);
+        }
+
+        color_init_state = false;
+    }
+
+    C_DEBUG("Init color heap pages with %lu pages for a given size of 0x%lx\n",
+            nr_pages, nr_pages * PAGE_SIZE);
+    C_DEBUG("Paging starting from: 0x%lx\n", page_to_maddr(pg));
+    total_avail_col_pages += nr_pages;
+
+    for ( i = 0; i < nr_pages; i++ )
+    {
+        pg->colored = true;
+        page_list_add_order(pg, page_to_head(pg));
+        pg++;
+    }
+
+    return true;
+}
+
 static void dump_col_heap(unsigned char key)
 {
     struct page_info *pg;
index eb9426d6962d95c8410234cba58a2ac699d7a7a0..dca012962743f15fc9861f01530184e45d5acfbd 100644 (file)
@@ -28,6 +28,9 @@
 #include <asm/coloring.h>
 #include <asm/io.h>
 
+/* Minimum size required for buddy allocator to work with colored one */
+unsigned long buddy_required_size __read_mostly = MB(512);
+
 /* Number of color(s) assigned to Xen */
 static uint64_t xen_col_num;
 /* Coloring configuration of Xen as bitmask */
@@ -179,6 +182,11 @@ bool __init coloring_init(void)
     return true;
 }
 
+uint64_t get_max_colors(void)
+{
+    return col_num_max;
+}
+
 /*************************
  * PARSING COLORING BOOTARGS
  */
@@ -242,6 +250,14 @@ static int __init parse_way_size(const char *s)
 }
 custom_param("way_size", parse_way_size);
 
+static int __init parse_buddy_required_size(const char *s)
+{
+    buddy_required_size = simple_strtoull(s, &s, 0);
+
+    return *s ? -EINVAL : 0;
+}
+custom_param("buddy_size", parse_buddy_required_size);
+
 static int __init parse_dom0_colors(const char *s)
 {
     return parse_color_config(s, &dom0_colors_mask, &dom0_colors_num);
index 7cb1bd368b6c2d96d3f8fcf4de15e54dda2ede16..d2736f1b2dc5fe25b710b415b2ebb450a94fa977 100644 (file)
 #include <asm/page.h>
 #include <asm/numa.h>
 #include <asm/flushtlb.h>
+#include <asm/coloring.h>
 #ifdef CONFIG_X86
 #include <asm/guest.h>
 #include <asm/p2m.h>
@@ -1846,6 +1847,12 @@ static unsigned long avail_heap_pages(
     return free_pages;
 }
 
+#if CONFIG_COLORING
+extern unsigned long buddy_required_size;
+#else
+static unsigned long buddy_required_size = 0;
+#endif
+
 void __init end_boot_allocator(void)
 {
     unsigned int i;
@@ -1862,12 +1869,46 @@ void __init end_boot_allocator(void)
             break;
         }
     }
+
     for ( i = nr_bootmem_regions; i-- > 0; )
     {
         struct bootmem_region *r = &bootmem_region_list[i];
-        if ( r->s < r->e )
-            init_heap_pages(mfn_to_page(_mfn(r->s)), r->e - r->s);
+
+       /*
+         * Find the first region that can fill the buddy allocator memory
+         * specified by XEN_COLOR_BUDDY_NR_PAGES macro.
+         * Assign the first XEN_COLOR_BUDDY_NR_PAGES of memory to the buddy
+         * allocator and the remaining one to the colored allocator.
+         */
+        if ( buddy_required_size && (r->e - r->s) >=
+            (buddy_required_size >> PAGE_SHIFT) )
+        {
+            unsigned long nr_pages = 0;
+
+            C_DEBUG("Allocating 0x%lx for buddy allocator starting from: 0x%lx\n",
+                buddy_required_size, pfn_to_paddr(r->s));
+            init_heap_pages(mfn_to_page(_mfn(r->s)),
+                (buddy_required_size >> PAGE_SHIFT));
+
+            r->s += (buddy_required_size >> PAGE_SHIFT);
+            nr_pages = (r->e - r->s);
+            C_DEBUG("COLORED: Init heap pages from 0x%lx with size: 0x%lx\n",
+                pfn_to_paddr(r->s), nr_pages*PAGE_SIZE);
+            if( !init_col_heap_pages(mfn_to_page(_mfn(r->s)), nr_pages) )
+                init_heap_pages(mfn_to_page(_mfn(r->s)), nr_pages);
+            buddy_required_size = 0;
+        }
+        else
+        {
+            C_DEBUG("COLORED: Init heap pages from 0x%lx with size: 0x%lx\n",
+                pfn_to_paddr(r->s),(r->e - r->s)*PAGE_SIZE);
+            if( !init_col_heap_pages(mfn_to_page(_mfn(r->s)), r->e - r->s) )
+                init_heap_pages(mfn_to_page(_mfn(r->s)), r->e - r->s);
+        }
     }
+
+    ASSERT(!buddy_required_size);
+
     nr_bootmem_regions = 0;
     init_heap_pages(virt_to_page(bootmem_region_list), 1);
 
index 70ac83dac1a6856f543d16f0c4f0558be88b2cb2..2be7e550a1e1152eb498dfefc3f9e92ad6f779dc 100644 (file)
 #ifdef CONFIG_COLORING
 bool __init coloring_init(void);
 
+/* Return the maximum available number of colors supported by the hardware */
+uint64_t get_max_colors(void);
+
 /* Colored allocator functions */
+bool init_col_heap_pages(struct page_info *pg, unsigned long nr_pages);
 struct page_info *alloc_col_domheap_page(
        struct domain *d, unsigned int memflags);
 void free_col_heap_page(struct page_info *pg);
@@ -48,12 +52,23 @@ static bool inline __init coloring_init(void)
     return true;
 }
 
+static inline bool init_col_heap_pages(
+       struct page_info *pg, unsigned long nr_pages)
+{
+       return false;
+}
+
 static inline struct page_info *alloc_col_domheap_page(
        struct domain *d, unsigned int memflags)
 {
        return NULL;
 }
 
+static inline uint64_t get_max_colors(void)
+{
+    return 0;
+}
+
 static inline void free_col_heap_page(struct page_info *pg)
 {
        return;