summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorotto <>2019-01-10 18:45:33 +0000
committerotto <>2019-01-10 18:45:33 +0000
commitb47254ee48a7d354c7678164212af18a383af476 (patch)
tree784abc603fef5572b908001bea3c5bbb51d05a25
parent7d5ad0e66b7cd66e61d1d75f07f57890307a72f6 (diff)
downloadopenbsd-b47254ee48a7d354c7678164212af18a383af476.tar.gz
openbsd-b47254ee48a7d354c7678164212af18a383af476.tar.bz2
openbsd-b47254ee48a7d354c7678164212af18a383af476.zip
Make the "not my pool" searching loop a tiny bit smarter, while
making the number of pools variable. Do not document the malloc conf settings atm, don't know yet if they will stay. Thanks to all the testers. ok deraadt@
-rw-r--r--src/lib/libc/include/thread_private.h4
-rw-r--r--src/lib/libc/stdlib/malloc.c57
2 files changed, 39 insertions, 22 deletions
diff --git a/src/lib/libc/include/thread_private.h b/src/lib/libc/include/thread_private.h
index ae8d554a8a..774e0cba1f 100644
--- a/src/lib/libc/include/thread_private.h
+++ b/src/lib/libc/include/thread_private.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: thread_private.h,v 1.33 2017/12/05 13:45:31 kettenis Exp $ */ 1/* $OpenBSD: thread_private.h,v 1.34 2019/01/10 18:45:33 otto Exp $ */
2 2
3/* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */ 3/* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */
4 4
@@ -7,7 +7,7 @@
7 7
8#include <stdio.h> /* for FILE and __isthreaded */ 8#include <stdio.h> /* for FILE and __isthreaded */
9 9
10#define _MALLOC_MUTEXES 4 10#define _MALLOC_MUTEXES 32
11void _malloc_init(int); 11void _malloc_init(int);
12#ifdef __LIBC__ 12#ifdef __LIBC__
13PROTO_NORMAL(_malloc_init); 13PROTO_NORMAL(_malloc_init);
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index de504cdd8b..2a1bcfc8b6 100644
--- a/src/lib/libc/stdlib/malloc.c
+++ b/src/lib/libc/stdlib/malloc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: malloc.c,v 1.257 2018/12/10 07:57:49 otto Exp $ */ 1/* $OpenBSD: malloc.c,v 1.258 2019/01/10 18:45:33 otto Exp $ */
2/* 2/*
3 * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net> 3 * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net>
4 * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> 4 * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
@@ -143,6 +143,8 @@ struct dir_info {
143 size_t cheap_reallocs; 143 size_t cheap_reallocs;
144 size_t malloc_used; /* bytes allocated */ 144 size_t malloc_used; /* bytes allocated */
145 size_t malloc_guarded; /* bytes used for guards */ 145 size_t malloc_guarded; /* bytes used for guards */
146 size_t pool_searches; /* searches for pool */
147 size_t other_pool; /* searches in other pool */
146#define STATS_ADD(x,y) ((x) += (y)) 148#define STATS_ADD(x,y) ((x) += (y))
147#define STATS_SUB(x,y) ((x) -= (y)) 149#define STATS_SUB(x,y) ((x) -= (y))
148#define STATS_INC(x) ((x)++) 150#define STATS_INC(x) ((x)++)
@@ -179,7 +181,9 @@ struct chunk_info {
179}; 181};
180 182
181struct malloc_readonly { 183struct malloc_readonly {
182 struct dir_info *malloc_pool[_MALLOC_MUTEXES]; /* Main bookkeeping information */ 184 /* Main bookkeeping information */
185 struct dir_info *malloc_pool[_MALLOC_MUTEXES];
186 u_int malloc_mutexes; /* how much in actual use? */
183 int malloc_mt; /* multi-threaded mode? */ 187 int malloc_mt; /* multi-threaded mode? */
184 int malloc_freecheck; /* Extensive double free check */ 188 int malloc_freecheck; /* Extensive double free check */
185 int malloc_freeunmap; /* mprotect free pages PROT_NONE? */ 189 int malloc_freeunmap; /* mprotect free pages PROT_NONE? */
@@ -267,7 +271,7 @@ getpool(void)
267 return mopts.malloc_pool[0]; 271 return mopts.malloc_pool[0];
268 else 272 else
269 return mopts.malloc_pool[TIB_GET()->tib_tid & 273 return mopts.malloc_pool[TIB_GET()->tib_tid &
270 (_MALLOC_MUTEXES - 1)]; 274 (mopts.malloc_mutexes - 1)];
271} 275}
272 276
273static __dead void 277static __dead void
@@ -316,6 +320,16 @@ static void
316omalloc_parseopt(char opt) 320omalloc_parseopt(char opt)
317{ 321{
318 switch (opt) { 322 switch (opt) {
323 case '+':
324 mopts.malloc_mutexes <<= 1;
325 if (mopts.malloc_mutexes > _MALLOC_MUTEXES)
326 mopts.malloc_mutexes = _MALLOC_MUTEXES;
327 break;
328 case '-':
329 mopts.malloc_mutexes >>= 1;
330 if (mopts.malloc_mutexes < 1)
331 mopts.malloc_mutexes = 1;
332 break;
319 case '>': 333 case '>':
320 mopts.malloc_cache <<= 1; 334 mopts.malloc_cache <<= 1;
321 if (mopts.malloc_cache > MALLOC_MAXCACHE) 335 if (mopts.malloc_cache > MALLOC_MAXCACHE)
@@ -395,6 +409,7 @@ omalloc_init(void)
395 /* 409 /*
396 * Default options 410 * Default options
397 */ 411 */
412 mopts.malloc_mutexes = 4;
398 mopts.malloc_junk = 1; 413 mopts.malloc_junk = 1;
399 mopts.malloc_cache = MALLOC_DEFAULT_CACHE; 414 mopts.malloc_cache = MALLOC_DEFAULT_CACHE;
400 415
@@ -485,7 +500,7 @@ omalloc_poolinit(struct dir_info **dp)
485 for (j = 0; j < MALLOC_CHUNK_LISTS; j++) 500 for (j = 0; j < MALLOC_CHUNK_LISTS; j++)
486 LIST_INIT(&d->chunk_dir[i][j]); 501 LIST_INIT(&d->chunk_dir[i][j]);
487 } 502 }
488 STATS_ADD(d->malloc_used, regioninfo_size); 503 STATS_ADD(d->malloc_used, regioninfo_size + 3 * MALLOC_PAGESIZE);
489 d->canary1 = mopts.malloc_canary ^ (u_int32_t)(uintptr_t)d; 504 d->canary1 = mopts.malloc_canary ^ (u_int32_t)(uintptr_t)d;
490 d->canary2 = ~d->canary1; 505 d->canary2 = ~d->canary1;
491 506
@@ -1196,7 +1211,7 @@ _malloc_init(int from_rthreads)
1196 if (!mopts.malloc_canary) 1211 if (!mopts.malloc_canary)
1197 omalloc_init(); 1212 omalloc_init();
1198 1213
1199 max = from_rthreads ? _MALLOC_MUTEXES : 1; 1214 max = from_rthreads ? mopts.malloc_mutexes : 1;
1200 if (((uintptr_t)&malloc_readonly & MALLOC_PAGEMASK) == 0) 1215 if (((uintptr_t)&malloc_readonly & MALLOC_PAGEMASK) == 0)
1201 mprotect(&malloc_readonly, sizeof(malloc_readonly), 1216 mprotect(&malloc_readonly, sizeof(malloc_readonly),
1202 PROT_READ | PROT_WRITE); 1217 PROT_READ | PROT_WRITE);
@@ -1281,16 +1296,19 @@ findpool(void *p, struct dir_info *argpool, struct dir_info **foundpool,
1281 struct dir_info *pool = argpool; 1296 struct dir_info *pool = argpool;
1282 struct region_info *r = find(pool, p); 1297 struct region_info *r = find(pool, p);
1283 1298
1299 STATS_INC(pool->pool_searches);
1284 if (r == NULL) { 1300 if (r == NULL) {
1285 if (mopts.malloc_mt) { 1301 if (mopts.malloc_mt) {
1286 int i; 1302 int i;
1287 1303
1288 for (i = 0; i < _MALLOC_MUTEXES; i++) { 1304 STATS_INC(pool->other_pool);
1289 if (i == argpool->mutex) 1305 for (i = 1; i < mopts.malloc_mutexes; i++) {
1290 continue; 1306 int j = (argpool->mutex + i) &
1307 (mopts.malloc_mutexes - 1);
1308
1291 pool->active--; 1309 pool->active--;
1292 _MALLOC_UNLOCK(pool->mutex); 1310 _MALLOC_UNLOCK(pool->mutex);
1293 pool = mopts.malloc_pool[i]; 1311 pool = mopts.malloc_pool[j];
1294 _MALLOC_LOCK(pool->mutex); 1312 _MALLOC_LOCK(pool->mutex);
1295 pool->active++; 1313 pool->active++;
1296 r = find(pool, p); 1314 r = find(pool, p);
@@ -2220,14 +2238,13 @@ malloc_dump1(int fd, int poolno, struct dir_info *d)
2220 return; 2238 return;
2221 dprintf(fd, "Region slots free %zu/%zu\n", 2239 dprintf(fd, "Region slots free %zu/%zu\n",
2222 d->regions_free, d->regions_total); 2240 d->regions_free, d->regions_total);
2223 dprintf(fd, "Finds %zu/%zu\n", d->finds, 2241 dprintf(fd, "Finds %zu/%zu\n", d->finds, d->find_collisions);
2224 d->find_collisions); 2242 dprintf(fd, "Inserts %zu/%zu\n", d->inserts, d->insert_collisions);
2225 dprintf(fd, "Inserts %zu/%zu\n", d->inserts, 2243 dprintf(fd, "Deletes %zu/%zu\n", d->deletes, d->delete_moves);
2226 d->insert_collisions);
2227 dprintf(fd, "Deletes %zu/%zu\n", d->deletes,
2228 d->delete_moves);
2229 dprintf(fd, "Cheap reallocs %zu/%zu\n", 2244 dprintf(fd, "Cheap reallocs %zu/%zu\n",
2230 d->cheap_reallocs, d->cheap_realloc_tries); 2245 d->cheap_reallocs, d->cheap_realloc_tries);
2246 dprintf(fd, "Other pool searches %zu/%zu\n",
2247 d->other_pool, d->pool_searches);
2231 dprintf(fd, "In use %zu\n", d->malloc_used); 2248 dprintf(fd, "In use %zu\n", d->malloc_used);
2232 dprintf(fd, "Guarded %zu\n", d->malloc_guarded); 2249 dprintf(fd, "Guarded %zu\n", d->malloc_guarded);
2233 dump_free_chunk_info(fd, d); 2250 dump_free_chunk_info(fd, d);
@@ -2289,7 +2306,7 @@ malloc_gdump(int fd)
2289 int i; 2306 int i;
2290 int saved_errno = errno; 2307 int saved_errno = errno;
2291 2308
2292 for (i = 0; i < _MALLOC_MUTEXES; i++) 2309 for (i = 0; i < mopts.malloc_mutexes; i++)
2293 malloc_dump(fd, i, mopts.malloc_pool[i]); 2310 malloc_dump(fd, i, mopts.malloc_pool[i]);
2294 2311
2295 errno = saved_errno; 2312 errno = saved_errno;
@@ -2305,15 +2322,15 @@ malloc_exit(void)
2305 if (fd != -1) { 2322 if (fd != -1) {
2306 dprintf(fd, "******** Start dump %s *******\n", __progname); 2323 dprintf(fd, "******** Start dump %s *******\n", __progname);
2307 dprintf(fd, 2324 dprintf(fd,
2308 "MT=%d I=%d F=%d U=%d J=%d R=%d X=%d C=%d cache=%u G=%zu\n", 2325 "MT=%d M=%u I=%d F=%d U=%d J=%d R=%d X=%d C=%d cache=%u G=%zu\n",
2309 mopts.malloc_mt, mopts.internal_funcs, 2326 mopts.malloc_mt, mopts.mallloc_mutexes,
2310 mopts.malloc_freecheck, 2327 mopts.internal_funcs, mopts.malloc_freecheck,
2311 mopts.malloc_freeunmap, mopts.malloc_junk, 2328 mopts.malloc_freeunmap, mopts.malloc_junk,
2312 mopts.malloc_realloc, mopts.malloc_xmalloc, 2329 mopts.malloc_realloc, mopts.malloc_xmalloc,
2313 mopts.chunk_canaries, mopts.malloc_cache, 2330 mopts.chunk_canaries, mopts.malloc_cache,
2314 mopts.malloc_guard); 2331 mopts.malloc_guard);
2315 2332
2316 for (i = 0; i < _MALLOC_MUTEXES; i++) 2333 for (i = 0; i < mopts.malloc_mutexes; i++)
2317 malloc_dump(fd, i, mopts.malloc_pool[i]); 2334 malloc_dump(fd, i, mopts.malloc_pool[i]);
2318 dprintf(fd, "******** End dump %s *******\n", __progname); 2335 dprintf(fd, "******** End dump %s *******\n", __progname);
2319 close(fd); 2336 close(fd);