[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] Re: [PATCH] xen: correctly rebuild mfn list list after migration.
On 10/12/2010 03:14 AM, Ian Campbell wrote: > Otherwise the second migration attempt fails because the mfn_list_list > still refers to all the old mfns. > > We need to update the entires in both p2m_top_mfn and the mid_mfn > pages which p2m_top_mfn refers to. > > In order to do this we need to keep track of the virtual addresses > mapping the p2m_mid_mfn pages since we cannot rely on > mfn_to_virt(p2m_top_mfn[idx]) since p2m_top_mfn[idx] will still > contain the old MFN after a migration, which may now belong to another > domain and hence have a different mapping in the m2p. > > Therefore add and maintain a third top level page, p2m_mid_mfn_p[], > which tracks the virtual addresses of the mfns contained in > p2m_top_mfn[]. > > We also need to update the content of the p2m_mid_missing_mfn page on > resume to refer to the page's new mfn. > > p2m_missing does not need updating since the migration process takes > care of the leaf p2m pages for us. > > Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> > --- > arch/x86/xen/mmu.c | 49 ++++++++++++++++++++++++++++++++++++++----------- > 1 files changed, 38 insertions(+), 11 deletions(-) > > diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c > index 16a8e25..8788064 100644 > --- a/arch/x86/xen/mmu.c > +++ b/arch/x86/xen/mmu.c > @@ -185,6 +185,8 @@ DEFINE_PER_CPU(unsigned long, xen_current_cr3); /* > actual vcpu cr3 */ > * / \ / \ / / > * p2m p2m p2m p2m p2m p2m p2m ... > * > + * The p2m_mid_mfn pages are mapped by p2m_mid_mfn_p. > + * > * The p2m_top and p2m_top_mfn levels are limited to 1 page, so the > * maximum representable pseudo-physical address space is: > * P2M_TOP_PER_PAGE * P2M_MID_PER_PAGE * P2M_PER_PAGE pages > @@ -209,6 +211,7 @@ static RESERVE_BRK_ARRAY(unsigned long, > p2m_mid_missing_mfn, P2M_MID_PER_PAGE); > > static RESERVE_BRK_ARRAY(unsigned long **, p2m_top, P2M_TOP_PER_PAGE); > static RESERVE_BRK_ARRAY(unsigned long, p2m_top_mfn, P2M_TOP_PER_PAGE); > +static RESERVE_BRK_ARRAY(unsigned long *, p2m_mid_mfn_p, P2M_TOP_PER_PAGE); > > RESERVE_BRK(p2m_mid, PAGE_SIZE * (MAX_DOMAIN_PAGES / (P2M_PER_PAGE * > P2M_MID_PER_PAGE))); > RESERVE_BRK(p2m_mid_mfn, PAGE_SIZE * (MAX_DOMAIN_PAGES / (P2M_PER_PAGE * > P2M_MID_PER_PAGE))); > @@ -245,6 +248,14 @@ static void p2m_top_mfn_init(unsigned long *top) > top[i] = virt_to_mfn(p2m_mid_missing_mfn); > } > > +static void p2m_mid_mfn_p_init(unsigned long **top) > +{ > + unsigned i; > + > + for (i = 0; i < P2M_TOP_PER_PAGE; i++) > + top[i] = p2m_mid_missing_mfn; > +} > + > static void p2m_mid_init(unsigned long **mid) > { > unsigned i; > @@ -301,15 +312,21 @@ EXPORT_SYMBOL(create_lookup_pte_addr); > */ > void xen_build_mfn_list_list(void) > { > - unsigned pfn; > + unsigned long pfn; > > /* Pre-initialize p2m_top_mfn to be completely missing */ > if (p2m_top_mfn == NULL) { > p2m_mid_missing_mfn = extend_brk(PAGE_SIZE, PAGE_SIZE); > p2m_mid_mfn_init(p2m_mid_missing_mfn); > > + p2m_mid_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE); > + p2m_mid_mfn_p_init(p2m_mid_mfn_p); > + > p2m_top_mfn = extend_brk(PAGE_SIZE, PAGE_SIZE); > p2m_top_mfn_init(p2m_top_mfn); > + } else { > + /* Reinitialise, mfn's all change after migration */ > + p2m_mid_mfn_init(p2m_mid_missing_mfn); > } > > for (pfn = 0; pfn < xen_max_p2m_pfn; pfn += P2M_PER_PAGE) { > @@ -322,14 +339,19 @@ void xen_build_mfn_list_list(void) > mid = p2m_top[topidx]; > > /* Don't bother allocating any mfn mid levels if > - they're just missing */ > - if (mid[mididx] == p2m_missing) > + * they're just missing, just update the stored mfn, > + * since all could have changed over a migrate. > + */ > + if (mid == p2m_mid_missing) { > + p2m_top_mfn[topidx] = virt_to_mfn(p2m_mid_missing); > + pfn += P2M_MID_PER_PAGE - 1; > continue; > + } > > - mid_mfn = p2m_top_mfn[topidx]; > - mid_mfn_p = mfn_to_virt(mid_mfn); > + mid_mfn_p = p2m_mid_mfn_p[topidx]; > + mid_mfn = virt_to_mfn(mid_mfn_p); > > - if (mid_mfn_p == p2m_mid_missing_mfn) { > + if (mid_mfn_p == p2m_missing) { > /* > * XXX boot-time only! We should never find > * missing parts of the mfn tree after > @@ -340,10 +362,11 @@ void xen_build_mfn_list_list(void) > p2m_mid_mfn_init(mid_mfn_p); > > mid_mfn = virt_to_mfn(mid_mfn_p); > - > - p2m_top_mfn[topidx] = mid_mfn; > + p2m_mid_mfn_p[topidx] = mid_mfn_p; > } > > + p2m_top_mfn[topidx] = mid_mfn; > + > mid_mfn_p[mididx] = virt_to_mfn(mid[mididx]); > } > } > @@ -362,7 +385,7 @@ void __init xen_build_dynamic_phys_to_machine(void) > { > unsigned long *mfn_list = (unsigned long *)xen_start_info->mfn_list; > unsigned long max_pfn = min(MAX_DOMAIN_PAGES, xen_start_info->nr_pages); > - unsigned pfn; > + unsigned long pfn; > > xen_max_p2m_pfn = max_pfn; > > @@ -452,7 +475,9 @@ static bool alloc_p2m(unsigned long pfn) > } > > top_mfn_p = &p2m_top_mfn[topidx]; > - mid_mfn = mfn_to_virt(*top_mfn_p); > + mid_mfn = p2m_mid_mfn_p[topidx]; > + > + BUG_ON(mid_mfn != mfn_to_virt(*top_mfn_p)); I'm getting this triggering at boot: PM: Adding info for No Bus:xen!gntdev ------------[ cut here ]------------ kernel BUG at /home/jeremy/git/linux/arch/x86/xen/mmu.c:480! invalid opcode: 0000 [#1] SMP last sysfs file: CPU 0 Modules linked in: Pid: 6, comm: events/0 Not tainted 2.6.32.24-next #220 RIP: e030:[<ffffffff8100d715>] [<ffffffff8100d715>] set_phys_to_machine+0x12f/0x2d9 RSP: e02b:ffff88001fd8bca0 EFLAGS: 00010206 RAX: ffff88000227d000 RBX: ffffffff8227d000 RCX: 0000000000000016 RDX: ffff880000000000 RSI: 0000000000195a4e RDI: 00000000000207ff RBP: ffff88001fd8bcf0 R08: 0000000000000003 R09: 00000003981ce0e5 R10: 0000000000000000 R11: 0000000000000003 R12: 00000000000207ff R13: 0000000000195a4d R14: 0000000000000000 R15: ffffffff8227f000 FS: 0000000000000000(0000) GS:ffff8800051bd000(0000) knlGS:0000000000000000 CS: e033 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000000 CR3: 0000000001001000 CR4: 0000000000002660 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process events/0 (pid: 6, threadinfo ffff88001fd8a000, task ffff88001fd88180) Stack: 2222222222222222 2222222222222222 2222222222222222 ffffffff82278000 <0> 0000000000000001 ffffea0000b2bfa8 00000000000207ff 0000000000000000 <0> 0000000000000200 0000000000000200 ffff88001fd8bdc0 ffffffff812a128e Call Trace: [<ffffffff812a128e>] balloon_process+0x20a/0x626 [<ffffffff81069cfb>] ? worker_thread+0x1fc/0x347 [<ffffffff81069d50>] worker_thread+0x251/0x347 [<ffffffff81069cfb>] ? worker_thread+0x1fc/0x347 [<ffffffff812a1084>] ? balloon_process+0x0/0x626 [<ffffffff8106e8ce>] ? autoremove_wake_function+0x0/0x39 [<ffffffff81069aff>] ? worker_thread+0x0/0x347 [<ffffffff8106e5f4>] kthread+0x7f/0x87 [<ffffffff81013e4a>] child_rip+0xa/0x20 [<ffffffff810137d0>] ? restore_args+0x0/0x30 [<ffffffff81013e40>] ? child_rip+0x0/0x20 Code: 83 c8 ff eb 10 48 c1 e0 03 31 d2 48 03 05 c4 c3 75 00 48 8b 00 48 c1 e0 0c 48 ba 00 00 00 00 00 88 ff ff 48 01 d0 48 39 c3 74 04 <0f> 0b eb fe 48 3b 1d 80 68 94 00 0f 85 bd 00 00 00 31 f6 bf d0 RIP [<ffffffff8100d715>] set_phys_to_machine+0x12f/0x2d9 RSP <ffff88001fd8bca0> ---[ end trace 93d72a36b9146f22 ]--- > > if (mid_mfn == p2m_mid_missing_mfn) { > /* Separately check the mid mfn level */ > @@ -464,11 +489,13 @@ static bool alloc_p2m(unsigned long pfn) > return false; > > p2m_mid_mfn_init(mid_mfn); > - > + > missing_mfn = virt_to_mfn(p2m_mid_missing_mfn); > mid_mfn_mfn = virt_to_mfn(mid_mfn); > if (cmpxchg(top_mfn_p, missing_mfn, mid_mfn_mfn) != missing_mfn) > free_p2m_page(mid_mfn); > + else > + p2m_mid_mfn_p[topidx] = mid_mfn; > } > > if (p2m_top[topidx][mididx] == p2m_missing) { _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |