summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2014-01-04 23:35:34 +0000
committermav <mav@FreeBSD.org>2014-01-04 23:35:34 +0000
commita5fd15da703197a01783bcee7a038aeaf3172e32 (patch)
treedc0e9a286940d7bacc639f9dcd7e1a3c19b9b7f5 /sys/vm
parentafcf784d4c189926df9c1f9e1a2203f05961ba1f (diff)
downloadFreeBSD-src-a5fd15da703197a01783bcee7a038aeaf3172e32.zip
FreeBSD-src-a5fd15da703197a01783bcee7a038aeaf3172e32.tar.gz
MFC r258336:
Implement soft pressure on UMA cache bucket sizes. Every time system detects low memory condition decrease bucket sizes for each zone by one item. As result, higher memory pressure will push to smaller bucket sizes and so smaller per-CPU caches and so more efficient memory use. Before this change there was no force to oppose buckets growth as result of practically inevitable zone lock conflicts, and after some run time per-CPU caches could consume enough RAM to kill the system.
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/uma_core.c9
-rw-r--r--sys/vm/uma_int.h3
2 files changed, 11 insertions, 1 deletions
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c
index 85c96e5..7ad6e84 100644
--- a/sys/vm/uma_core.c
+++ b/sys/vm/uma_core.c
@@ -702,6 +702,13 @@ bucket_cache_drain(uma_zone_t zone)
bucket_free(zone, bucket, NULL);
ZONE_LOCK(zone);
}
+
+ /*
+ * Shrink further bucket sizes. Price of single zone lock collision
+ * is probably lower then price of global cache drain.
+ */
+ if (zone->uz_count > zone->uz_count_min)
+ zone->uz_count--;
}
static void
@@ -1462,6 +1469,7 @@ zone_ctor(void *mem, int size, void *udata, int flags)
zone->uz_fails = 0;
zone->uz_sleeps = 0;
zone->uz_count = 0;
+ zone->uz_count_min = 0;
zone->uz_flags = 0;
zone->uz_warning = NULL;
timevalclear(&zone->uz_ratecheck);
@@ -1553,6 +1561,7 @@ out:
zone->uz_count = bucket_select(zone->uz_size);
else
zone->uz_count = BUCKET_MAX;
+ zone->uz_count_min = zone->uz_count;
return (0);
}
diff --git a/sys/vm/uma_int.h b/sys/vm/uma_int.h
index 00e8519..1ffc7d5 100644
--- a/sys/vm/uma_int.h
+++ b/sys/vm/uma_int.h
@@ -300,7 +300,8 @@ struct uma_zone {
volatile u_long uz_fails; /* Total number of alloc failures */
volatile u_long uz_frees; /* Total number of frees */
uint64_t uz_sleeps; /* Total number of alloc sleeps */
- uint16_t uz_count; /* Highest amount of items in bucket */
+ uint16_t uz_count; /* Amount of items in full bucket */
+ uint16_t uz_count_min; /* Minimal amount of items there */
/* The next three fields are used to print a rate-limited warnings. */
const char *uz_warning; /* Warning to print on failure */
OpenPOWER on IntegriCloud