|
|
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 |
|