If one process is making smalloc calls and another process is making
sfree calls, pool->free_blocks and pool->next_non_full will not be
synchronized because the two processes each have independent, local
copies of the variables.
This patch allocates space for the array of struct pool instances from
shared storage so that separate processes will be modifying quantities
stored at the same locations.
This issue was discovered on the server side running a client/server job
with --status-interval=1. Such a job encountered an OOM error when only
~50 objects were allocated from the smalloc pool.
Signed-off-by: Jens Axboe <axboe@kernel.dk>
*/
static const bool enable_smalloc_debug = false;
*/
static const bool enable_smalloc_debug = false;
-static struct pool mp[MAX_POOLS];
static unsigned int nr_pools;
static unsigned int last_pool;
static unsigned int nr_pools;
static unsigned int last_pool;
+ /*
+ * 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)
for (i = 0; i < INITIAL_POOLS; i++) {
ret = add_pool(&mp[nr_pools], smalloc_pool_size);
if (!ret)
for (i = 0; i < nr_pools; i++)
cleanup_pool(&mp[i]);
for (i = 0; i < nr_pools; i++)
cleanup_pool(&mp[i]);
+
+ munmap(mp, MAX_POOLS * sizeof(struct pool));