Author: stefan2
Date: Sat Oct 13 23:19:30 2012
New Revision: 1397967
URL: http://svn.apache.org/viewvc?rev=1397967&view=rev
Log:
For people with copious amounts of RAM (> 512GB), we may run
into the APR allocation limit of 4GB per apr_palloc. Thus, limit the
cache segment size accordingly.
* subversion/libsvn_subr/cache-membuffer.c
(MAX_SEGMENT_SIZE): declare new constant
(svn_cache__membuffer_cache_create): limit the segment size
Modified:
subversion/trunk/subversion/libsvn_subr/cache-membuffer.c
Modified: subversion/trunk/subversion/libsvn_subr/cache-membuffer.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/cache-membuffer.c?rev=1397967&r1=1397966&r2=1397967&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/trunk/subversion/libsvn_subr/cache-membuffer.c Sat Oct 13
23:19:30 2012
@@ -130,6 +130,11 @@
*/
#define MAX_SEGMENT_COUNT 0x10000
+/* As of today, APR won't allocate chunks of 4GB or more. So, limit the
+ * segment size to slightly below that.
+ */
+#define MAX_SEGMENT_SIZE 0xffff0000ull
+
/* We don't mark the initialization status for every group but initialize
* a number of groups at once. That will allow for a very small init flags
* vector that is likely to fit into the CPU caches even for fairly large
@@ -1140,6 +1145,11 @@ svn_cache__membuffer_cache_create(svn_me
apr_uint64_t data_size;
apr_uint64_t max_entry_size;
+ /* Limit the total size
+ */
+ if (total_size > MAX_SEGMENT_SIZE * MAX_SEGMENT_COUNT)
+ total_size = MAX_SEGMENT_SIZE * MAX_SEGMENT_COUNT;
+
/* Limit the segment count
*/
if (segment_count > MAX_SEGMENT_COUNT)
@@ -1177,6 +1187,14 @@ svn_cache__membuffer_cache_create(svn_me
segment_count = 1 << segment_count_shift;
}
+ /* If we have an extremely large cache (>512 GB), the default segment
+ * size may exceed the amount allocatable as one chunk. In that case,
+ * increase segmentation until we are under the threshold.
+ */
+ while ( total_size / segment_count > MAX_SEGMENT_SIZE
+ && segment_count < MAX_SEGMENT_COUNT)
+ segment_count *= 2;
+
/* allocate cache as an array of segments / cache objects */
c = apr_palloc(pool, segment_count * sizeof(*c));