Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 89877e42827f16fa5f86b1df0c2860b1 > files > 2864

kernel-2.6.18-128.1.10.el5.src.rpm

From: Tetsu Yamamoto <tyamamot@redhat.com>
Date: Tue, 12 Aug 2008 16:07:40 -0400
Subject: [xen] page scrub: serialise softirq with a new lock
Message-id: 20080812200740.4832.40135.sendpatchset@pq0-1.lab.bos.redhat.com
O-Subject: [RHEL5.3 PATCH 7/7] xen: page scrub: Serialise softirq with a new lock.
Bugzilla: 456171
RH-Acked-by: Chris Lalancette <clalance@redhat.com>
RH-Acked-by: Bill Burns <bburns@redhat.com>

bz456171
# HG changeset patch
# User Keir Fraser <keir.fraser@citrix.com>
# Date 1218453611 -3600
# Node ID 32aa43364f5d8e19389d1f72d9b0bf51e198152f
# Parent  ce085fc0d2e423aa1c602ce117cc775b000470ba
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>

diff --git a/common/page_alloc.c b/common/page_alloc.c
index 7a54dbe..834e09e 100644
--- a/common/page_alloc.c
+++ b/common/page_alloc.c
@@ -1017,9 +1017,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;
@@ -1027,10 +1028,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. */
@@ -1046,6 +1049,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 )
         {
@@ -1058,9 +1063,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)