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);
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;
#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 */
return true;
}
+uint64_t get_max_colors(void)
+{
+ return col_num_max;
+}
+
/*************************
* PARSING COLORING BOOTARGS
*/
}
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);
#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>
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;
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);
#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);
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;