|
|
50dc83 |
From 2449a1824c6f7b57889335caaeb09f4c5cb3efce Mon Sep 17 00:00:00 2001
|
|
|
50dc83 |
From: Soumya Koduri <skoduri@redhat.com>
|
|
|
50dc83 |
Date: Thu, 28 Mar 2019 14:59:00 +0530
|
|
|
50dc83 |
Subject: [PATCH 48/52] gfapi: Unblock epoll thread for upcall processing
|
|
|
50dc83 |
|
|
|
50dc83 |
With commit#ad35193,we have made changes to offload
|
|
|
50dc83 |
processing upcall notifications to synctask so as not
|
|
|
50dc83 |
to block epoll threads. However seems like the issue wasnt
|
|
|
50dc83 |
fully addressed.
|
|
|
50dc83 |
|
|
|
50dc83 |
In "glfs_cbk_upcall_data" -> "synctask_new1" after creating synctask
|
|
|
50dc83 |
if there is no callback defined, the thread waits on synctask_join
|
|
|
50dc83 |
till the syncfn is finished. So that way even with those changes,
|
|
|
50dc83 |
epoll threads are blocked till the upcalls are processed.
|
|
|
50dc83 |
|
|
|
50dc83 |
Hence the right fix now is to define a callback function for that
|
|
|
50dc83 |
synctask "glfs_cbk_upcall_syncop" so as to unblock epoll/notify threads
|
|
|
50dc83 |
completely and the upcall processing can happen in parallel by synctask
|
|
|
50dc83 |
threads.
|
|
|
50dc83 |
|
|
|
50dc83 |
Upstream references-
|
|
|
50dc83 |
mainline : https://review.gluster.org/22436
|
|
|
50dc83 |
release-6.0 : https://review.gluster.org/22459
|
|
|
50dc83 |
|
|
|
50dc83 |
Change-Id: I4d8645e3588fab2c3ca534e0112773aaab68a5dd
|
|
|
50dc83 |
fixes: bz#1694565
|
|
|
50dc83 |
Signed-off-by: Soumya Koduri <skoduri@redhat.com>
|
|
|
50dc83 |
Reviewed-on: https://code.engineering.redhat.com/gerrit/166586
|
|
|
50dc83 |
Tested-by: RHGS Build Bot <nigelb@redhat.com>
|
|
|
50dc83 |
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
|
|
|
50dc83 |
---
|
|
|
50dc83 |
api/src/glfs-fops.c | 42 ++++++++++++++++++++++++++++++++++--------
|
|
|
50dc83 |
1 file changed, 34 insertions(+), 8 deletions(-)
|
|
|
50dc83 |
|
|
|
50dc83 |
diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c
|
|
|
50dc83 |
index 88cd32b..01ba60b 100644
|
|
|
50dc83 |
--- a/api/src/glfs-fops.c
|
|
|
50dc83 |
+++ b/api/src/glfs-fops.c
|
|
|
50dc83 |
@@ -5714,6 +5714,16 @@ out:
|
|
|
50dc83 |
}
|
|
|
50dc83 |
|
|
|
50dc83 |
static int
|
|
|
50dc83 |
+glfs_upcall_syncop_cbk(int ret, call_frame_t *frame, void *opaque)
|
|
|
50dc83 |
+{
|
|
|
50dc83 |
+ struct upcall_syncop_args *args = opaque;
|
|
|
50dc83 |
+
|
|
|
50dc83 |
+ GF_FREE(args->upcall_data);
|
|
|
50dc83 |
+ GF_FREE(args);
|
|
|
50dc83 |
+ return 0;
|
|
|
50dc83 |
+}
|
|
|
50dc83 |
+
|
|
|
50dc83 |
+static int
|
|
|
50dc83 |
glfs_cbk_upcall_syncop(void *opaque)
|
|
|
50dc83 |
{
|
|
|
50dc83 |
struct upcall_syncop_args *args = opaque;
|
|
|
50dc83 |
@@ -5770,15 +5780,13 @@ out:
|
|
|
50dc83 |
GLFS_FREE(up_arg);
|
|
|
50dc83 |
}
|
|
|
50dc83 |
|
|
|
50dc83 |
- return ret;
|
|
|
50dc83 |
+ return 0;
|
|
|
50dc83 |
}
|
|
|
50dc83 |
|
|
|
50dc83 |
static void
|
|
|
50dc83 |
glfs_cbk_upcall_data(struct glfs *fs, struct gf_upcall *upcall_data)
|
|
|
50dc83 |
{
|
|
|
50dc83 |
- struct upcall_syncop_args args = {
|
|
|
50dc83 |
- 0,
|
|
|
50dc83 |
- };
|
|
|
50dc83 |
+ struct upcall_syncop_args *args = NULL;
|
|
|
50dc83 |
int ret = -1;
|
|
|
50dc83 |
|
|
|
50dc83 |
if (!fs || !upcall_data)
|
|
|
50dc83 |
@@ -5789,16 +5797,34 @@ glfs_cbk_upcall_data(struct glfs *fs, struct gf_upcall *upcall_data)
|
|
|
50dc83 |
goto out;
|
|
|
50dc83 |
}
|
|
|
50dc83 |
|
|
|
50dc83 |
- args.fs = fs;
|
|
|
50dc83 |
- args.upcall_data = upcall_data;
|
|
|
50dc83 |
+ args = GF_CALLOC(1, sizeof(struct upcall_syncop_args),
|
|
|
50dc83 |
+ glfs_mt_upcall_entry_t);
|
|
|
50dc83 |
+ if (!args) {
|
|
|
50dc83 |
+ gf_msg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED,
|
|
|
50dc83 |
+ "Upcall syncop args allocation failed.");
|
|
|
50dc83 |
+ goto out;
|
|
|
50dc83 |
+ }
|
|
|
50dc83 |
+
|
|
|
50dc83 |
+ /* Note: we are not taking any ref on fs here.
|
|
|
50dc83 |
+ * Ideally applications have to unregister for upcall events
|
|
|
50dc83 |
+ * or stop polling for upcall events before performing
|
|
|
50dc83 |
+ * glfs_fini. And as for outstanding synctasks created, we wait
|
|
|
50dc83 |
+ * for all syncenv threads to finish tasks before cleaning up the
|
|
|
50dc83 |
+ * fs->ctx. Hence it seems safe to process these callback
|
|
|
50dc83 |
+ * notification without taking any lock/ref.
|
|
|
50dc83 |
+ */
|
|
|
50dc83 |
+ args->fs = fs;
|
|
|
50dc83 |
+ args->upcall_data = gf_memdup(upcall_data, sizeof(*upcall_data));
|
|
|
50dc83 |
|
|
|
50dc83 |
- ret = synctask_new(THIS->ctx->env, glfs_cbk_upcall_syncop, NULL, NULL,
|
|
|
50dc83 |
- &args);
|
|
|
50dc83 |
+ ret = synctask_new(THIS->ctx->env, glfs_cbk_upcall_syncop,
|
|
|
50dc83 |
+ glfs_upcall_syncop_cbk, NULL, args);
|
|
|
50dc83 |
/* should we retry incase of failure? */
|
|
|
50dc83 |
if (ret) {
|
|
|
50dc83 |
gf_msg(THIS->name, GF_LOG_ERROR, errno, API_MSG_UPCALL_SYNCOP_FAILED,
|
|
|
50dc83 |
"Synctak for Upcall event_type(%d) and gfid(%s) failed",
|
|
|
50dc83 |
upcall_data->event_type, (char *)(upcall_data->gfid));
|
|
|
50dc83 |
+ GF_FREE(args->upcall_data);
|
|
|
50dc83 |
+ GF_FREE(args);
|
|
|
50dc83 |
}
|
|
|
50dc83 |
|
|
|
50dc83 |
out:
|
|
|
50dc83 |
--
|
|
|
50dc83 |
1.8.3.1
|
|
|
50dc83 |
|