From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Jan Beulich <JBeulich@suse.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>,
xen-devel <xen-devel@lists.xenproject.org>,
Keir Fraser <keir@xen.org>, Tim Deegan <tim@xen.org>
Subject: Re: [PATCH 2/2] use return value of domain_adjust_tot_pages() where feasible
Date: Wed, 27 Nov 2013 10:07:21 +0000 [thread overview]
Message-ID: <5295C459.1080103@citrix.com> (raw)
In-Reply-To: <5295BAD0020000780010765E@nat28.tlf.novell.com>
On 27/11/13 08:26, Jan Beulich wrote:
> This is generally cheaper than re-reading ->tot_pages.
>
> While doing so I also noticed an improper use (lacking error handling)
> of get_domain() as well as lacks of ->is_dying checks in the memory
> sharing code, which the patch fixes at once. In the course of doing
> this I further noticed other error paths there pointlessly calling
> put_page() et al with ->page_alloc_lock still held, which is also being
> reversed.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
>
> --- a/xen/arch/x86/mm/mem_sharing.c
> +++ b/xen/arch/x86/mm/mem_sharing.c
> @@ -611,9 +611,16 @@ static int page_make_sharable(struct dom
> struct page_info *page,
> int expected_refcnt)
> {
> - int drop_dom_ref;
> + bool_t drop_dom_ref;
> +
> spin_lock(&d->page_alloc_lock);
>
> + if ( d->is_dying )
> + {
> + spin_unlock(&d->page_alloc_lock);
> + return -EBUSY;
> + }
> +
> /* Change page type and count atomically */
> if ( !get_page_and_type(page, d, PGT_shared_page) )
> {
> @@ -624,8 +631,8 @@ static int page_make_sharable(struct dom
> /* 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);
> + put_page_and_type(page);
> return -EEXIST;
> }
>
> @@ -633,15 +640,14 @@ static int page_make_sharable(struct dom
> * the second from get_page_and_type at the top of this function */
> if ( page->count_info != (PGC_allocated | (2 + expected_refcnt)) )
> {
> + spin_unlock(&d->page_alloc_lock);
> /* Return type count back to zero */
> put_page_and_type(page);
> - spin_unlock(&d->page_alloc_lock);
> return -E2BIG;
> }
>
> page_set_owner(page, dom_cow);
> - domain_adjust_tot_pages(d, -1);
> - drop_dom_ref = (d->tot_pages == 0);
> + drop_dom_ref = !domain_adjust_tot_pages(d, -1);
> page_list_del(page, &d->page_list);
> spin_unlock(&d->page_alloc_lock);
>
> @@ -659,6 +665,13 @@ static int page_make_private(struct doma
>
> spin_lock(&d->page_alloc_lock);
>
> + if ( d->is_dying )
> + {
> + spin_unlock(&d->page_alloc_lock);
> + put_page(page);
> + return -EBUSY;
> + }
> +
> /* We can only change the type if count is one */
> /* Because we are locking pages individually, we need to drop
> * the lock here, while the page is typed. We cannot risk the
> @@ -666,8 +679,8 @@ static int page_make_private(struct doma
> expected_type = (PGT_shared_page | PGT_validated | PGT_locked | 2);
> if ( page->u.inuse.type_info != expected_type )
> {
> - put_page(page);
> spin_unlock(&d->page_alloc_lock);
> + put_page(page);
> return -EEXIST;
> }
>
> @@ -682,7 +695,7 @@ static int page_make_private(struct doma
> page_set_owner(page, d);
>
> if ( domain_adjust_tot_pages(d, 1) == 1 )
> - get_domain(d);
> + get_knownalive_domain(d);
> page_list_add_tail(page, &d->page_list);
> spin_unlock(&d->page_alloc_lock);
>
> --- a/xen/common/memory.c
> +++ b/xen/common/memory.c
> @@ -475,8 +475,8 @@ static long memory_exchange(XEN_GUEST_HA
> (j * (1UL << exch.out.extent_order)));
>
> spin_lock(&d->page_alloc_lock);
> - domain_adjust_tot_pages(d, -dec_count);
> - drop_dom_ref = (dec_count && !d->tot_pages);
> + drop_dom_ref = (dec_count &&
> + !domain_adjust_tot_pages(d, -dec_count));
> spin_unlock(&d->page_alloc_lock);
>
> if ( drop_dom_ref )
> --- a/xen/common/page_alloc.c
> +++ b/xen/common/page_alloc.c
> @@ -1516,8 +1516,9 @@ struct page_info *alloc_domheap_pages(
>
> void free_domheap_pages(struct page_info *pg, unsigned int order)
> {
> - int i, drop_dom_ref;
> struct domain *d = page_get_owner(pg);
> + unsigned int i;
> + bool_t drop_dom_ref;
>
> ASSERT(!in_irq());
>
> @@ -1545,8 +1546,7 @@ void free_domheap_pages(struct page_info
> page_list_del2(&pg[i], &d->page_list, &d->arch.relmem_list);
> }
>
> - domain_adjust_tot_pages(d, -(1 << order));
> - drop_dom_ref = (d->tot_pages == 0);
> + drop_dom_ref = !domain_adjust_tot_pages(d, -(1 << order));
>
> spin_unlock_recursive(&d->page_alloc_lock);
>
>
>
next prev parent reply other threads:[~2013-11-27 10:07 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-27 8:07 [PATCH 0/2] XSA-74 follow-ups Jan Beulich
2013-11-27 8:25 ` [PATCH 1/2] fix locking in offline_page() Jan Beulich
2013-11-27 10:01 ` Andrew Cooper
2013-11-27 10:05 ` Jan Beulich
2013-11-27 10:34 ` Tim Deegan
2013-11-27 10:43 ` Jan Beulich
2013-11-27 10:48 ` Tim Deegan
2013-11-27 10:53 ` Tim Deegan
2013-11-27 10:55 ` Jan Beulich
2013-11-28 10:25 ` Tim Deegan
2013-11-28 14:38 ` Jan Beulich
2013-11-28 15:11 ` Tim Deegan
2013-11-27 14:48 ` George Dunlap
2013-11-27 8:26 ` [PATCH 2/2] use return value of domain_adjust_tot_pages() where feasible Jan Beulich
2013-11-27 10:07 ` Andrew Cooper [this message]
2013-11-27 14:44 ` George Dunlap
2013-11-27 15:46 ` Jan Beulich
2013-11-27 16:51 ` George Dunlap
2013-11-27 10:42 ` [PATCH 0/2] XSA-74 follow-ups Tim Deegan
2013-12-03 9:20 ` Keir Fraser
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5295C459.1080103@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=George.Dunlap@eu.citrix.com \
--cc=JBeulich@suse.com \
--cc=keir@xen.org \
--cc=tim@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.