aboutsummaryrefslogtreecommitdiff
path: root/sys/vm
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2018-10-22 15:48:07 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2018-10-22 15:48:07 +0000
commit81c0d72c60f450f35a454fdf55d2d8dc526e491f (patch)
tree3497d33379d874e81ba46ae1ee0bee602ad35d24 /sys/vm
parentca8f3d1ca2db70399a8b0f7bada026a73e8a491f (diff)
downloadsrc-81c0d72c60f450f35a454fdf55d2d8dc526e491f.tar.gz
src-81c0d72c60f450f35a454fdf55d2d8dc526e491f.zip
If we lost race or were migrated during bucket allocation for the per-CPU
cache, then we put new bucket on generic bucket cache. However, code didn't honor UMA_ZONE_NOBUCKETCACHE flag, so potentially we could start a cache on a zone that clearly forbids that. Fix this. Reviewed by: markj
Notes
Notes: svn path=/head/; revision=339596
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/uma_core.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c
index 837eb0787915..849d8a1ef271 100644
--- a/sys/vm/uma_core.c
+++ b/sys/vm/uma_core.c
@@ -2410,6 +2410,7 @@ uma_zalloc_arg(uma_zone_t zone, void *udata, int flags)
* the current cache; when we re-acquire the critical section, we
* must detect and handle migration if it has occurred.
*/
+zalloc_restart:
critical_enter();
cpu = curcpu;
cache = &zone->uz_cpu[cpu];
@@ -2551,12 +2552,18 @@ zalloc_start:
* initialized bucket to make this less likely or claim
* the memory directly.
*/
- if (cache->uc_allocbucket != NULL ||
- (zone->uz_flags & UMA_ZONE_NUMA &&
- domain != PCPU_GET(domain)))
- LIST_INSERT_HEAD(&zdom->uzd_buckets, bucket, ub_link);
- else
+ if (cache->uc_allocbucket == NULL &&
+ ((zone->uz_flags & UMA_ZONE_NUMA) == 0 ||
+ domain == PCPU_GET(domain))) {
cache->uc_allocbucket = bucket;
+ } else if ((zone->uz_flags & UMA_ZONE_NOBUCKETCACHE) != 0) {
+ critical_exit();
+ ZONE_UNLOCK(zone);
+ bucket_drain(zone, bucket);
+ bucket_free(zone, bucket, udata);
+ goto zalloc_restart;
+ } else
+ LIST_INSERT_HEAD(&zdom->uzd_buckets, bucket, ub_link);
ZONE_UNLOCK(zone);
goto zalloc_start;
}