3604df
From 162ac9b69e9df8708cf6c3ac70704e05264429c4 Mon Sep 17 00:00:00 2001
3604df
From: Pranith Kumar K <pkarampu@redhat.com>
3604df
Date: Sun, 9 Oct 2016 21:36:40 +0530
3604df
Subject: [PATCH 138/141] performance/io-threads: Exit all threads on PARENT_DOWN
3604df
3604df
Problem:
3604df
When glfs_fini() is called on a volume where client.io-threads is enabled,
3604df
fini() will free up iothread xl's private structure but there would be some
3604df
threads that are sleeping which would wakeup after the timedwait completes
3604df
leading to accessing already free'd memory.
3604df
3604df
Fix:
3604df
As part of parent-down, exit all sleeping threads.
3604df
3604df
Please note that the upstream patch differs from this a little bit,
3604df
because least-prio-throttling feature is removed from master, 3.9
3604df
3604df
 >BUG: 1381830
3604df
 >Change-Id: I0bb8d90241112c355fb22ee3fbfd7307f475b339
3604df
 >Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
3604df
 >Reviewed-on: http://review.gluster.org/15620
3604df
 >Smoke: Gluster Build System <jenkins@build.gluster.org>
3604df
 >CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
3604df
 >NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
3604df
 >Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
3604df
 >(cherry picked from commit d7a5ca16911caca03cec1112d4be56a9cda2ee30)
3604df
3604df
BUG: 1380619
3604df
Change-Id: I450e5db84c83fae3237aaa7915c08cd3ee9bde2c
3604df
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
3604df
Reviewed-on: https://code.engineering.redhat.com/gerrit/87972
3604df
Reviewed-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
3604df
Tested-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
3604df
---
3604df
 xlators/performance/io-threads/src/io-threads.c |   71 +++++++++++++++-------
3604df
 xlators/performance/io-threads/src/io-threads.h |    1 +
3604df
 2 files changed, 49 insertions(+), 23 deletions(-)
3604df
3604df
diff --git a/xlators/performance/io-threads/src/io-threads.c b/xlators/performance/io-threads/src/io-threads.c
3604df
index c81a97d..394be8a 100644
3604df
--- a/xlators/performance/io-threads/src/io-threads.c
3604df
+++ b/xlators/performance/io-threads/src/io-threads.c
3604df
@@ -153,9 +153,8 @@ iot_worker (void *data)
3604df
         struct timespec   sleep_till = {0, };
3604df
         int               ret = 0;
3604df
         int               pri = -1;
3604df
-        char              timeout = 0;
3604df
-        char              bye = 0;
3604df
 	struct timespec	  sleep = {0,};
3604df
+        gf_boolean_t      bye = _gf_false;
3604df
 
3604df
         conf = data;
3604df
         this = conf->this;
3604df
@@ -171,6 +170,11 @@ iot_worker (void *data)
3604df
                                 pri = -1;
3604df
                         }
