X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=smalloc.c;h=fa00f0ee3325b25fa6bdc5abe6c3bf405026a743;hp=0d7054a429480a51c60d774496191ba7de193850;hb=4a4199035ee07da312b5a611637a164ebe8a4805;hpb=82a90566caf08964064e74241e5eb5e42c6fb189 diff --git a/smalloc.c b/smalloc.c index 0d7054a4..fa00f0ee 100644 --- a/smalloc.c +++ b/smalloc.c @@ -54,7 +54,7 @@ struct block_hdr { */ static const bool enable_smalloc_debug = false; -static struct pool mp[MAX_POOLS]; +static struct pool *mp; static unsigned int nr_pools; static unsigned int last_pool; @@ -173,7 +173,7 @@ static bool add_pool(struct pool *pool, unsigned int alloc_size) pool->mmap_size = alloc_size; pool->nr_blocks = bitmap_blocks; - pool->free_blocks = bitmap_blocks * SMALLOC_BPB; + pool->free_blocks = bitmap_blocks * SMALLOC_BPI; mmap_flags = OS_MAP_ANON; #ifdef CONFIG_ESX @@ -208,6 +208,20 @@ void sinit(void) bool ret; int i; + /* + * sinit() can be called more than once if alloc-size is + * set. But we want to allocate space for the struct pool + * instances only once. + */ + if (!mp) { + mp = (struct pool *) mmap(NULL, + MAX_POOLS * sizeof(struct pool), + PROT_READ | PROT_WRITE, + OS_MAP_ANON | MAP_SHARED, -1, 0); + + assert(mp != MAP_FAILED); + } + for (i = 0; i < INITIAL_POOLS; i++) { ret = add_pool(&mp[nr_pools], smalloc_pool_size); if (!ret) @@ -239,6 +253,8 @@ void scleanup(void) for (i = 0; i < nr_pools; i++) cleanup_pool(&mp[i]); + + munmap(mp, MAX_POOLS * sizeof(struct pool)); } #ifdef SMALLOC_REDZONE @@ -338,18 +354,23 @@ void sfree(void *ptr) log_err("smalloc: ptr %p not from smalloc pool\n", ptr); } -static unsigned int firstfree(struct pool *pool) +static unsigned int find_best_index(struct pool *pool) { - unsigned int i; + unsigned int i; - for (i = 0; i < pool->nr_blocks; i++) - if (pool->bitmap[i] != -1U) - return i; + assert(pool->free_blocks); - assert(0); + for (i = pool->next_non_full; pool->bitmap[i] == -1U; i++) { + if (i == pool->nr_blocks - 1) { + unsigned int j; - /* we will never get here but this fixes a compiler warning */ - return -1U; + for (j = 0; j < pool->nr_blocks; j++) + if (pool->bitmap[j] != -1U) + return j; + } + } + + return i; } static void *__smalloc_pool(struct pool *pool, size_t size) @@ -366,16 +387,11 @@ static void *__smalloc_pool(struct pool *pool, size_t size) if (nr_blocks > pool->free_blocks) goto fail; - for (i = pool->next_non_full; pool->bitmap[i] == -1U; i++) - if (i == pool->nr_blocks - 1) { - i = firstfree(pool); - break; - } - - pool->next_non_full = i; + pool->next_non_full = find_best_index(pool); last_idx = 0; offset = -1U; + i = pool->next_non_full; while (i < pool->nr_blocks) { unsigned int idx;