summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2013-11-23 13:42:56 +0000
committermav <mav@FreeBSD.org>2013-11-23 13:42:56 +0000
commit21d101ccc523a786a6b5d18d7d784eae8017e9c5 (patch)
tree52dae21b6c37b3368ba2d3cc5847d47d8231d4ce /sys/vm
parentc68617cf155ff030a33c997841409093543a3d6d (diff)
downloadFreeBSD-src-21d101ccc523a786a6b5d18d7d784eae8017e9c5.zip
FreeBSD-src-21d101ccc523a786a6b5d18d7d784eae8017e9c5.tar.gz
When purging per-CPU UMA caches do not return empty buckets into the global
full bucket cache to not trigger assertion if allocation happen before that global cache get purged.
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/uma_core.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c
index 2b32a3e..62c2c52 100644
--- a/sys/vm/uma_core.c
+++ b/sys/vm/uma_core.c
@@ -701,25 +701,37 @@ static void
cache_drain_safe_cpu(uma_zone_t zone)
{
uma_cache_t cache;
+ uma_bucket_t b1, b2;
if (zone->uz_flags & UMA_ZFLAG_INTERNAL)
return;
+ b1 = b2 = NULL;
ZONE_LOCK(zone);
critical_enter();
cache = &zone->uz_cpu[curcpu];
if (cache->uc_allocbucket) {
- LIST_INSERT_HEAD(&zone->uz_buckets, cache->uc_allocbucket,
- ub_link);
+ if (cache->uc_allocbucket->ub_cnt != 0)
+ LIST_INSERT_HEAD(&zone->uz_buckets,
+ cache->uc_allocbucket, ub_link);
+ else
+ b1 = cache->uc_allocbucket;
cache->uc_allocbucket = NULL;
}
if (cache->uc_freebucket) {
- LIST_INSERT_HEAD(&zone->uz_buckets, cache->uc_freebucket,
- ub_link);
+ if (cache->uc_freebucket->ub_cnt != 0)
+ LIST_INSERT_HEAD(&zone->uz_buckets,
+ cache->uc_freebucket, ub_link);
+ else
+ b2 = cache->uc_freebucket;
cache->uc_freebucket = NULL;
}
critical_exit();
ZONE_UNLOCK(zone);
+ if (b1)
+ bucket_free(zone, b1, NULL);
+ if (b2)
+ bucket_free(zone, b2, NULL);
}
/*
OpenPOWER on IntegriCloud