summaryrefslogtreecommitdiffstats
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
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.
-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