From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bob Liu Subject: [PATCH 3/4] xen: separate a function merge_free_trunks from Date: Tue, 17 Jun 2014 19:49:42 +0800 Message-ID: <1403005783-30746-3-git-send-email-bob.liu@oracle.com> References: <1403005783-30746-1-git-send-email-bob.liu@oracle.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from mail6.bemta4.messagelabs.com ([85.158.143.247]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1Wwrtv-0000GC-2u for xen-devel@lists.xenproject.org; Tue, 17 Jun 2014 11:50:07 +0000 Received: by mail-pd0-f173.google.com with SMTP id r10so5502757pdi.4 for ; Tue, 17 Jun 2014 04:50:03 -0700 (PDT) In-Reply-To: <1403005783-30746-1-git-send-email-bob.liu@oracle.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xenproject.org Cc: keir@xen.org, ian.campbell@citrix.com, George.Dunlap@eu.citrix.com, andrew.cooper3@citrix.com, jbeulich@suse.com List-Id: xen-devel@lists.xenproject.org This function will be used when scrubbing a page from idle vcpus. Signed-off-by: Bob Liu --- xen/common/page_alloc.c | 137 +++++++++++++++++++++++++---------------------- 1 file changed, 74 insertions(+), 63 deletions(-) diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 723d273..5698596 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -827,73 +827,14 @@ static int reserve_offlined_page(struct page_info *head) return count; } -/* Free 2^@order set of pages. */ -static void free_heap_pages( +/* Caller must hold heap lock */ +static void merge_free_trunks( struct page_info *pg, unsigned int order, bool_t need_scrub) { - unsigned long mask, mfn = page_to_mfn(pg); - unsigned int i, node = phys_to_nid(page_to_maddr(pg)), tainted = 0; + unsigned long mask; + unsigned int node = phys_to_nid(page_to_maddr(pg)); unsigned int zone = page_to_zone(pg); - ASSERT(order <= MAX_ORDER); - ASSERT(node >= 0); - - spin_lock(&heap_lock); - - for ( i = 0; i < (1 << order); i++ ) - { - /* - * Cannot assume that count_info == 0, as there are some corner cases - * where it isn't the case and yet it isn't a bug: - * 1. page_get_owner() is NULL - * 2. page_get_owner() is a domain that was never accessible by - * its domid (e.g., failed to fully construct the domain). - * 3. page was never addressable by the guest (e.g., it's an - * auto-translate-physmap guest and the page was never included - * in its pseudophysical address space). - * In all the above cases there can be no guest mappings of this page. - */ - ASSERT(!page_state_is(&pg[i], offlined)); - pg[i].count_info = - ((pg[i].count_info & PGC_broken) | - (page_state_is(&pg[i], offlining) - ? PGC_state_offlined : PGC_state_free)); - if ( page_state_is(&pg[i], offlined) ) - tainted = 1; - - /* If a page has no owner it will need no safety TLB flush. */ - pg[i].u.free.need_tlbflush = (page_get_owner(&pg[i]) != NULL); - if ( pg[i].u.free.need_tlbflush ) - pg[i].tlbflush_timestamp = tlbflush_current_time(); - - /* This page is not a guest frame any more. */ - page_set_owner(&pg[i], NULL); /* set_gpfn_from_mfn snoops pg owner */ - set_gpfn_from_mfn(mfn + i, INVALID_M2P_ENTRY); - } - - avail[node][zone] += 1 << order; - total_avail_pages += 1 << order; - - if ( opt_tmem ) - midsize_alloc_zone_pages = max( - midsize_alloc_zone_pages, total_avail_pages / MIDSIZE_ALLOC_FRAC); - - if ( need_scrub ) - { - /* Specail for tainted case */ - if ( tainted ) - { - for ( i = 0; i < (1 << order); i++ ) - scrub_one_page(&pg[i]); - need_scrub = 0; - } - else - { - for ( i = 0; i < (1 << order); i++ ) - pg[i].count_info |= PGC_need_scrub; - } - } - /* Merge chunks as far as possible. */ while ( order < MAX_ORDER ) { @@ -961,6 +902,76 @@ static void free_heap_pages( { page_list_add_tail(pg, &heap(node, zone, order)); } +} + +/* Free 2^@order set of pages. */ +static void free_heap_pages( + struct page_info *pg, unsigned int order, bool_t need_scrub) +{ + unsigned long mfn = page_to_mfn(pg); + unsigned int i, node = phys_to_nid(page_to_maddr(pg)), tainted = 0; + unsigned int zone = page_to_zone(pg); + + ASSERT(order <= MAX_ORDER); + ASSERT(node >= 0); + + spin_lock(&heap_lock); + + for ( i = 0; i < (1 << order); i++ ) + { + /* + * Cannot assume that count_info == 0, as there are some corner cases + * where it isn't the case and yet it isn't a bug: + * 1. page_get_owner() is NULL + * 2. page_get_owner() is a domain that was never accessible by + * its domid (e.g., failed to fully construct the domain). + * 3. page was never addressable by the guest (e.g., it's an + * auto-translate-physmap guest and the page was never included + * in its pseudophysical address space). + * In all the above cases there can be no guest mappings of this page. + */ + ASSERT(!page_state_is(&pg[i], offlined)); + pg[i].count_info = + ((pg[i].count_info & PGC_broken) | + (page_state_is(&pg[i], offlining) + ? PGC_state_offlined : PGC_state_free)); + if ( page_state_is(&pg[i], offlined) ) + tainted = 1; + + /* If a page has no owner it will need no safety TLB flush. */ + pg[i].u.free.need_tlbflush = (page_get_owner(&pg[i]) != NULL); + if ( pg[i].u.free.need_tlbflush ) + pg[i].tlbflush_timestamp = tlbflush_current_time(); + + /* This page is not a guest frame any more. */ + page_set_owner(&pg[i], NULL); /* set_gpfn_from_mfn snoops pg owner */ + set_gpfn_from_mfn(mfn + i, INVALID_M2P_ENTRY); + } + + avail[node][zone] += 1 << order; + total_avail_pages += 1 << order; + + if ( opt_tmem ) + midsize_alloc_zone_pages = max( + midsize_alloc_zone_pages, total_avail_pages / MIDSIZE_ALLOC_FRAC); + + if ( need_scrub ) + { + /* Specail for tainted case */ + if ( tainted ) + { + for ( i = 0; i < (1 << order); i++ ) + scrub_one_page(&pg[i]); + need_scrub = 0; + } + else + { + for ( i = 0; i < (1 << order); i++ ) + pg[i].count_info |= PGC_need_scrub; + } + } + + merge_free_trunks(pg, order, need_scrub); if ( tainted ) reserve_offlined_page(pg); -- 1.7.10.4