WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] Re: [PATCH] xen: correctly rebuild mfn list list after migra

To: Ian Campbell <ian.campbell@xxxxxxxxxx>
Subject: [Xen-devel] Re: [PATCH] xen: correctly rebuild mfn list list after migration.
From: Jeremy Fitzhardinge <jeremy@xxxxxxxx>
Date: Wed, 13 Oct 2010 17:37:34 -0700
Cc: xen-devel@xxxxxxxxxxxxxxxxxxx
Delivery-date: Wed, 13 Oct 2010 17:38:38 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <1286878488-9027-1-git-send-email-ian.campbell@xxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <1286878488-9027-1-git-send-email-ian.campbell@xxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.9) Gecko/20100921 Fedora/3.1.4-1.fc13 Lightning/1.0b3pre Thunderbird/3.1.4
 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