From d48de09adaffdf6b75f30d78f8a1cd287e6fa8ae Mon Sep 17 00:00:00 2001 From: Soumya Koduri Date: Mon, 6 Apr 2020 12:36:44 +0530 Subject: gfapi: Suspend synctasks instead of blocking them There are certain conditions which blocks the current execution thread (like waiting on mutex lock or condition variable or I/O response). In such cases, if it is a synctask thread, we should suspend the task instead of blocking it (like done in SYNCOP using synctask_yield) This is to avoid deadlock like the one mentioned below - 1) synctaskA sets fs->migration_in_progress to 1 and does I/O (LOOKUP) 2) Other synctask threads wait for fs->migration_in_progress to be reset to 0 by synctaskA and hence blocked 3) but synctaskA cannot resume as all synctask threads are blocked on (2). Note: this same approach is already used by few other components like syncbarrier etc. Change-Id: If90f870d663bb242c702a5b86ac52eeda67c6f0d Fixes: #1146 Signed-off-by: Soumya Koduri (cherry picked from commit 55914f968d907ed747774da15285b42653afda61) --- api/src/glfs.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'api/src/glfs.c') diff --git a/api/src/glfs.c b/api/src/glfs.c index 98054b6bdb6..ab77f6c1eae 100644 --- a/api/src/glfs.c +++ b/api/src/glfs.c @@ -741,6 +741,7 @@ glfs_new_fs(const char *volname) INIT_LIST_HEAD(&fs->openfds); INIT_LIST_HEAD(&fs->upcall_list); + INIT_LIST_HEAD(&fs->waitq); PTHREAD_MUTEX_INIT(&fs->mutex, NULL, fs->pthread_flags, GLFS_INIT_MUTEX, err); @@ -1229,6 +1230,7 @@ pub_glfs_fini(struct glfs *fs) call_pool_t *call_pool = NULL; int fs_init = 0; int err = -1; + struct synctask *waittask = NULL; DECLARE_OLD_THIS; @@ -1250,6 +1252,13 @@ pub_glfs_fini(struct glfs *fs) call_pool = fs->ctx->pool; + /* Wake up any suspended synctasks */ + while (!list_empty(&fs->waitq)) { + waittask = list_entry(fs->waitq.next, struct synctask, waitq); + list_del_init(&waittask->waitq); + synctask_wake(waittask); + } + while (countdown--) { /* give some time for background frames to finish */ pthread_mutex_lock(&fs->mutex); -- cgit