kernel - Fix swapcached problems when max-swap use reached
authorMatthew Dillon <dillon@apollo.backplane.com>
Fri, 18 Nov 2011 18:48:09 +0000 (10:48 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Fri, 18 Nov 2011 18:48:09 +0000 (10:48 -0800)
* A calculation could reverse-index the limit counter and cause
  swapcached to eat an excessive amount of cpu, causing other
  processes to stall.

* Fixes network problems between avalon and the dragonfly core network.

sys/vm/swap_pager.c
sys/vm/vm_swapcache.c

index da6e7f7..a8b9209 100644 (file)
@@ -595,6 +595,8 @@ int
 swap_pager_condfree(vm_object_t object, vm_pindex_t *basei, int count)
 {
        struct swfreeinfo info;
+       int n;
+       int t;
 
        ASSERT_LWKT_TOKEN_HELD(vm_object_token(object));
 
@@ -606,9 +608,17 @@ swap_pager_condfree(vm_object_t object, vm_pindex_t *basei, int count)
        swblock_rb_tree_RB_SCAN(&object->swblock_root, rb_swblock_condcmp,
                                swap_pager_condfree_callback, &info);
        *basei = info.basei;
-       if (info.endi < 0 && info.begi <= count)
-               info.begi = count + 1;
-       return(count - (int)info.begi);
+
+       /*
+        * Take the higher difference swblocks vs pages
+        */
+       n = count - (int)info.begi;
+       t = count * 8 - (int)info.endi;
+       if (n < t)
+               n = t;
+       if (n < 1)
+               n = 1;
+       return(n);
 }
 
 /*
index fe44599..b62158b 100644 (file)
@@ -231,7 +231,7 @@ vm_swapcached_thread(void)
                        if (vm_swap_cache_use > SWAPMAX(0))
                                state = SWAPC_CLEANING;
                } else {
-                       if (vm_swap_cache_use < SWAPMAX(-5))
+                       if (vm_swap_cache_use < SWAPMAX(-10))
                                state = SWAPC_WRITING;
                }
 
@@ -678,7 +678,9 @@ vm_swapcache_cleaning(vm_object_t marker)
                 * requested number of blocks, it will return n >= count
                 * and we break and pick it back up on a future attempt.
                 */
+               lwkt_reltoken(&vmobj_token);
                n = swap_pager_condfree(object, &marker->size, count);
+               lwkt_gettoken(&vmobj_token);
 
                vm_object_drop(object);