File xenpaging.speedup-page-out.policy_choose_victim.patch of Package xen

Skip longs with all bits set.
Iterate only once over the entire gfn range.
---
 tools/xenpaging/policy_default.c |   55 ++++++++++++++++++++++++++-------------
 1 file changed, 38 insertions(+), 17 deletions(-)

Index: xen-4.1.2-testing/tools/xenpaging/policy_default.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/policy_default.c
+++ xen-4.1.2-testing/tools/xenpaging/policy_default.c
@@ -80,34 +80,55 @@ int policy_init(xenpaging_t *paging)
 int policy_choose_victim(xenpaging_t *paging, xenpaging_victim_t *victim)
 {
     xc_interface *xch = paging->xc_handle;
-    unsigned long wrap = current_gfn;
+    unsigned long i;
 
-    do
+    /* One iteration over all possible gfns */
+    for ( i = 0; i < max_pages; i++)
     {
         current_gfn++;
         if ( current_gfn >= max_pages )
             current_gfn = 0;
-        /* Could not nominate any gfn */
-        if ( wrap == current_gfn )
+
+        if ( (current_gfn & (BITS_PER_LONG - 1)) == 0 )
         {
-            paging->use_poll_timeout = 1;
-            /* Count wrap arounds */
-            unconsumed_cleared++;
-            /* Force retry every few seconds (depends on poll() timeout) */
-            if ( unconsumed_cleared > 123)
+            /* All gfns busy */
+            if ( ~bitmap[current_gfn >> ORDER_LONG] == 0 || ~unconsumed[current_gfn >> ORDER_LONG] == 0 )
             {
-                /* Force retry of unconsumed gfns */
-                bitmap_clear(unconsumed, max_pages);
-                unconsumed_cleared = 0;
-                DPRINTF("clearing unconsumed, wrap %lx", wrap);
-                /* One more round before returning ENOSPC */
+                current_gfn += BITS_PER_LONG;
+                i += BITS_PER_LONG;
                 continue;
             }
-            victim->gfn = INVALID_MFN;
-            return -ENOSPC;
         }
+
+        /* gfn busy */
+        if ( test_bit(current_gfn, bitmap) )
+            continue;
+
+        /* gfn already tested */
+        if ( test_bit(current_gfn, unconsumed) )
+            continue;
+
+        /* gfn found */
+        break;
+    }
+
+    /* Could not nominate any gfn */
+    if ( i >= max_pages )
+    {
+        paging->use_poll_timeout = 1;
+        /* Count wrap arounds */
+        unconsumed_cleared++;
+        /* Force retry every few seconds (depends on poll() timeout) */
+        if ( unconsumed_cleared > 123)
+        {
+            /* Force retry of unconsumed gfns in next call */
+            bitmap_clear(unconsumed, max_pages);
+            unconsumed_cleared = 0;
+            DPRINTF("clearing unconsumed, current_gfn %lx", current_gfn);
+        }
+        victim->gfn = INVALID_MFN;
+        return -ENOSPC;
     }
-    while ( test_bit(current_gfn, bitmap) || test_bit(current_gfn, unconsumed) );
 
     set_bit(current_gfn, unconsumed);
     victim->gfn = current_gfn;
openSUSE Build Service is sponsored by