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