summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/vm/uma_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/vm/uma_core.c')
-rw-r--r--freebsd/sys/vm/uma_core.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/freebsd/sys/vm/uma_core.c b/freebsd/sys/vm/uma_core.c
index 7738c5d2..8c3a84b4 100644
--- a/freebsd/sys/vm/uma_core.c
+++ b/freebsd/sys/vm/uma_core.c
@@ -189,8 +189,14 @@ SYSCTL_ULONG(_vm, OID_AUTO, uma_kmem_total, CTLFLAG_RD, &uma_kmem_total, 0,
#ifndef __rtems__
/* Is the VM done starting up? */
-static enum { BOOT_COLD = 0, BOOT_STRAPPED, BOOT_PAGEALLOC, BOOT_BUCKETS,
- BOOT_RUNNING } booted = BOOT_COLD;
+static enum {
+ BOOT_COLD,
+ BOOT_STRAPPED,
+ BOOT_PAGEALLOC,
+ BOOT_BUCKETS,
+ BOOT_RUNNING,
+ BOOT_SHUTDOWN,
+} booted = BOOT_COLD;
#endif /* __rtems__ */
/*
@@ -311,6 +317,9 @@ static int hash_expand(struct uma_hash *, struct uma_hash *);
static void hash_free(struct uma_hash *hash);
static void uma_timeout(void *);
static void uma_startup3(void);
+#ifndef __rtems__
+static void uma_shutdown(void);
+#endif /* __rtems__ */
static void *zone_alloc_item(uma_zone_t, void *, int, int);
static void zone_free_item(uma_zone_t, void *, void *, enum zfreeskip);
static void bucket_enable(void);
@@ -1255,8 +1264,7 @@ startup_alloc(uma_zone_t zone, vm_size_t bytes, int domain, uint8_t *pflag,
case BOOT_PAGEALLOC:
if (keg->uk_ppera > 1)
break;
- case BOOT_BUCKETS:
- case BOOT_RUNNING:
+ default:
#ifdef UMA_MD_SMALL_ALLOC
keg->uk_allocf = (keg->uk_ppera > 1) ?
page_alloc : uma_small_alloc;
@@ -2259,10 +2267,6 @@ uma_startup2(void)
}
#endif /* __rtems__ */
-/*
- * Initialize our callout handle
- *
- */
static void
uma_startup3(void)
{
@@ -2278,9 +2282,21 @@ uma_startup3(void)
callout_reset(&uma_callout, UMA_TIMEOUT * hz, uma_timeout, NULL);
#ifndef __rtems__
booted = BOOT_RUNNING;
+
+ EVENTHANDLER_REGISTER(shutdown_post_sync, uma_shutdown, NULL,
+ EVENTHANDLER_PRI_FIRST);
#endif /* __rtems__ */
}
+#ifndef __rtems__
+static void
+uma_shutdown(void)
+{
+
+ booted = BOOT_SHUTDOWN;
+}
+#endif /* __rtems__ */
+
static uma_keg_t
uma_kcreate(uma_zone_t zone, size_t size, uma_init uminit, uma_fini fini,
int align, uint32_t flags)
@@ -2518,6 +2534,16 @@ void
uma_zdestroy(uma_zone_t zone)
{
+#ifndef __rtems__
+ /*
+ * Large slabs are expensive to reclaim, so don't bother doing
+ * unnecessary work if we're shutting down.
+ */
+ if (booted == BOOT_SHUTDOWN &&
+ zone->uz_fini == NULL &&
+ zone->uz_release == (uma_release)zone_release)
+ return;
+#endif /* __rtems__ */
sx_slock(&uma_drain_lock);
zone_free_item(zones, zone, NULL, SKIP_NONE);
sx_sunlock(&uma_drain_lock);