Print this page
XXXX kmem: double-calling kmem_depot_ws_update isn't obvious
While the double-call is documented in a comment, it's not obvious what
exactly it is trying to accomplish. The easiest way to address this is to
introduce a new function that "zeroes-out" the working set statistics to
force everything to be eligible for reaping.
@@ -18,10 +18,11 @@
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/*
* Kernel memory allocator, as described in the following two papers and a
* statement about the consolidator:
@@ -2167,10 +2168,25 @@
cp->cache_empty.ml_min = cp->cache_empty.ml_total;
mutex_exit(&cp->cache_depot_lock);
}
/*
+ * Set the working set statistics for cp's depot to zero. (Everything is
+ * eligible for reaping.)
+ */
+static void
+kmem_depot_ws_zero(kmem_cache_t *cp)
+{
+ mutex_enter(&cp->cache_depot_lock);
+ cp->cache_full.ml_reaplimit = cp->cache_full.ml_total;
+ cp->cache_full.ml_min = cp->cache_full.ml_total;
+ cp->cache_empty.ml_reaplimit = cp->cache_empty.ml_total;
+ cp->cache_empty.ml_min = cp->cache_empty.ml_total;
+ mutex_exit(&cp->cache_depot_lock);
+}
+
+/*
* Reap all magazines that have fallen out of the depot's working set.
*/
static void
kmem_depot_ws_reap(kmem_cache_t *cp)
{
@@ -3236,18 +3252,11 @@
kmem_magazine_destroy(cp, mp, rounds);
if (pmp)
kmem_magazine_destroy(cp, pmp, prounds);
}
- /*
- * Updating the working set statistics twice in a row has the
- * effect of setting the working set size to zero, so everything
- * is eligible for reaping.
- */
- kmem_depot_ws_update(cp);
- kmem_depot_ws_update(cp);
-
+ kmem_depot_ws_zero(cp);
kmem_depot_ws_reap(cp);
}
/*
* Enable per-cpu magazines on a cache.
@@ -3268,20 +3277,18 @@
}
}
/*
- * Reap (almost) everything right now. See kmem_cache_magazine_purge()
- * for explanation of the back-to-back kmem_depot_ws_update() calls.
+ * Reap (almost) everything right now.
*/
void
kmem_cache_reap_now(kmem_cache_t *cp)
{
ASSERT(list_link_active(&cp->cache_link));
- kmem_depot_ws_update(cp);
- kmem_depot_ws_update(cp);
+ kmem_depot_ws_zero(cp);
(void) taskq_dispatch(kmem_taskq,
(task_func_t *)kmem_depot_ws_reap, cp, TQ_SLEEP);
taskq_wait(kmem_taskq);
}