[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86/mm: make page-sharing use the proper typecount functions
# HG changeset patch # User Tim Deegan <Tim.Deegan@xxxxxxxxxx> # Date 1294933573 0 # Node ID 32b7a4f2d39950aea45bde3dbf4b94f3b53f6535 # Parent b01ef59c8c805df751a8f6ae63cdd5c6a4565255 x86/mm: make page-sharing use the proper typecount functions instead of having its own cmpxchg loops. This should remove some confusion about the use of PGT_none, and also makes page-sharing participate properly in the TLB flushing discipline. Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx> --- xen/arch/x86/mm.c | 79 ++++++++++++++++++++---------------------------------- 1 files changed, 30 insertions(+), 49 deletions(-) diff -r b01ef59c8c80 -r 32b7a4f2d399 xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Thu Jan 13 15:46:13 2011 +0000 +++ b/xen/arch/x86/mm.c Thu Jan 13 15:46:13 2011 +0000 @@ -2367,7 +2367,7 @@ static int __get_page_type(struct page_i /* No special validation needed for writable pages. */ /* Page tables and GDT/LDT need to be scanned for validity. */ - if ( type == PGT_writable_page ) + if ( type == PGT_writable_page || type == PGT_shared_page ) nx |= PGT_validated; } } @@ -4167,32 +4167,25 @@ int page_make_sharable(struct domain *d, struct page_info *page, int expected_refcnt) { - unsigned long x, nx, y; - - /* Acquire ref first, so that the page doesn't dissapear from us */ - if(!get_page(page, d)) + spin_lock(&d->page_alloc_lock); + + /* Change page type and count atomically */ + if ( !get_page_and_type(page, d, PGT_shared_page) ) + { + spin_unlock(&d->page_alloc_lock); return -EINVAL; - - spin_lock(&d->page_alloc_lock); - - /* Change page type and count atomically */ - y = page->u.inuse.type_info; - nx = PGT_shared_page | PGT_validated | 1; - do { - x = y; - /* We can only change the type if count is zero, and - type is PGT_none */ - if((x & (PGT_type_mask | PGT_count_mask)) != PGT_none) - { - put_page(page); - spin_unlock(&d->page_alloc_lock); - return -EEXIST; - } - y = cmpxchg(&page->u.inuse.type_info, x, nx); - } while(x != y); - - /* Check if the ref count is 2. The first from PGT_allocated, and the second - * from get_page at the top of this function */ + } + + /* Check it wasn't already sharable and undo if it was */ + if ( (page->u.inuse.type_info & PGT_count_mask) != 1 ) + { + put_page_and_type(page); + spin_unlock(&d->page_alloc_lock); + return -EEXIST; + } + + /* Check if the ref count is 2. The first from PGT_allocated, and + * the second from get_page_and_type at the top of this function */ if(page->count_info != (PGC_allocated | (2 + expected_refcnt))) { /* Return type count back to zero */ @@ -4205,39 +4198,27 @@ int page_make_sharable(struct domain *d, d->tot_pages--; page_list_del(page, &d->page_list); spin_unlock(&d->page_alloc_lock); - - /* NOTE: We are not putting the page back. In effect this function acquires - * one ref and type ref for the caller */ - return 0; } int page_make_private(struct domain *d, struct page_info *page) { - unsigned long x, y; - if(!get_page(page, dom_cow)) return -EINVAL; spin_lock(&d->page_alloc_lock); - /* Change page type and count atomically */ - y = page->u.inuse.type_info; - do { - x = y; - /* We can only change the type if count is one */ - if((x & (PGT_type_mask | PGT_count_mask)) != - (PGT_shared_page | 1)) - { - put_page(page); - spin_unlock(&d->page_alloc_lock); - return -EEXIST; - } - y = cmpxchg(&page->u.inuse.type_info, x, PGT_none); - } while(x != y); - - /* We dropped type ref above, drop one ref count too */ - put_page(page); + /* We can only change the type if count is one */ + if ( (page->u.inuse.type_info & (PGT_type_mask | PGT_count_mask)) + != (PGT_shared_page | 1) ) + { + put_page(page); + spin_unlock(&d->page_alloc_lock); + return -EEXIST; + } + + /* Drop the final typecount */ + put_page_and_type(page); /* Change the owner */ ASSERT(page_get_owner(page) == dom_cow); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |