path: root/libglusterfs/src/mem-pool.h
diff options
authorJeff Darcy <>2015-04-28 04:40:00 -0400
committerNiels de Vos <>2015-05-09 14:27:36 -0700
commita3af10a801a40fe990ee5db63c6dd6cb97713e4c (patch)
tree937a8588aeea9465fa56da53950664efb2b34bf1 /libglusterfs/src/mem-pool.h
parentec055e1e6908ac829efc103deb548cc0a774cf23 (diff)
core: use reference counting for mem_acct structures
When freeing memory, our memory-accounting code expects to be able to dereference from the (previously) allocated block to its owning translator. However, as we have already found once in option validation and twice in logging, that translator might itself have been freed and the dereference attempt causes on of our daemons to crash with SIGSEGV. This patch attempts to fix that as follows: * We no longer embed a struct mem_acct directly in a struct xlator, but instead allocate it separately. * Allocated memory blocks now contain a pointer to the mem_acct instead of the xlator. * The mem_acct structure contains a reference count, manipulated in both the normal and translator allocate/free code using atomic increments and decrements. * Because it's now a separate structure, we can defer freeing the mem_acct until its reference count reaches zero (either way). * Some unit tests were disabled, because they embedded their own copies of the implementation for what they were supposedly testing. Life's too short to spend time fixing tests that seem designed to impede progress by requiring a certain implementation as well as behavior. Change-Id: Id929b11387927136f78626901729296b6c0d0fd7 BUG: 1219026 Signed-off-by: Jeff Darcy <> Reviewed-on: Tested-by: Gluster Build System <> Reviewed-by: Krishnan Parthasarathi <> Reviewed-by: Niels de Vos <> Reviewed-by: Pranith Kumar Karampuri <> Reviewed-on: Tested-by: NetBSD Build System
Diffstat (limited to 'libglusterfs/src/mem-pool.h')
1 files changed, 19 insertions, 11 deletions
diff --git a/libglusterfs/src/mem-pool.h b/libglusterfs/src/mem-pool.h
index 81fb579a0ab..5115cef9f93 100644
--- a/libglusterfs/src/mem-pool.h
+++ b/libglusterfs/src/mem-pool.h
@@ -36,11 +36,6 @@
-struct mem_acct {
- uint32_t num_types;
- struct mem_acct_rec *rec;
struct mem_acct_rec {
const char *typestr;
size_t size;
@@ -51,12 +46,25 @@ struct mem_acct_rec {
gf_lock_t lock;
+struct mem_acct {
+ uint32_t num_types;
+ /*
+ * The lock is only used on ancient platforms (e.g. RHEL5) to keep
+ * refcnt increment/decrement atomic. We could even make its existence
+ * conditional on the right set of version/feature checks, but it's so
+ * lightweight that it's not worth the obfuscation.
+ */
+ gf_lock_t lock;
+ unsigned int refcnt;
+ struct mem_acct_rec rec[0];
struct mem_header {
- uint32_t type;
- size_t size;
- void *xlator;
- uint32_t magic;
- int padding[8];
+ uint32_t type;
+ size_t size;
+ struct mem_acct *mem_acct;
+ uint32_t magic;
+ int padding[8];
#define GF_MEM_HEADER_SIZE (sizeof (struct mem_header))
@@ -64,7 +72,7 @@ struct mem_header {
#ifdef DEBUG
struct mem_invalid {
uint32_t magic;
- void *xlator;
+ void *mem_acct;
uint32_t type;
size_t size;
void *baseaddr;