e7a346
From 3cc901acea41632df0c342639c4292c10bd90964 Mon Sep 17 00:00:00 2001
e7a346
From: Mohit Agrawal <moagrawa@redhat.com>
e7a346
Date: Tue, 18 Dec 2018 15:39:14 +0530
e7a346
Subject: [PATCH 487/493] mem-pool: add tracking of mem_pool that requested the
e7a346
 allocation
e7a346
e7a346
This renames the current 'struct mem_pool' to 'struct mem_pool_shared'.
e7a346
The mem_pool_shared is globally allocated and not specific for
e7a346
particular objects.
e7a346
e7a346
A new 'struct mem_pool' gets allocated when mem_pool_new() is called. It
e7a346
points to the mem_pool_shared that handles the actual allocation
e7a346
requests. The 'struct mem_pool' is only used for accounting of the
e7a346
objects that the caller requested and free'd.
e7a346
e7a346
All of these changes will be used to collect all the memory pools a
e7a346
glusterfs_ctx_t is consuming, so that statedumps can be collected per
e7a346
context.
e7a346
e7a346
> Updates: #307
e7a346
> Change-Id: I6355d3f0251c928e0bbfc71be3431307c6f3a3da
e7a346
> Signed-off-by: Niels de Vos <ndevos@redhat.com>
e7a346
> Reviewed-on: https://review.gluster.org/18073
e7a346
> Smoke: Gluster Build System <jenkins@build.gluster.org>
e7a346
> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
e7a346
> Reviewed-by: Amar Tumballi <amarts@redhat.com>
e7a346
> Reviewed-by: Jeff Darcy <jeff@pl.atyp.us>
e7a346
> Cherry picked from commit 2645e730b79b44fc035170657e43bb52f3e855c5
e7a346
e7a346
Change-Id: I6cce6284e4553c6ca59a90ad124c23c950db3148
e7a346
BUG: 1648893
e7a346
Signed-off-by: Mohit Agrawal <moagrawa@redhat.com>
e7a346
e7a346
Signed-off-by: Mohit Agrawal <moagrawa@redhat.com>
e7a346
Change-Id: I363d71152b1dd17eca53d9c327fcdf2f26c0fb61
e7a346
Reviewed-on: https://code.engineering.redhat.com/gerrit/158930
e7a346
Tested-by: RHGS Build Bot <nigelb@redhat.com>
e7a346
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
e7a346
---
e7a346
 libglusterfs/src/mem-pool.c  | 69 +++++++++++++++++++++++++++-----------------
e7a346
 libglusterfs/src/mem-pool.h  | 20 +++++++++++--
e7a346
 libglusterfs/src/mem-types.h |  2 --
e7a346
 3 files changed, 60 insertions(+), 31 deletions(-)
e7a346
e7a346
diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c
e7a346
index 8ff261c..a8a9347 100644
e7a346
--- a/libglusterfs/src/mem-pool.c
e7a346
+++ b/libglusterfs/src/mem-pool.c
e7a346
@@ -14,15 +14,6 @@
e7a346
 #include <stdlib.h>
e7a346
 #include <stdarg.h>
e7a346
 
e7a346
-#define GF_MEM_POOL_LIST_BOUNDARY        (sizeof(struct list_head))
e7a346
-#define GF_MEM_POOL_PTR                  (sizeof(struct mem_pool*))
e7a346
-#define GF_MEM_POOL_PAD_BOUNDARY         (GF_MEM_POOL_LIST_BOUNDARY  + GF_MEM_POOL_PTR + sizeof(int))
e7a346
-#define mem_pool_chunkhead2ptr(head)     ((head) + GF_MEM_POOL_PAD_BOUNDARY)
e7a346
-#define mem_pool_ptr2chunkhead(ptr)      ((ptr) - GF_MEM_POOL_PAD_BOUNDARY)
e7a346
-#define is_mem_chunk_in_use(ptr)         (*ptr == 1)
e7a346
-#define mem_pool_from_ptr(ptr)           ((ptr) + GF_MEM_POOL_LIST_BOUNDARY)
e7a346
-
e7a346
-#define GLUSTERFS_ENV_MEM_ACCT_STR  "GLUSTERFS_DISABLE_MEM_ACCT"
e7a346
 
e7a346
 #include "unittest/unittest.h"
e7a346
 #include "libglusterfs-messages.h"
e7a346
@@ -380,7 +371,7 @@ static pthread_mutex_t          pool_lock       = PTHREAD_MUTEX_INITIALIZER;
e7a346
 static struct list_head         pool_threads;
e7a346
 static pthread_mutex_t          pool_free_lock  = PTHREAD_MUTEX_INITIALIZER;
e7a346
 static struct list_head         pool_free_threads;
e7a346
-static struct mem_pool          pools[NPOOLS];
e7a346
+static struct mem_pool_shared   pools[NPOOLS];
e7a346
 static size_t                   pool_list_size;
e7a346
 
e7a346
 #if !defined(GF_DISABLE_MEMPOOL)
