[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] memory hotadd 4/7: Setup frametable for hot-added memory
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1260521764 0 # Node ID 283a5357d1968b85278d926ec6082dad70954b17 # Parent 0ca5a5f477be011814ee35949dfcefd53fb4390b memory hotadd 4/7: Setup frametable for hot-added memory We can't use alloc_boot_pages for memory hot-add, so change it to use the pages range passed in. One changes need notice is, when memory hotplug needed, we have to setup initial frametable as pdx index (i.e. the pdx_gorund_valid) aligned, to make sure mfn_valid() still works after the max_page is not maximum anymore. Signed-off-by: Jiang, Yunhong <yunhong.jiang@xxxxxxxxx> --- xen/arch/x86/mm.c | 12 ++++ xen/arch/x86/setup.c | 2 xen/arch/x86/x86_64/mm.c | 110 +++++++++++++++++++++++++++++++++++++++++++++ xen/include/asm-x86/page.h | 2 4 files changed, 123 insertions(+), 3 deletions(-) diff -r 0ca5a5f477be -r 283a5357d196 xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Fri Dec 11 08:55:08 2009 +0000 +++ b/xen/arch/x86/mm.c Fri Dec 11 08:56:04 2009 +0000 @@ -219,8 +219,16 @@ void __init init_frametable(void) init_frametable_chunk(pdx_to_page(sidx * PDX_GROUP_COUNT), pdx_to_page(eidx * PDX_GROUP_COUNT)); } - init_frametable_chunk(pdx_to_page(sidx * PDX_GROUP_COUNT), - pdx_to_page(max_pdx - 1) + 1); + if ( !mem_hotplug ) + init_frametable_chunk(pdx_to_page(sidx * PDX_GROUP_COUNT), + pdx_to_page(max_pdx - 1) + 1); + else + { + init_frametable_chunk(pdx_to_page(sidx *PDX_GROUP_COUNT), + pdx_to_page(max_idx * PDX_GROUP_COUNT)); + memset(pdx_to_page(max_pdx), -1, (unsigned long)pdx_to_page(max_idx) - + (unsigned long)(pdx_to_page(max_pdx))); + } } void __init arch_init_memory(void) diff -r 0ca5a5f477be -r 283a5357d196 xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Fri Dec 11 08:55:08 2009 +0000 +++ b/xen/arch/x86/setup.c Fri Dec 11 08:56:04 2009 +0000 @@ -304,7 +304,7 @@ static void __init setup_max_pdx(void) #endif } -static void __init set_pdx_range(unsigned long smfn, unsigned long emfn) +void set_pdx_range(unsigned long smfn, unsigned long emfn) { unsigned long idx, eidx; diff -r 0ca5a5f477be -r 283a5357d196 xen/arch/x86/x86_64/mm.c --- a/xen/arch/x86/x86_64/mm.c Fri Dec 11 08:55:08 2009 +0000 +++ b/xen/arch/x86/x86_64/mm.c Fri Dec 11 08:56:04 2009 +0000 @@ -801,6 +801,116 @@ int __cpuinit setup_compat_arg_xlat(unsi return 0; } +void cleanup_frame_table(struct mem_hotadd_info *info) +{ + unsigned long sva, eva; + l3_pgentry_t l3e; + l2_pgentry_t l2e; + unsigned long spfn, epfn; + + spfn = info->spfn; + epfn = info->epfn; + + sva = (unsigned long)pdx_to_page(pfn_to_pdx(spfn)); + eva = (unsigned long)pdx_to_page(pfn_to_pdx(epfn)); + + /* Intialize all page */ + memset(mfn_to_page(spfn), -1, mfn_to_page(epfn) - mfn_to_page(spfn)); + + while (sva < eva) + { + l3e = l4e_to_l3e(idle_pg_table[l4_table_offset(sva)])[ + l3_table_offset(sva)]; + if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) || + (l3e_get_flags(l3e) & _PAGE_PSE) ) + { + sva = (sva & ~((1UL << L3_PAGETABLE_SHIFT) - 1)) + + (1UL << L3_PAGETABLE_SHIFT); + continue; + } + + l2e = l3e_to_l2e(l3e)[l2_table_offset(sva)]; + ASSERT(l2e_get_flags(l2e) & _PAGE_PRESENT); + + if ( (l2e_get_flags(l2e) & (_PAGE_PRESENT | _PAGE_PSE)) == + (_PAGE_PSE | _PAGE_PRESENT) ) + { + if (hotadd_mem_valid(l2e_get_pfn(l2e), info)) + destroy_xen_mappings(sva & ~((1UL << L2_PAGETABLE_SHIFT) - 1), + ((sva & ~((1UL << L2_PAGETABLE_SHIFT) -1 )) + + (1UL << L2_PAGETABLE_SHIFT) - 1)); + + sva = (sva & ~((1UL << L2_PAGETABLE_SHIFT) -1 )) + + (1UL << L2_PAGETABLE_SHIFT); + continue; + } + + ASSERT(l1e_get_flags(l2e_to_l1e(l2e)[l1_table_offset(sva)]) & + _PAGE_PRESENT); + sva = (sva & ~((1UL << PAGE_SHIFT) - 1)) + + (1UL << PAGE_SHIFT); + } + + /* Brute-Force flush all TLB */ + flush_tlb_all(); +} + +/* Should we be paraniod failure in map_pages_to_xen? */ +static int setup_frametable_chunk(void *start, void *end, + struct mem_hotadd_info *info) +{ + unsigned long s = (unsigned long)start; + unsigned long e = (unsigned long)end; + unsigned long mfn; + + ASSERT(!(s & ((1 << L2_PAGETABLE_SHIFT) - 1))); + ASSERT(!(e & ((1 << L2_PAGETABLE_SHIFT) - 1))); + + for ( ; s < e; s += (1UL << L2_PAGETABLE_SHIFT)) + { + mfn = alloc_hotadd_mfn(info); + map_pages_to_xen(s, mfn, 1UL << PAGETABLE_ORDER, PAGE_HYPERVISOR); + } + memset(start, -1, s - (unsigned long)start); + + return 0; +} + +int extend_frame_table(struct mem_hotadd_info *info) +{ + unsigned long cidx, nidx, eidx, spfn, epfn; + + spfn = info->spfn; + epfn = info->epfn; + + eidx = (pfn_to_pdx(epfn) + PDX_GROUP_COUNT - 1) / PDX_GROUP_COUNT; + nidx = cidx = pfn_to_pdx(spfn)/PDX_GROUP_COUNT; + + ASSERT( pfn_to_pdx(epfn) <= (DIRECTMAP_SIZE >> PAGE_SHIFT) && + (pfn_to_pdx(epfn) <= FRAMETABLE_SIZE / sizeof(struct page_info)) ); + + if ( test_bit(cidx, pdx_group_valid) ) + cidx = find_next_zero_bit(pdx_group_valid, eidx, cidx); + + if ( cidx >= eidx ) + return 0; + + while ( cidx < eidx ) + { + nidx = find_next_bit(pdx_group_valid, eidx, cidx); + if ( nidx >= eidx ) + nidx = eidx; + setup_frametable_chunk(pdx_to_page(cidx * PDX_GROUP_COUNT ), + pdx_to_page(nidx * PDX_GROUP_COUNT), + info); + + cidx = find_next_zero_bit(pdx_group_valid, eidx, nidx); + } + + memset(mfn_to_page(spfn), 0, mfn_to_page(epfn) - mfn_to_page(spfn)); + return 0; +} + void __init subarch_init_memory(void) { unsigned long i, n, v, m2p_start_mfn; diff -r 0ca5a5f477be -r 283a5357d196 xen/include/asm-x86/page.h --- a/xen/include/asm-x86/page.h Fri Dec 11 08:55:08 2009 +0000 +++ b/xen/include/asm-x86/page.h Fri Dec 11 08:56:04 2009 +0000 @@ -360,6 +360,8 @@ l3_pgentry_t *virt_to_xen_l3e(unsigned l l3_pgentry_t *virt_to_xen_l3e(unsigned long v); #endif +extern void set_pdx_range(unsigned long smfn, unsigned long emfn); + /* Map machine page range in Xen virtual address space. */ #define MAP_SMALL_PAGES _PAGE_AVAIL0 /* don't use superpages for the mapping */ int map_pages_to_xen( _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |