From c6742adc98a9747f5e16c242aaddc28ea991ec5a Mon Sep 17 00:00:00 2001 From: Pranith Kumar K Date: Tue, 30 Jun 2015 23:01:36 +0530 Subject: cluster/ec: Make background healing optional behavior Provide options to control number of active background heal count and qlen. Change-Id: Idc2419219d881f47e7d2e9bbc1dcdd999b372033 BUG: 1237381 Signed-off-by: Pranith Kumar K Reviewed-on: http://review.gluster.org/11473 Reviewed-by: Xavier Hernandez Tested-by: Gluster Build System --- xlators/cluster/ec/src/ec-heal.c | 14 +++++------ xlators/cluster/ec/src/ec.c | 50 +++++++++++++++++++++++++++++++++++++--- xlators/cluster/ec/src/ec.h | 2 ++ 3 files changed, 55 insertions(+), 11 deletions(-) (limited to 'xlators/cluster/ec') diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c index 31685356db0..6ee1f9ee832 100644 --- a/xlators/cluster/ec/src/ec-heal.c +++ b/xlators/cluster/ec/src/ec-heal.c @@ -26,9 +26,6 @@ #include "syncop-utils.h" #include "cluster-syncop.h" -#define EC_MAX_BACKGROUND_HEALS 8 -#define EC_MAX_HEAL_WAITERS 128 - #define alloca0(size) ({void *__ptr; __ptr = alloca(size); memset(__ptr, 0, size); __ptr; }) #define EC_COUNT(array, max) ({int __i; int __res = 0; for (__i = 0; __i < max; __i++) if (array[__i]) __res++; __res; }) #define EC_INTERSECT(dst, src1, src2, max) ({int __i; for (__i = 0; __i < max; __i++) dst[__i] = src1[__i] && src2[__i]; }) @@ -2329,10 +2326,9 @@ __ec_dequeue_heals (ec_t *ec) if (list_empty (&ec->heal_waiting)) goto none; - if (ec->healers == EC_MAX_BACKGROUND_HEALS) + if ((ec->background_heals > 0) && (ec->healers >= ec->background_heals)) goto none; - GF_ASSERT (ec->healers < EC_MAX_BACKGROUND_HEALS); fop = list_entry(ec->heal_waiting.next, ec_fop_data_t, healer); ec->heal_waiters--; list_del_init(&fop->healer); @@ -2400,12 +2396,14 @@ ec_heal_throttle (xlator_t *this, ec_fop_data_t *fop) LOCK (&ec->lock); { - if (ec->heal_waiters >= EC_MAX_HEAL_WAITERS) { - can_heal = _gf_false; - } else { + if ((ec->background_heals > 0) && + (ec->heal_wait_qlen + ec->background_heals) > + (ec->heal_waiters + ec->healers)) { list_add_tail(&fop->healer, &ec->heal_waiting); ec->heal_waiters++; fop = __ec_dequeue_heals (ec); + } else { + can_heal = _gf_false; } } UNLOCK (&ec->lock); diff --git a/xlators/cluster/ec/src/ec.c b/xlators/cluster/ec/src/ec.c index dd51630ea79..e28f402e6fe 100644 --- a/xlators/cluster/ec/src/ec.c +++ b/xlators/cluster/ec/src/ec.c @@ -219,15 +219,35 @@ int32_t mem_acct_init(xlator_t * this) return 0; } +void +ec_configure_background_heal_opts (ec_t *ec, int background_heals, + int heal_wait_qlen) +{ + if (background_heals == 0) { + ec->heal_wait_qlen = 0; + } else { + ec->heal_wait_qlen = heal_wait_qlen; + } + ec->background_heals = background_heals; +} + int32_t reconfigure (xlator_t *this, dict_t *options) { - ec_t *ec = this->private; + ec_t *ec = this->private; + uint32_t heal_wait_qlen = 0; + uint32_t background_heals = 0; - GF_OPTION_RECONF ("self-heal-daemon", ec->shd.enabled, options, bool, failed); + GF_OPTION_RECONF ("self-heal-daemon", ec->shd.enabled, options, bool, + failed); GF_OPTION_RECONF ("iam-self-heal-daemon", ec->shd.iamshd, options, bool, failed); - + GF_OPTION_RECONF ("background-heals", background_heals, options, + uint32, failed); + GF_OPTION_RECONF ("heal-wait-qlength", heal_wait_qlen, options, + uint32, failed); + ec_configure_background_heal_opts (ec, background_heals, + heal_wait_qlen); return 0; failed: return -1; @@ -577,6 +597,10 @@ init (xlator_t *this) ec_method_initialize(); GF_OPTION_INIT ("self-heal-daemon", ec->shd.enabled, bool, failed); GF_OPTION_INIT ("iam-self-heal-daemon", ec->shd.iamshd, bool, failed); + GF_OPTION_INIT ("background-heals", ec->background_heals, uint32, failed); + GF_OPTION_INIT ("heal-wait-qlength", ec->heal_wait_qlen, uint32, failed); + ec_configure_background_heal_opts (ec, ec->background_heals, + ec->heal_wait_qlen); if (ec->shd.iamshd) ec_selfheal_daemon_init (this); @@ -1188,6 +1212,10 @@ int32_t ec_dump_private(xlator_t *this) gf_proc_dump_write("childs_up", "%u", ec->xl_up_count); gf_proc_dump_write("childs_up_mask", "%s", ec_bin(tmp, sizeof(tmp), ec->xl_up, ec->nodes)); + gf_proc_dump_write("background-heals", "%d", ec->background_heals); + gf_proc_dump_write("heal-wait-qlength", "%d", ec->heal_wait_qlen); + gf_proc_dump_write("healers", "%d", ec->healers); + gf_proc_dump_write("heal-waiters", "%d", ec->heal_waiters); return 0; } @@ -1271,5 +1299,21 @@ struct volume_options options[] = "translator is running as part of self-heal-daemon " "or not." }, + { .key = {"background-heals"}, + .type = GF_OPTION_TYPE_INT, + .min = 0,/*Disabling background heals*/ + .max = 256, + .default_value = "8", + .description = "This option can be used to control number of parallel" + " heals", + }, + { .key = {"heal-wait-qlength"}, + .type = GF_OPTION_TYPE_INT, + .min = 0, + .max = 65536, /*Around 100MB as of now with sizeof(ec_fop_data_t) at 1800*/ + .default_value = "128", + .description = "This option can be used to control number of heals" + " that can wait", + }, { } }; diff --git a/xlators/cluster/ec/src/ec.h b/xlators/cluster/ec/src/ec.h index 7f140204ece..f335fd52afc 100644 --- a/xlators/cluster/ec/src/ec.h +++ b/xlators/cluster/ec/src/ec.h @@ -47,6 +47,8 @@ struct _ec gf_lock_t lock; gf_timer_t * timer; gf_boolean_t shutdown; + uint32_t background_heals; + uint32_t heal_wait_qlen; struct list_head pending_fops; struct list_head heal_waiting; struct list_head healing; -- cgit