summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiels de Vos <ndevos@redhat.com>2017-07-13 13:44:19 +0200
committerJeff Darcy <jeff@pl.atyp.us>2017-07-20 11:35:23 +0000
commit8a09d78076cf506f0750cccd63cc983496473cf3 (patch)
treed023ccddaa6bbf1ccaa1da98169856e6555316fe
parent1e8e6264033669332d4cfa117faf678d7631a7b1 (diff)
mem-pool: free objects from pools on mem_pools_fini()
When using a minimal gfapi application that only initializes a small graph (sink, shard and meta xlators) the following memory leaks are reported by Valgrind: HEAP SUMMARY: in use at exit: 322,976 bytes in 75 blocks total heap usage: 684 allocs, 609 frees, 2,092,116 bytes allocated With this change, the mem-pools are cleaned up on calling of mem_pools_fini() and the objects in the pool are free'd. HEAP SUMMARY: in use at exit: 315,265 bytes in 58 blocks total heap usage: 684 allocs, 626 frees, 2,092,079 bytes allocated This information was gathered with `./run-xlator.sh features/shard` that comes with `gfapi-load-volfile` from gluster-debug-tools. While working on the free'ing of the per_thread_pool_list_t structures, it became apparent that GF_CALLOC() in mem_get_pool_list() gets redirected to a standard calloc() without prepending the Gluster specific memory header. This is because mem_pools_init() gets called before THIS->ctx is valid, so it is not possible to check if memory accounting is enabled or not. Because of this, the GF_CALLOC() call in mem_get_pool_list() has been replaced by CALLOC() to prevent potential mismatches between the allocation/free'ing of per_thread_pool_list_t structures. Change-Id: Id6f558816f399b0c613d74df36deac2300b6dd98 BUG: 1470170 URL: https://github.com/gluster/gluster-debug-tools Signed-off-by: Niels de Vos <ndevos@redhat.com> Reviewed-on: https://review.gluster.org/17768 Smoke: Gluster Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Jeff Darcy <jeff@pl.atyp.us> Reviewed-by: soumya k <skoduri@redhat.com>
-rw-r--r--libglusterfs/src/mem-pool.c29
-rw-r--r--libglusterfs/src/mem-types.h2
2 files changed, 29 insertions, 2 deletions
diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c
index b064837ac00..61ab8d379d4 100644
--- a/libglusterfs/src/mem-pool.c
+++ b/libglusterfs/src/mem-pool.c
@@ -594,6 +594,11 @@ mem_pools_fini (void)
*/
break;
case 1:
+ {
+ per_thread_pool_list_t *pool_list;
+ per_thread_pool_list_t *next_pl;
+ unsigned int i;
+
/* if only mem_pools_init_early() was called, sweeper_tid will
* be invalid and the functions will error out. That is not
* critical. In all other cases, the sweeper_tid will be valid
@@ -609,7 +614,28 @@ mem_pools_fini (void)
* per_thread_pool_list_t structure. */
(void) pthread_key_delete (pool_key);
+ /* free all objects from all pools */
+ list_for_each_entry_safe (pool_list, next_pl,
+ &pool_threads, thr_list) {
+ for (i = 0; i < NPOOLS; ++i) {
+ free_obj_list (pool_list->pools[i].hot_list);
+ free_obj_list (pool_list->pools[i].cold_list);
+ pool_list->pools[i].hot_list = NULL;
+ pool_list->pools[i].cold_list = NULL;
+ }
+
+ list_del (&pool_list->thr_list);
+ FREE (pool_list);
+ }
+
+ list_for_each_entry_safe (pool_list, next_pl,
+ &pool_free_threads, thr_list) {
+ list_del (&pool_list->thr_list);
+ FREE (pool_list);
+ }
+
/* Fall through. */
+ }
default:
--init_count;
}
@@ -686,8 +712,7 @@ mem_get_pool_list (void)
(void) pthread_mutex_unlock (&pool_free_lock);
if (!pool_list) {
- pool_list = GF_CALLOC (pool_list_size, 1,
- gf_common_mt_mem_pool);
+ pool_list = CALLOC (pool_list_size, 1);
if (!pool_list) {
return NULL;
}
diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h
index c2ac088f639..d244fb528e3 100644
--- a/libglusterfs/src/mem-types.h
+++ b/libglusterfs/src/mem-types.h
@@ -61,7 +61,9 @@ enum gf_common_mem_types_ {
gf_common_mt_char,
gf_common_mt_rbthash_table_t,
gf_common_mt_rbthash_bucket,
+#if defined(GF_DISABLE_MEMPOOL)
gf_common_mt_mem_pool,
+#endif
gf_common_mt_long,
gf_common_mt_rpcsvc_auth_list,
gf_common_mt_rpcsvc_t,