e7a346
@@ -689,6 +680,8 @@ mem_pool_new_fn (unsigned long sizeof_type,
e7a346
                  unsigned long count, char *name)
e7a346
 {
e7a346
         unsigned int            i;
e7a346
+        struct mem_pool         *new = NULL;
e7a346
+        struct mem_pool_shared  *pool = NULL;
e7a346
 
e7a346
         if (!sizeof_type) {
e7a346
                 gf_msg_callingfn ("mem-pool", GF_LOG_ERROR, EINVAL,
e7a346
@@ -698,13 +691,27 @@ mem_pool_new_fn (unsigned long sizeof_type,
e7a346
 
e7a346
         for (i = 0; i < NPOOLS; ++i) {
e7a346
                 if (sizeof_type <= AVAILABLE_SIZE(pools[i].power_of_two)) {
e7a346
-                        return &pools[i];
e7a346
+                        pool = &pools[i];
e7a346
+                        break;
e7a346
                 }
e7a346
         }
e7a346
 
e7a346
-        gf_msg_callingfn ("mem-pool", GF_LOG_ERROR, EINVAL,
e7a346
-                          LG_MSG_INVALID_ARG, "invalid argument");
e7a346
-        return NULL;
e7a346
+        if (!pool) {
e7a346
+                gf_msg_callingfn ("mem-pool", GF_LOG_ERROR, EINVAL,
e7a346
+                                  LG_MSG_INVALID_ARG, "invalid argument");
e7a346
+                return NULL;
e7a346
+        }
e7a346
+
e7a346
+        new = GF_CALLOC (sizeof (struct mem_pool), 1, gf_common_mt_mem_pool);
e7a346
+        if (!new)
e7a346
+                return NULL;
e7a346
+
e7a346
+        new->sizeof_type = sizeof_type;
e7a346
+        new->count = count;
e7a346
+        new->name = name;
e7a346
+        new->pool = pool;
e7a346
+
e7a346
+        return new;
e7a346
 }
e7a346
 
e7a346
 void*
e7a346
@@ -721,7 +728,7 @@ mem_get0 (struct mem_pool *mem_pool)
e7a346
         ptr = mem_get(mem_pool);
e7a346
 
e7a346
         if (ptr) {
e7a346
-                memset (ptr, 0, AVAILABLE_SIZE(mem_pool->power_of_two));
e7a346
+                memset (ptr, 0, AVAILABLE_SIZE(mem_pool->pool->power_of_two));
e7a346
         }
e7a346
 
e7a346
         return ptr;
e7a346
@@ -784,7 +791,7 @@ mem_get_from_pool (struct mem_pool *mem_pool)
e7a346
                 return NULL;
e7a346
         }
e7a346
 
e7a346
-        pt_pool = &pool_list->pools[mem_pool->power_of_two-POOL_SMALLEST];
e7a346
+        pt_pool = &pool_list->pools[mem_pool->pool->power_of_two-POOL_SMALLEST];
e7a346
 
e7a346
         (void) pthread_spin_lock (&pool_list->lock);
e7a346
 
e7a346
@@ -802,7 +809,7 @@ mem_get_from_pool (struct mem_pool *mem_pool)
e7a346
                 } else {
e7a346
                         (void) pthread_spin_unlock (&pool_list->lock);
e7a346
                         GF_ATOMIC_INC (pt_pool->parent->allocs_stdc);
e7a346
-                        retval = malloc (1 << mem_pool->power_of_two);
e7a346
+                        retval = malloc (1 << mem_pool->pool->power_of_two);
e7a346
                 }
e7a346
         }
e7a346
 
e7a346
@@ -810,7 +817,7 @@ mem_get_from_pool (struct mem_pool *mem_pool)
e7a346
                 retval->magic = GF_MEM_HEADER_MAGIC;
e7a346
                 retval->next = NULL;
e7a346
                 retval->pool_list = pool_list;
e7a346
-                retval->power_of_two = mem_pool->power_of_two;
e7a346
+                retval->power_of_two = mem_pool->pool->power_of_two;
e7a346
         }
e7a346
 
e7a346
         return retval;
e7a346
@@ -821,9 +828,10 @@ void *
e7a346
 mem_get (struct mem_pool *mem_pool)
