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] mem_sharing: fix race condition of nominate and

To: Jui-Hao Chiang <juihaochiang@xxxxxxxxx>
Subject: [Xen-devel] Re: [PATCH] mem_sharing: fix race condition of nominate and unshare
From: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
Date: Thu, 6 Jan 2011 16:54:50 +0000
Cc: tinnycloud <tinnycloud@xxxxxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Delivery-date: Thu, 06 Jan 2011 08:55:24 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <AANLkTinMp1v1zex2BfcUuszotPuxJFWZQNUp40gu_gxL@xxxxxxxxxxxxxx>
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: <AANLkTinMp1v1zex2BfcUuszotPuxJFWZQNUp40gu_gxL@xxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.20 (2009-06-14)
At 16:11 +0000 on 06 Jan (1294330319), Jui-Hao Chiang wrote:
> Hi, this patch does the following
> (1) When updating/checking p2m type for mem_sharing, we must hold shr_lock
> (2) For nominate operation, if the page is already nominated, return the 
> handle from page_info->shr_handle
> (3) For unshare operation, it is possible that multiple users unshare a page 
> via hvm_hap_nested_page_fault() at the same time. If the page is already 
> un-shared by someone else, simply return success.

I'm going to apply this, since it looks like an improvement, but I'm not
convinced it properly solves the problem.

> NOTE: we assume that nobody holds page_alloc_lock/p2m_lock before calling 
> nominate/share/unshare.

As I told you earlier, that's not the case.  p2m_teardown() can call
mem_sharing_unshare_page() with the p2m lock held.

Cheers,

Tim.

> Signed-off-by: Jui-Hao Chiang 
> <juihaochiang@xxxxxxxxx<mailto:juihaochiang@xxxxxxxxx>>
> Signed-off-by: Han-Lin Li <Han-Lin.Li@xxxxxxxxxxx<mailto:Li@xxxxxxxxxxx>>
> 
> Bests,
> Jui-Hao

> diff -r 7b4c82f07281 xen/arch/x86/mm/mem_sharing.c
> --- a/xen/arch/x86/mm/mem_sharing.c   Wed Jan 05 23:54:15 2011 +0000
> +++ b/xen/arch/x86/mm/mem_sharing.c   Thu Jan 06 23:46:28 2011 +0800
> @@ -502,6 +502,7 @@ int mem_sharing_nominate_page(struct p2m
>  
>      *phandle = 0UL;
>  
> +    shr_lock(); 
>      mfn = gfn_to_mfn(p2m, gfn, &p2mt);
>  
>      /* Check if mfn is valid */
> @@ -509,29 +510,33 @@ int mem_sharing_nominate_page(struct p2m
>      if (!mfn_valid(mfn))
>          goto out;
>  
> +    /* Return the handle if the page is already shared */
> +    page = mfn_to_page(mfn);
> +    if (p2m_is_shared(p2mt)) {
> +        *phandle = page->shr_handle;
> +        ret = 0;
> +        goto out;
> +    }
> +
>      /* Check p2m type */
>      if (!p2m_is_sharable(p2mt))
>          goto out;
>  
>      /* Try to convert the mfn to the sharable type */
> -    page = mfn_to_page(mfn);
>      ret = page_make_sharable(d, page, expected_refcnt); 
>      if(ret) 
>          goto out;
>  
>      /* Create the handle */
>      ret = -ENOMEM;
> -    shr_lock(); 
>      handle = next_handle++;  
>      if((hash_entry = mem_sharing_hash_insert(handle, mfn)) == NULL)
>      {
> -        shr_unlock();
>          goto out;
>      }
>      if((gfn_info = mem_sharing_gfn_alloc()) == NULL)
>      {
>          mem_sharing_hash_destroy(hash_entry);
> -        shr_unlock();
>          goto out;
>      }
>  
> @@ -545,7 +550,6 @@ int mem_sharing_nominate_page(struct p2m
>          BUG_ON(page_make_private(d, page) != 0);
>          mem_sharing_hash_destroy(hash_entry);
>          mem_sharing_gfn_destroy(gfn_info, 0);
> -        shr_unlock();
>          goto out;
>      }
>  
> @@ -559,11 +563,11 @@ int mem_sharing_nominate_page(struct p2m
>      gfn_info->domain = d->domain_id;
>      page->shr_handle = handle;
>      *phandle = handle;
> -    shr_unlock();
>  
>      ret = 0;
>  
>  out:
> +    shr_unlock();
>      return ret;
>  }
>  
> @@ -633,14 +637,21 @@ int mem_sharing_unshare_page(struct p2m_
>      struct list_head *le;
>      struct domain *d = p2m->domain;
>  
> +    mem_sharing_audit();
> +    /* Remove the gfn_info from the list */
> +    shr_lock();
> +    
>      mfn = gfn_to_mfn(p2m, gfn, &p2mt);
> +    
> +    /* Has someone already unshared it? */
> +    if (!p2m_is_shared(p2mt)) {
> +        shr_unlock();
> +        return 0;
> +    }
>  
>      page = mfn_to_page(mfn);
>      handle = page->shr_handle;
>   
> -    mem_sharing_audit();
> -    /* Remove the gfn_info from the list */
> -    shr_lock();
>      hash_entry = mem_sharing_hash_lookup(handle); 
>      list_for_each(le, &hash_entry->gfns)
>      {
> @@ -707,7 +718,6 @@ private_page_found:
>          mem_sharing_hash_delete(handle);
>      else
>          atomic_dec(&nr_saved_mfns);
> -    shr_unlock();
>  
>      if(p2m_change_type(p2m, gfn, p2m_ram_shared, p2m_ram_rw) != 
>                                                  p2m_ram_shared) 
> @@ -718,6 +728,7 @@ private_page_found:
>      /* Update m2p entry */
>      set_gpfn_from_mfn(mfn_x(page_to_mfn(page)), gfn);
>  
> +    shr_unlock();
>      return 0;
>  }
>  


-- 
Tim Deegan <Tim.Deegan@xxxxxxxxxx>
Principal Software Engineer, Xen Platform Team
Citrix Systems UK Ltd.  (Company #02937203, SL9 0BG)

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel