[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] create multiple banks for dom0 in 1:1 mapping if necessary
Create multiple banks to hold dom0 memory in case of 1:1 mapping if we failed to find 1 large contiguous memory to hold the whole thing. Signed-off-by: Karim Raslan <karim.allah.ahmed@xxxxxxxxx> --- xen/arch/arm/domain_build.c | 74 ++++++++++++++++++++++++++----------- xen/arch/arm/kernel.c | 86 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 121 insertions(+), 39 deletions(-) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index faff88e..bb44cdd 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -69,39 +69,71 @@ static void allocate_memory_11(struct domain *d, struct kernel_info *kinfo) { paddr_t start; paddr_t size; + unsigned int cur_order, cur_bank, nr_banks = 1, index = 0; struct page_info *pg = NULL; - unsigned int order = get_order_from_bytes(dom0_mem); + unsigned int order = get_order_from_bytes(kinfo->unassigned_mem); int res; paddr_t spfn; unsigned int bits; - for ( bits = PAGE_SHIFT + 1; bits < PADDR_BITS; bits++ ) +#define MIN_BANK_ORDER 10 + + kinfo->mem.nr_banks = 0; + + /* + * We always first try to allocate all dom0 memory in 1 bank. + * However, if we failed to allocate physically contiguous memory + * from the allocator, then we try to create more than one bank. + */ + for ( cur_order = order; cur_order > MIN_BANK_ORDER; cur_order--) { - pg = alloc_domheap_pages(d, order, MEMF_bits(bits)); - if ( pg != NULL ) - break; + for( cur_bank = 1; cur_bank <= nr_banks; cur_bank++ ) + { + for ( bits = PAGE_SHIFT + 1; bits < PADDR_BITS; bits++ ) + { + pg = alloc_domheap_pages(d, cur_order, MEMF_bits(bits)); + if ( pg != NULL ) + break; + } + + if ( !pg ) + break; + + spfn = page_to_mfn(pg); + start = pfn_to_paddr(spfn); + size = pfn_to_paddr((1 << cur_order)); + + kinfo->mem.bank[index].start = start; + kinfo->mem.bank[index].size = size; + index++; + kinfo->mem.nr_banks++; + } + + if( pg ) + break; + + nr_banks = (nr_banks - cur_bank + 1) << 1; } - if ( !pg ) - panic("Failed to allocate contiguous memory for dom0"); + if ( !pg ) + panic("Failed to allocate contiguous memory for dom0"); - spfn = page_to_mfn(pg); - start = pfn_to_paddr(spfn); - size = pfn_to_paddr((1 << order)); + for ( index = 0; index < kinfo->mem.nr_banks; index++ ) + { + start = kinfo->mem.bank[index].start; + size = kinfo->mem.bank[index].size; + spfn = paddr_to_pfn(start); + order = get_order_from_bytes(size); - // 1:1 mapping - printk("Populate P2M %#"PRIx64"->%#"PRIx64" (1:1 mapping for dom0)\n", - start, start + size); - res = guest_physmap_add_page(d, spfn, spfn, order); - - if ( res ) - panic("Unable to add pages in DOM0: %d", res); + printk("Populate P2M %#"PRIx64"->%#"PRIx64" (1:1 mapping for dom0 - order : %i)\n", + start, start + size, order); + res = guest_physmap_add_page(d, spfn, spfn, order); - kinfo->mem.bank[0].start = start; - kinfo->mem.bank[0].size = size; - kinfo->mem.nr_banks = 1; + if ( res ) + panic("Unable to add pages in DOM0: %d", res); - kinfo->unassigned_mem -= size; + kinfo->unassigned_mem -= size; + } } static void allocate_memory(struct domain *d, struct kernel_info *kinfo) diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c index 6a5772b..658c3de 100644 --- a/xen/arch/arm/kernel.c +++ b/xen/arch/arm/kernel.c @@ -79,15 +79,43 @@ static void place_modules(struct kernel_info *info, const paddr_t total = initrd_len + dtb_len; /* Convenient */ - const paddr_t mem_start = info->mem.bank[0].start; - const paddr_t mem_size = info->mem.bank[0].size; - const paddr_t mem_end = mem_start + mem_size; - const paddr_t kernel_size = kernel_end - kernel_start; + unsigned int i, min_i = -1; + bool_t same_bank = false; + + paddr_t mem_start, mem_end, mem_size; + paddr_t kernel_size; paddr_t addr; - if ( total + kernel_size > mem_size ) - panic("Not enough memory in the first bank for the dtb+initrd"); + kernel_size = kernel_end - kernel_start; + + for ( i = 0; i < info->mem.nr_banks; i++ ) + { + mem_start = info->mem.bank[i].start; + mem_size = info->mem.bank[i].size; + mem_end = mem_start + mem_size - 1; + + if ( (kernel_end > mem_start) && (kernel_end <= mem_end) ) + same_bank = true; + else + same_bank = false; + + if ( same_bank && ((total + kernel_size) < mem_size) ) + min_i = i; + else if ( (!same_bank) && (total < mem_size) ) + min_i = i; + else + continue; + + break; + } + + if ( min_i == -1 ) + panic("Not enough memory for the dtb+initrd"); + + mem_start = info->mem.bank[min_i].start; + mem_size = info->mem.bank[min_i].size; + mem_end = mem_start + mem_size; /* * DTB must be loaded such that it does not conflict with the @@ -104,17 +132,25 @@ static void place_modules(struct kernel_info *info, * just after the kernel, if there is room, otherwise just before. */ - if ( kernel_end < MIN(mem_start + MB(128), mem_end - total) ) - addr = MIN(mem_start + MB(128), mem_end - total); - else if ( mem_end - ROUNDUP(kernel_end, MB(2)) >= total ) - addr = ROUNDUP(kernel_end, MB(2)); - else if ( kernel_start - mem_start >= total ) - addr = kernel_start - total; - else + if ( same_bank ) { - panic("Unable to find suitable location for dtb+initrd"); - return; - } + if ( kernel_end < MIN(mem_start + MB(128), mem_end - total) ) + addr = MIN(mem_start + MB(128), mem_end - total); + if ( mem_end - ROUNDUP(kernel_end, MB(2)) >= total ) + addr = ROUNDUP(kernel_end, MB(2)); + else if ( kernel_start - mem_start >= total ) + addr = kernel_start - total; + else + { + /* + * We should never hit this condition because we've already + * done the check while choosing the bank. + */ + panic("Unable to find suitable location for dtb+initrd"); + return; + } + } else + addr = ROUNDUP(mem_end - total, MB(2)); info->dtb_paddr = addr; info->initrd_paddr = info->dtb_paddr + dtb_len; @@ -264,10 +300,24 @@ static int kernel_try_zimage32_prepare(struct kernel_info *info, */ if (start == 0) { + unsigned int i, min_i = 0, min_start = -1; paddr_t load_end; - load_end = info->mem.bank[0].start + info->mem.bank[0].size; - load_end = MIN(info->mem.bank[0].start + MB(128), load_end); + /* + * Load kernel at the lowest possible bank + * ( check commit 6c21cb36e263de2db8716b477157a5b6cd531e1e for reason behind that ) + */ + for ( i = 0; i < info->mem.nr_banks; i++ ) + { + if( (unsigned int)info->mem.bank[i].start < min_start ) + { + min_start = info->mem.bank[i].start; + min_i = i; + } + } + + load_end = info->mem.bank[min_i].start + info->mem.bank[min_i].size; + load_end = MIN(info->mem.bank[min_i].start + MB(128), load_end); info->zimage.load_addr = load_end - end; /* Align to 2MB */ -- 1.7.9.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |