diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-08-11 12:20:11 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-08-11 12:20:11 +0100 |
commit | 42b54bfe29e05563b5bd17182d4b8c2dd5cb1dc6 (patch) | |
tree | 63ecc3f622682b515977513eea0706584bb0ad39 | |
parent | 3ca259a393756ab0a00ce0a332184d596b37b8b1 (diff) | |
download | xen-42b54bfe29e05563b5bd17182d4b8c2dd5cb1dc6.tar.gz xen-42b54bfe29e05563b5bd17182d4b8c2dd5cb1dc6.tar.bz2 xen-42b54bfe29e05563b5bd17182d4b8c2dd5cb1dc6.zip |
page scrub: Serialise softirq with a new lock.
Avoids holding up acquiring page_scrub_lock in free_domheap_pages().
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
-rw-r--r-- | xen/common/page_alloc.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index b202570a0f..d9e0a2946a 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -950,9 +950,10 @@ static void page_scrub_softirq(void) void *p; int i; s_time_t start = NOW(); + static spinlock_t serialise_lock = SPIN_LOCK_UNLOCKED; /* free_heap_pages() does not parallelise well. Serialise this function. */ - if ( !spin_trylock(&page_scrub_lock) ) + if ( !spin_trylock(&serialise_lock) ) { set_timer(&this_cpu(page_scrub_timer), NOW() + MILLISECS(1)); return; @@ -960,10 +961,12 @@ static void page_scrub_softirq(void) /* Aim to do 1ms of work every 10ms. */ do { + spin_lock(&page_scrub_lock); + if ( unlikely((ent = page_scrub_list.next) == &page_scrub_list) ) { spin_unlock(&page_scrub_lock); - return; + goto out; } /* Peel up to 16 pages from the list. */ @@ -979,6 +982,8 @@ static void page_scrub_softirq(void) page_scrub_list.next = ent->next; scrub_pages -= (i+1); + spin_unlock(&page_scrub_lock); + /* Working backwards, scrub each page in turn. */ while ( ent != &page_scrub_list ) { @@ -991,9 +996,10 @@ static void page_scrub_softirq(void) } } while ( (NOW() - start) < MILLISECS(1) ); - spin_unlock(&page_scrub_lock); - set_timer(&this_cpu(page_scrub_timer), NOW() + MILLISECS(10)); + + out: + spin_unlock(&serialise_lock); } static void page_scrub_timer_fn(void *unused) |