diff options
| author | Niels de Vos <ndevos@redhat.com> | 2017-07-13 13:44:19 +0200 | 
|---|---|---|
| committer | Jeff Darcy <jeff@pl.atyp.us> | 2017-07-20 11:35:23 +0000 | 
| commit | 8a09d78076cf506f0750cccd63cc983496473cf3 (patch) | |
| tree | d023ccddaa6bbf1ccaa1da98169856e6555316fe | |
| parent | 1e8e6264033669332d4cfa117faf678d7631a7b1 (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.c | 29 | ||||
| -rw-r--r-- | libglusterfs/src/mem-types.h | 2 | 
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,  | 