3604df
                         while (conf->queue_size == 0) {
3604df
+                                if (conf->down) {
3604df
+                                        bye = _gf_true;/*Avoid sleep*/
3604df
+                                        break;
3604df
+                                }
3604df
+
3604df
                                 conf->sleep_count++;
3604df
 
3604df
                                 ret = pthread_cond_timedwait (&conf->cond,
3604df
@@ -178,48 +182,48 @@ iot_worker (void *data)
3604df
                                                               &sleep_till);
3604df
                                 conf->sleep_count--;
3604df
 
3604df
-                                if (ret == ETIMEDOUT) {
3604df
-                                        timeout = 1;
3604df
+                                if (conf->down || ret == ETIMEDOUT) {
3604df
+                                        bye = _gf_true;
3604df
                                         break;
3604df
                                 }
3604df
                         }
3604df
 
3604df
-                        if (timeout) {
3604df
-                                if (conf->curr_count > IOT_MIN_THREADS) {
3604df
+                        if (bye) {
3604df
+                                if (conf->down ||
3604df
+                                    conf->curr_count > IOT_MIN_THREADS) {
3604df
                                         conf->curr_count--;
3604df
-                                        bye = 1;
3604df
+                                        if (conf->curr_count == 0)
3604df
+                                           pthread_cond_broadcast (&conf->cond);
3604df
                                         gf_msg_debug (conf->this->name, 0,
3604df
-                                                      "timeout, terminated. conf->curr_count=%d",
3604df
+                                                      "terminated. "
3604df
+                                                      "conf->curr_count=%d",
3604df
                                                       conf->curr_count);
3604df
                                 } else {
3604df
-                                        timeout = 0;
3604df
+                                        bye = _gf_false;
3604df
                                 }
3604df
                         }
3604df
 
3604df
-                        stub = __iot_dequeue (conf, &pri, &sleep);
3604df
-			if (!stub && (sleep.tv_sec || sleep.tv_nsec)) {
3604df
-				pthread_cond_timedwait(&conf->cond,
3604df
-						       &conf->mutex, &sleep);
3604df
-				pthread_mutex_unlock(&conf->mutex);
3604df
-				continue;
3604df
-			}
3604df
+                        if (!bye) {
3604df
+                                stub = __iot_dequeue (conf, &pri, &sleep);
3604df
+                                if (!stub && (sleep.tv_sec || sleep.tv_nsec)) {
3604df
+                                        pthread_cond_timedwait(&conf->cond,
3604df
+                                                               &conf->mutex,
3604df
+                                                               &sleep);
3604df
+                                        pthread_mutex_unlock(&conf->mutex);
3604df
+                                        continue;
3604df
+                                }
3604df
+                        }
3604df
                 }
3604df
                 pthread_mutex_unlock (&conf->mutex);
3604df
 
3604df
                 if (stub) /* guard against spurious wakeups */
3604df
                         call_resume (stub);
3604df
+                stub = NULL;
3604df
 
3604df
                 if (bye)
3604df
                         break;
3604df
         }
3604df
 
3604df
-        if (pri != -1) {
3604df
-                pthread_mutex_lock (&conf->mutex);
3604df
-                {
3604df
-                        conf->ac_iot_count[pri]--;
3604df
-                }
3604df
-                pthread_mutex_unlock (&conf->mutex);
3604df
-        }
3604df
         return NULL;
3604df
 }
3604df
 
3604df
@@ -1021,6 +1025,27 @@ out:
3604df
 	return ret;
3604df
 }
3604df
 
3604df
+int
3604df
+notify (xlator_t *this, int32_t event, void *data, ...)
3604df
+{
3604df
+        iot_conf_t *conf = this->private;
3604df
+
3604df
+        if (GF_EVENT_PARENT_DOWN == event) {
3604df
+                pthread_mutex_lock (&conf->mutex);
3604df
+                {
3604df
+                        conf->down = _gf_true;
3604df
+                        /*Let all the threads know that xl is going down*/
3604df
+                        pthread_cond_broadcast (&conf->cond);
3604df
+                        while (conf->curr_count)/*Wait for threads to exit*/
3604df
+                                pthread_cond_wait (&conf->cond, &conf->mutex);
3604df
+                }
3604df
+                pthread_mutex_unlock (&conf->mutex);
3604df
+        }
3604df
+
3604df
+        default_notify (this, event, data);
3604df
+
3604df
+        return 0;
3604df
+}
3604df
 
3604df
 void
3604df
 fini (xlator_t *this)
3604df
diff --git a/xlators/performance/io-threads/src/io-threads.h b/xlators/performance/io-threads/src/io-threads.h
3604df
index d8eea2c..cb984f0 100644
3604df
--- a/xlators/performance/io-threads/src/io-threads.h
3604df
+++ b/xlators/performance/io-threads/src/io-threads.h
3604df
@@ -79,6 +79,7 @@ struct iot_conf {
3604df
         xlator_t            *this;
3604df
         size_t              stack_size;
3604df
 
3604df
+        gf_boolean_t         down; /*PARENT_DOWN event is notified*/
3604df
 	struct iot_least_throttle throttle;
3604df
 };
3604df
 
3604df
-- 
3604df
1.7.1
3604df