[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v2] xen/mm: Avoid assuming the page is inuse in assign_pages()


  • To: Julien Grall <julien@xxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: "Durrant, Paul" <pdurrant@xxxxxxxxxxxx>
  • Date: Thu, 6 Feb 2020 10:52:26 +0000
  • Accept-language: en-GB, en-US
  • Cc: "Grall, Julien" <jgrall@xxxxxxxxxx>
  • Delivery-date: Thu, 06 Feb 2020 10:52:48 +0000
  • Ironport-sdr: GHAlpYm8zv9RlPb9+TKP0PnfdS5CKEWnuGdjnYgIluYtpttVB6aCHh//z6jMLueUpnzG4oLcTm +jEzR3ihMuBQ==
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHV3Nm0k5iP3kZyl0WYA/ycra3uAqgN++Dg
  • Thread-topic: [PATCH v2] xen/mm: Avoid assuming the page is inuse in assign_pages()

> -----Original Message-----
> From: Julien Grall <julien@xxxxxxx>
> Sent: 06 February 2020 10:39
> To: xen-devel@xxxxxxxxxxxxxxxxxxxx
> Cc: julien@xxxxxxx; Durrant, Paul <pdurrant@xxxxxxxxxxxx>; Grall, Julien
> <jgrall@xxxxxxxxxx>
> Subject: [PATCH v2] xen/mm: Avoid assuming the page is inuse in
> assign_pages()
> 
> From: Julien Grall <jgrall@xxxxxxxxxx>
> 
> At the moment, assign_pages() on the page to be inuse (PGC_state_inuse)
> and the state value to be 0.
> 
> However, the code may race with the page offlining code (see
> offline_page()). Depending on the ordering, the page may be in offlining
> state (PGC_state_offlining) before it is assigned to a domain.
> 
> On debug build, this may result to hit the assert or just clobber the
> state. On non-debug build, the state will get clobbered.
> 
> Incidentally the flag PGC_broken will get clobbered as well.
> 
> Grab the heap_lock to prevent a race with offline_page() and keep the
> state and broken flag around.
> 
> Signed-off-by: Julien Grall <jgrall@xxxxxxxxxx>

This seems like a reasonable change. I guess having assign_pages() take the 
global lock is no more problem than its existing call to 
domain_adjust_tot_pages() which also takes the same lock.

  Paul

> 
> ---
>     Changes in v2:
>         - Superseed <20200204133357.32101-1-julien@xxxxxxx>
>         - Fix the race with offline_page()
> ---
>  xen/common/page_alloc.c | 16 ++++++++++++++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
> index 97902d42c1..a684dbf37c 100644
> --- a/xen/common/page_alloc.c
> +++ b/xen/common/page_alloc.c
> @@ -2283,15 +2283,27 @@ int assign_pages(
>              get_knownalive_domain(d);
>      }
> 
> +    spin_lock(&heap_lock);
>      for ( i = 0; i < (1 << order); i++ )
>      {
> +        /*
> +         * We should only be here if the page is inuse or offlining.
> +         * The latter happen if we race with mark_page_offline() as we
> +         * don't hold the heap_lock.
> +         */
> +        ASSERT(page_state_is(&pg[i], inuse) ||
> +               page_state_is(&pg[i], offlining));
> +        ASSERT(!(pg[i].count_info & ~(PGC_state | PGC_broken)));
>          ASSERT(page_get_owner(&pg[i]) == NULL);
> -        ASSERT(!pg[i].count_info);
>          page_set_owner(&pg[i], d);
>          smp_wmb(); /* Domain pointer must be visible before updating
> refcnt. */
> -        pg[i].count_info = PGC_allocated | 1;
> +
> +        pg[i].count_info &= PGC_state | PGC_broken;
> +        pg[i].count_info |= PGC_allocated | 1;
> +
>          page_list_add_tail(&pg[i], &d->page_list);
>      }
> +    spin_unlock(&heap_lock);
> 
>   out:
>      spin_unlock(&d->page_alloc_lock);
> --
> 2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.