ia64/xen-unstable

changeset 18306:f10d436d9a9e

Serialize scrubbing pages

I noticed that parallel scrubbing pages is not efficient
due to spinlock contention. (also memory bandwidth?)
Actually heap_lock becomes a bottleneck.

In my investigation, it often takes 1 millisec just to acquire
the lock on ia64 with 8cpus. It's very wasteful.

Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Aug 11 11:18:50 2008 +0100 (2008-08-11)
parents 3d5515f40b9b
children ce085fc0d2e4
files xen/common/page_alloc.c
line diff
     1.1 --- a/xen/common/page_alloc.c	Mon Aug 11 10:52:18 2008 +0100
     1.2 +++ b/xen/common/page_alloc.c	Mon Aug 11 11:18:50 2008 +0100
     1.3 @@ -951,10 +951,15 @@ static void page_scrub_softirq(void)
     1.4      int               i;
     1.5      s_time_t          start = NOW();
     1.6  
     1.7 +    /* free_heap_pages() does not parallelise well. Serialise this function. */
     1.8 +    if ( !spin_trylock(&page_scrub_lock) )
     1.9 +    {
    1.10 +        set_timer(&this_cpu(page_scrub_timer), NOW() + MILLISECS(1));
    1.11 +        return;
    1.12 +    }
    1.13 +
    1.14      /* Aim to do 1ms of work every 10ms. */
    1.15      do {
    1.16 -        spin_lock(&page_scrub_lock);
    1.17 -
    1.18          if ( unlikely((ent = page_scrub_list.next) == &page_scrub_list) )
    1.19          {
    1.20              spin_unlock(&page_scrub_lock);
    1.21 @@ -974,8 +979,6 @@ static void page_scrub_softirq(void)
    1.22          page_scrub_list.next = ent->next;
    1.23          scrub_pages -= (i+1);
    1.24  
    1.25 -        spin_unlock(&page_scrub_lock);
    1.26 -
    1.27          /* Working backwards, scrub each page in turn. */
    1.28          while ( ent != &page_scrub_list )
    1.29          {
    1.30 @@ -988,6 +991,8 @@ static void page_scrub_softirq(void)
    1.31          }
    1.32      } while ( (NOW() - start) < MILLISECS(1) );
    1.33  
    1.34 +    spin_unlock(&page_scrub_lock);
    1.35 +
    1.36      set_timer(&this_cpu(page_scrub_timer), NOW() + MILLISECS(10));
    1.37  }
    1.38