887953
From 3de9cc04cdf5a65825cc86c8239734a284775470 Mon Sep 17 00:00:00 2001
887953
From: Raghavendra G <rgowdapp@redhat.com>
887953
Date: Wed, 6 Feb 2019 17:30:30 +0530
887953
Subject: [PATCH 524/529] program/GF-DUMP: Shield ping processing from traffic
887953
 to Glusterfs Program
887953
887953
Since poller thread bears the brunt of execution till the request is
887953
handed over to io-threads, poller thread experiencies lock
887953
contention(s) in the control flow till io-threads, which slows it
887953
down. This delay invariably affects reading ping requests from network
887953
and responding to them, resulting in increased ping latencies, which
887953
sometimes results in a ping-timer-expiry on client leading to
887953
disconnect of transport. So, this patch aims to free up poller thread
887953
from executing code of Glusterfs Program. We do this by making
887953
887953
* Glusterfs Program registering itself asking rpcsvc to execute its
887953
  actors in its own threads.
887953
* GF-DUMP Program registering itself asking rpcsvc to _NOT_ execute
887953
  its actors in its own threads. Otherwise program's ownthreads become
887953
  bottleneck in processing ping traffic. This means that poller thread
887953
  reads a ping packet, invokes its actor and hands the response msg to
887953
  transport queue.
887953
887953
Change-Id: I526268c10bdd5ef93f322a4f95385137550a6a49
887953
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
887953
BUG: 1390151
887953
Reviewed-on: https://review.gluster.org/17105
887953
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
887953
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
887953
Smoke: Gluster Build System <jenkins@build.gluster.org>
887953
Reviewed-by: Amar Tumballi <amarts@redhat.com>
887953
Reviewed-by: Jeff Darcy <jeff@pl.atyp.us>
887953
(cherry picked from commit 2e72b24707f1886833db0b09e48b3f48b8d68d37)
887953
Reviewed-on: https://code.engineering.redhat.com/gerrit/162426
887953
Tested-by: RHGS Build Bot <nigelb@redhat.com>
887953
---
887953
 rpc/rpc-lib/src/rpcsvc.c                      | 90 ++++++++++++++++++++++++++-
887953
 rpc/rpc-lib/src/rpcsvc.h                      | 18 +++++-
887953
 xlators/protocol/server/src/server-helpers.c  |  4 --
887953
 xlators/protocol/server/src/server-rpc-fops.c |  1 +
887953
 4 files changed, 106 insertions(+), 7 deletions(-)
887953
887953
diff --git a/rpc/rpc-lib/src/rpcsvc.c b/rpc/rpc-lib/src/rpcsvc.c
887953
index 695e9fb..faa1956 100644
887953
--- a/rpc/rpc-lib/src/rpcsvc.c
887953
+++ b/rpc/rpc-lib/src/rpcsvc.c
887953
@@ -304,6 +304,7 @@ rpcsvc_program_actor (rpcsvc_request_t *req)
887953
                 goto err;
887953
         }
887953
 
887953
+        req->ownthread = program->ownthread;
887953
         req->synctask = program->synctask;
887953
 
887953
         err = SUCCESS;
