diff mbox series

[12/20] lustre: ptlrpc: use wait_woken() in ptlrpcd()

Message ID 1633974049-26490-13-git-send-email-jsimmons@infradead.org (mailing list archive)
State New, archived
Headers show
Series lustre: sync to OpenSFS Oct 11, 2021 | expand

Commit Message

James Simmons Oct. 11, 2021, 5:40 p.m. UTC
From: Mr NeilBrown <neilb@suse.de>

Using wait_event() to wait for ptlrpcd_check() to succeed is
problematic.  ptlrpcd_check() is complex and can wait for other
events.  This nested waiting can behave differently to expectation and
generates a warning

do not call blocking ops when !TASK_RUNNING

This happens because the task state is set to TASK_IDLE before
ptlrpcd_check() is calls.

A better approach (introduce for precisely this use-case) is to use
wait_woken() and woken_wake_function().

When a wake_up is requested on the waitq, woken_wake_function() sets a
flag to record the wakeup.  wait_woken() will wait until this flag is
set.  This way, the task state doesn't need to be set until after
ptlrpcd_check() has completed.

WC-bug-id: https://jira.whamcloud.com/browse/LU-12362
Lustre-commit: 885b494632ca16d95 ("LU-12362 ptlrpc: use wait_woken() in ptlrpcd()")
Signed-off-by: Mr NeilBrown <neilb@suse.de>
Reviewed-on: https://review.whamcloud.com/45069
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Patrick Farrell <pfarrell@whamcloud.com>
Reviewed-by: xinliang <xinliang.liu@linaro.org>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Signed-off-by: James Simmons <jsimmons@infradead.org>
---
 fs/lustre/ptlrpc/ptlrpcd.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/fs/lustre/ptlrpc/ptlrpcd.c b/fs/lustre/ptlrpc/ptlrpcd.c
index ed3f0e1..9cd9d39 100644
--- a/fs/lustre/ptlrpc/ptlrpcd.c
+++ b/fs/lustre/ptlrpc/ptlrpcd.c
@@ -435,18 +435,31 @@  static int ptlrpcd(void *arg)
 	 * new_req_list and ptlrpcd_check() moves them into the set.
 	 */
 	do {
+		DEFINE_WAIT_FUNC(wait, woken_wake_function);
 		time64_t timeout;
 
 		timeout = ptlrpc_set_next_timeout(set);
 
 		lu_context_enter(&env.le_ctx);
 		lu_context_enter(env.le_ses);
-		/* If timeout==0, wait indefinitely */
-		if (wait_event_idle_timeout(
-			    set->set_waitq,
-			    ptlrpcd_check(&env, pc),
-			    timeout ? (timeout * HZ) : MAX_SCHEDULE_TIMEOUT) == 0)
+
+		add_wait_queue(&set->set_waitq, &wait);
+		while (!ptlrpcd_check(&env, pc)) {
+			int ret;
+
+			if (timeout == 0)
+				ret = wait_woken(&wait, TASK_IDLE,
+						 MAX_SCHEDULE_TIMEOUT);
+			else
+				ret = wait_woken(&wait, TASK_IDLE,
+						 HZ * timeout);
+			if (ret != 0)
+				continue;
+			/* Timed out */
 			ptlrpc_expired_set(set);
+			break;
+		}
+		remove_wait_queue(&set->set_waitq, &wait);
 
 		lu_context_exit(&env.le_ctx);
 		lu_context_exit(env.le_ses);