ia64/xen-unstable

changeset 17643:7211d37de25b

x86: Avoid deep recusrsion when destroying a domain and reaping pagetables.

From: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue May 13 10:16:54 2008 +0100 (2008-05-13)
parents 22f589f09da5
children 5d9430d492e3
files xen/arch/x86/domain.c xen/arch/x86/mm.c xen/include/asm-x86/config.h
line diff
     1.1 --- a/xen/arch/x86/domain.c	Tue May 13 09:58:18 2008 +0100
     1.2 +++ b/xen/arch/x86/domain.c	Tue May 13 10:16:54 2008 +0100
     1.3 @@ -1725,6 +1725,27 @@ static int relinquish_memory(
     1.4          if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
     1.5              put_page(page);
     1.6  
     1.7 +#ifdef DOMAIN_DESTRUCT_AVOID_RECURSION
     1.8 +        /*
     1.9 +         * Forcibly drop reference counts of page tables above top most (which
    1.10 +         * were skipped to prevent long latencies due to deep recursion - see
    1.11 +         * the special treatment in free_lX_table()).
    1.12 +         */
    1.13 +        y = page->u.inuse.type_info;
    1.14 +        if ( (type < PGT_root_page_table) &&
    1.15 +             unlikely(((y + PGT_type_mask) &
    1.16 +                       (PGT_type_mask|PGT_validated)) == type) )
    1.17 +        {
    1.18 +            BUG_ON((y & PGT_count_mask) >=
    1.19 +                   (page->count_info & PGC_count_mask));
    1.20 +            while ( y & PGT_count_mask )
    1.21 +            {
    1.22 +                put_page_and_type(page);
    1.23 +                y = page->u.inuse.type_info;
    1.24 +            }
    1.25 +        }
    1.26 +#endif
    1.27 +
    1.28          /*
    1.29           * Forcibly invalidate top-most, still valid page tables at this point
    1.30           * to break circular 'linear page table' references. This is okay
    1.31 @@ -1896,6 +1917,11 @@ int domain_relinquish_resources(struct d
    1.32          /* fallthrough */
    1.33  
    1.34      case RELMEM_done:
    1.35 +#ifdef DOMAIN_DESTRUCT_AVOID_RECURSION
    1.36 +        ret = relinquish_memory(d, &d->page_list, PGT_l1_page_table);
    1.37 +        if ( ret )
    1.38 +            return ret;
    1.39 +#endif
    1.40          break;
    1.41  
    1.42      default:
     2.1 --- a/xen/arch/x86/mm.c	Tue May 13 09:58:18 2008 +0100
     2.2 +++ b/xen/arch/x86/mm.c	Tue May 13 10:16:54 2008 +0100
     2.3 @@ -1320,6 +1320,11 @@ static void free_l3_table(struct page_in
     2.4      l3_pgentry_t *pl3e;
     2.5      int           i;
     2.6  
     2.7 +#ifdef DOMAIN_DESTRUCT_AVOID_RECURSION
     2.8 +    if ( d->arch.relmem == RELMEM_dom_l3 )
     2.9 +        return;
    2.10 +#endif
    2.11 +
    2.12      pl3e = map_domain_page(pfn);
    2.13  
    2.14      for ( i = 0; i < L3_PAGETABLE_ENTRIES; i++ )
    2.15 @@ -1343,6 +1348,11 @@ static void free_l4_table(struct page_in
    2.16      l4_pgentry_t *pl4e = page_to_virt(page);
    2.17      int           i;
    2.18  
    2.19 +#ifdef DOMAIN_DESTRUCT_AVOID_RECURSION
    2.20 +    if ( d->arch.relmem == RELMEM_dom_l4 )
    2.21 +        return;
    2.22 +#endif
    2.23 +
    2.24      for ( i = 0; i < L4_PAGETABLE_ENTRIES; i++ )
    2.25          if ( is_guest_l4_slot(d, i) )
    2.26              put_page_from_l4e(pl4e[i], pfn);
     3.1 --- a/xen/include/asm-x86/config.h	Tue May 13 09:58:18 2008 +0100
     3.2 +++ b/xen/include/asm-x86/config.h	Tue May 13 10:16:54 2008 +0100
     3.3 @@ -41,6 +41,14 @@
     3.4  #define CONFIG_HOTPLUG 1
     3.5  #define CONFIG_HOTPLUG_CPU 1
     3.6  
     3.7 +/*
     3.8 + * Avoid deep recursion when tearing down pagetables during domain destruction,
     3.9 + * causing dom0 to become unresponsive and Xen to miss time-critical softirq
    3.10 + * deadlines. This will ultimately be replaced by built-in preemptibility of
    3.11 + * get_page_type().
    3.12 + */
    3.13 +#define DOMAIN_DESTRUCT_AVOID_RECURSION 1
    3.14 +
    3.15  #define HZ 100
    3.16  
    3.17  #define OPT_CONSOLE_STR "vga"