diff options
Diffstat (limited to 'libglusterfs')
-rw-r--r-- | libglusterfs/src/Makefile.am | 11 | ||||
-rw-r--r-- | libglusterfs/src/client_t.c | 17 | ||||
-rw-r--r-- | libglusterfs/src/client_t.h | 17 | ||||
-rw-r--r-- | libglusterfs/src/mem-pool.c | 101 | ||||
-rw-r--r-- | libglusterfs/src/mem-pool.h | 30 | ||||
-rw-r--r-- | libglusterfs/src/options.c | 2 | ||||
-rw-r--r-- | libglusterfs/src/statedump.c | 38 | ||||
-rw-r--r-- | libglusterfs/src/unittest/mem_pool_unittest.c | 99 | ||||
-rw-r--r-- | libglusterfs/src/xlator.c | 42 | ||||
-rw-r--r-- | libglusterfs/src/xlator.h | 2 |
10 files changed, 189 insertions, 170 deletions
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am index e5f9f52f323..929923b0953 100644 --- a/libglusterfs/src/Makefile.am +++ b/libglusterfs/src/Makefile.am @@ -77,15 +77,4 @@ if UNITTEST CLEANFILES += *.gcda *.gcno *_xunit.xml noinst_PROGRAMS = TESTS = - -mem_pool_unittest_CPPFLAGS = $(libglusterfs_la_CPPFLAGS) -mem_pool_unittest_SOURCES = mem-pool.c \ - mem-pool.h \ - unittest/mem_pool_unittest.c \ - unittest/log_mock.c \ - unittest/global_mock.c -mem_pool_unittest_CFLAGS = $(UNITTEST_CFLAGS) -mem_pool_unittest_LDFLAGS = $(UNITTEST_LDFLAGS) -noinst_PROGRAMS += mem_pool_unittest -TESTS += mem_pool_unittest endif diff --git a/libglusterfs/src/client_t.c b/libglusterfs/src/client_t.c index 5b0fd87a9c1..84257e66b09 100644 --- a/libglusterfs/src/client_t.c +++ b/libglusterfs/src/client_t.c @@ -155,23 +155,6 @@ gf_client_clienttable_destroy (clienttable_t *clienttable) /* - * a more comprehensive feature test is shown at - * http://lists.iptel.org/pipermail/semsdev/2010-October/005075.html - * this is sufficient for RHEL5 i386 builds - */ -#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && !defined(__i386__) -# define INCREMENT_ATOMIC(lk,op) __sync_add_and_fetch(&op, 1) -# define DECREMENT_ATOMIC(lk,op) __sync_sub_and_fetch(&op, 1) -#else -/* These are only here for old gcc, e.g. on RHEL5 i386. - * We're not ever going to use this in an if stmt, - * but let's be pedantically correct for style points */ -# define INCREMENT_ATOMIC(lk,op) do { LOCK (&lk); ++op; UNLOCK (&lk); } while (0) -/* this is a gcc 'statement expression', it works with llvm/clang too */ -# define DECREMENT_ATOMIC(lk,op) ({ LOCK (&lk); --op; UNLOCK (&lk); op; }) -#endif - -/* * Increments ref.bind if the client is already present or creates a new * client with ref.bind = 1,ref.count = 1 it signifies that * as long as ref.bind is > 0 client should be alive. diff --git a/libglusterfs/src/client_t.h b/libglusterfs/src/client_t.h index 2accf0c6fc2..64c0514c8ac 100644 --- a/libglusterfs/src/client_t.h +++ b/libglusterfs/src/client_t.h @@ -78,6 +78,23 @@ typedef struct clienttable clienttable_t; struct rpcsvc_auth_data; +/* + * a more comprehensive feature test is shown at + * http://lists.iptel.org/pipermail/semsdev/2010-October/005075.html + * this is sufficient for RHEL5 i386 builds + */ +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && !defined(__i386__) +# define INCREMENT_ATOMIC(lk,op) __sync_add_and_fetch(&op, 1) +# define DECREMENT_ATOMIC(lk,op) __sync_sub_and_fetch(&op, 1) +#else +/* These are only here for old gcc, e.g. on RHEL5 i386. + * We're not ever going to use this in an if stmt, + * but let's be pedantically correct for style points */ +# define INCREMENT_ATOMIC(lk,op) do { LOCK (&lk); ++op; UNLOCK (&lk); } while (0) +/* this is a gcc 'statement expression', it works with llvm/clang too */ +# define DECREMENT_ATOMIC(lk,op) ({ LOCK (&lk); --op; UNLOCK (&lk); op; }) +#endif + client_t * gf_client_get (xlator_t *this, struct rpcsvc_auth_data *cred, char *client_uid); diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c index 0f9d792c0f1..7d95364c4b2 100644 --- a/libglusterfs/src/mem-pool.c +++ b/libglusterfs/src/mem-pool.c @@ -59,30 +59,32 @@ gf_mem_set_acct_info (xlator_t *xl, char **alloc_ptr, size_t size, GF_ASSERT (xl != NULL); - GF_ASSERT (xl->mem_acct.rec != NULL); + GF_ASSERT (xl->mem_acct != NULL); - GF_ASSERT (type <= xl->mem_acct.num_types); + GF_ASSERT (type <= xl->mem_acct->num_types); - LOCK(&xl->mem_acct.rec[type].lock); + LOCK(&xl->mem_acct->rec[type].lock); { - if (!xl->mem_acct.rec[type].typestr) - xl->mem_acct.rec[type].typestr = typestr; - xl->mem_acct.rec[type].size += size; - xl->mem_acct.rec[type].num_allocs++; - xl->mem_acct.rec[type].total_allocs++; - xl->mem_acct.rec[type].max_size = - max (xl->mem_acct.rec[type].max_size, - xl->mem_acct.rec[type].size); - xl->mem_acct.rec[type].max_num_allocs = - max (xl->mem_acct.rec[type].max_num_allocs, - xl->mem_acct.rec[type].num_allocs); + if (!xl->mem_acct->rec[type].typestr) + xl->mem_acct->rec[type].typestr = typestr; + xl->mem_acct->rec[type].size += size; + xl->mem_acct->rec[type].num_allocs++; + xl->mem_acct->rec[type].total_allocs++; + xl->mem_acct->rec[type].max_size = + max (xl->mem_acct->rec[type].max_size, + xl->mem_acct->rec[type].size); + xl->mem_acct->rec[type].max_num_allocs = + max (xl->mem_acct->rec[type].max_num_allocs, + xl->mem_acct->rec[type].num_allocs); } - UNLOCK(&xl->mem_acct.rec[type].lock); + UNLOCK(&xl->mem_acct->rec[type].lock); + + INCREMENT_ATOMIC (xl->mem_acct->lock, xl->mem_acct->refcnt); header = (struct mem_header *) ptr; header->type = type; header->size = size; - header->xlator = xl; + header->mem_acct = xl->mem_acct; header->magic = GF_MEM_HEADER_MAGIC; ptr += sizeof (struct mem_header); @@ -149,27 +151,23 @@ __gf_malloc (size_t size, uint32_t type, const char *typestr) void * __gf_realloc (void *ptr, size_t size) { - uint32_t type = 0; size_t tot_size = 0; - xlator_t *xl = NULL; char *new_ptr; - struct mem_header *header = NULL; + struct mem_header *old_header = NULL; + struct mem_header *new_header = NULL; + struct mem_header tmp_header; if (!THIS->ctx->mem_acct_enable) return REALLOC (ptr, size); REQUIRE(NULL != ptr); - tot_size = size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE; - - header = (struct mem_header *) (ptr - GF_MEM_HEADER_SIZE); - - GF_ASSERT (header->magic == GF_MEM_HEADER_MAGIC); + old_header = (struct mem_header *) (ptr - GF_MEM_HEADER_SIZE); + GF_ASSERT (old_header->magic == GF_MEM_HEADER_MAGIC); + tmp_header = *old_header; - xl = (xlator_t *) header->xlator; - type = header->type; - - new_ptr = realloc (header, tot_size); + tot_size = size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE; + new_ptr = realloc (old_header, tot_size); if (!new_ptr) { gf_msg_nomem ("", GF_LOG_ALERT, tot_size); return NULL; @@ -181,8 +179,25 @@ __gf_realloc (void *ptr, size_t size) * in ptr, but the compiler warnings complained * about the casting to and forth from void ** to * char **. - */ + * TBD: it would be nice to adjust the memory accounting info here, + * but calling gf_mem_set_acct_info here is wrong because it bumps + * up counts as though this is a new allocation - which it's not. + * The consequence of doing nothing here is only that the sizes will be + * wrong, but at least the counts won't be. + uint32_t type = 0; + xlator_t *xl = NULL; + type = header->type; + xl = (xlator_t *) header->xlator; gf_mem_set_acct_info (xl, &new_ptr, size, type, NULL); + */ + + new_header = (struct mem_header *) new_ptr; + *new_header = tmp_header; + new_header->size = size; + + new_ptr += sizeof (struct mem_header); + /* data follows in this gap of 'size' bytes */ + *(uint32_t *) (new_ptr + size) = GF_MEM_TRAILER_MAGIC; return (void *)new_ptr; } @@ -235,7 +250,7 @@ __gf_mem_invalidate (void *ptr) struct mem_invalid inval = { .magic = GF_MEM_INVALID_MAGIC, - .xlator = header->xlator, + .mem_acct = header->mem_acct, .type = header->type, .size = header->size, .baseaddr = ptr + GF_MEM_HEADER_SIZE, @@ -271,7 +286,7 @@ void __gf_free (void *free_ptr) { void *ptr = NULL; - xlator_t *xl = NULL; + struct mem_acct *mem_acct; struct mem_header *header = NULL; if (!THIS->ctx->mem_acct_enable) { @@ -288,11 +303,8 @@ __gf_free (void *free_ptr) //Possible corruption, assert here GF_ASSERT (GF_MEM_HEADER_MAGIC == header->magic); - //gf_free expects xl to be available - GF_ASSERT (header->xlator != NULL); - xl = header->xlator; - - if (!xl->mem_acct.rec) { + mem_acct = header->mem_acct; + if (!mem_acct) { goto free; } @@ -300,16 +312,21 @@ __gf_free (void *free_ptr) GF_ASSERT (GF_MEM_TRAILER_MAGIC == *(uint32_t *)((char *)free_ptr + header->size)); - LOCK (&xl->mem_acct.rec[header->type].lock); + LOCK (&mem_acct->rec[header->type].lock); { - xl->mem_acct.rec[header->type].size -= header->size; - xl->mem_acct.rec[header->type].num_allocs--; + mem_acct->rec[header->type].size -= header->size; + mem_acct->rec[header->type].num_allocs--; /* If all the instaces are freed up then ensure typestr is * set to NULL */ - if (!xl->mem_acct.rec[header->type].num_allocs) - xl->mem_acct.rec[header->type].typestr = NULL; + if (!mem_acct->rec[header->type].num_allocs) + mem_acct->rec[header->type].typestr = NULL; } - UNLOCK (&xl->mem_acct.rec[header->type].lock); + UNLOCK (&mem_acct->rec[header->type].lock); + + if (DECREMENT_ATOMIC (mem_acct->lock, mem_acct->refcnt) == 0) { + FREE (mem_acct); + } + free: #ifdef DEBUG __gf_mem_invalidate (ptr); 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 @@ #define GF_MEM_TRAILER_MAGIC 0xBAADF00D #define GF_MEM_INVALID_MAGIC 0xDEADC0DE -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; diff --git a/libglusterfs/src/options.c b/libglusterfs/src/options.c index 44f74a498c5..75dce0ea3b6 100644 --- a/libglusterfs/src/options.c +++ b/libglusterfs/src/options.c @@ -1019,7 +1019,7 @@ xlator_validate_rec (xlator_t *xlator, char **op_errstr) THIS = xlator; /* Need this here, as this graph has not yet called init() */ - if (!xlator->mem_acct.num_types) { + if (!xlator->mem_acct) { if (!xlator->mem_acct_init) xlator->mem_acct_init = default_mem_acct_init; xlator->mem_acct_init (xlator); diff --git a/libglusterfs/src/statedump.c b/libglusterfs/src/statedump.c index a13f6a5f4ac..3eebd2106f9 100644 --- a/libglusterfs/src/statedump.c +++ b/libglusterfs/src/statedump.c @@ -225,29 +225,29 @@ gf_proc_dump_xlator_mem_info (xlator_t *xl) if (!xl) return; - if (!xl->mem_acct.rec) + if (!xl->mem_acct) return; gf_proc_dump_add_section ("%s.%s - Memory usage", xl->type, xl->name); - gf_proc_dump_write ("num_types", "%d", xl->mem_acct.num_types); + gf_proc_dump_write ("num_types", "%d", xl->mem_acct->num_types); - for (i = 0; i < xl->mem_acct.num_types; i++) { - if (!(memcmp (&xl->mem_acct.rec[i], &rec, + for (i = 0; i < xl->mem_acct->num_types; i++) { + if (!(memcmp (&xl->mem_acct->rec[i], &rec, sizeof (struct mem_acct)))) continue; gf_proc_dump_add_section ("%s.%s - usage-type %s memusage", xl->type, xl->name, - xl->mem_acct.rec[i].typestr); - gf_proc_dump_write ("size", "%u", xl->mem_acct.rec[i].size); + xl->mem_acct->rec[i].typestr); + gf_proc_dump_write ("size", "%u", xl->mem_acct->rec[i].size); gf_proc_dump_write ("num_allocs", "%u", - xl->mem_acct.rec[i].num_allocs); + xl->mem_acct->rec[i].num_allocs); gf_proc_dump_write ("max_size", "%u", - xl->mem_acct.rec[i].max_size); + xl->mem_acct->rec[i].max_size); gf_proc_dump_write ("max_num_allocs", "%u", - xl->mem_acct.rec[i].max_num_allocs); + xl->mem_acct->rec[i].max_num_allocs); gf_proc_dump_write ("total_allocs", "%u", - xl->mem_acct.rec[i].total_allocs); + xl->mem_acct->rec[i].total_allocs); } return; @@ -261,29 +261,29 @@ gf_proc_dump_xlator_mem_info_only_in_use (xlator_t *xl) if (!xl) return; - if (!xl->mem_acct.rec) + if (!xl->mem_acct->rec) return; gf_proc_dump_add_section ("%s.%s - Memory usage", xl->type, xl->name); - gf_proc_dump_write ("num_types", "%d", xl->mem_acct.num_types); + gf_proc_dump_write ("num_types", "%d", xl->mem_acct->num_types); - for (i = 0; i < xl->mem_acct.num_types; i++) { - if (!xl->mem_acct.rec[i].size) + for (i = 0; i < xl->mem_acct->num_types; i++) { + if (!xl->mem_acct->rec[i].size) continue; gf_proc_dump_add_section ("%s.%s - usage-type %d", xl->type, xl->name,i); gf_proc_dump_write ("size", "%u", - xl->mem_acct.rec[i].size); + xl->mem_acct->rec[i].size); gf_proc_dump_write ("max_size", "%u", - xl->mem_acct.rec[i].max_size); + xl->mem_acct->rec[i].max_size); gf_proc_dump_write ("num_allocs", "%u", - xl->mem_acct.rec[i].num_allocs); + xl->mem_acct->rec[i].num_allocs); gf_proc_dump_write ("max_num_allocs", "%u", - xl->mem_acct.rec[i].max_num_allocs); + xl->mem_acct->rec[i].max_num_allocs); gf_proc_dump_write ("total_allocs", "%u", - xl->mem_acct.rec[i].total_allocs); + xl->mem_acct->rec[i].total_allocs); } return; diff --git a/libglusterfs/src/unittest/mem_pool_unittest.c b/libglusterfs/src/unittest/mem_pool_unittest.c index 906ebb0a7f3..00c7688637f 100644 --- a/libglusterfs/src/unittest/mem_pool_unittest.c +++ b/libglusterfs/src/unittest/mem_pool_unittest.c @@ -58,19 +58,20 @@ helper_xlator_init(uint32_t num_types) xl = test_calloc(1, sizeof(xlator_t)); assert_non_null(xl); - xl->mem_acct.num_types = num_types; - xl->mem_acct.rec = test_calloc(num_types, sizeof(struct mem_acct_rec)); - assert_non_null(xl->mem_acct.rec); + xl->mem_acct->num_types = num_types; + xl->mem_acct = test_calloc (sizeof(struct mem_acct) + + sizeof(struct mem_acct_rec) * num_types); + assert_non_null(xl->mem_acct); xl->ctx = test_calloc(1, sizeof(glusterfs_ctx_t)); assert_non_null(xl->ctx); for (i = 0; i < num_types; i++) { - ret = LOCK_INIT(&(xl->mem_acct.rec[i].lock)); + ret = LOCK_INIT(&(xl->mem_acct->rec[i].lock)); assert_int_equal(ret, 0); } - ENSURE(num_types == xl->mem_acct.num_types); + ENSURE(num_types == xl->mem_acct->num_types); ENSURE(NULL != xl); return xl; @@ -81,12 +82,12 @@ helper_xlator_destroy(xlator_t *xl) { int i, ret; - for (i = 0; i < xl->mem_acct.num_types; i++) { - ret = LOCK_DESTROY(&(xl->mem_acct.rec[i].lock)); + for (i = 0; i < xl->mem_acct->num_types; i++) { + ret = LOCK_DESTROY(&(xl->mem_acct->rec[i].lock)); assert_int_equal(ret, 0); } - free(xl->mem_acct.rec); + free(xl->mem_acct->rec); free(xl->ctx); free(xl); return 0; @@ -145,9 +146,9 @@ test_gf_mem_set_acct_info_asserts(void **state) // Check xl is NULL expect_assert_failure(gf_mem_set_acct_info(NULL, &alloc_ptr, size, type, "")); - // Check xl->mem_acct.rec = NULL + // Check xl->mem_acct = NULL expect_assert_failure(gf_mem_set_acct_info(&xltest, &alloc_ptr, 0, type, "")); - // Check type <= xl->mem_acct.num_types + // Check type <= xl->mem_acct->num_types type = 100; expect_assert_failure(gf_mem_set_acct_info(&xltest, &alloc_ptr, 0, type, "")); // Check alloc is NULL @@ -158,8 +159,8 @@ test_gf_mem_set_acct_info_asserts(void **state) // Test number of types type = 100; - assert_true(NULL != xl->mem_acct.rec); - assert_true(type > xl->mem_acct.num_types); + assert_true(NULL != xl->mem_acct); + assert_true(type > xl->mem_acct->num_types); expect_assert_failure(gf_mem_set_acct_info(xl, &alloc_ptr, size, type, "")); helper_xlator_destroy(xl); @@ -180,7 +181,7 @@ test_gf_mem_set_acct_info_memory(void **state) // Initialize xl xl = helper_xlator_init(10); - assert_null(xl->mem_acct.rec[type].typestr); + assert_null(xl->mem_acct->rec[type].typestr); // Test allocation temp_ptr = test_calloc(1, size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE); @@ -189,12 +190,12 @@ test_gf_mem_set_acct_info_memory(void **state) gf_mem_set_acct_info(xl, &alloc_ptr, size, type, typestr); //Check values - assert_ptr_equal(typestr, xl->mem_acct.rec[type].typestr); - assert_int_equal(xl->mem_acct.rec[type].size, size); - assert_int_equal(xl->mem_acct.rec[type].num_allocs, 1); - assert_int_equal(xl->mem_acct.rec[type].total_allocs, 1); - assert_int_equal(xl->mem_acct.rec[type].max_size, size); - assert_int_equal(xl->mem_acct.rec[type].max_num_allocs, 1); + assert_ptr_equal(typestr, xl->mem_acct->rec[type].typestr); + assert_int_equal(xl->mem_acct->rec[type].size, size); + assert_int_equal(xl->mem_acct->rec[type].num_allocs, 1); + assert_int_equal(xl->mem_acct->rec[type].total_allocs, 1); + assert_int_equal(xl->mem_acct->rec[type].max_size, size); + assert_int_equal(xl->mem_acct->rec[type].max_num_allocs, 1); // Check memory helper_check_memory_headers(temp_ptr, xl, size, type); @@ -235,11 +236,11 @@ test_gf_calloc_default_calloc(void **state) memset(mem, 0x5A, size); // Check xl did not change - assert_int_equal(xl->mem_acct.rec[type].size, 0); - assert_int_equal(xl->mem_acct.rec[type].num_allocs, 0); - assert_int_equal(xl->mem_acct.rec[type].total_allocs, 0); - assert_int_equal(xl->mem_acct.rec[type].max_size, 0); - assert_int_equal(xl->mem_acct.rec[type].max_num_allocs, 0); + assert_int_equal(xl->mem_acct->rec[type].size, 0); + assert_int_equal(xl->mem_acct->rec[type].num_allocs, 0); + assert_int_equal(xl->mem_acct->rec[type].total_allocs, 0); + assert_int_equal(xl->mem_acct->rec[type].max_size, 0); + assert_int_equal(xl->mem_acct->rec[type].max_num_allocs, 0); free(mem); helper_xlator_destroy(xl); @@ -269,11 +270,11 @@ test_gf_calloc_mem_acct_enabled(void **state) memset(mem, 0x5A, size); // Check xl values - assert_int_equal(xl->mem_acct.rec[type].size, size); - assert_int_equal(xl->mem_acct.rec[type].num_allocs, 1); - assert_int_equal(xl->mem_acct.rec[type].total_allocs, 1); - assert_int_equal(xl->mem_acct.rec[type].max_size, size); - assert_int_equal(xl->mem_acct.rec[type].max_num_allocs, 1); + assert_int_equal(xl->mem_acct->rec[type].size, size); + assert_int_equal(xl->mem_acct->rec[type].num_allocs, 1); + assert_int_equal(xl->mem_acct->rec[type].total_allocs, 1); + assert_int_equal(xl->mem_acct->rec[type].max_size, size); + assert_int_equal(xl->mem_acct->rec[type].max_num_allocs, 1); // Check memory helper_check_memory_headers(mem - sizeof(mem_header_t), xl, size, type); @@ -302,11 +303,11 @@ test_gf_malloc_default_malloc(void **state) memset(mem, 0x5A, size); // Check xl did not change - assert_int_equal(xl->mem_acct.rec[type].size, 0); - assert_int_equal(xl->mem_acct.rec[type].num_allocs, 0); - assert_int_equal(xl->mem_acct.rec[type].total_allocs, 0); - assert_int_equal(xl->mem_acct.rec[type].max_size, 0); - assert_int_equal(xl->mem_acct.rec[type].max_num_allocs, 0); + assert_int_equal(xl->mem_acct->rec[type].size, 0); + assert_int_equal(xl->mem_acct->rec[type].num_allocs, 0); + assert_int_equal(xl->mem_acct->rec[type].total_allocs, 0); + assert_int_equal(xl->mem_acct->rec[type].max_size, 0); + assert_int_equal(xl->mem_acct->rec[type].max_num_allocs, 0); free(mem); helper_xlator_destroy(xl); @@ -336,11 +337,11 @@ test_gf_malloc_mem_acct_enabled(void **state) memset(mem, 0x5A, size); // Check xl values - assert_int_equal(xl->mem_acct.rec[type].size, size); - assert_int_equal(xl->mem_acct.rec[type].num_allocs, 1); - assert_int_equal(xl->mem_acct.rec[type].total_allocs, 1); - assert_int_equal(xl->mem_acct.rec[type].max_size, size); - assert_int_equal(xl->mem_acct.rec[type].max_num_allocs, 1); + assert_int_equal(xl->mem_acct->rec[type].size, size); + assert_int_equal(xl->mem_acct->rec[type].num_allocs, 1); + assert_int_equal(xl->mem_acct->rec[type].total_allocs, 1); + assert_int_equal(xl->mem_acct->rec[type].max_size, size); + assert_int_equal(xl->mem_acct->rec[type].max_num_allocs, 1); // Check memory helper_check_memory_headers(mem - sizeof(mem_header_t), xl, size, type); @@ -374,11 +375,11 @@ test_gf_realloc_default_realloc(void **state) memset(mem, 0x5A, size); // Check xl did not change - assert_int_equal(xl->mem_acct.rec[type].size, 0); - assert_int_equal(xl->mem_acct.rec[type].num_allocs, 0); - assert_int_equal(xl->mem_acct.rec[type].total_allocs, 0); - assert_int_equal(xl->mem_acct.rec[type].max_size, 0); - assert_int_equal(xl->mem_acct.rec[type].max_num_allocs, 0); + assert_int_equal(xl->mem_acct->rec[type].size, 0); + assert_int_equal(xl->mem_acct->rec[type].num_allocs, 0); + assert_int_equal(xl->mem_acct->rec[type].total_allocs, 0); + assert_int_equal(xl->mem_acct->rec[type].max_size, 0); + assert_int_equal(xl->mem_acct->rec[type].max_num_allocs, 0); free(mem); helper_xlator_destroy(xl); @@ -419,11 +420,11 @@ test_gf_realloc_mem_acct_enabled(void **state) // not to the realloc + the malloc. // Is this a bug? // - assert_int_equal(xl->mem_acct.rec[type].size, size+1024); - assert_int_equal(xl->mem_acct.rec[type].num_allocs, 2); - assert_int_equal(xl->mem_acct.rec[type].total_allocs, 2); - assert_int_equal(xl->mem_acct.rec[type].max_size, size+1024); - assert_int_equal(xl->mem_acct.rec[type].max_num_allocs, 2); + assert_int_equal(xl->mem_acct->rec[type].size, size+1024); + assert_int_equal(xl->mem_acct->rec[type].num_allocs, 2); + assert_int_equal(xl->mem_acct->rec[type].total_allocs, 2); + assert_int_equal(xl->mem_acct->rec[type].max_size, size+1024); + assert_int_equal(xl->mem_acct->rec[type].max_num_allocs, 2); // Check memory helper_check_memory_headers(mem - sizeof(mem_header_t), xl, size, type); diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index c670ee97aee..628f3499956 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -509,16 +509,22 @@ xlator_mem_acct_init (xlator_t *xl, int num_types) if (!xl->ctx->mem_acct_enable) return 0; - xl->mem_acct.num_types = num_types; - xl->mem_acct.rec = CALLOC(num_types, sizeof(struct mem_acct_rec)); + xl->mem_acct = MALLOC (sizeof(struct mem_acct) + + sizeof(struct mem_acct_rec) * num_types); - if (!xl->mem_acct.rec) { + if (!xl->mem_acct) { return -1; } + memset (xl->mem_acct, 0, sizeof(struct mem_acct)); + + xl->mem_acct->num_types = num_types; + LOCK_INIT (&xl->mem_acct->lock); + xl->mem_acct->refcnt = 1; for (i = 0; i < num_types; i++) { - ret = LOCK_INIT(&(xl->mem_acct.rec[i].lock)); + memset (&xl->mem_acct->rec[i], 0, sizeof(struct mem_acct_rec)); + ret = LOCK_INIT(&(xl->mem_acct->rec[i].lock)); if (ret) { fprintf(stderr, "Unable to lock..errno : %d",errno); } @@ -559,17 +565,22 @@ xlator_list_destroy (xlator_list_t *list) static int xlator_memrec_free (xlator_t *xl) { - uint32_t i = 0; + uint32_t i = 0; + struct mem_acct *mem_acct = NULL; - if (!xl) + if (!xl) { return 0; + } + mem_acct = xl->mem_acct; - if (xl->mem_acct.rec) { - for (i = 0; i < xl->mem_acct.num_types; i++) { - LOCK_DESTROY (&(xl->mem_acct.rec[i].lock)); + if (mem_acct) { + for (i = 0; i < mem_acct->num_types; i++) { + LOCK_DESTROY (&(mem_acct->rec[i].lock)); + } + if (DECREMENT_ATOMIC (mem_acct->lock, mem_acct->refcnt) == 0) { + FREE (mem_acct); + xl->mem_acct = NULL; } - FREE (xl->mem_acct.rec); - xl->mem_acct.rec = NULL; } return 0; @@ -653,7 +664,6 @@ xlator_tree_free_memacct (xlator_t *tree) { xlator_t *trav = tree; xlator_t *prev = tree; - int i = 0; if (!tree) { gf_log ("parser", GF_LOG_ERROR, "Translator tree not found"); @@ -662,13 +672,7 @@ xlator_tree_free_memacct (xlator_t *tree) while (prev) { trav = prev->next; - if (prev->mem_acct.rec) { - for (i = 0; i < prev->mem_acct.num_types; i++) { - LOCK_DESTROY (&(prev->mem_acct.rec[i].lock)); - } - FREE (prev->mem_acct.rec); - } - GF_FREE (prev); + xlator_memrec_free (prev); prev = trav; } diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index a238913d03b..ca30f99650e 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -889,7 +889,7 @@ struct _xlator { inode_table_t *itable; char init_succeeded; void *private; - struct mem_acct mem_acct; + struct mem_acct *mem_acct; uint64_t winds; char switched; |