From ce8a569e9f18cfff2f2befe259c2022d9b37538f Mon Sep 17 00:00:00 2001 From: Kaushal M Date: Wed, 14 Sep 2011 09:50:45 +0530 Subject: performance/io-cache,quick-read: increase cache-size limit Does the following: 1. Increases cache-size limit from 6GB to 32GB. 2. Prevents 'volume set'from failing when cache-size is set over the limit. Just issues a warning. 3. Performs check on cache-size by comparing with total system memory available in init () and reconfigure () methods. Change-Id: I7dd4d8c53051b89a293696abf1ee8dc237e39a20 BUG: 3495 Reviewed-on: http://review.gluster.com/409 Tested-by: Gluster Build System Reviewed-by: Amar Tumballi Reviewed-by: Vijay Bellur --- libglusterfs/src/common-utils.c | 31 +++++++++++++ libglusterfs/src/common-utils.h | 2 + libglusterfs/src/options.c | 22 ++++++--- xlators/performance/io-cache/src/io-cache.c | 59 ++++++++++++++++++++++--- xlators/performance/quick-read/src/quick-read.c | 58 +++++++++++++++++++++--- 5 files changed, 155 insertions(+), 17 deletions(-) diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index b2e91608b..2d4415f50 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -1896,3 +1896,34 @@ gf_path_strip_trailing_slashes (char *path) return; } + +uint64_t +get_mem_size () +{ + uint64_t memsize = -1; + +#ifdef __linux__ + FILE *fp = NULL; + char line[1028] = {0,}; + + fp = fopen ("/proc/meminfo", "r"); + if (!fp) { + gf_log ("common-utils", GF_LOG_DEBUG, + "Could not open /proc/meminfo"); + return memsize; + } + + while (fgets (line, sizeof (line), fp) != 0) { + if (strncmp (line, "MemTotal:", 9) == 0) { + sscanf (line, "%*s %"SCNu64" kB", &memsize); + memsize *= 1024; //convert to bytes + gf_log ("common-utils", GF_LOG_INFO, + "Total Mem: %"PRIu64, memsize); + break; + } + } +#endif + // TODO: Methods for other platforms + + return memsize; +} diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index 82e499b39..2a5e00c5e 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -50,6 +50,7 @@ void trap (void); #include "uuid.h" + #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) #define roof(a,b) ((((a)+(b)-1)/((b)?(b):1))*(b)) @@ -399,4 +400,5 @@ int validate_brick_name (char *brick); char *get_host_name (char *word, char **host); char *get_path_name (char *word, char **path); void gf_path_strip_trailing_slashes (char *path); +uint64_t get_mem_size (); #endif /* _COMMON_UTILS_H */ diff --git a/libglusterfs/src/options.c b/libglusterfs/src/options.c index b64b24e04..1e6413cc0 100644 --- a/libglusterfs/src/options.c +++ b/libglusterfs/src/options.c @@ -131,12 +131,22 @@ xlator_option_validate_sizet (xlator_t *xl, const char *key, const char *value, } if ((size < opt->min) || (size > opt->max)) { - snprintf (errstr, 256, - "'%"PRId64"' in 'option %s %s' is out of range " - "[%"PRId64" - %"PRId64"]", - size, key, value, opt->min, opt->max); - gf_log (xl->name, GF_LOG_ERROR, "%s", errstr); - goto out; + if (strncmp (key, "cache-size", 10) == 0) { + snprintf (errstr, 256, "Cache size %"PRId64" is out of " + "range [%"PRId64" - %"PRId64"]", + size, opt->min, opt->max); + //*op_errstr = gf_strdup (errstr); + gf_log (xl->name, GF_LOG_WARNING, "%s", errstr); + ret = 0; + goto out; + } else { + snprintf (errstr, 256, + "'%"PRId64"' in 'option %s %s' " + "is out of range [%"PRId64" - %"PRId64"]", + size, key, value, opt->min, opt->max); + gf_log (xl->name, GF_LOG_ERROR, "%s", errstr); + goto out; + } } ret = 0; diff --git a/xlators/performance/io-cache/src/io-cache.c b/xlators/performance/io-cache/src/io-cache.c index 90c14ea7d..375004c93 100644 --- a/xlators/performance/io-cache/src/io-cache.c +++ b/xlators/performance/io-cache/src/io-cache.c @@ -1514,13 +1514,50 @@ mem_acct_init (xlator_t *this) } +gf_boolean_t +check_cache_size_ok (xlator_t *this, uint64_t cache_size) +{ + gf_boolean_t ret = _gf_true; + uint64_t total_mem = 0; + uint64_t max_cache_size = 0; + volume_option_t *opt = NULL; + + GF_ASSERT (this); + opt = xlator_volume_option_get (this, "cache-size"); + if (!opt) { + ret = _gf_false; + gf_log (this->name, GF_LOG_ERROR, + "could not get cache-size option"); + goto out; + } + + total_mem = get_mem_size (); + if (-1 == total_mem) + max_cache_size = opt->max; + else + max_cache_size = total_mem; + + gf_log (this->name, GF_LOG_INFO, "Max cache size is %"PRIu64, + max_cache_size); + + if (cache_size > max_cache_size) { + ret = _gf_false; + gf_log (this->name, GF_LOG_ERROR, "Cache size %"PRIu64 + " is greater than the max size of %"PRIu64, + cache_size, max_cache_size); + goto out; + } +out: + return ret; +} + int reconfigure (xlator_t *this, dict_t *options) { data_t *data = NULL; ioc_table_t *table = NULL; int ret = -1; - + uint64_t cache_size_new = 0; if (!this || !this->private) goto out; @@ -1531,9 +1568,6 @@ reconfigure (xlator_t *this, dict_t *options) GF_OPTION_RECONF ("cache-timeout", table->cache_timeout, options, int32, unlock); - GF_OPTION_RECONF ("cache-size", table->cache_size, - options, size, unlock); - data = dict_get (options, "priority"); if (data) { char *option_list = data_to_str (data); @@ -1566,6 +1600,16 @@ reconfigure (xlator_t *this, dict_t *options) goto unlock; } + GF_OPTION_RECONF ("cache-size", cache_size_new, + options, size, unlock); + if (!check_cache_size_ok (this, cache_size_new)) { + ret = -1; + gf_log (this->name, GF_LOG_ERROR, + "Not reconfiguring cache-size"); + goto unlock; + } + table->cache_size = cache_size_new; + ret = 0; } unlock: @@ -1621,6 +1665,11 @@ init (xlator_t *this) GF_OPTION_INIT ("max-file-size", table->max_file_size, size, out); + if (!check_cache_size_ok (this, table->cache_size)) { + ret = -1; + goto out; + } + INIT_LIST_HEAD (&table->priority_list); table->max_pri = 1; data = dict_get (xl_options, "priority"); @@ -1921,7 +1970,7 @@ struct volume_options options[] = { { .key = {"cache-size"}, .type = GF_OPTION_TYPE_SIZET, .min = 4 * GF_UNIT_MB, - .max = 6 * GF_UNIT_GB, + .max = 32 * GF_UNIT_GB, .default_value = "32MB", .description = "Size of the read cache." }, diff --git a/xlators/performance/quick-read/src/quick-read.c b/xlators/performance/quick-read/src/quick-read.c index b5a6161d2..287ce5afc 100644 --- a/xlators/performance/quick-read/src/quick-read.c +++ b/xlators/performance/quick-read/src/quick-read.c @@ -3401,14 +3401,49 @@ mem_acct_init (xlator_t *this) return ret; } +gf_boolean_t +check_cache_size_ok (xlator_t *this, int64_t cache_size) +{ + int ret = _gf_true; + uint64_t total_mem = 0; + uint64_t max_cache_size = 0; + volume_option_t *opt = NULL; + + GF_ASSERT (this); + opt = xlator_volume_option_get (this, "cache-size"); + if (!opt) { + ret = _gf_false; + gf_log (this->name, GF_LOG_ERROR, + "could not get cache-size option"); + goto out; + } + + total_mem = get_mem_size (); + if (-1 == total_mem) + max_cache_size = opt->max; + else + max_cache_size = total_mem; + + gf_log (this->name, GF_LOG_INFO, "Max cache size is %"PRIu64, + max_cache_size); + if (cache_size > max_cache_size) { + ret = _gf_false; + gf_log (this->name, GF_LOG_ERROR, "Cache size %"PRIu64 + " is greater than the max size of %"PRIu64, + cache_size, max_cache_size); + goto out; + } +out: + return ret; +} int reconfigure (xlator_t *this, dict_t *options) { - int32_t ret = -1; - qr_private_t *priv = NULL; - qr_conf_t *conf = NULL; - + int32_t ret = -1; + qr_private_t *priv = NULL; + qr_conf_t *conf = NULL; + uint64_t cache_size_new = 0; GF_VALIDATE_OR_GOTO ("quick-read", this, out); GF_VALIDATE_OR_GOTO (this->name, this->private, out); GF_VALIDATE_OR_GOTO (this->name, options, out); @@ -3423,7 +3458,14 @@ reconfigure (xlator_t *this, dict_t *options) GF_OPTION_RECONF ("cache-timeout", conf->cache_timeout, options, int32, out); - GF_OPTION_RECONF ("cache-size", conf->cache_size, options, size, out); + GF_OPTION_RECONF ("cache-size", cache_size_new, options, size, out); + if (!check_cache_size_ok (this, cache_size_new)) { + ret = -1; + gf_log (this->name, GF_LOG_ERROR, + "Not reconfiguring cache-size"); + goto out; + } + conf->cache_size = cache_size_new; ret = 0; out: @@ -3566,6 +3608,10 @@ init (xlator_t *this) GF_OPTION_INIT ("cache-timeout", conf->cache_timeout, int32, out); GF_OPTION_INIT ("cache-size", conf->cache_size, size, out); + if (!check_cache_size_ok (this, conf->cache_size)) { + ret = -1; + goto out; + } INIT_LIST_HEAD (&conf->priority_list); conf->max_pri = 1; @@ -3648,7 +3694,7 @@ struct volume_options options[] = { { .key = {"cache-size"}, .type = GF_OPTION_TYPE_SIZET, .min = 0, - .max = 6 * GF_UNIT_GB, + .max = 32 * GF_UNIT_GB, .default_value = "128MB", .description = "Size of the read cache." }, -- cgit