887953
@@ -411,6 +412,7 @@ rpcsvc_request_init (rpcsvc_t *svc, rpc_transport_t *trans,
887953
         req->progver = rpc_call_progver (callmsg);
887953
         req->procnum = rpc_call_progproc (callmsg);
887953
         req->trans = rpc_transport_ref (trans);
887953
+        gf_client_ref (req->trans->xl_private);
887953
         req->count = msg->count;
887953
         req->msg[0] = progmsg;
887953
         req->iobref = iobref_ref (msg->iobref);
887953
@@ -426,6 +428,7 @@ rpcsvc_request_init (rpcsvc_t *svc, rpc_transport_t *trans,
887953
         req->trans_private = msg->private;
887953
 
887953
         INIT_LIST_HEAD (&req->txlist);
887953
+        INIT_LIST_HEAD (&req->request_list);
887953
         req->payloadsize = 0;
887953
 
887953
         /* By this time, the data bytes for the auth scheme would have already
887953
@@ -576,7 +579,7 @@ rpcsvc_handle_rpc_call (rpcsvc_t *svc, rpc_transport_t *trans,
887953
         rpcsvc_request_t       *req            = NULL;
887953
         int                     ret            = -1;
887953
         uint16_t                port           = 0;
887953
-        gf_boolean_t            is_unix        = _gf_false;
887953
+        gf_boolean_t            is_unix        = _gf_false, empty = _gf_false;
887953
         gf_boolean_t            unprivileged   = _gf_false;
887953
         drc_cached_op_t        *reply          = NULL;
887953
         rpcsvc_drc_globals_t   *drc            = NULL;
887953
@@ -692,6 +695,20 @@ rpcsvc_handle_rpc_call (rpcsvc_t *svc, rpc_transport_t *trans,
887953
                                             (synctask_fn_t) actor_fn,
887953
                                             rpcsvc_check_and_reply_error, NULL,
887953
                                             req);
887953
+                } else if (req->ownthread) {
887953
+                        pthread_mutex_lock (&req->prog->queue_lock);
887953
+                        {
887953
+                                empty = list_empty (&req->prog->request_queue);
887953
+
887953
+                                list_add_tail (&req->request_list,
887953
+                                               &req->prog->request_queue);
887953
+
887953
+                                if (empty)
887953
+                                        pthread_cond_signal (&req->prog->queue_cond);
887953
+                        }
887953
+                        pthread_mutex_unlock (&req->prog->queue_lock);
887953
+
887953
+                        ret = 0;
887953
                 } else {
887953
                         ret = actor_fn (req);
887953
                 }
887953
@@ -1572,6 +1589,12 @@ rpcsvc_program_unregister (rpcsvc_t *svc, rpcsvc_program_t *program)
887953
                 " Ver: %d, Port: %d", prog->progname, prog->prognum,
887953
                 prog->progver, prog->progport);
887953
 
887953
+        if (prog->ownthread) {
887953
+                prog->alive = _gf_false;
887953
+                ret = 0;
887953
+                goto out;
887953
+        }
887953
+
887953
         pthread_mutex_lock (&svc->rpclock);
887953
         {
887953
                 list_del_init (&prog->program);
887953
@@ -1838,6 +1861,56 @@ out:
887953
         return ret;
887953
 }
887953
 
887953
+void *
887953
+rpcsvc_request_handler (void *arg)
887953
+{
887953
+        rpcsvc_program_t *program = arg;
887953
+        rpcsvc_request_t *req     = NULL;
887953
+        rpcsvc_actor_t   *actor   = NULL;
887953
+        gf_boolean_t      done    = _gf_false;
887953
+        int               ret     = 0;
887953
+
887953
+        if (!program)
887953
+                return NULL;
887953
+
887953
+        while (1) {
887953
+                pthread_mutex_lock (&program->queue_lock);
887953
+                {
887953
+                        if (!program->alive
887953
+                            && list_empty (&program->request_queue)) {
887953
+                                done = 1;
887953
+                                goto unlock;
887953
+                        }
887953
+
887953
+                        while (list_empty (&program->request_queue))
887953
+                                pthread_cond_wait (&program->queue_cond,
887953
+                                                   &program->queue_lock);
887953
+
887953
+                        req = list_entry (program->request_queue.next,
887953
+                                          typeof (*req), request_list);
887953
+
887953
+                        list_del_init (&req->request_list);
887953
+                }
887953
+        unlock:
887953
+                pthread_mutex_unlock (&program->queue_lock);
887953
+
887953
+                if (done)
887953
+                        break;
887953
+
887953
+                THIS = req->svc->xl;
887953
+
887953
+                actor = rpcsvc_program_actor (req);
887953
+
887953
+                ret = actor->actor (req);
887953
+
887953
+                if (ret != 0) {
887953
+                        rpcsvc_check_and_reply_error (ret, NULL, req);
887953
+                }
887953
+        }
887953
+
887953
+        return NULL;
887953
+}
887953
+
887953
 int
887953
 rpcsvc_program_register (rpcsvc_t *svc, rpcsvc_program_t *program)
887953
 {
887953
@@ -1878,6 +1951,21 @@ rpcsvc_program_register (rpcsvc_t *svc, rpcsvc_program_t *program)
887953
         memcpy (newprog, program, sizeof (*program));
887953
 
887953
         INIT_LIST_HEAD (&newprog->program);
887953
+        INIT_LIST_HEAD (&newprog->request_queue);
887953
+        pthread_mutex_init (&newprog->queue_lock, NULL);
887953
+        pthread_cond_init (&newprog->queue_cond, NULL);
887953
+
887953
+        newprog->alive = _gf_true;
887953
+
887953
+        /* make sure synctask gets priority over ownthread */
887953
+        if (newprog->synctask)
887953
+                newprog->ownthread = _gf_false;
887953
+
887953
+        if (newprog->ownthread) {
887953
+                gf_thread_create (&newprog->thread, NULL,
887953
+                                  rpcsvc_request_handler,
887953
+                                  newprog, "reqhnd");
887953
+        }
887953
 
887953
         pthread_mutex_lock (&svc->rpclock);
887953
         {
887953
diff --git a/rpc/rpc-lib/src/rpcsvc.h b/rpc/rpc-lib/src/rpcsvc.h
887953
index d3aafac..58c0055 100644
887953
--- a/rpc/rpc-lib/src/rpcsvc.h
887953
+++ b/rpc/rpc-lib/src/rpcsvc.h
887953
@@ -233,7 +233,9 @@ struct rpcsvc_request {
887953
          */
887953
         rpcsvc_auth_data_t      verf;
887953
 
887953
-	/* Execute this request's actor function as a synctask?*/
887953
+        /* Execute this request's actor function in ownthread of program?*/
887953
+        gf_boolean_t            ownthread;
887953
+
887953
         gf_boolean_t            synctask;
887953
         /* Container for a RPC program wanting to store a temp
887953
          * request-specific item.
887953
@@ -245,6 +247,10 @@ struct rpcsvc_request {
887953
 
887953
         /* pointer to cached reply for use in DRC */
887953
         drc_cached_op_t         *reply;
887953
+
887953
+        /* request queue in rpcsvc */
887953
+        struct list_head         request_list;
887953
+
887953
 };
887953
 
887953
 #define rpcsvc_request_program(req) ((rpcsvc_program_t *)((req)->prog))
887953
@@ -395,10 +401,18 @@ struct rpcsvc_program {
887953
          */
887953
         int                     min_auth;
887953
 
887953
-	/* Execute actor function as a synctask? */
887953
+        /* Execute actor function in program's own thread? */
887953
+        /* This will reduce the workload on poller threads */
887953
+        gf_boolean_t            ownthread;
887953
+        gf_boolean_t            alive;
887953
+
887953
         gf_boolean_t            synctask;
887953
         /* list member to link to list of registered services with rpcsvc */
887953
         struct list_head        program;
887953
+        struct list_head        request_queue;
887953
+        pthread_mutex_t         queue_lock;
887953
+        pthread_cond_t          queue_cond;
887953
+        pthread_t               thread;
887953
 };
887953
 
887953
 typedef struct rpcsvc_cbk_program {
887953
diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c
887953
index 30045ef..7cc3d15 100644
887953
--- a/xlators/protocol/server/src/server-helpers.c
887953
+++ b/xlators/protocol/server/src/server-helpers.c
887953
@@ -557,10 +557,6 @@ get_frame_from_request (rpcsvc_request_t *req)
887953
                 }
887953
         }
887953
 
887953
-        /* Add a ref for this fop */
887953
-        if (client)
887953
-                gf_client_ref (client);
887953
-
887953
         frame->root->uid      = req->uid;
887953
         frame->root->gid      = req->gid;
887953
         frame->root->pid      = req->pid;
887953
diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c
887953
index b7bb26a..db4242d 100644
887953
--- a/xlators/protocol/server/src/server-rpc-fops.c
887953
+++ b/xlators/protocol/server/src/server-rpc-fops.c
887953
@@ -6143,4 +6143,5 @@ struct rpcsvc_program glusterfs3_3_fop_prog = {
887953
         .progver   = GLUSTER_FOP_VERSION,
887953
         .numactors = GLUSTER_FOP_PROCCNT,
887953
         .actors    = glusterfs3_3_fop_actors,
887953
+        .ownthread = _gf_true,
887953
 };
887953
-- 
887953
1.8.3.1
887953