kernel - SWAP CACHE part 11/many - Write improvements, fix backing store free
authorMatthew Dillon <dillon@apollo.backplane.com>
Sat, 6 Feb 2010 00:21:10 +0000 (16:21 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sat, 6 Feb 2010 00:21:10 +0000 (16:21 -0800)
* Improve write staging by not counting VM pages which already have a
  swap assignment when doing the limited scan of the INACTIVE VM page
  queue.

  As the swapcache starts to perform more and more disk I/O goes to it,
  radically increasing the data rate and also radically increasing the
  rate at which pages are shuffled between VM page queues.  At some
  point enough data is coming from the swapcache that vm.swapcache.maxlaunder
  is unable to keep up even when sufficient burst bandwidth is available.

  This led to an asymptotic caching curve.  After the fix the caching
  curve is linear (for data sets which fit in the swapcache).

* The swapcache associated with meta-data (VCHR vnodes) was not being
  destroyed on umount.  Adjust a conditional such that it is properly
  destroyed.  Otherwise stale data might be retained across e.g. a
  media change.

sys/vm/vm_object.c
sys/vm/vm_swapcache.c

index 484b4bf..1d38824 100644 (file)
@@ -1564,10 +1564,10 @@ vm_object_page_remove(vm_object_t object, vm_pindex_t start, vm_pindex_t end,
        } while (info.error);
 
        /*
-        * Remove any related swap or fast-cache backing store if we are
-        * destroying the pages.
+        * Remove any related swap if throwing away pages, or for
+        * non-swap objects (the swap is a clean copy in that case).
         */
-       if (clean_only == FALSE) {
+       if (object->type != OBJT_SWAP || clean_only == FALSE) {
                if (all)
                        swap_pager_freespace_all(object);
                else
index 24d5302..d603fb8 100644 (file)
@@ -194,16 +194,21 @@ vm_swapcached(void)
                 * suitable pages to push to the swap cache.
                 *
                 * We are looking for clean vnode-backed pages.
+                *
+                * NOTE: PG_SWAPPED pages in particular are not part of
+                *       our count because once the cache stabilizes we
+                *       can end up with a very high datarate of VM pages
+                *       cycling from it.
                 */
                m = &marker;
                while ((m = TAILQ_NEXT(m, pageq)) != NULL && count--) {
-                       if (m->flags & PG_MARKER) {
+                       if (m->flags & (PG_MARKER | PG_SWAPPED)) {
                                ++count;
                                continue;
                        }
                        if (vm_swapcache_curburst < 0)
                                break;
-                       if (m->flags & (PG_SWAPPED | PG_BUSY | PG_UNMANAGED))
+                       if (m->flags & (PG_BUSY | PG_UNMANAGED))
                                continue;
                        if (m->busy || m->hold_count || m->wire_count)
                                continue;