e7a346
 {
e7a346
 #if defined(GF_DISABLE_MEMPOOL)
e7a346
-        return GF_CALLOC (1, AVAILABLE_SIZE (mem_pool->power_of_two),
e7a346
+        return GF_CALLOC (1, AVAILABLE_SIZE (mem_pool->pool->power_of_two),
e7a346
                           gf_common_mt_mem_pool);
e7a346
 #else
e7a346
+        per_thread_pool_list_t  *pool_list;
e7a346
         pooled_obj_hdr_t        *retval;
e7a346
 
e7a346
         if (!mem_pool) {
e7a346
@@ -832,11 +840,22 @@ mem_get (struct mem_pool *mem_pool)
e7a346
                 return NULL;
e7a346
         }
e7a346
 
e7a346
+        pool_list = mem_get_pool_list ();
e7a346
+        if (!pool_list || pool_list->poison) {
e7a346
+                return NULL;
e7a346
+        }
e7a346
+
e7a346
         retval = mem_get_from_pool (mem_pool);
e7a346
+
e7a346
         if (!retval) {
e7a346
                 return NULL;
e7a346
         }
e7a346
 
e7a346
+        retval->magic = GF_MEM_HEADER_MAGIC;
e7a346
+        retval->pool = mem_pool;
e7a346
+        retval->pool_list = pool_list;
e7a346
+        retval->power_of_two = mem_pool->pool->power_of_two;
e7a346
+
e7a346
         return retval + 1;
e7a346
 #endif /* GF_DISABLE_MEMPOOL */
e7a346
 }
e7a346
@@ -886,14 +905,12 @@ mem_put (void *ptr)
e7a346
 void
e7a346
 mem_pool_destroy (struct mem_pool *pool)
e7a346
 {
e7a346
-        if (!pool)
e7a346
-                return;
e7a346
+        GF_FREE (pool);
e7a346
 
e7a346
         /*
e7a346
-         * Pools are now permanent, so this does nothing.  Yes, this means we
e7a346
-         * can keep allocating from a pool after calling mem_destroy on it, but
e7a346
-         * that's kind of OK.  All of the objects *in* the pool will eventually
e7a346
-         * be freed via the pool-sweeper thread, and this way we don't have to
e7a346
-         * add a lot of reference-counting complexity.
e7a346
+         * Pools are now permanent, so the mem_pool->pool is kept around. All
e7a346
+         * of the objects *in* the pool will eventually be freed via the
e7a346
+         * pool-sweeper thread, and this way we don't have to add a lot of
e7a346
+         * reference-counting complexity.
e7a346
          */
e7a346
 }
e7a346
diff --git a/libglusterfs/src/mem-pool.h b/libglusterfs/src/mem-pool.h
e7a346
index dfe1f9a..057d957 100644
e7a346
--- a/libglusterfs/src/mem-pool.h
e7a346
+++ b/libglusterfs/src/mem-pool.h
e7a346
@@ -204,18 +204,31 @@ out:
e7a346
         return dup_mem;
e7a346
 }
e7a346
 
e7a346
+/* kind of 'header' for the actual mem_pool_shared structure, this might make
e7a346
+ * it possible to dump some more details in a statedump */
e7a346
+struct mem_pool {
e7a346
+        unsigned long           sizeof_type;
e7a346
+        unsigned long           count;
e7a346
+        char                    *name;
e7a346
+
e7a346
+        struct mem_pool_shared  *pool;
e7a346
+};
e7a346
+
e7a346
 typedef struct pooled_obj_hdr {
e7a346
         unsigned long                   magic;
e7a346
         struct pooled_obj_hdr           *next;
e7a346
         struct per_thread_pool_list     *pool_list;
e7a346
         unsigned int                    power_of_two;
e7a346
+
e7a346
+        /* track the pool that was used to request this object */
e7a346
+        struct mem_pool                 *pool;
e7a346
 } pooled_obj_hdr_t;
e7a346
 
e7a346
 #define AVAILABLE_SIZE(p2)      ((1 << (p2)) - sizeof(pooled_obj_hdr_t))
e7a346
 
e7a346
 typedef struct per_thread_pool {
e7a346
-        /* This never changes, so doesn't need a lock. */
e7a346
-        struct mem_pool         *parent;
e7a346
+        /* the pool that was used to request this allocation */
e7a346
+        struct mem_pool_shared         *parent;
e7a346
         /* Everything else is protected by our own lock. */
e7a346
         pooled_obj_hdr_t        *hot_list;
e7a346
         pooled_obj_hdr_t        *cold_list;
e7a346
@@ -243,7 +256,8 @@ typedef struct per_thread_pool_list {
e7a346
         per_thread_pool_t       pools[1];
e7a346
 } per_thread_pool_list_t;
e7a346
 
e7a346
-struct mem_pool {
e7a346
+/* actual pool structure, shared between different mem_pools */
e7a346
+struct mem_pool_shared {
e7a346
         unsigned int            power_of_two;
e7a346
         /*
e7a346
          * Updates to these are *not* protected by a global lock, so races
e7a346
diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h
e7a346
index 85cb5d2..64d0e90 100644
e7a346
--- a/libglusterfs/src/mem-types.h
e7a346
+++ b/libglusterfs/src/mem-types.h
e7a346
@@ -61,9 +61,7 @@ enum gf_common_mem_types_ {
e7a346
         gf_common_mt_char,
e7a346
         gf_common_mt_rbthash_table_t,
e7a346
         gf_common_mt_rbthash_bucket,
e7a346
-#if defined(GF_DISABLE_MEMPOOL)
e7a346
         gf_common_mt_mem_pool,
e7a346
-#endif
e7a346
         gf_common_mt_long,
e7a346
         gf_common_mt_rpcsvc_auth_list,
e7a346
         gf_common_mt_rpcsvc_t,
e7a346
-- 
e7a346
1.8.3.1
e7a346