diff options
author | otto <> | 2019-01-10 18:45:33 +0000 |
---|---|---|
committer | otto <> | 2019-01-10 18:45:33 +0000 |
commit | b47254ee48a7d354c7678164212af18a383af476 (patch) | |
tree | 784abc603fef5572b908001bea3c5bbb51d05a25 | |
parent | 7d5ad0e66b7cd66e61d1d75f07f57890307a72f6 (diff) | |
download | openbsd-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.h | 4 | ||||
-rw-r--r-- | src/lib/libc/stdlib/malloc.c | 57 |
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 |
11 | void _malloc_init(int); | 11 | void _malloc_init(int); |
12 | #ifdef __LIBC__ | 12 | #ifdef __LIBC__ |
13 | PROTO_NORMAL(_malloc_init); | 13 | PROTO_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 | ||
181 | struct malloc_readonly { | 183 | struct 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 | ||
273 | static __dead void | 277 | static __dead void |
@@ -316,6 +320,16 @@ static void | |||
316 | omalloc_parseopt(char opt) | 320 | omalloc_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); |