All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/19] RESEND staging: lustre: use standard wait_event macros
@ 2018-02-12 21:22 ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

Hi,
 this is a resend of patch series that I sent a little over a month
 ago.  Since then I've recieved Reviewed-By:from James Simmons
 (thanks) and confirmation that it passes his testing.
 I cannot quite say that all tests pass for me with these patch,
 but the tests produce the same results both with and without the
 patches.

 No non-trivial changes - a couple of typos in change descriptions
 fixes, and reviewed-by's added.

Previous intro text:
Hi,
 this is a revised version of the patch series I sent under a similar
 subject in mid December.
 Improvements are:
   - new wait_event_idle* macros are now in include/linux/wait.h which
     Ack from peterz.
   - *all* waits are now TASK_IDLE or TASK_INTERRUPTIBLE and so don't
     affect the load average.  There is no need to choose whether load
     is appropriate or not in each case.
   - all l_wait_event() users are handled so l_wait_event() is
     removed.  The one case I had left out before uses
     wait_event_idle_exclusive() with and option of using
     wait_event_idle_exclusive_lifo() is that ever gets approved.

 I think this set is ready to go.
 If you only review two patches, please review

    staging: lustre: simplify waiting in ldlm_completion_ast()
and
    staging: lustre: remove back_to_sleep()

 as in both of those, the actual behaviour of the current code (as I
 understand it) doesn't seem to agree with comments/debug message, or
 just generally looks odd.

Thanks,
NeilBrown

---

NeilBrown (19):
      sched/wait: add wait_event_idle() functions.
      staging: lustre: discard SVC_SIGNAL and related functions
      staging: lustre: replace simple cases of l_wait_event() with wait_event().
      staging: lustre: discard cfs_time_seconds()
      staging: lustre: use wait_event_idle_timeout() where appropriate.
      staging: lustre: introduce and use l_wait_event_abortable()
      staging: lustre: simplify l_wait_event when intr handler but no timeout.
      staging: lustre: simplify waiting in ldlm_completion_ast()
      staging: lustre: open code polling loop instead of using l_wait_event()
      staging: lustre: simplify waiting in ptlrpc_invalidate_import()
      staging: lustre: remove back_to_sleep()
      staging: lustre: make polling loop in ptlrpc_unregister_bulk more obvious
      staging: lustre: use wait_event_idle_timeout in ptlrpcd()
      staging: lustre: improve waiting in sptlrpc_req_refresh_ctx
      staging: lustre: use explicit poll loop in ptlrpc_service_unlink_rqbd
      staging: lustre: use explicit poll loop in ptlrpc_unregister_reply
      staging: lustre: remove l_wait_event from ptlrpc_set_wait
      staging: lustre: replace l_wait_event_exclusive_head() with wait_event_idle_exclusive
      staging: lustre: remove l_wait_event() and related code


 .../lustre/include/linux/libcfs/libcfs_debug.h     |    4 
 .../lustre/include/linux/libcfs/libcfs_time.h      |    2 
 .../lustre/include/linux/libcfs/linux/linux-time.h |    7 
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c    |    8 -
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c |    4 
 .../staging/lustre/lnet/klnds/socklnd/socklnd.c    |    6 
 .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c |   22 +
 drivers/staging/lustre/lnet/libcfs/debug.c         |    2 
 drivers/staging/lustre/lnet/libcfs/fail.c          |    2 
 drivers/staging/lustre/lnet/libcfs/tracefile.c     |    4 
 drivers/staging/lustre/lnet/lnet/acceptor.c        |    2 
 drivers/staging/lustre/lnet/lnet/api-ni.c          |    4 
 drivers/staging/lustre/lnet/lnet/lib-move.c        |    4 
 drivers/staging/lustre/lnet/lnet/net_fault.c       |   14 -
 drivers/staging/lustre/lnet/lnet/peer.c            |    2 
 drivers/staging/lustre/lnet/lnet/router.c          |    8 -
 drivers/staging/lustre/lnet/selftest/conrpc.c      |    4 
 drivers/staging/lustre/lnet/selftest/rpc.c         |    2 
 drivers/staging/lustre/lnet/selftest/selftest.h    |    2 
 drivers/staging/lustre/lnet/selftest/timer.c       |    2 
 drivers/staging/lustre/lustre/include/lustre_dlm.h |    2 
 drivers/staging/lustre/lustre/include/lustre_lib.h |  296 ++------------------
 drivers/staging/lustre/lustre/include/lustre_mdc.h |    2 
 drivers/staging/lustre/lustre/include/lustre_net.h |    8 -
 drivers/staging/lustre/lustre/ldlm/ldlm_flock.c    |   30 --
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c     |   14 -
 drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c    |   12 -
 drivers/staging/lustre/lustre/ldlm/ldlm_pool.c     |   17 -
 drivers/staging/lustre/lustre/ldlm/ldlm_request.c  |   55 +---
 drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |   14 -
 drivers/staging/lustre/lustre/llite/llite_lib.c    |   23 +-
 drivers/staging/lustre/lustre/llite/statahead.c    |   60 ++--
 drivers/staging/lustre/lustre/lov/lov_object.c     |    6 
 drivers/staging/lustre/lustre/lov/lov_request.c    |   12 -
 drivers/staging/lustre/lustre/mdc/mdc_request.c    |    5 
 drivers/staging/lustre/lustre/mgc/mgc_request.c    |   19 -
 drivers/staging/lustre/lustre/obdclass/cl_io.c     |   23 +-
 drivers/staging/lustre/lustre/obdclass/genops.c    |   24 +-
 drivers/staging/lustre/lustre/obdclass/llog_obd.c  |    5 
 .../staging/lustre/lustre/obdecho/echo_client.c    |    2 
 drivers/staging/lustre/lustre/osc/osc_cache.c      |   28 +-
 drivers/staging/lustre/lustre/osc/osc_object.c     |    6 
 drivers/staging/lustre/lustre/osc/osc_page.c       |    6 
 drivers/staging/lustre/lustre/osc/osc_request.c    |    6 
 drivers/staging/lustre/lustre/ptlrpc/client.c      |  101 +++----
 drivers/staging/lustre/lustre/ptlrpc/events.c      |    7 
 drivers/staging/lustre/lustre/ptlrpc/import.c      |   51 +--
 drivers/staging/lustre/lustre/ptlrpc/niobuf.c      |   15 +
 .../staging/lustre/lustre/ptlrpc/pack_generic.c    |    9 -
 drivers/staging/lustre/lustre/ptlrpc/pinger.c      |   28 +-
 .../staging/lustre/lustre/ptlrpc/ptlrpc_internal.h |    2 
 drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c     |   18 +
 drivers/staging/lustre/lustre/ptlrpc/recover.c     |   12 -
 drivers/staging/lustre/lustre/ptlrpc/sec.c         |   34 ++
 drivers/staging/lustre/lustre/ptlrpc/sec_gc.c      |   23 --
 drivers/staging/lustre/lustre/ptlrpc/service.c     |   84 +++---
 include/linux/wait.h                               |  114 ++++++++
 57 files changed, 516 insertions(+), 762 deletions(-)

--
Signature

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH 08/19] staging: lustre: simplify waiting in ldlm_completion_ast()
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 21:22   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

If a signal-callback (lwi_on_signal) is set without lwi_allow_intr, as
is the case in ldlm_completion_ast(), the behavior depends on the
timeout set.

If a timeout is set, then signals are ignored.  If the timeout is
reached, the timeout handler is called.  If the timeout handler
return 0, which ldlm_expired_completion_wait() always does, the
l_wait_event() switches to exactly the behavior if no timeout was set.

If no timeout is set, then "fatal" signals are not ignored.  If one
arrives the callback is run, but as the callback is empty in this
case, that is not relevant.

This can be simplified to:
 if a timeout is wanted
     wait_event_idle_timeout()
     if that timed out, call the timeout handler
 l_wait_event_abortable()

i.e. the code always waits indefinitely.  Sometimes it performs a
non-abortable wait first.  Sometimes it doesn't.  But it only
aborts before the condition is true if it is signaled.
This doesn't quite agree with the comments and debug messages.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 drivers/staging/lustre/lustre/ldlm/ldlm_request.c |   55 +++++++--------------
 1 file changed, 18 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index a244fa717134..f1233d844bbd 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -72,15 +72,6 @@ MODULE_PARM_DESC(ldlm_enqueue_min, "lock enqueue timeout minimum");
 /* in client side, whether the cached locks will be canceled before replay */
 unsigned int ldlm_cancel_unused_locks_before_replay = 1;
 
-static void interrupted_completion_wait(void *data)
-{
-}
-
-struct lock_wait_data {
-	struct ldlm_lock *lwd_lock;
-	__u32	     lwd_conn_cnt;
-};
-
 struct ldlm_async_args {
 	struct lustre_handle lock_handle;
 };
@@ -112,10 +103,8 @@ static int ldlm_request_bufsize(int count, int type)
 	return sizeof(struct ldlm_request) + avail;
 }
 
-static int ldlm_expired_completion_wait(void *data)
+static void ldlm_expired_completion_wait(struct ldlm_lock *lock, struct obd_import *imp2)
 {
-	struct lock_wait_data *lwd = data;
-	struct ldlm_lock *lock = lwd->lwd_lock;
 	struct obd_import *imp;
 	struct obd_device *obd;
 
@@ -135,19 +124,17 @@ static int ldlm_expired_completion_wait(void *data)
 			if (last_dump == 0)
 				libcfs_debug_dumplog();
 		}
-		return 0;
+		return;
 	}
 
 	obd = lock->l_conn_export->exp_obd;
 	imp = obd->u.cli.cl_import;
-	ptlrpc_fail_import(imp, lwd->lwd_conn_cnt);
+	ptlrpc_fail_import(imp, imp2 ? imp2->imp_conn_cnt : 0);
 	LDLM_ERROR(lock,
 		   "lock timed out (enqueued at %lld, %llds ago), entering recovery for %s@%s",
 		   (s64)lock->l_last_activity,
 		   (s64)(ktime_get_real_seconds() - lock->l_last_activity),
 		   obd2cli_tgt(obd), imp->imp_connection->c_remote_uuid.uuid);
-
-	return 0;
 }
 
 /**
@@ -251,10 +238,8 @@ EXPORT_SYMBOL(ldlm_completion_ast_async);
 int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 {
 	/* XXX ALLOCATE - 160 bytes */
-	struct lock_wait_data lwd;
 	struct obd_device *obd;
 	struct obd_import *imp = NULL;
-	struct l_wait_info lwi;
 	__u32 timeout;
 	int rc = 0;
 
@@ -281,32 +266,28 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 
 	timeout = ldlm_cp_timeout(lock);
 
-	lwd.lwd_lock = lock;
 	lock->l_last_activity = ktime_get_real_seconds();
 
-	if (ldlm_is_no_timeout(lock)) {
-		LDLM_DEBUG(lock, "waiting indefinitely because of NO_TIMEOUT");
-		lwi = LWI_INTR(interrupted_completion_wait, &lwd);
-	} else {
-		lwi = LWI_TIMEOUT_INTR(timeout * HZ,
-				       ldlm_expired_completion_wait,
-				       interrupted_completion_wait, &lwd);
-	}
-
-	if (imp) {
-		spin_lock(&imp->imp_lock);
-		lwd.lwd_conn_cnt = imp->imp_conn_cnt;
-		spin_unlock(&imp->imp_lock);
-	}
-
 	if (OBD_FAIL_CHECK_RESET(OBD_FAIL_LDLM_INTR_CP_AST,
 				 OBD_FAIL_LDLM_CP_BL_RACE | OBD_FAIL_ONCE)) {
 		ldlm_set_fail_loc(lock);
 		rc = -EINTR;
 	} else {
-		/* Go to sleep until the lock is granted or cancelled. */
-		rc = l_wait_event(lock->l_waitq,
-				  is_granted_or_cancelled(lock), &lwi);
+		/* Go to sleep until the lock is granted or canceled. */
+		if (!ldlm_is_no_timeout(lock)) {
+			/* Wait uninterruptible for a while first */
+			rc = wait_event_idle_timeout(lock->l_waitq,
+						     is_granted_or_cancelled(lock),
+						     timeout * HZ);
+			if (rc == 0)
+				ldlm_expired_completion_wait(lock, imp);
+		}
+		/* Now wait abortable */
+		if (rc == 0)
+			rc = l_wait_event_abortable(lock->l_waitq,
+						    is_granted_or_cancelled(lock));
+		else
+			rc = 0;
 	}
 
 	if (rc) {

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 06/19] staging: lustre: introduce and use l_wait_event_abortable()
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 21:22   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

lustre sometimes wants to wait for an event, but abort if
one of a specific list of signals arrives.  This is a little
bit like wait_event_killable(), except that the signals are
identified a different way.

So introduce l_wait_event_abortable() which provides this
functionality.
Having separate functions for separate needs is more in line
with the pattern set by include/linux/wait.h, than having a
single function which tries to include all possible needs.

Also introduce l_wait_event_abortable_exclusive().

Note that l_wait_event() return -EINTR on a signal, while
Linux wait_event functions return -ERESTARTSYS.
l_wait_event_{abortable_,}exclusive follow the Linux pattern.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |   24 ++++++++++++++++++++
 drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |   12 +++++-----
 drivers/staging/lustre/lustre/llite/llite_lib.c    |   12 +++-------
 drivers/staging/lustre/lustre/obdclass/genops.c    |    9 +++-----
 drivers/staging/lustre/lustre/obdclass/llog_obd.c  |    5 ++--
 drivers/staging/lustre/lustre/osc/osc_page.c       |    6 ++---
 drivers/staging/lustre/lustre/osc/osc_request.c    |    6 ++---
 7 files changed, 43 insertions(+), 31 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
index 7d950c53e962..b2a64d0e682c 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -336,4 +336,28 @@ do {									   \
 /** @} lib */
 
 
+
+/* l_wait_event_abortable() is a bit like wait_event_killable()
+ * except there is a fixed set of signals which will abort:
+ * LUSTRE_FATAL_SIGS
+ */
+#define l_wait_event_abortable(wq, condition)				\
+({									\
+	sigset_t __blocked;						\
+	int __ret = 0;							\
+	__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);		\
+	__ret = wait_event_interruptible(wq, condition);		\
+	cfs_restore_sigs(__blocked);					\
+	__ret;								\
+})
+
+#define l_wait_event_abortable_exclusive(wq, condition)			\
+({									\
+	sigset_t __blocked;						\
+	int __ret = 0;							\
+	__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);		\
+	__ret = wait_event_interruptible_exclusive(wq, condition);	\
+	cfs_restore_sigs(__blocked);					\
+	__ret;								\
+})
 #endif /* _LUSTRE_LIB_H */
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
index 2e66825c8f4b..4c44603ab6f9 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
@@ -879,7 +879,6 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, int force)
 	ldlm_namespace_cleanup(ns, force ? LDLM_FL_LOCAL_ONLY : 0);
 
 	if (atomic_read(&ns->ns_bref) > 0) {
-		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
 		int rc;
 
 		CDEBUG(D_DLMTRACE,
@@ -887,11 +886,12 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, int force)
 		       ldlm_ns_name(ns), atomic_read(&ns->ns_bref));
 force_wait:
 		if (force)
-			lwi = LWI_TIMEOUT(msecs_to_jiffies(obd_timeout *
-					  MSEC_PER_SEC) / 4, NULL, NULL);
-
-		rc = l_wait_event(ns->ns_waitq,
-				  atomic_read(&ns->ns_bref) == 0, &lwi);
+			rc = wait_event_idle_timeout(ns->ns_waitq,
+						     atomic_read(&ns->ns_bref) == 0,
+						     obd_timeout * HZ / 4) ? 0 : -ETIMEDOUT;
+		else
+			rc = l_wait_event_abortable(ns->ns_waitq,
+						    atomic_read(&ns->ns_bref) == 0);
 
 		/* Forced cleanups should be able to reclaim all references,
 		 * so it's safe to wait forever... we can't leak locks...
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
index c820b201af71..ccb614bd7f53 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -986,16 +986,12 @@ void ll_put_super(struct super_block *sb)
 	}
 
 	/* Wait for unstable pages to be committed to stable storage */
-	if (!force) {
-		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
-
-		rc = l_wait_event(sbi->ll_cache->ccc_unstable_waitq,
-				  !atomic_long_read(&sbi->ll_cache->ccc_unstable_nr),
-				  &lwi);
-	}
+	if (!force)
+		rc = l_wait_event_abortable(sbi->ll_cache->ccc_unstable_waitq,
+					    !atomic_long_read(&sbi->ll_cache->ccc_unstable_nr));
 
 	ccc_count = atomic_long_read(&sbi->ll_cache->ccc_unstable_nr);
-	if (!force && rc != -EINTR)
+	if (!force && rc != -ERESTARTSYS)
 		LASSERTF(!ccc_count, "count: %li\n", ccc_count);
 
 	/* We need to set force before the lov_disconnect in
diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
index 3ff25b8d3b48..8f776a4058a9 100644
--- a/drivers/staging/lustre/lustre/obdclass/genops.c
+++ b/drivers/staging/lustre/lustre/obdclass/genops.c
@@ -1332,7 +1332,6 @@ static bool obd_request_slot_avail(struct client_obd *cli,
 int obd_get_request_slot(struct client_obd *cli)
 {
 	struct obd_request_slot_waiter orsw;
-	struct l_wait_info lwi;
 	int rc;
 
 	spin_lock(&cli->cl_loi_list_lock);
@@ -1347,11 +1346,9 @@ int obd_get_request_slot(struct client_obd *cli)
 	orsw.orsw_signaled = false;
 	spin_unlock(&cli->cl_loi_list_lock);
 
-	lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
-	rc = l_wait_event(orsw.orsw_waitq,
-			  obd_request_slot_avail(cli, &orsw) ||
-			  orsw.orsw_signaled,
-			  &lwi);
+	rc = l_wait_event_abortable(orsw.orsw_waitq,
+				    obd_request_slot_avail(cli, &orsw) ||
+				    orsw.orsw_signaled);
 
 	/*
 	 * Here, we must take the lock to avoid the on-stack 'orsw' to be
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_obd.c b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
index 28bbaa2136ac..26aea114a29b 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_obd.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
@@ -104,7 +104,6 @@ EXPORT_SYMBOL(__llog_ctxt_put);
 
 int llog_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt)
 {
-	struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
 	struct obd_llog_group *olg;
 	int rc, idx;
 
@@ -129,8 +128,8 @@ int llog_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt)
 		CERROR("Error %d while cleaning up ctxt %p\n",
 		       rc, ctxt);
 
-	l_wait_event(olg->olg_waitq,
-		     llog_group_ctxt_null(olg, idx), &lwi);
+	l_wait_event_abortable(olg->olg_waitq,
+			     llog_group_ctxt_null(olg, idx));
 
 	return rc;
 }
diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c
index 20094b6309f9..6fdd521feb21 100644
--- a/drivers/staging/lustre/lustre/osc/osc_page.c
+++ b/drivers/staging/lustre/lustre/osc/osc_page.c
@@ -759,7 +759,6 @@ static long osc_lru_reclaim(struct client_obd *cli, unsigned long npages)
 static int osc_lru_alloc(const struct lu_env *env, struct client_obd *cli,
 			 struct osc_page *opg)
 {
-	struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
 	struct osc_io *oio = osc_env_io(env);
 	int rc = 0;
 
@@ -782,9 +781,8 @@ static int osc_lru_alloc(const struct lu_env *env, struct client_obd *cli,
 
 		cond_resched();
 
-		rc = l_wait_event(osc_lru_waitq,
-				  atomic_long_read(cli->cl_lru_left) > 0,
-				  &lwi);
+		rc = l_wait_event_abortable(osc_lru_waitq,
+					    atomic_long_read(cli->cl_lru_left) > 0);
 
 		if (rc < 0)
 			break;
diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
index 45b1ebf33363..074b5ce6284c 100644
--- a/drivers/staging/lustre/lustre/osc/osc_request.c
+++ b/drivers/staging/lustre/lustre/osc/osc_request.c
@@ -552,14 +552,12 @@ static int osc_destroy(const struct lu_env *env, struct obd_export *exp,
 
 	req->rq_interpret_reply = osc_destroy_interpret;
 	if (!osc_can_send_destroy(cli)) {
-		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
-
 		/*
 		 * Wait until the number of on-going destroy RPCs drops
 		 * under max_rpc_in_flight
 		 */
-		l_wait_event_exclusive(cli->cl_destroy_waitq,
-				       osc_can_send_destroy(cli), &lwi);
+		l_wait_event_abortable_exclusive(cli->cl_destroy_waitq,
+					       osc_can_send_destroy(cli));
 	}
 
 	/* Do not wait for response */

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 07/19] staging: lustre: simplify l_wait_event when intr handler but no timeout.
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 21:22   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

If l_wait_event() is given a function to be called on a signal,
but no timeout or timeout handler, then the intr function is simply
called at the end if the wait was aborted by a signal.
So a simpler way to write the code (in the one place this case is
used) it to open-code the body of the function after the
wait_event, if -ERESTARTSYS was returned.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 drivers/staging/lustre/lustre/ldlm/ldlm_flock.c |   30 +++++------------------
 1 file changed, 7 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
index 657ab95091a0..411b540b96d9 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
@@ -310,24 +310,6 @@ static int ldlm_process_flock_lock(struct ldlm_lock *req)
 	return LDLM_ITER_CONTINUE;
 }
 
-struct ldlm_flock_wait_data {
-	struct ldlm_lock *fwd_lock;
-};
-
-static void
-ldlm_flock_interrupted_wait(void *data)
-{
-	struct ldlm_lock *lock;
-
-	lock = ((struct ldlm_flock_wait_data *)data)->fwd_lock;
-
-	lock_res_and_lock(lock);
-
-	/* client side - set flag to prevent lock from being put on LRU list */
-	ldlm_set_cbpending(lock);
-	unlock_res_and_lock(lock);
-}
-
 /**
  * Flock completion callback function.
  *
@@ -342,8 +324,6 @@ int
 ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 {
 	struct file_lock		*getlk = lock->l_ast_data;
-	struct ldlm_flock_wait_data	fwd;
-	struct l_wait_info		lwi;
 	int				rc = 0;
 
 	OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_CP_CB_WAIT2, 4);
@@ -372,13 +352,17 @@ ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 
 	LDLM_DEBUG(lock,
 		   "client-side enqueue returned a blocked lock, sleeping");
-	fwd.fwd_lock = lock;
-	lwi = LWI_TIMEOUT_INTR(0, NULL, ldlm_flock_interrupted_wait, &fwd);
 
 	/* Go to sleep until the lock is granted. */
-	rc = l_wait_event(lock->l_waitq, is_granted_or_cancelled(lock), &lwi);
+	rc = l_wait_event_abortable(lock->l_waitq, is_granted_or_cancelled(lock));
 
 	if (rc) {
+		lock_res_and_lock(lock);
+
+		/* client side - set flag to prevent lock from being put on LRU list */
+		ldlm_set_cbpending(lock);
+		unlock_res_and_lock(lock);
+
 		LDLM_DEBUG(lock, "client-side enqueue waking up: failed (%d)",
 			   rc);
 		return rc;

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 05/19] staging: lustre: use wait_event_idle_timeout() where appropriate.
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 21:22   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

When the lwi arg has a timeout, but no timeout
callback function, l_wait_event() acts much the same as
wait_event_idle_timeout() - the wait is not interruptible and
simply waits for the event or the timeouts.

The most noticable difference is that the return value is
-ETIMEDOUT or 0, rather than 0 or non-zero.

Another difference is that if the timeout is zero, l_wait_event()
will not time out at all.  In the one case where that is possible
we need to conditionally use wait_event_idle().

So replace all such calls with wait_event_idle_timeout(), being
careful of the return value.

In one case, there is no event expected, only the timeout
is needed.  So use schedule_timeout_uninterruptible().

Note that the presence or absence of LWI_ON_SIGNAL_NOOP
has no effect in these cases.  It only has effect if the timeout
callback is non-NULL, or the timeout is zero, or
LWI_TIMEOUT_INTR_ALL() is used.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c     |   10 ++------
 drivers/staging/lustre/lustre/ldlm/ldlm_pool.c     |   12 +++-------
 drivers/staging/lustre/lustre/llite/statahead.c    |   14 ++++-------
 drivers/staging/lustre/lustre/mdc/mdc_request.c    |    5 +---
 drivers/staging/lustre/lustre/mgc/mgc_request.c    |   15 +++++-------
 drivers/staging/lustre/lustre/obdclass/cl_io.c     |   17 ++++++++------
 drivers/staging/lustre/lustre/osc/osc_cache.c      |   25 ++++++++++----------
 drivers/staging/lustre/lustre/ptlrpc/events.c      |    7 +-----
 drivers/staging/lustre/lustre/ptlrpc/import.c      |   12 ++++------
 .../staging/lustre/lustre/ptlrpc/pack_generic.c    |    9 +++----
 drivers/staging/lustre/lustre/ptlrpc/pinger.c      |   12 +++-------
 drivers/staging/lustre/lustre/ptlrpc/recover.c     |   12 ++++------
 drivers/staging/lustre/lustre/ptlrpc/sec_gc.c      |   10 ++------
 drivers/staging/lustre/lustre/ptlrpc/service.c     |   11 ++++-----
 14 files changed, 68 insertions(+), 103 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
index 773abe78708a..95bea351d21d 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
@@ -1349,7 +1349,6 @@ enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags,
 		if ((flags & LDLM_FL_LVB_READY) && !ldlm_is_lvb_ready(lock)) {
 			__u64 wait_flags = LDLM_FL_LVB_READY |
 				LDLM_FL_DESTROYED | LDLM_FL_FAIL_NOTIFIED;
-			struct l_wait_info lwi;
 
 			if (lock->l_completion_ast) {
 				int err = lock->l_completion_ast(lock,
@@ -1366,13 +1365,10 @@ enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags,
 				}
 			}
 
-			lwi = LWI_TIMEOUT_INTR(obd_timeout * HZ,
-					       NULL, LWI_ON_SIGNAL_NOOP, NULL);
-
 			/* XXX FIXME see comment on CAN_MATCH in lustre_dlm.h */
-			l_wait_event(lock->l_waitq,
-				     lock->l_flags & wait_flags,
-				     &lwi);
+			wait_event_idle_timeout(lock->l_waitq,
+						lock->l_flags & wait_flags,
+						obd_timeout * HZ);
 			if (!ldlm_is_lvb_ready(lock)) {
 				if (flags & LDLM_FL_TEST_LOCK)
 					LDLM_LOCK_RELEASE(lock);
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
index 622245a5f049..a0e486b57e08 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
@@ -997,8 +997,6 @@ static int ldlm_pools_thread_main(void *arg)
 	       "ldlm_poold", current_pid());
 
 	while (1) {
-		struct l_wait_info lwi;
-
 		/*
 		 * Recal all pools on this tick.
 		 */
@@ -1008,12 +1006,10 @@ static int ldlm_pools_thread_main(void *arg)
 		 * Wait until the next check time, or until we're
 		 * stopped.
 		 */
-		lwi = LWI_TIMEOUT(c_time * HZ,
-				  NULL, NULL);
-		l_wait_event(thread->t_ctl_waitq,
-			     thread_is_stopping(thread) ||
-			     thread_is_event(thread),
-			     &lwi);
+		wait_event_idle_timeout(thread->t_ctl_waitq,
+					thread_is_stopping(thread) ||
+					thread_is_event(thread),
+					c_time * HZ);
 
 		if (thread_test_and_clear_flags(thread, SVC_STOPPING))
 			break;
diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c
index 96360f104b92..6052bfd7ff05 100644
--- a/drivers/staging/lustre/lustre/llite/statahead.c
+++ b/drivers/staging/lustre/lustre/llite/statahead.c
@@ -1151,10 +1151,9 @@ static int ll_statahead_thread(void *arg)
 	 */
 	while (sai->sai_sent != sai->sai_replied) {
 		/* in case we're not woken up, timeout wait */
-		struct l_wait_info lwi = LWI_TIMEOUT(msecs_to_jiffies(MSEC_PER_SEC >> 3),
-						     NULL, NULL);
-		l_wait_event(sa_thread->t_ctl_waitq,
-			     sai->sai_sent == sai->sai_replied, &lwi);
+		wait_event_idle_timeout(sa_thread->t_ctl_waitq,
+					sai->sai_sent == sai->sai_replied,
+					HZ>>3);
 	}
 
 	/* release resources held by statahead RPCs */
@@ -1374,7 +1373,6 @@ static int revalidate_statahead_dentry(struct inode *dir,
 {
 	struct ll_inode_info *lli = ll_i2info(dir);
 	struct sa_entry *entry = NULL;
-	struct l_wait_info lwi = { 0 };
 	struct ll_dentry_data *ldd;
 	int rc = 0;
 
@@ -1424,10 +1422,8 @@ static int revalidate_statahead_dentry(struct inode *dir,
 		spin_lock(&lli->lli_sa_lock);
 		sai->sai_index_wait = entry->se_index;
 		spin_unlock(&lli->lli_sa_lock);
-		lwi = LWI_TIMEOUT_INTR(30 * HZ, NULL,
-				       LWI_ON_SIGNAL_NOOP, NULL);
-		rc = l_wait_event(sai->sai_waitq, sa_ready(entry), &lwi);
-		if (rc < 0) {
+		if (0 == wait_event_idle_timeout(sai->sai_waitq,
+						 sa_ready(entry), 30 * HZ)) {
 			/*
 			 * entry may not be ready, so it may be used by inflight
 			 * statahead RPC, don't free it.
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c
index b12518ba5ae9..ab48746ce433 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_request.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c
@@ -838,7 +838,6 @@ static int mdc_getpage(struct obd_export *exp, const struct lu_fid *fid,
 	struct ptlrpc_bulk_desc *desc;
 	struct ptlrpc_request *req;
 	wait_queue_head_t waitq;
-	struct l_wait_info lwi;
 	int resends = 0;
 	int rc;
 	int i;
@@ -888,9 +887,7 @@ static int mdc_getpage(struct obd_export *exp, const struct lu_fid *fid,
 			       exp->exp_obd->obd_name, -EIO);
 			return -EIO;
 		}
-		lwi = LWI_TIMEOUT_INTR(resends * HZ, NULL, NULL,
-				       NULL);
-		l_wait_event(waitq, 0, &lwi);
+		wait_event_idle_timeout(waitq, 0, resends * HZ);
 
 		goto restart_bulk;
 	}
diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c
index a01d13bde102..c61cd23a96df 100644
--- a/drivers/staging/lustre/lustre/mgc/mgc_request.c
+++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c
@@ -535,7 +535,6 @@ static int mgc_requeue_thread(void *data)
 	spin_lock(&config_list_lock);
 	rq_state |= RQ_RUNNING;
 	while (!(rq_state & RQ_STOP)) {
-		struct l_wait_info lwi;
 		struct config_llog_data *cld, *cld_prev;
 		int rand = prandom_u32_max(MGC_TIMEOUT_RAND_CENTISEC);
 		int to;
@@ -556,9 +555,9 @@ static int mgc_requeue_thread(void *data)
 		to = msecs_to_jiffies(MGC_TIMEOUT_MIN_SECONDS * MSEC_PER_SEC);
 		/* rand is centi-seconds */
 		to += msecs_to_jiffies(rand * MSEC_PER_SEC / 100);
-		lwi = LWI_TIMEOUT(to, NULL, NULL);
-		l_wait_event(rq_waitq, rq_state & (RQ_STOP | RQ_PRECLEANUP),
-			     &lwi);
+		wait_event_idle_timeout(rq_waitq,
+					rq_state & (RQ_STOP | RQ_PRECLEANUP),
+					to);
 
 		/*
 		 * iterate & processing through the list. for each cld, process
@@ -1628,9 +1627,7 @@ int mgc_process_log(struct obd_device *mgc, struct config_llog_data *cld)
 
 		if (rcl == -ESHUTDOWN &&
 		    atomic_read(&mgc->u.cli.cl_mgc_refcount) > 0 && !retry) {
-			int secs = obd_timeout * HZ;
 			struct obd_import *imp;
-			struct l_wait_info lwi;
 
 			mutex_unlock(&cld->cld_lock);
 			imp = class_exp2cliimp(mgc->u.cli.cl_mgc_mgsexp);
@@ -1645,9 +1642,9 @@ int mgc_process_log(struct obd_device *mgc, struct config_llog_data *cld)
 			 */
 			ptlrpc_pinger_force(imp);
 
-			lwi = LWI_TIMEOUT(secs, NULL, NULL);
-			l_wait_event(imp->imp_recovery_waitq,
-				     !mgc_import_in_recovery(imp), &lwi);
+			wait_event_idle_timeout(imp->imp_recovery_waitq,
+						!mgc_import_in_recovery(imp),
+						obd_timeout * HZ);
 
 			if (imp->imp_state == LUSTRE_IMP_FULL) {
 				retry = true;
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
index ce5e7bdda692..ab84e011b560 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -1097,16 +1097,19 @@ EXPORT_SYMBOL(cl_sync_io_init);
 int cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
 		    long timeout)
 {
-	struct l_wait_info lwi = LWI_TIMEOUT_INTR(timeout * HZ,
-						  NULL, NULL, NULL);
-	int rc;
+	int rc = 1;
 
 	LASSERT(timeout >= 0);
 
-	rc = l_wait_event(anchor->csi_waitq,
-			  atomic_read(&anchor->csi_sync_nr) == 0,
-			  &lwi);
-	if (rc < 0) {
+	if (timeout == 0)
+		wait_event_idle(anchor->csi_waitq,
+				atomic_read(&anchor->csi_sync_nr) == 0);
+	else
+		rc = wait_event_idle_timeout(anchor->csi_waitq,
+					     atomic_read(&anchor->csi_sync_nr) == 0,
+					     timeout * HZ);
+	if (rc == 0) {
+		rc = -ETIMEDOUT;
 		CERROR("IO failed: %d, still wait for %d remaining entries\n",
 		       rc, atomic_read(&anchor->csi_sync_nr));
 
diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c
index 0797e671f667..dacfab12c501 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cache.c
+++ b/drivers/staging/lustre/lustre/osc/osc_cache.c
@@ -934,8 +934,6 @@ static int osc_extent_wait(const struct lu_env *env, struct osc_extent *ext,
 			   enum osc_extent_state state)
 {
 	struct osc_object *obj = ext->oe_obj;
-	struct l_wait_info lwi = LWI_TIMEOUT_INTR(600 * HZ, NULL,
-						  LWI_ON_SIGNAL_NOOP, NULL);
 	int rc = 0;
 
 	osc_object_lock(obj);
@@ -958,17 +956,19 @@ static int osc_extent_wait(const struct lu_env *env, struct osc_extent *ext,
 		osc_extent_release(env, ext);
 
 	/* wait for the extent until its state becomes @state */
-	rc = l_wait_event(ext->oe_waitq, extent_wait_cb(ext, state), &lwi);
-	if (rc == -ETIMEDOUT) {
+	rc = wait_event_idle_timeout(ext->oe_waitq,
+				     extent_wait_cb(ext, state), 600 * HZ);
+	if (rc == 0) {
 		OSC_EXTENT_DUMP(D_ERROR, ext,
 				"%s: wait ext to %u timedout, recovery in progress?\n",
 				cli_name(osc_cli(obj)), state);
 
 		wait_event_idle(ext->oe_waitq, extent_wait_cb(ext, state));
-		rc = 0;
 	}
-	if (rc == 0 && ext->oe_rc < 0)
+	if (ext->oe_rc < 0)
 		rc = ext->oe_rc;
+	else
+		rc = 0;
 	return rc;
 }
 
@@ -1568,12 +1568,9 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli,
 	struct osc_object *osc = oap->oap_obj;
 	struct lov_oinfo *loi = osc->oo_oinfo;
 	struct osc_cache_waiter ocw;
-	struct l_wait_info lwi;
+	unsigned long timeout = (AT_OFF ? obd_timeout : at_max) * HZ;
 	int rc = -EDQUOT;
 
-	lwi = LWI_TIMEOUT_INTR((AT_OFF ? obd_timeout : at_max) * HZ,
-			       NULL, LWI_ON_SIGNAL_NOOP, NULL);
-
 	OSC_DUMP_GRANT(D_CACHE, cli, "need:%d\n", bytes);
 
 	spin_lock(&cli->cl_loi_list_lock);
@@ -1616,13 +1613,15 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli,
 		CDEBUG(D_CACHE, "%s: sleeping for cache space @ %p for %p\n",
 		       cli_name(cli), &ocw, oap);
 
-		rc = l_wait_event(ocw.ocw_waitq, ocw_granted(cli, &ocw), &lwi);
+		rc = wait_event_idle_timeout(ocw.ocw_waitq,
+					     ocw_granted(cli, &ocw), timeout);
 
 		spin_lock(&cli->cl_loi_list_lock);
 
-		if (rc < 0) {
-			/* l_wait_event is interrupted by signal, or timed out */
+		if (rc == 0) {
+			/* wait_event is interrupted by signal, or timed out */
 			list_del_init(&ocw.ocw_entry);
+			rc = -ETIMEDOUT;
 			break;
 		}
 		LASSERT(list_empty(&ocw.ocw_entry));
diff --git a/drivers/staging/lustre/lustre/ptlrpc/events.c b/drivers/staging/lustre/lustre/ptlrpc/events.c
index 71f7588570ef..130bacc2c891 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/events.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/events.c
@@ -490,8 +490,6 @@ int ptlrpc_uuid_to_peer(struct obd_uuid *uuid,
 
 static void ptlrpc_ni_fini(void)
 {
-	wait_queue_head_t waitq;
-	struct l_wait_info lwi;
 	int rc;
 	int retries;
 
@@ -515,10 +513,7 @@ static void ptlrpc_ni_fini(void)
 			if (retries != 0)
 				CWARN("Event queue still busy\n");
 
-			/* Wait for a bit */
-			init_waitqueue_head(&waitq);
-			lwi = LWI_TIMEOUT(2 * HZ, NULL, NULL);
-			l_wait_event(waitq, 0, &lwi);
+			schedule_timeout_uninterruptible(2 * HZ);
 			break;
 		}
 	}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c
index 0eba5f18bd3b..ed210550f61f 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/import.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/import.c
@@ -430,21 +430,19 @@ void ptlrpc_fail_import(struct obd_import *imp, __u32 conn_cnt)
 
 int ptlrpc_reconnect_import(struct obd_import *imp)
 {
-	struct l_wait_info lwi;
-	int secs = obd_timeout * HZ;
 	int rc;
 
 	ptlrpc_pinger_force(imp);
 
 	CDEBUG(D_HA, "%s: recovery started, waiting %u seconds\n",
-	       obd2cli_tgt(imp->imp_obd), secs);
+	       obd2cli_tgt(imp->imp_obd), obd_timeout);
 
-	lwi = LWI_TIMEOUT(secs, NULL, NULL);
-	rc = l_wait_event(imp->imp_recovery_waitq,
-			  !ptlrpc_import_in_recovery(imp), &lwi);
+	rc = wait_event_idle_timeout(imp->imp_recovery_waitq,
+				     !ptlrpc_import_in_recovery(imp),
+				     obd_timeout * HZ);
 	CDEBUG(D_HA, "%s: recovery finished s:%s\n", obd2cli_tgt(imp->imp_obd),
 	       ptlrpc_import_state_name(imp->imp_state));
-	return rc;
+	return rc == 0 ? -ETIMEDOUT : 0;
 }
 EXPORT_SYMBOL(ptlrpc_reconnect_import);
 
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
index c060d6f5015a..f73463ac401f 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
@@ -260,17 +260,16 @@ lustre_get_emerg_rs(struct ptlrpc_service_part *svcpt)
 
 	/* See if we have anything in a pool, and wait if nothing */
 	while (list_empty(&svcpt->scp_rep_idle)) {
-		struct l_wait_info lwi;
 		int rc;
 
 		spin_unlock(&svcpt->scp_rep_lock);
 		/* If we cannot get anything for some long time, we better
 		 * bail out instead of waiting infinitely
 		 */
-		lwi = LWI_TIMEOUT(10 * HZ, NULL, NULL);
-		rc = l_wait_event(svcpt->scp_rep_waitq,
-				  !list_empty(&svcpt->scp_rep_idle), &lwi);
-		if (rc != 0)
+		rc = wait_event_idle_timeout(svcpt->scp_rep_waitq,
+					     !list_empty(&svcpt->scp_rep_idle),
+					     10 * HZ);
+		if (rc == 0)
 			goto out;
 		spin_lock(&svcpt->scp_rep_lock);
 	}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
index 010a1cdf05fa..639070f6e68e 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
@@ -228,7 +228,6 @@ static int ptlrpc_pinger_main(void *arg)
 	/* And now, loop forever, pinging as needed. */
 	while (1) {
 		unsigned long this_ping = cfs_time_current();
-		struct l_wait_info lwi;
 		long time_to_next_wake;
 		struct timeout_item *item;
 		struct list_head *iter;
@@ -266,13 +265,10 @@ static int ptlrpc_pinger_main(void *arg)
 		       cfs_time_add(this_ping,
 				    PING_INTERVAL * HZ));
 		if (time_to_next_wake > 0) {
-			lwi = LWI_TIMEOUT(max_t(long, time_to_next_wake,
-						HZ),
-					  NULL, NULL);
-			l_wait_event(thread->t_ctl_waitq,
-				     thread_is_stopping(thread) ||
-				     thread_is_event(thread),
-				     &lwi);
+			wait_event_idle_timeout(thread->t_ctl_waitq,
+						thread_is_stopping(thread) ||
+						thread_is_event(thread),
+						max_t(long, time_to_next_wake, HZ));
 			if (thread_test_and_clear_flags(thread, SVC_STOPPING))
 				break;
 			/* woken after adding import to reset timer */
diff --git a/drivers/staging/lustre/lustre/ptlrpc/recover.c b/drivers/staging/lustre/lustre/ptlrpc/recover.c
index 5bbd23eebfa6..7b5f2429d144 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/recover.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/recover.c
@@ -346,17 +346,15 @@ int ptlrpc_recover_import(struct obd_import *imp, char *new_uuid, int async)
 		goto out;
 
 	if (!async) {
-		struct l_wait_info lwi;
-		int secs = obd_timeout * HZ;
-
 		CDEBUG(D_HA, "%s: recovery started, waiting %u seconds\n",
-		       obd2cli_tgt(imp->imp_obd), secs);
+		       obd2cli_tgt(imp->imp_obd), obd_timeout);
 
-		lwi = LWI_TIMEOUT(secs, NULL, NULL);
-		rc = l_wait_event(imp->imp_recovery_waitq,
-				  !ptlrpc_import_in_recovery(imp), &lwi);
+		rc = wait_event_idle_timeout(imp->imp_recovery_waitq,
+					     !ptlrpc_import_in_recovery(imp),
+					     obd_timeout * HZ);
 		CDEBUG(D_HA, "%s: recovery finished\n",
 		       obd2cli_tgt(imp->imp_obd));
+		rc = rc? 0 : -ETIMEDOUT;
 	}
 
 out:
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
index b61e1aa25e8c..48f1a72afd77 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
@@ -142,7 +142,6 @@ static void sec_do_gc(struct ptlrpc_sec *sec)
 static int sec_gc_main(void *arg)
 {
 	struct ptlrpc_thread *thread = arg;
-	struct l_wait_info lwi;
 
 	unshare_fs_struct();
 
@@ -179,12 +178,9 @@ static int sec_gc_main(void *arg)
 
 		/* check ctx list again before sleep */
 		sec_process_ctx_list();
-
-		lwi = LWI_TIMEOUT(msecs_to_jiffies(SEC_GC_INTERVAL * MSEC_PER_SEC),
-				  NULL, NULL);
-		l_wait_event(thread->t_ctl_waitq,
-			     thread_is_stopping(thread),
-			     &lwi);
+		wait_event_idle_timeout(thread->t_ctl_waitq,
+					thread_is_stopping(thread),
+					SEC_GC_INTERVAL * HZ);
 
 		if (thread_test_and_clear_flags(thread, SVC_STOPPING))
 			break;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
index 6d4229ebc9d9..5c41297d23d2 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -2588,13 +2588,12 @@ static void ptlrpc_wait_replies(struct ptlrpc_service_part *svcpt)
 {
 	while (1) {
 		int rc;
-		struct l_wait_info lwi = LWI_TIMEOUT(10 * HZ,
-						     NULL, NULL);
 
-		rc = l_wait_event(svcpt->scp_waitq,
-				  atomic_read(&svcpt->scp_nreps_difficult) == 0,
-				  &lwi);
-		if (rc == 0)
+		rc = wait_event_idle_timeout(
+			svcpt->scp_waitq,
+			atomic_read(&svcpt->scp_nreps_difficult) == 0,
+			10 * HZ);
+		if (rc > 0)
 			break;
 		CWARN("Unexpectedly long timeout %s %p\n",
 		      svcpt->scp_service->srv_name, svcpt->scp_service);

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 04/19] staging: lustre: discard cfs_time_seconds()
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 21:22   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

cfs_time_seconds() converts a number of seconds to the
matching number of jiffies.
The standard way to do this in Linux is  "* HZ".
So discard cfs_time_seconds() and use "* HZ" instead.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 .../lustre/include/linux/libcfs/libcfs_debug.h     |    4 ++--
 .../lustre/include/linux/libcfs/libcfs_time.h      |    2 +-
 .../lustre/include/linux/libcfs/linux/linux-time.h |    7 +-----
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c    |    8 ++++---
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c |    4 ++--
 .../staging/lustre/lnet/klnds/socklnd/socklnd.c    |    6 +++--
 .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c |   22 ++++++++++----------
 drivers/staging/lustre/lnet/libcfs/debug.c         |    2 +-
 drivers/staging/lustre/lnet/libcfs/fail.c          |    2 +-
 drivers/staging/lustre/lnet/libcfs/tracefile.c     |    4 ++--
 drivers/staging/lustre/lnet/lnet/acceptor.c        |    2 +-
 drivers/staging/lustre/lnet/lnet/api-ni.c          |    4 ++--
 drivers/staging/lustre/lnet/lnet/lib-move.c        |    4 ++--
 drivers/staging/lustre/lnet/lnet/net_fault.c       |   14 +++++--------
 drivers/staging/lustre/lnet/lnet/peer.c            |    2 +-
 drivers/staging/lustre/lnet/lnet/router.c          |    8 ++++---
 drivers/staging/lustre/lnet/selftest/conrpc.c      |    4 ++--
 drivers/staging/lustre/lnet/selftest/rpc.c         |    2 +-
 drivers/staging/lustre/lnet/selftest/selftest.h    |    2 +-
 drivers/staging/lustre/lnet/selftest/timer.c       |    2 +-
 drivers/staging/lustre/lustre/include/lustre_dlm.h |    2 +-
 drivers/staging/lustre/lustre/include/lustre_mdc.h |    2 +-
 drivers/staging/lustre/lustre/include/lustre_net.h |    2 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c     |    2 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c    |    4 ++--
 drivers/staging/lustre/lustre/ldlm/ldlm_pool.c     |    2 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_request.c  |    2 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |    2 +-
 drivers/staging/lustre/lustre/llite/llite_lib.c    |    4 ++--
 drivers/staging/lustre/lustre/llite/statahead.c    |    2 +-
 drivers/staging/lustre/lustre/lov/lov_request.c    |    4 ++--
 drivers/staging/lustre/lustre/mdc/mdc_request.c    |    2 +-
 drivers/staging/lustre/lustre/mgc/mgc_request.c    |    2 +-
 drivers/staging/lustre/lustre/obdclass/cl_io.c     |    2 +-
 .../staging/lustre/lustre/obdecho/echo_client.c    |    2 +-
 drivers/staging/lustre/lustre/osc/osc_cache.c      |    4 ++--
 drivers/staging/lustre/lustre/osc/osc_object.c     |    2 +-
 drivers/staging/lustre/lustre/ptlrpc/client.c      |   10 +++++----
 drivers/staging/lustre/lustre/ptlrpc/events.c      |    2 +-
 drivers/staging/lustre/lustre/ptlrpc/import.c      |   15 ++++++--------
 drivers/staging/lustre/lustre/ptlrpc/niobuf.c      |    4 ++--
 .../staging/lustre/lustre/ptlrpc/pack_generic.c    |    2 +-
 drivers/staging/lustre/lustre/ptlrpc/pinger.c      |    8 ++++---
 drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c     |    4 ++--
 drivers/staging/lustre/lustre/ptlrpc/recover.c     |    2 +-
 drivers/staging/lustre/lustre/ptlrpc/service.c     |    8 ++++---
 46 files changed, 96 insertions(+), 106 deletions(-)

diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
index 1b98f0953afb..9290a19429e7 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
@@ -66,8 +66,8 @@ extern unsigned int libcfs_panic_on_lbug;
 # define DEBUG_SUBSYSTEM S_UNDEFINED
 #endif
 
-#define CDEBUG_DEFAULT_MAX_DELAY (cfs_time_seconds(600))	 /* jiffies */
-#define CDEBUG_DEFAULT_MIN_DELAY ((cfs_time_seconds(1) + 1) / 2) /* jiffies */
+#define CDEBUG_DEFAULT_MAX_DELAY (600 * HZ)	 /* jiffies */
+#define CDEBUG_DEFAULT_MIN_DELAY ((HZ + 1) / 2) /* jiffies */
 #define CDEBUG_DEFAULT_BACKOFF   2
 struct cfs_debug_limit_state {
 	unsigned long   cdls_next;
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h
index 9699646decb9..c4f25be78268 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h
@@ -62,7 +62,7 @@ static inline int cfs_time_aftereq(unsigned long t1, unsigned long t2)
 
 static inline unsigned long cfs_time_shift(int seconds)
 {
-	return cfs_time_add(cfs_time_current(), cfs_time_seconds(seconds));
+	return cfs_time_add(cfs_time_current(), seconds * HZ);
 }
 
 /*
diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h
index aece13698eb4..805cb326af86 100644
--- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h
+++ b/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h
@@ -65,11 +65,6 @@ static inline unsigned long cfs_time_current(void)
 	return jiffies;
 }
 
-static inline long cfs_time_seconds(int seconds)
-{
-	return ((long)seconds) * msecs_to_jiffies(MSEC_PER_SEC);
-}
-
 static inline long cfs_duration_sec(long d)
 {
 	return d / msecs_to_jiffies(MSEC_PER_SEC);
@@ -85,7 +80,7 @@ static inline u64 cfs_time_add_64(u64 t, u64 d)
 static inline u64 cfs_time_shift_64(int seconds)
 {
 	return cfs_time_add_64(cfs_time_current_64(),
-			       cfs_time_seconds(seconds));
+			       seconds * HZ);
 }
 
 static inline int cfs_time_before_64(u64 t1, u64 t2)
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
index ec84edfda271..7ae2955c4db6 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
@@ -1211,7 +1211,7 @@ static struct kib_hca_dev *kiblnd_current_hdev(struct kib_dev *dev)
 			CDEBUG(D_NET, "%s: Wait for failover\n",
 			       dev->ibd_ifname);
 		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1) / 100);
+		schedule_timeout(HZ / 100);
 
 		read_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
 	}
@@ -1921,7 +1921,7 @@ struct list_head *kiblnd_pool_alloc_node(struct kib_poolset *ps)
 
 		set_current_state(TASK_INTERRUPTIBLE);
 		schedule_timeout(interval);
-		if (interval < cfs_time_seconds(1))
+		if (interval < HZ)
 			interval *= 2;
 
 		goto again;
@@ -2541,7 +2541,7 @@ static void kiblnd_base_shutdown(void)
 			       "Waiting for %d threads to terminate\n",
 			       atomic_read(&kiblnd_data.kib_nthreads));
 			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(cfs_time_seconds(1));
+			schedule_timeout(HZ);
 		}
 
 		/* fall through */
@@ -2592,7 +2592,7 @@ static void kiblnd_shutdown(struct lnet_ni *ni)
 			       libcfs_nid2str(ni->ni_nid),
 			       atomic_read(&net->ibn_npeers));
 			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(cfs_time_seconds(1));
+			schedule_timeout(HZ);
 		}
 
 		kiblnd_net_fini_pools(net);
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
index b3e7f28eb978..ca094555e04b 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
@@ -3728,8 +3728,8 @@ kiblnd_failover_thread(void *arg)
 		add_wait_queue(&kiblnd_data.kib_failover_waitq, &wait);
 		write_unlock_irqrestore(glock, flags);
 
-		rc = schedule_timeout(long_sleep ? cfs_time_seconds(10) :
-						   cfs_time_seconds(1));
+		rc = schedule_timeout(long_sleep ? 10 * HZ :
+						   HZ);
 		remove_wait_queue(&kiblnd_data.kib_failover_waitq, &wait);
 		write_lock_irqsave(glock, flags);
 
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
index ff292216290d..7086678e1c3e 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
@@ -1677,7 +1677,7 @@ ksocknal_destroy_conn(struct ksock_conn *conn)
 	switch (conn->ksnc_rx_state) {
 	case SOCKNAL_RX_LNET_PAYLOAD:
 		last_rcv = conn->ksnc_rx_deadline -
-			   cfs_time_seconds(*ksocknal_tunables.ksnd_timeout);
+			   *ksocknal_tunables.ksnd_timeout * HZ;
 		CERROR("Completing partial receive from %s[%d], ip %pI4h:%d, with error, wanted: %zd, left: %d, last alive is %ld secs ago\n",
 		       libcfs_id2str(conn->ksnc_peer->ksnp_id), conn->ksnc_type,
 		       &conn->ksnc_ipaddr, conn->ksnc_port,
@@ -2356,7 +2356,7 @@ ksocknal_base_shutdown(void)
 				ksocknal_data.ksnd_nthreads);
 			read_unlock(&ksocknal_data.ksnd_global_lock);
 			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(cfs_time_seconds(1));
+			schedule_timeout(HZ);
 			read_lock(&ksocknal_data.ksnd_global_lock);
 		}
 		read_unlock(&ksocknal_data.ksnd_global_lock);
@@ -2599,7 +2599,7 @@ ksocknal_shutdown(struct lnet_ni *ni)
 		       "waiting for %d peers to disconnect\n",
 		       net->ksnn_npeers);
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1));
+		schedule_timeout(HZ);
 
 		ksocknal_debug_peerhash(ni);
 
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
index 11fd3a36424f..63e452f666bf 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
@@ -189,7 +189,7 @@ ksocknal_transmit(struct ksock_conn *conn, struct ksock_tx *tx)
 
 	if (ksocknal_data.ksnd_stall_tx) {
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(ksocknal_data.ksnd_stall_tx));
+		schedule_timeout(ksocknal_data.ksnd_stall_tx * HZ);
 	}
 
 	LASSERT(tx->tx_resid);
@@ -294,7 +294,7 @@ ksocknal_receive(struct ksock_conn *conn)
 
 	if (ksocknal_data.ksnd_stall_rx) {
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(ksocknal_data.ksnd_stall_rx));
+		schedule_timeout(ksocknal_data.ksnd_stall_rx * HZ);
 	}
 
 	rc = ksocknal_connsock_addref(conn);
@@ -1780,7 +1780,7 @@ ksocknal_connect(struct ksock_route *route)
 	int rc = 0;
 
 	deadline = cfs_time_add(cfs_time_current(),
-				cfs_time_seconds(*ksocknal_tunables.ksnd_timeout));
+				*ksocknal_tunables.ksnd_timeout * HZ);
 
 	write_lock_bh(&ksocknal_data.ksnd_global_lock);
 
@@ -1878,7 +1878,7 @@ ksocknal_connect(struct ksock_route *route)
 			 * so min_reconnectms should be good heuristic
 			 */
 			route->ksnr_retry_interval =
-				cfs_time_seconds(*ksocknal_tunables.ksnd_min_reconnectms) / 1000;
+				*ksocknal_tunables.ksnd_min_reconnectms * HZ / 1000;
 			route->ksnr_timeout = cfs_time_add(cfs_time_current(),
 							   route->ksnr_retry_interval);
 		}
@@ -1899,10 +1899,10 @@ ksocknal_connect(struct ksock_route *route)
 	route->ksnr_retry_interval *= 2;
 	route->ksnr_retry_interval =
 		max(route->ksnr_retry_interval,
-		    cfs_time_seconds(*ksocknal_tunables.ksnd_min_reconnectms) / 1000);
+		    (long)*ksocknal_tunables.ksnd_min_reconnectms * HZ / 1000);
 	route->ksnr_retry_interval =
 		min(route->ksnr_retry_interval,
-		    cfs_time_seconds(*ksocknal_tunables.ksnd_max_reconnectms) / 1000);
+		    (long)*ksocknal_tunables.ksnd_max_reconnectms * HZ / 1000);
 
 	LASSERT(route->ksnr_retry_interval);
 	route->ksnr_timeout = cfs_time_add(cfs_time_current(),
@@ -1972,7 +1972,7 @@ ksocknal_connd_check_start(time64_t sec, long *timeout)
 
 	if (sec - ksocknal_data.ksnd_connd_failed_stamp <= 1) {
 		/* may run out of resource, retry later */
-		*timeout = cfs_time_seconds(1);
+		*timeout = HZ;
 		return 0;
 	}
 
@@ -2031,8 +2031,8 @@ ksocknal_connd_check_stop(time64_t sec, long *timeout)
 	val = (int)(ksocknal_data.ksnd_connd_starting_stamp +
 		    SOCKNAL_CONND_TIMEOUT - sec);
 
-	*timeout = (val > 0) ? cfs_time_seconds(val) :
-			       cfs_time_seconds(SOCKNAL_CONND_TIMEOUT);
+	*timeout = (val > 0) ? val * HZ :
+			       SOCKNAL_CONND_TIMEOUT * HZ;
 	if (val > 0)
 		return 0;
 
@@ -2307,7 +2307,7 @@ ksocknal_send_keepalive_locked(struct ksock_peer *peer)
 	if (*ksocknal_tunables.ksnd_keepalive <= 0 ||
 	    time_before(cfs_time_current(),
 			cfs_time_add(peer->ksnp_last_alive,
-				     cfs_time_seconds(*ksocknal_tunables.ksnd_keepalive))))
+				     *ksocknal_tunables.ksnd_keepalive * HZ)))
 		return 0;
 
 	if (time_before(cfs_time_current(), peer->ksnp_send_keepalive))
@@ -2563,7 +2563,7 @@ ksocknal_reaper(void *arg)
 					     ksocknal_data.ksnd_peer_hash_size;
 			}
 
-			deadline = cfs_time_add(deadline, cfs_time_seconds(p));
+			deadline = cfs_time_add(deadline, p * HZ);
 		}
 
 		if (nenomem_conns) {
diff --git a/drivers/staging/lustre/lnet/libcfs/debug.c b/drivers/staging/lustre/lnet/libcfs/debug.c
index 551c45bf4108..c70d2ae29b11 100644
--- a/drivers/staging/lustre/lnet/libcfs/debug.c
+++ b/drivers/staging/lustre/lnet/libcfs/debug.c
@@ -113,7 +113,7 @@ static int param_set_delay_minmax(const char *val,
 	if (rc)
 		return -EINVAL;
 
-	d = cfs_time_seconds(sec) / 100;
+	d = sec * HZ / 100;
 	if (d < min || d > max)
 		return -EINVAL;
 
diff --git a/drivers/staging/lustre/lnet/libcfs/fail.c b/drivers/staging/lustre/lnet/libcfs/fail.c
index 39439b303d65..d3f1e866c6a7 100644
--- a/drivers/staging/lustre/lnet/libcfs/fail.c
+++ b/drivers/staging/lustre/lnet/libcfs/fail.c
@@ -134,7 +134,7 @@ int __cfs_fail_timeout_set(u32 id, u32 value, int ms, int set)
 		CERROR("cfs_fail_timeout id %x sleeping for %dms\n",
 		       id, ms);
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(ms) / 1000);
+		schedule_timeout(ms * HZ / 1000);
 		CERROR("cfs_fail_timeout id %x awake\n", id);
 	}
 	return ret;
diff --git a/drivers/staging/lustre/lnet/libcfs/tracefile.c b/drivers/staging/lustre/lnet/libcfs/tracefile.c
index 57913aae1d88..4affca750bc5 100644
--- a/drivers/staging/lustre/lnet/libcfs/tracefile.c
+++ b/drivers/staging/lustre/lnet/libcfs/tracefile.c
@@ -441,7 +441,7 @@ int libcfs_debug_vmsg2(struct libcfs_debug_msg_data *msgdata,
 
 		if (cfs_time_after(cfs_time_current(),
 				   cdls->cdls_next + libcfs_console_max_delay +
-				   cfs_time_seconds(10))) {
+				   10 * HZ)) {
 			/* last timeout was a long time ago */
 			cdls->cdls_delay /= libcfs_console_backoff * 4;
 		} else {
@@ -1071,7 +1071,7 @@ static int tracefiled(void *arg)
 		init_waitqueue_entry(&__wait, current);
 		add_wait_queue(&tctl->tctl_waitq, &__wait);
 		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1));
+		schedule_timeout(HZ);
 		remove_wait_queue(&tctl->tctl_waitq, &__wait);
 	}
 	complete(&tctl->tctl_stop);
diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c
index ee85cab6f437..6c1f4941d4ba 100644
--- a/drivers/staging/lustre/lnet/lnet/acceptor.c
+++ b/drivers/staging/lustre/lnet/lnet/acceptor.c
@@ -365,7 +365,7 @@ lnet_acceptor(void *arg)
 			if (rc != -EAGAIN) {
 				CWARN("Accept error %d: pausing...\n", rc);
 				set_current_state(TASK_UNINTERRUPTIBLE);
-				schedule_timeout(cfs_time_seconds(1));
+				schedule_timeout(HZ);
 			}
 			continue;
 		}
diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c
index 2c7abad57104..93e6274e9dac 100644
--- a/drivers/staging/lustre/lnet/lnet/api-ni.c
+++ b/drivers/staging/lustre/lnet/lnet/api-ni.c
@@ -970,7 +970,7 @@ lnet_ping_md_unlink(struct lnet_ping_info *pinfo,
 	while (pinfo->pi_features != LNET_PING_FEAT_INVAL) {
 		CDEBUG(D_NET, "Still waiting for ping MD to unlink\n");
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1));
+		schedule_timeout(HZ);
 	}
 
 	cfs_restore_sigs(blocked);
@@ -1109,7 +1109,7 @@ lnet_clear_zombies_nis_locked(void)
 				       libcfs_nid2str(ni->ni_nid));
 			}
 			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(cfs_time_seconds(1));
+			schedule_timeout(HZ);
 			lnet_net_lock(LNET_LOCK_EX);
 			continue;
 		}
diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c
index c673037dbce4..ed43b3f4b114 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-move.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-move.c
@@ -524,7 +524,7 @@ lnet_peer_is_alive(struct lnet_peer *lp, unsigned long now)
 		return 0;
 
 	deadline = cfs_time_add(lp->lp_last_alive,
-				cfs_time_seconds(lp->lp_ni->ni_peertimeout));
+				lp->lp_ni->ni_peertimeout * HZ);
 	alive = cfs_time_after(deadline, now);
 
 	/* Update obsolete lp_alive except for routers assumed to be dead
@@ -562,7 +562,7 @@ lnet_peer_alive_locked(struct lnet_peer *lp)
 
 		unsigned long next_query =
 			   cfs_time_add(lp->lp_last_query,
-					cfs_time_seconds(lnet_queryinterval));
+					lnet_queryinterval * HZ);
 
 		if (time_before(now, next_query)) {
 			if (lp->lp_alive)
diff --git a/drivers/staging/lustre/lnet/lnet/net_fault.c b/drivers/staging/lustre/lnet/lnet/net_fault.c
index e3468cef273b..a63b7941d435 100644
--- a/drivers/staging/lustre/lnet/lnet/net_fault.c
+++ b/drivers/staging/lustre/lnet/lnet/net_fault.c
@@ -315,9 +315,8 @@ drop_rule_match(struct lnet_drop_rule *rule, lnet_nid_t src,
 				rule->dr_time_base = now;
 
 			rule->dr_drop_time = rule->dr_time_base +
-				cfs_time_seconds(
-					prandom_u32_max(attr->u.drop.da_interval));
-			rule->dr_time_base += cfs_time_seconds(attr->u.drop.da_interval);
+				prandom_u32_max(attr->u.drop.da_interval) * HZ;
+			rule->dr_time_base += attr->u.drop.da_interval * HZ;
 
 			CDEBUG(D_NET, "Drop Rule %s->%s: next drop : %lu\n",
 			       libcfs_nid2str(attr->fa_src),
@@ -440,8 +439,7 @@ static struct delay_daemon_data	delay_dd;
 static unsigned long
 round_timeout(unsigned long timeout)
 {
-	return cfs_time_seconds((unsigned int)
-			cfs_duration_sec(cfs_time_sub(timeout, 0)) + 1);
+	return (unsigned int)rounddown(timeout, HZ) + HZ;
 }
 
 static void
@@ -483,10 +481,8 @@ delay_rule_match(struct lnet_delay_rule *rule, lnet_nid_t src,
 				rule->dl_time_base = now;
 
 			rule->dl_delay_time = rule->dl_time_base +
-				cfs_time_seconds(
-					prandom_u32_max(
-						attr->u.delay.la_interval));
-			rule->dl_time_base += cfs_time_seconds(attr->u.delay.la_interval);
+				prandom_u32_max(attr->u.delay.la_interval) * HZ;
+			rule->dl_time_base += attr->u.delay.la_interval * HZ;
 
 			CDEBUG(D_NET, "Delay Rule %s->%s: next delay : %lu\n",
 			       libcfs_nid2str(attr->fa_src),
diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c
index 3e157c10fec4..3d4caa609c83 100644
--- a/drivers/staging/lustre/lnet/lnet/peer.c
+++ b/drivers/staging/lustre/lnet/lnet/peer.c
@@ -137,7 +137,7 @@ lnet_peer_table_deathrow_wait_locked(struct lnet_peer_table *ptable,
 			       ptable->pt_zombies);
 		}
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1) >> 1);
+		schedule_timeout(HZ >> 1);
 		lnet_net_lock(cpt_locked);
 	}
 }
diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c
index 6504761ca598..ec1d3e58519a 100644
--- a/drivers/staging/lustre/lnet/lnet/router.c
+++ b/drivers/staging/lustre/lnet/lnet/router.c
@@ -808,7 +808,7 @@ lnet_wait_known_routerstate(void)
 			return;
 
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1));
+		schedule_timeout(HZ);
 	}
 }
 
@@ -1011,7 +1011,7 @@ lnet_ping_router_locked(struct lnet_peer *rtr)
 
 	if (secs && !rtr->lp_ping_notsent &&
 	    cfs_time_after(now, cfs_time_add(rtr->lp_ping_timestamp,
-					     cfs_time_seconds(secs)))) {
+					     secs * HZ))) {
 		int rc;
 		struct lnet_process_id id;
 		struct lnet_handle_md mdh;
@@ -1185,7 +1185,7 @@ lnet_prune_rc_data(int wait_unlink)
 		CDEBUG(((i & (-i)) == i) ? D_WARNING : D_NET,
 		       "Waiting for rc buffers to unlink\n");
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1) / 4);
+		schedule_timeout(HZ / 4);
 
 		lnet_net_lock(LNET_LOCK_EX);
 	}
@@ -1282,7 +1282,7 @@ lnet_router_checker(void *arg)
 		else
 			wait_event_interruptible_timeout(the_lnet.ln_rc_waitq,
 							 false,
-							 cfs_time_seconds(1));
+							 HZ);
 	}
 
 	lnet_prune_rc_data(1); /* wait for UNLINK */
diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c
index 7aa515c34594..6dcc966b293b 100644
--- a/drivers/staging/lustre/lnet/selftest/conrpc.c
+++ b/drivers/staging/lustre/lnet/selftest/conrpc.c
@@ -359,7 +359,7 @@ lstcon_rpc_trans_postwait(struct lstcon_rpc_trans *trans, int timeout)
 
 	rc = wait_event_interruptible_timeout(trans->tas_waitq,
 					      lstcon_rpc_trans_check(trans),
-					      cfs_time_seconds(timeout));
+					      timeout * HZ);
 	rc = (rc > 0) ? 0 : ((rc < 0) ? -EINTR : -ETIMEDOUT);
 
 	mutex_lock(&console_session.ses_mutex);
@@ -1350,7 +1350,7 @@ lstcon_rpc_cleanup_wait(void)
 
 		CWARN("Session is shutting down, waiting for termination of transactions\n");
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1));
+		schedule_timeout(HZ);
 
 		mutex_lock(&console_session.ses_mutex);
 	}
diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c
index f8198ad1046e..9613b0a77007 100644
--- a/drivers/staging/lustre/lnet/selftest/rpc.c
+++ b/drivers/staging/lustre/lnet/selftest/rpc.c
@@ -1604,7 +1604,7 @@ srpc_startup(void)
 
 	/* 1 second pause to avoid timestamp reuse */
 	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(cfs_time_seconds(1));
+	schedule_timeout(HZ);
 	srpc_data.rpc_matchbits = ((__u64)ktime_get_real_seconds()) << 48;
 
 	srpc_data.rpc_state = SRPC_STATE_NONE;
diff --git a/drivers/staging/lustre/lnet/selftest/selftest.h b/drivers/staging/lustre/lnet/selftest/selftest.h
index ad04534f000c..05466b85e1c0 100644
--- a/drivers/staging/lustre/lnet/selftest/selftest.h
+++ b/drivers/staging/lustre/lnet/selftest/selftest.h
@@ -575,7 +575,7 @@ swi_state2str(int state)
 #define selftest_wait_events()					\
 	do {							\
 		set_current_state(TASK_UNINTERRUPTIBLE);	\
-		schedule_timeout(cfs_time_seconds(1) / 10);	\
+		schedule_timeout(HZ / 10);	\
 	} while (0)
 
 #define lst_wait_until(cond, lock, fmt, ...)				\
diff --git a/drivers/staging/lustre/lnet/selftest/timer.c b/drivers/staging/lustre/lnet/selftest/timer.c
index ab125a8524c5..9716afeb3c94 100644
--- a/drivers/staging/lustre/lnet/selftest/timer.c
+++ b/drivers/staging/lustre/lnet/selftest/timer.c
@@ -177,7 +177,7 @@ stt_timer_main(void *arg)
 
 		rc = wait_event_timeout(stt_data.stt_waitq,
 					stt_data.stt_shuttingdown,
-					cfs_time_seconds(STTIMER_SLOTTIME));
+					STTIMER_SLOTTIME * HZ);
 	}
 
 	spin_lock(&stt_data.stt_lock);
diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h
index e0b17052b2ea..239aa2b1268f 100644
--- a/drivers/staging/lustre/lustre/include/lustre_dlm.h
+++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h
@@ -60,7 +60,7 @@ struct obd_device;
 #define OBD_LDLM_DEVICENAME  "ldlm"
 
 #define LDLM_DEFAULT_LRU_SIZE (100 * num_online_cpus())
-#define LDLM_DEFAULT_MAX_ALIVE (cfs_time_seconds(3900)) /* 65 min */
+#define LDLM_DEFAULT_MAX_ALIVE (65 * 60 * HZ) /* 65 min */
 #define LDLM_DEFAULT_PARALLEL_AST_LIMIT 1024
 
 /**
diff --git a/drivers/staging/lustre/lustre/include/lustre_mdc.h b/drivers/staging/lustre/lustre/include/lustre_mdc.h
index 007e1ec3f0f4..a9c9992a2502 100644
--- a/drivers/staging/lustre/lustre/include/lustre_mdc.h
+++ b/drivers/staging/lustre/lustre/include/lustre_mdc.h
@@ -124,7 +124,7 @@ static inline void mdc_get_rpc_lock(struct mdc_rpc_lock *lck,
 	 */
 	while (unlikely(lck->rpcl_it == MDC_FAKE_RPCL_IT)) {
 		mutex_unlock(&lck->rpcl_mutex);
-		schedule_timeout(cfs_time_seconds(1) / 4);
+		schedule_timeout(HZ / 4);
 		goto again;
 	}
 
diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h
index 4c665eca2467..5a4434e7c85a 100644
--- a/drivers/staging/lustre/lustre/include/lustre_net.h
+++ b/drivers/staging/lustre/lustre/include/lustre_net.h
@@ -2262,7 +2262,7 @@ static inline int ptlrpc_send_limit_expired(struct ptlrpc_request *req)
 {
 	if (req->rq_delay_limit != 0 &&
 	    time_before(cfs_time_add(req->rq_queued_time,
-				     cfs_time_seconds(req->rq_delay_limit)),
+				     req->rq_delay_limit * HZ),
 			cfs_time_current())) {
 		return 1;
 	}
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
index 4f700ddb47c6..773abe78708a 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
@@ -1366,7 +1366,7 @@ enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags,
 				}
 			}
 
-			lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(obd_timeout),
+			lwi = LWI_TIMEOUT_INTR(obd_timeout * HZ,
 					       NULL, LWI_ON_SIGNAL_NOOP, NULL);
 
 			/* XXX FIXME see comment on CAN_MATCH in lustre_dlm.h */
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
index 6c7c4b19a0a0..58913e628124 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
@@ -163,7 +163,7 @@ static void ldlm_handle_cp_callback(struct ptlrpc_request *req,
 	LDLM_DEBUG(lock, "client completion callback handler START");
 
 	if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_CANCEL_BL_CB_RACE)) {
-		int to = cfs_time_seconds(1);
+		int to = HZ;
 
 		while (to > 0) {
 			set_current_state(TASK_INTERRUPTIBLE);
@@ -327,7 +327,7 @@ static void ldlm_handle_gl_callback(struct ptlrpc_request *req,
 	    !lock->l_readers && !lock->l_writers &&
 	    cfs_time_after(cfs_time_current(),
 			   cfs_time_add(lock->l_last_used,
-					cfs_time_seconds(10)))) {
+					10 * HZ))) {
 		unlock_res_and_lock(lock);
 		if (ldlm_bl_to_thread_lock(ns, NULL, lock))
 			ldlm_handle_bl_callback(ns, NULL, lock);
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
index f27c2694793a..622245a5f049 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
@@ -1008,7 +1008,7 @@ static int ldlm_pools_thread_main(void *arg)
 		 * Wait until the next check time, or until we're
 		 * stopped.
 		 */
-		lwi = LWI_TIMEOUT(cfs_time_seconds(c_time),
+		lwi = LWI_TIMEOUT(c_time * HZ,
 				  NULL, NULL);
 		l_wait_event(thread->t_ctl_waitq,
 			     thread_is_stopping(thread) ||
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index 6aa37463db46..a244fa717134 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -288,7 +288,7 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 		LDLM_DEBUG(lock, "waiting indefinitely because of NO_TIMEOUT");
 		lwi = LWI_INTR(interrupted_completion_wait, &lwd);
 	} else {
-		lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(timeout),
+		lwi = LWI_TIMEOUT_INTR(timeout * HZ,
 				       ldlm_expired_completion_wait,
 				       interrupted_completion_wait, &lwd);
 	}
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
index 9958533cc227..2e66825c8f4b 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
@@ -799,7 +799,7 @@ static void cleanup_resource(struct ldlm_resource *res, struct list_head *q,
 			LDLM_DEBUG(lock, "setting FL_LOCAL_ONLY");
 			if (lock->l_flags & LDLM_FL_FAIL_LOC) {
 				set_current_state(TASK_UNINTERRUPTIBLE);
-				schedule_timeout(cfs_time_seconds(4));
+				schedule_timeout(4 * HZ);
 				set_current_state(TASK_RUNNING);
 			}
 			if (lock->l_completion_ast)
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
index 020f0faeb750..c820b201af71 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -2026,8 +2026,8 @@ void ll_umount_begin(struct super_block *sb)
 	 * to decrement mnt_cnt and hope to finish it within 10sec.
 	 */
 	init_waitqueue_head(&waitq);
-	lwi = LWI_TIMEOUT_INTERVAL(cfs_time_seconds(10),
-				   cfs_time_seconds(1), NULL, NULL);
+	lwi = LWI_TIMEOUT_INTERVAL(10 * HZ,
+				   HZ, NULL, NULL);
 	l_wait_event(waitq, may_umount(sbi->ll_mnt.mnt), &lwi);
 
 	schedule();
diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c
index 78005cc6e831..96360f104b92 100644
--- a/drivers/staging/lustre/lustre/llite/statahead.c
+++ b/drivers/staging/lustre/lustre/llite/statahead.c
@@ -1424,7 +1424,7 @@ static int revalidate_statahead_dentry(struct inode *dir,
 		spin_lock(&lli->lli_sa_lock);
 		sai->sai_index_wait = entry->se_index;
 		spin_unlock(&lli->lli_sa_lock);
-		lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(30), NULL,
+		lwi = LWI_TIMEOUT_INTR(30 * HZ, NULL,
 				       LWI_ON_SIGNAL_NOOP, NULL);
 		rc = l_wait_event(sai->sai_waitq, sa_ready(entry), &lwi);
 		if (rc < 0) {
diff --git a/drivers/staging/lustre/lustre/lov/lov_request.c b/drivers/staging/lustre/lustre/lov/lov_request.c
index cfa1d7f92b0f..fb3b7a7fa32a 100644
--- a/drivers/staging/lustre/lustre/lov/lov_request.c
+++ b/drivers/staging/lustre/lustre/lov/lov_request.c
@@ -126,8 +126,8 @@ static int lov_check_and_wait_active(struct lov_obd *lov, int ost_idx)
 	mutex_unlock(&lov->lov_lock);
 
 	init_waitqueue_head(&waitq);
-	lwi = LWI_TIMEOUT_INTERVAL(cfs_time_seconds(obd_timeout),
-				   cfs_time_seconds(1), NULL, NULL);
+	lwi = LWI_TIMEOUT_INTERVAL(obd_timeout * HZ,
+				   HZ, NULL, NULL);
 
 	rc = l_wait_event(waitq, lov_check_set(lov, ost_idx), &lwi);
 	if (tgt->ltd_active)
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c
index 03e55bca4ada..b12518ba5ae9 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_request.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c
@@ -888,7 +888,7 @@ static int mdc_getpage(struct obd_export *exp, const struct lu_fid *fid,
 			       exp->exp_obd->obd_name, -EIO);
 			return -EIO;
 		}
-		lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(resends), NULL, NULL,
+		lwi = LWI_TIMEOUT_INTR(resends * HZ, NULL, NULL,
 				       NULL);
 		l_wait_event(waitq, 0, &lwi);
 
diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c
index b743aee62349..a01d13bde102 100644
--- a/drivers/staging/lustre/lustre/mgc/mgc_request.c
+++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c
@@ -1628,7 +1628,7 @@ int mgc_process_log(struct obd_device *mgc, struct config_llog_data *cld)
 
 		if (rcl == -ESHUTDOWN &&
 		    atomic_read(&mgc->u.cli.cl_mgc_refcount) > 0 && !retry) {
-			int secs = cfs_time_seconds(obd_timeout);
+			int secs = obd_timeout * HZ;
 			struct obd_import *imp;
 			struct l_wait_info lwi;
 
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
index 902bad22013b..ce5e7bdda692 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -1097,7 +1097,7 @@ EXPORT_SYMBOL(cl_sync_io_init);
 int cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
 		    long timeout)
 {
-	struct l_wait_info lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(timeout),
+	struct l_wait_info lwi = LWI_TIMEOUT_INTR(timeout * HZ,
 						  NULL, NULL, NULL);
 	int rc;
 
diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c
index b9c1dc7e61b0..9c5ce5074b66 100644
--- a/drivers/staging/lustre/lustre/obdecho/echo_client.c
+++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c
@@ -752,7 +752,7 @@ static struct lu_device *echo_device_free(const struct lu_env *env,
 		spin_unlock(&ec->ec_lock);
 		CERROR("echo_client still has objects at cleanup time, wait for 1 second\n");
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1));
+		schedule_timeout(HZ);
 		lu_site_purge(env, ed->ed_site, -1);
 		spin_lock(&ec->ec_lock);
 	}
diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c
index b8d5adca94e1..0797e671f667 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cache.c
+++ b/drivers/staging/lustre/lustre/osc/osc_cache.c
@@ -934,7 +934,7 @@ static int osc_extent_wait(const struct lu_env *env, struct osc_extent *ext,
 			   enum osc_extent_state state)
 {
 	struct osc_object *obj = ext->oe_obj;
-	struct l_wait_info lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(600), NULL,
+	struct l_wait_info lwi = LWI_TIMEOUT_INTR(600 * HZ, NULL,
 						  LWI_ON_SIGNAL_NOOP, NULL);
 	int rc = 0;
 
@@ -1571,7 +1571,7 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli,
 	struct l_wait_info lwi;
 	int rc = -EDQUOT;
 
-	lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(AT_OFF ? obd_timeout : at_max),
+	lwi = LWI_TIMEOUT_INTR((AT_OFF ? obd_timeout : at_max) * HZ,
 			       NULL, LWI_ON_SIGNAL_NOOP, NULL);
 
 	OSC_DUMP_GRANT(D_CACHE, cli, "need:%d\n", bytes);
diff --git a/drivers/staging/lustre/lustre/osc/osc_object.c b/drivers/staging/lustre/lustre/osc/osc_object.c
index 6c424f0290bb..6baa8e2e00c9 100644
--- a/drivers/staging/lustre/lustre/osc/osc_object.c
+++ b/drivers/staging/lustre/lustre/osc/osc_object.c
@@ -328,7 +328,7 @@ int osc_object_is_contended(struct osc_object *obj)
 	 * ll_file_is_contended.
 	 */
 	retry_time = cfs_time_add(obj->oo_contention_time,
-				  cfs_time_seconds(osc_contention_time));
+				  osc_contention_time * HZ);
 	if (cfs_time_after(cur_time, retry_time)) {
 		osc_object_clear_contended(obj);
 		return 0;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index bac4b2304bad..0ab13f8e5993 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -766,7 +766,7 @@ int ptlrpc_request_bufs_pack(struct ptlrpc_request *request,
 			 * fail_loc
 			 */
 			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(cfs_time_seconds(2));
+			schedule_timeout(2 * HZ);
 			set_current_state(TASK_RUNNING);
 		}
 	}
@@ -2284,7 +2284,7 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 			 * We still want to block for a limited time,
 			 * so we allow interrupts during the timeout.
 			 */
-			lwi = LWI_TIMEOUT_INTR_ALL(cfs_time_seconds(1),
+			lwi = LWI_TIMEOUT_INTR_ALL(HZ,
 						   ptlrpc_expired_set,
 						   ptlrpc_interrupted_set, set);
 		else
@@ -2293,7 +2293,7 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 			 * interrupts are allowed. Wait until all
 			 * complete, or an in-flight req times out.
 			 */
-			lwi = LWI_TIMEOUT(cfs_time_seconds(timeout ? timeout : 1),
+			lwi = LWI_TIMEOUT((timeout ? timeout : 1) * HZ,
 					  ptlrpc_expired_set, set);
 
 		rc = l_wait_event(set->set_waitq, ptlrpc_check_set(NULL, set), &lwi);
@@ -2538,8 +2538,8 @@ static int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async)
 		 * Network access will complete in finite time but the HUGE
 		 * timeout lets us CWARN for visibility of sluggish NALs
 		 */
-		lwi = LWI_TIMEOUT_INTERVAL(cfs_time_seconds(LONG_UNLINK),
-					   cfs_time_seconds(1), NULL, NULL);
+		lwi = LWI_TIMEOUT_INTERVAL(LONG_UNLINK * HZ,
+					   HZ, NULL, NULL);
 		rc = l_wait_event(*wq, !ptlrpc_client_recv_or_unlink(request),
 				  &lwi);
 		if (rc == 0) {
diff --git a/drivers/staging/lustre/lustre/ptlrpc/events.c b/drivers/staging/lustre/lustre/ptlrpc/events.c
index 811b7ab3a582..71f7588570ef 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/events.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/events.c
@@ -517,7 +517,7 @@ static void ptlrpc_ni_fini(void)
 
 			/* Wait for a bit */
 			init_waitqueue_head(&waitq);
-			lwi = LWI_TIMEOUT(cfs_time_seconds(2), NULL, NULL);
+			lwi = LWI_TIMEOUT(2 * HZ, NULL, NULL);
 			l_wait_event(waitq, 0, &lwi);
 			break;
 		}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c
index 5b0f65536c29..0eba5f18bd3b 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/import.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/import.c
@@ -307,9 +307,9 @@ void ptlrpc_invalidate_import(struct obd_import *imp)
 		 * have been locally cancelled by ptlrpc_abort_inflight.
 		 */
 		lwi = LWI_TIMEOUT_INTERVAL(
-			cfs_timeout_cap(cfs_time_seconds(timeout)),
-			(timeout > 1) ? cfs_time_seconds(1) :
-			cfs_time_seconds(1) / 2,
+			cfs_timeout_cap(timeout * HZ),
+			(timeout > 1) ? HZ :
+			HZ / 2,
 			NULL, NULL);
 		rc = l_wait_event(imp->imp_recovery_waitq,
 				  (atomic_read(&imp->imp_inflight) == 0),
@@ -431,7 +431,7 @@ void ptlrpc_fail_import(struct obd_import *imp, __u32 conn_cnt)
 int ptlrpc_reconnect_import(struct obd_import *imp)
 {
 	struct l_wait_info lwi;
-	int secs = cfs_time_seconds(obd_timeout);
+	int secs = obd_timeout * HZ;
 	int rc;
 
 	ptlrpc_pinger_force(imp);
@@ -1508,14 +1508,13 @@ int ptlrpc_disconnect_import(struct obd_import *imp, int noclose)
 
 		if (AT_OFF) {
 			if (imp->imp_server_timeout)
-				timeout = cfs_time_seconds(obd_timeout / 2);
+				timeout = obd_timeout * HZ / 2;
 			else
-				timeout = cfs_time_seconds(obd_timeout);
+				timeout = obd_timeout * HZ;
 		} else {
 			int idx = import_at_get_index(imp,
 				imp->imp_client->cli_request_portal);
-			timeout = cfs_time_seconds(
-				at_get(&imp->imp_at.iat_service_estimate[idx]));
+			timeout = at_get(&imp->imp_at.iat_service_estimate[idx]) * HZ;
 		}
 
 		lwi = LWI_TIMEOUT_INTR(cfs_timeout_cap(timeout),
diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
index 047d712e850c..0c2ded721c49 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
@@ -270,8 +270,8 @@ int ptlrpc_unregister_bulk(struct ptlrpc_request *req, int async)
 		/* Network access will complete in finite time but the HUGE
 		 * timeout lets us CWARN for visibility of sluggish LNDs
 		 */
-		lwi = LWI_TIMEOUT_INTERVAL(cfs_time_seconds(LONG_UNLINK),
-					   cfs_time_seconds(1), NULL, NULL);
+		lwi = LWI_TIMEOUT_INTERVAL(LONG_UNLINK * HZ,
+					   HZ, NULL, NULL);
 		rc = l_wait_event(*wq, !ptlrpc_client_bulk_active(req), &lwi);
 		if (rc == 0) {
 			ptlrpc_rqphase_move(req, req->rq_next_phase);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
index a64e125df95f..c060d6f5015a 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
@@ -267,7 +267,7 @@ lustre_get_emerg_rs(struct ptlrpc_service_part *svcpt)
 		/* If we cannot get anything for some long time, we better
 		 * bail out instead of waiting infinitely
 		 */
-		lwi = LWI_TIMEOUT(cfs_time_seconds(10), NULL, NULL);
+		lwi = LWI_TIMEOUT(10 * HZ, NULL, NULL);
 		rc = l_wait_event(svcpt->scp_rep_waitq,
 				  !list_empty(&svcpt->scp_rep_idle), &lwi);
 		if (rc != 0)
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
index af707cb2b62b..010a1cdf05fa 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
@@ -141,7 +141,7 @@ static long pinger_check_timeout(unsigned long time)
 	}
 	mutex_unlock(&pinger_mutex);
 
-	return cfs_time_sub(cfs_time_add(time, cfs_time_seconds(timeout)),
+	return cfs_time_sub(cfs_time_add(time, timeout * HZ),
 					 cfs_time_current());
 }
 
@@ -247,7 +247,7 @@ static int ptlrpc_pinger_main(void *arg)
 			if (imp->imp_pingable && imp->imp_next_ping &&
 			    cfs_time_after(imp->imp_next_ping,
 					   cfs_time_add(this_ping,
-							cfs_time_seconds(PING_INTERVAL))))
+							PING_INTERVAL * HZ)))
 				ptlrpc_update_next_ping(imp, 0);
 		}
 		mutex_unlock(&pinger_mutex);
@@ -264,10 +264,10 @@ static int ptlrpc_pinger_main(void *arg)
 		CDEBUG(D_INFO, "next wakeup in " CFS_DURATION_T " (%ld)\n",
 		       time_to_next_wake,
 		       cfs_time_add(this_ping,
-				    cfs_time_seconds(PING_INTERVAL)));
+				    PING_INTERVAL * HZ));
 		if (time_to_next_wake > 0) {
 			lwi = LWI_TIMEOUT(max_t(long, time_to_next_wake,
-						cfs_time_seconds(1)),
+						HZ),
 					  NULL, NULL);
 			l_wait_event(thread->t_ctl_waitq,
 				     thread_is_stopping(thread) ||
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
index 8b865294d933..dad2f9290f70 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
@@ -230,7 +230,7 @@ void ptlrpcd_add_req(struct ptlrpc_request *req)
 
 	spin_lock(&req->rq_lock);
 	if (req->rq_invalid_rqset) {
-		struct l_wait_info lwi = LWI_TIMEOUT(cfs_time_seconds(5),
+		struct l_wait_info lwi = LWI_TIMEOUT(5 * HZ,
 						     back_to_sleep, NULL);
 
 		req->rq_invalid_rqset = 0;
@@ -438,7 +438,7 @@ static int ptlrpcd(void *arg)
 		int timeout;
 
 		timeout = ptlrpc_set_next_timeout(set);
-		lwi = LWI_TIMEOUT(cfs_time_seconds(timeout ? timeout : 1),
+		lwi = LWI_TIMEOUT((timeout ? timeout : 1) * HZ,
 				  ptlrpc_expired_set, set);
 
 		lu_context_enter(&env.le_ctx);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/recover.c b/drivers/staging/lustre/lustre/ptlrpc/recover.c
index e4d3f23e9f3a..5bbd23eebfa6 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/recover.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/recover.c
@@ -347,7 +347,7 @@ int ptlrpc_recover_import(struct obd_import *imp, char *new_uuid, int async)
 
 	if (!async) {
 		struct l_wait_info lwi;
-		int secs = cfs_time_seconds(obd_timeout);
+		int secs = obd_timeout * HZ;
 
 		CDEBUG(D_HA, "%s: recovery started, waiting %u seconds\n",
 		       obd2cli_tgt(imp->imp_obd), secs);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
index 1f22926c1355..6d4229ebc9d9 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -2149,7 +2149,7 @@ static int ptlrpc_main(void *arg)
 			 * Wait for a timeout (unless something else
 			 * happens) before I try again
 			 */
-			svcpt->scp_rqbd_timeout = cfs_time_seconds(1) / 10;
+			svcpt->scp_rqbd_timeout = HZ / 10;
 			CDEBUG(D_RPCTRACE, "Posted buffers: %d\n",
 			       svcpt->scp_nrqbds_posted);
 		}
@@ -2588,7 +2588,7 @@ static void ptlrpc_wait_replies(struct ptlrpc_service_part *svcpt)
 {
 	while (1) {
 		int rc;
-		struct l_wait_info lwi = LWI_TIMEOUT(cfs_time_seconds(10),
+		struct l_wait_info lwi = LWI_TIMEOUT(10 * HZ,
 						     NULL, NULL);
 
 		rc = l_wait_event(svcpt->scp_waitq,
@@ -2660,8 +2660,8 @@ ptlrpc_service_unlink_rqbd(struct ptlrpc_service *svc)
 			 * of sluggish LNDs
 			 */
 			lwi = LWI_TIMEOUT_INTERVAL(
-					cfs_time_seconds(LONG_UNLINK),
-					cfs_time_seconds(1), NULL, NULL);
+					LONG_UNLINK * HZ,
+					HZ, NULL, NULL);
 			rc = l_wait_event(svcpt->scp_waitq,
 					  svcpt->scp_nrqbds_posted == 0, &lwi);
 			if (rc == -ETIMEDOUT) {

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 03/19] staging: lustre: replace simple cases of l_wait_event() with wait_event().
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 21:22   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

When the lwi arg is full of zeros, l_wait_event() behaves almost
identically to the standard wait_event_idle() interface, so use that
instead.

l_wait_event() uses TASK_INTERRUPTIBLE, but blocks all signals.
wait_event_idle() uses the new TASK_IDLE and so avoids adding
to the load average without needing to block signals.

In one case, wait_event_idle_exclusive() is needed.

Also remove all l_wait_condition*() macros which were short-cuts
for setting lwi to {0}.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |   19 --------
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c     |    4 --
 drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c    |    8 +--
 drivers/staging/lustre/lustre/ldlm/ldlm_pool.c     |    5 +-
 drivers/staging/lustre/lustre/llite/statahead.c    |   50 ++++++++------------
 drivers/staging/lustre/lustre/lov/lov_object.c     |    6 +-
 drivers/staging/lustre/lustre/mgc/mgc_request.c    |    4 --
 drivers/staging/lustre/lustre/obdclass/cl_io.c     |    6 +-
 drivers/staging/lustre/lustre/obdclass/genops.c    |   15 ++----
 drivers/staging/lustre/lustre/osc/osc_cache.c      |    5 +-
 drivers/staging/lustre/lustre/osc/osc_object.c     |    4 --
 drivers/staging/lustre/lustre/ptlrpc/pinger.c      |   10 ++--
 drivers/staging/lustre/lustre/ptlrpc/sec_gc.c      |   11 ++--
 drivers/staging/lustre/lustre/ptlrpc/service.c     |   13 ++---
 14 files changed, 53 insertions(+), 107 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
index ca1dce15337e..7d950c53e962 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -333,24 +333,7 @@ do {									   \
 	__ret;						  \
 })
 
-#define l_wait_condition(wq, condition)			 \
-({							      \
-	struct l_wait_info lwi = { 0 };			 \
-	l_wait_event(wq, condition, &lwi);		      \
-})
-
-#define l_wait_condition_exclusive(wq, condition)	       \
-({							      \
-	struct l_wait_info lwi = { 0 };			 \
-	l_wait_event_exclusive(wq, condition, &lwi);	    \
-})
-
-#define l_wait_condition_exclusive_head(wq, condition)	  \
-({							      \
-	struct l_wait_info lwi = { 0 };			 \
-	l_wait_event_exclusive_head(wq, condition, &lwi);       \
-})
-
 /** @} lib */
 
+
 #endif /* _LUSTRE_LIB_H */
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
index 7cbc6a06afec..4f700ddb47c6 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
@@ -1913,14 +1913,12 @@ void ldlm_cancel_callback(struct ldlm_lock *lock)
 		ldlm_set_bl_done(lock);
 		wake_up_all(&lock->l_waitq);
 	} else if (!ldlm_is_bl_done(lock)) {
-		struct l_wait_info lwi = { 0 };
-
 		/*
 		 * The lock is guaranteed to have been canceled once
 		 * returning from this function.
 		 */
 		unlock_res_and_lock(lock);
-		l_wait_event(lock->l_waitq, is_bl_done(lock), &lwi);
+		wait_event_idle(lock->l_waitq, is_bl_done(lock));
 		lock_res_and_lock(lock);
 	}
 }
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
index 5f6e7c933b81..6c7c4b19a0a0 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
@@ -833,17 +833,15 @@ static int ldlm_bl_thread_main(void *arg)
 	/* cannot use bltd after this, it is only on caller's stack */
 
 	while (1) {
-		struct l_wait_info lwi = { 0 };
 		struct ldlm_bl_work_item *blwi = NULL;
 		struct obd_export *exp = NULL;
 		int rc;
 
 		rc = ldlm_bl_get_work(blp, &blwi, &exp);
 		if (!rc)
-			l_wait_event_exclusive(blp->blp_waitq,
-					       ldlm_bl_get_work(blp, &blwi,
-								&exp),
-					       &lwi);
+			wait_event_idle_exclusive(blp->blp_waitq,
+						  ldlm_bl_get_work(blp, &blwi,
+								   &exp));
 		atomic_inc(&blp->blp_busy_threads);
 
 		if (ldlm_bl_thread_need_create(blp, blwi))
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
index 8563bd32befa..f27c2694793a 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
@@ -1031,7 +1031,6 @@ static int ldlm_pools_thread_main(void *arg)
 
 static int ldlm_pools_thread_start(void)
 {
-	struct l_wait_info lwi = { 0 };
 	struct task_struct *task;
 
 	if (ldlm_pools_thread)
@@ -1052,8 +1051,8 @@ static int ldlm_pools_thread_start(void)
 		ldlm_pools_thread = NULL;
 		return PTR_ERR(task);
 	}
-	l_wait_event(ldlm_pools_thread->t_ctl_waitq,
-		     thread_is_running(ldlm_pools_thread), &lwi);
+	wait_event_idle(ldlm_pools_thread->t_ctl_waitq,
+			thread_is_running(ldlm_pools_thread));
 	return 0;
 }
 
diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c
index 90c7324575e4..78005cc6e831 100644
--- a/drivers/staging/lustre/lustre/llite/statahead.c
+++ b/drivers/staging/lustre/lustre/llite/statahead.c
@@ -864,7 +864,6 @@ static int ll_agl_thread(void *arg)
 	struct ll_sb_info	*sbi    = ll_i2sbi(dir);
 	struct ll_statahead_info *sai;
 	struct ptlrpc_thread *thread;
-	struct l_wait_info	lwi    = { 0 };
 
 	sai = ll_sai_get(dir);
 	thread = &sai->sai_agl_thread;
@@ -885,10 +884,9 @@ static int ll_agl_thread(void *arg)
 	wake_up(&thread->t_ctl_waitq);
 
 	while (1) {
-		l_wait_event(thread->t_ctl_waitq,
-			     !list_empty(&sai->sai_agls) ||
-			     !thread_is_running(thread),
-			     &lwi);
+		wait_event_idle(thread->t_ctl_waitq,
+				!list_empty(&sai->sai_agls) ||
+				!thread_is_running(thread));
 
 		if (!thread_is_running(thread))
 			break;
@@ -932,7 +930,6 @@ static int ll_agl_thread(void *arg)
 static void ll_start_agl(struct dentry *parent, struct ll_statahead_info *sai)
 {
 	struct ptlrpc_thread *thread = &sai->sai_agl_thread;
-	struct l_wait_info    lwi    = { 0 };
 	struct ll_inode_info  *plli;
 	struct task_struct *task;
 
@@ -948,9 +945,8 @@ static void ll_start_agl(struct dentry *parent, struct ll_statahead_info *sai)
 		return;
 	}
 
-	l_wait_event(thread->t_ctl_waitq,
-		     thread_is_running(thread) || thread_is_stopped(thread),
-		     &lwi);
+	wait_event_idle(thread->t_ctl_waitq,
+			thread_is_running(thread) || thread_is_stopped(thread));
 }
 
 /* statahead thread main function */
@@ -968,7 +964,6 @@ static int ll_statahead_thread(void *arg)
 	int		       first  = 0;
 	int		       rc     = 0;
 	struct md_op_data *op_data;
-	struct l_wait_info	lwi    = { 0 };
 
 	sai = ll_sai_get(dir);
 	sa_thread = &sai->sai_thread;
@@ -1069,12 +1064,11 @@ static int ll_statahead_thread(void *arg)
 
 			/* wait for spare statahead window */
 			do {
-				l_wait_event(sa_thread->t_ctl_waitq,
-					     !sa_sent_full(sai) ||
-					     sa_has_callback(sai) ||
-					     !list_empty(&sai->sai_agls) ||
-					     !thread_is_running(sa_thread),
-					     &lwi);
+				wait_event_idle(sa_thread->t_ctl_waitq,
+						!sa_sent_full(sai) ||
+						sa_has_callback(sai) ||
+						!list_empty(&sai->sai_agls) ||
+						!thread_is_running(sa_thread));
 				sa_handle_callback(sai);
 
 				spin_lock(&lli->lli_agl_lock);
@@ -1128,11 +1122,10 @@ static int ll_statahead_thread(void *arg)
 	 * for file release to stop me.
 	 */
 	while (thread_is_running(sa_thread)) {
-		l_wait_event(sa_thread->t_ctl_waitq,
-			     sa_has_callback(sai) ||
-			     !agl_list_empty(sai) ||
-			     !thread_is_running(sa_thread),
-			     &lwi);
+		wait_event_idle(sa_thread->t_ctl_waitq,
+				sa_has_callback(sai) ||
+				!agl_list_empty(sai) ||
+				!thread_is_running(sa_thread));
 
 		sa_handle_callback(sai);
 	}
@@ -1145,9 +1138,8 @@ static int ll_statahead_thread(void *arg)
 
 		CDEBUG(D_READA, "stop agl thread: sai %p pid %u\n",
 		       sai, (unsigned int)agl_thread->t_pid);
-		l_wait_event(agl_thread->t_ctl_waitq,
-			     thread_is_stopped(agl_thread),
-			     &lwi);
+		wait_event_idle(agl_thread->t_ctl_waitq,
+				thread_is_stopped(agl_thread));
 	} else {
 		/* Set agl_thread flags anyway. */
 		thread_set_flags(agl_thread, SVC_STOPPED);
@@ -1159,8 +1151,8 @@ static int ll_statahead_thread(void *arg)
 	 */
 	while (sai->sai_sent != sai->sai_replied) {
 		/* in case we're not woken up, timeout wait */
-		lwi = LWI_TIMEOUT(msecs_to_jiffies(MSEC_PER_SEC >> 3),
-				  NULL, NULL);
+		struct l_wait_info lwi = LWI_TIMEOUT(msecs_to_jiffies(MSEC_PER_SEC >> 3),
+						     NULL, NULL);
 		l_wait_event(sa_thread->t_ctl_waitq,
 			     sai->sai_sent == sai->sai_replied, &lwi);
 	}
@@ -1520,7 +1512,6 @@ static int start_statahead_thread(struct inode *dir, struct dentry *dentry)
 {
 	struct ll_inode_info *lli = ll_i2info(dir);
 	struct ll_statahead_info *sai = NULL;
-	struct l_wait_info lwi = { 0 };
 	struct ptlrpc_thread *thread;
 	struct task_struct *task;
 	struct dentry *parent = dentry->d_parent;
@@ -1570,9 +1561,8 @@ static int start_statahead_thread(struct inode *dir, struct dentry *dentry)
 		goto out;
 	}
 
-	l_wait_event(thread->t_ctl_waitq,
-		     thread_is_running(thread) || thread_is_stopped(thread),
-		     &lwi);
+	wait_event_idle(thread->t_ctl_waitq,
+			thread_is_running(thread) || thread_is_stopped(thread));
 	ll_sai_put(sai);
 
 	/*
diff --git a/drivers/staging/lustre/lustre/lov/lov_object.c b/drivers/staging/lustre/lustre/lov/lov_object.c
index 897cf2cd4a24..86cd4f9fbd0c 100644
--- a/drivers/staging/lustre/lustre/lov/lov_object.c
+++ b/drivers/staging/lustre/lustre/lov/lov_object.c
@@ -723,15 +723,13 @@ static void lov_conf_unlock(struct lov_object *lov)
 
 static int lov_layout_wait(const struct lu_env *env, struct lov_object *lov)
 {
-	struct l_wait_info lwi = { 0 };
-
 	while (atomic_read(&lov->lo_active_ios) > 0) {
 		CDEBUG(D_INODE, "file:" DFID " wait for active IO, now: %d.\n",
 		       PFID(lu_object_fid(lov2lu(lov))),
 		       atomic_read(&lov->lo_active_ios));
 
-		l_wait_event(lov->lo_waitq,
-			     atomic_read(&lov->lo_active_ios) == 0, &lwi);
+		wait_event_idle(lov->lo_waitq,
+				atomic_read(&lov->lo_active_ios) == 0);
 	}
 	return 0;
 }
diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c
index 79ff85feab64..b743aee62349 100644
--- a/drivers/staging/lustre/lustre/mgc/mgc_request.c
+++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c
@@ -601,9 +601,7 @@ static int mgc_requeue_thread(void *data)
 			config_log_put(cld_prev);
 
 		/* Wait a bit to see if anyone else needs a requeue */
-		lwi = (struct l_wait_info) { 0 };
-		l_wait_event(rq_waitq, rq_state & (RQ_NOW | RQ_STOP),
-			     &lwi);
+		wait_event_idle(rq_waitq, rq_state & (RQ_NOW | RQ_STOP));
 		spin_lock(&config_list_lock);
 	}
 
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
index 6ec5218a18c1..902bad22013b 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -1110,10 +1110,8 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
 		CERROR("IO failed: %d, still wait for %d remaining entries\n",
 		       rc, atomic_read(&anchor->csi_sync_nr));
 
-		lwi = (struct l_wait_info) { 0 };
-		(void)l_wait_event(anchor->csi_waitq,
-				   atomic_read(&anchor->csi_sync_nr) == 0,
-				   &lwi);
+		wait_event_idle(anchor->csi_waitq,
+				atomic_read(&anchor->csi_sync_nr) == 0);
 	} else {
 		rc = anchor->csi_sync_rc;
 	}
diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
index b1d6ba4a3190..3ff25b8d3b48 100644
--- a/drivers/staging/lustre/lustre/obdclass/genops.c
+++ b/drivers/staging/lustre/lustre/obdclass/genops.c
@@ -1237,12 +1237,10 @@ static int obd_zombie_is_idle(void)
  */
 void obd_zombie_barrier(void)
 {
-	struct l_wait_info lwi = { 0 };
-
 	if (obd_zombie_pid == current_pid())
 		/* don't wait for myself */
 		return;
-	l_wait_event(obd_zombie_waitq, obd_zombie_is_idle(), &lwi);
+	wait_event_idle(obd_zombie_waitq, obd_zombie_is_idle());
 }
 EXPORT_SYMBOL(obd_zombie_barrier);
 
@@ -1257,10 +1255,8 @@ static int obd_zombie_impexp_thread(void *unused)
 	obd_zombie_pid = current_pid();
 
 	while (!test_bit(OBD_ZOMBIE_STOP, &obd_zombie_flags)) {
-		struct l_wait_info lwi = { 0 };
-
-		l_wait_event(obd_zombie_waitq,
-			     !obd_zombie_impexp_check(NULL), &lwi);
+		wait_event_idle(obd_zombie_waitq,
+				!obd_zombie_impexp_check(NULL));
 		obd_zombie_impexp_cull();
 
 		/*
@@ -1593,7 +1589,6 @@ static inline bool obd_mod_rpc_slot_avail(struct client_obd *cli,
 u16 obd_get_mod_rpc_slot(struct client_obd *cli, __u32 opc,
 			 struct lookup_intent *it)
 {
-	struct l_wait_info lwi = LWI_INTR(NULL, NULL);
 	bool close_req = false;
 	u16 i, max;
 
@@ -1631,8 +1626,8 @@ u16 obd_get_mod_rpc_slot(struct client_obd *cli, __u32 opc,
 		CDEBUG(D_RPCTRACE, "%s: sleeping for a modify RPC slot opc %u, max %hu\n",
 		       cli->cl_import->imp_obd->obd_name, opc, max);
 
-		l_wait_event(cli->cl_mod_rpcs_waitq,
-			     obd_mod_rpc_slot_avail(cli, close_req), &lwi);
+		wait_event_idle(cli->cl_mod_rpcs_waitq,
+				obd_mod_rpc_slot_avail(cli, close_req));
 	} while (true);
 }
 EXPORT_SYMBOL(obd_get_mod_rpc_slot);
diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c
index 5767ac2a7d16..b8d5adca94e1 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cache.c
+++ b/drivers/staging/lustre/lustre/osc/osc_cache.c
@@ -964,9 +964,8 @@ static int osc_extent_wait(const struct lu_env *env, struct osc_extent *ext,
 				"%s: wait ext to %u timedout, recovery in progress?\n",
 				cli_name(osc_cli(obj)), state);
 
-		lwi = LWI_INTR(NULL, NULL);
-		rc = l_wait_event(ext->oe_waitq, extent_wait_cb(ext, state),
-				  &lwi);
+		wait_event_idle(ext->oe_waitq, extent_wait_cb(ext, state));
+		rc = 0;
 	}
 	if (rc == 0 && ext->oe_rc < 0)
 		rc = ext->oe_rc;
diff --git a/drivers/staging/lustre/lustre/osc/osc_object.c b/drivers/staging/lustre/lustre/osc/osc_object.c
index f82c87a77550..6c424f0290bb 100644
--- a/drivers/staging/lustre/lustre/osc/osc_object.c
+++ b/drivers/staging/lustre/lustre/osc/osc_object.c
@@ -454,12 +454,10 @@ struct lu_object *osc_object_alloc(const struct lu_env *env,
 
 int osc_object_invalidate(const struct lu_env *env, struct osc_object *osc)
 {
-	struct l_wait_info lwi = { 0 };
-
 	CDEBUG(D_INODE, "Invalidate osc object: %p, # of active IOs: %d\n",
 	       osc, atomic_read(&osc->oo_nr_ios));
 
-	l_wait_event(osc->oo_io_waitq, !atomic_read(&osc->oo_nr_ios), &lwi);
+	wait_event_idle(osc->oo_io_waitq, !atomic_read(&osc->oo_nr_ios));
 
 	/* Discard all dirty pages of this object. */
 	osc_cache_truncate_start(env, osc, 0, NULL);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
index fe6b47bfe8be..af707cb2b62b 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
@@ -291,7 +291,6 @@ static struct ptlrpc_thread pinger_thread;
 
 int ptlrpc_start_pinger(void)
 {
-	struct l_wait_info lwi = { 0 };
 	struct task_struct *task;
 	int rc;
 
@@ -310,8 +309,8 @@ int ptlrpc_start_pinger(void)
 		CERROR("cannot start pinger thread: rc = %d\n", rc);
 		return rc;
 	}
-	l_wait_event(pinger_thread.t_ctl_waitq,
-		     thread_is_running(&pinger_thread), &lwi);
+	wait_event_idle(pinger_thread.t_ctl_waitq,
+			thread_is_running(&pinger_thread));
 
 	return 0;
 }
@@ -320,7 +319,6 @@ static int ptlrpc_pinger_remove_timeouts(void);
 
 int ptlrpc_stop_pinger(void)
 {
-	struct l_wait_info lwi = { 0 };
 	int rc = 0;
 
 	if (thread_is_init(&pinger_thread) ||
@@ -331,8 +329,8 @@ int ptlrpc_stop_pinger(void)
 	thread_set_flags(&pinger_thread, SVC_STOPPING);
 	wake_up(&pinger_thread.t_ctl_waitq);
 
-	l_wait_event(pinger_thread.t_ctl_waitq,
-		     thread_is_stopped(&pinger_thread), &lwi);
+	wait_event_idle(pinger_thread.t_ctl_waitq,
+			thread_is_stopped(&pinger_thread));
 
 	return rc;
 }
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
index d85c8638c009..b61e1aa25e8c 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
@@ -197,7 +197,6 @@ static int sec_gc_main(void *arg)
 
 int sptlrpc_gc_init(void)
 {
-	struct l_wait_info lwi = { 0 };
 	struct task_struct *task;
 
 	mutex_init(&sec_gc_mutex);
@@ -214,18 +213,16 @@ int sptlrpc_gc_init(void)
 		return PTR_ERR(task);
 	}
 
-	l_wait_event(sec_gc_thread.t_ctl_waitq,
-		     thread_is_running(&sec_gc_thread), &lwi);
+	wait_event_idle(sec_gc_thread.t_ctl_waitq,
+			thread_is_running(&sec_gc_thread));
 	return 0;
 }
 
 void sptlrpc_gc_fini(void)
 {
-	struct l_wait_info lwi = { 0 };
-
 	thread_set_flags(&sec_gc_thread, SVC_STOPPING);
 	wake_up(&sec_gc_thread.t_ctl_waitq);
 
-	l_wait_event(sec_gc_thread.t_ctl_waitq,
-		     thread_is_stopped(&sec_gc_thread), &lwi);
+	wait_event_idle(sec_gc_thread.t_ctl_waitq,
+			thread_is_stopped(&sec_gc_thread));
 }
diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
index 63be6e7273f3..1f22926c1355 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -2233,7 +2233,7 @@ static int ptlrpc_hr_main(void *arg)
 	wake_up(&ptlrpc_hr.hr_waitq);
 
 	while (!ptlrpc_hr.hr_stopping) {
-		l_wait_condition(hrt->hrt_waitq, hrt_dont_sleep(hrt, &replies));
+		wait_event_idle(hrt->hrt_waitq, hrt_dont_sleep(hrt, &replies));
 
 		while (!list_empty(&replies)) {
 			struct ptlrpc_reply_state *rs;
@@ -2312,7 +2312,6 @@ static int ptlrpc_start_hr_threads(void)
 
 static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt)
 {
-	struct l_wait_info lwi = { 0 };
 	struct ptlrpc_thread *thread;
 	LIST_HEAD(zombie);
 
@@ -2341,8 +2340,8 @@ static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt)
 
 		CDEBUG(D_INFO, "waiting for stopping-thread %s #%u\n",
 		       svcpt->scp_service->srv_thread_name, thread->t_id);
-		l_wait_event(thread->t_ctl_waitq,
-			     thread_is_stopped(thread), &lwi);
+		wait_event_idle(thread->t_ctl_waitq,
+				thread_is_stopped(thread));
 
 		spin_lock(&svcpt->scp_lock);
 	}
@@ -2403,7 +2402,6 @@ int ptlrpc_start_threads(struct ptlrpc_service *svc)
 
 int ptlrpc_start_thread(struct ptlrpc_service_part *svcpt, int wait)
 {
-	struct l_wait_info lwi = { 0 };
 	struct ptlrpc_thread *thread;
 	struct ptlrpc_service *svc;
 	struct task_struct *task;
@@ -2499,9 +2497,8 @@ int ptlrpc_start_thread(struct ptlrpc_service_part *svcpt, int wait)
 	if (!wait)
 		return 0;
 
-	l_wait_event(thread->t_ctl_waitq,
-		     thread_is_running(thread) || thread_is_stopped(thread),
-		     &lwi);
+	wait_event_idle(thread->t_ctl_waitq,
+			thread_is_running(thread) || thread_is_stopped(thread));
 
 	rc = thread_is_stopped(thread) ? thread->t_id : 0;
 	return rc;

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 02/19] staging: lustre: discard SVC_SIGNAL and related functions
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 21:22   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

This flag is never set, so remove checks and remove
the flag.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 drivers/staging/lustre/lustre/include/lustre_net.h |    6 ------
 drivers/staging/lustre/lustre/ptlrpc/sec_gc.c      |    4 +---
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h
index 3ff5de4770e8..4c665eca2467 100644
--- a/drivers/staging/lustre/lustre/include/lustre_net.h
+++ b/drivers/staging/lustre/lustre/include/lustre_net.h
@@ -1260,7 +1260,6 @@ enum {
 	SVC_STARTING    = 1 << 2,
 	SVC_RUNNING     = 1 << 3,
 	SVC_EVENT       = 1 << 4,
-	SVC_SIGNAL      = 1 << 5,
 };
 
 #define PTLRPC_THR_NAME_LEN		32
@@ -1333,11 +1332,6 @@ static inline int thread_is_event(struct ptlrpc_thread *thread)
 	return !!(thread->t_flags & SVC_EVENT);
 }
 
-static inline int thread_is_signal(struct ptlrpc_thread *thread)
-{
-	return !!(thread->t_flags & SVC_SIGNAL);
-}
-
 static inline void thread_clear_flags(struct ptlrpc_thread *thread, __u32 flags)
 {
 	thread->t_flags &= ~flags;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
index 8d1e0edfcede..d85c8638c009 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
@@ -153,7 +153,6 @@ static int sec_gc_main(void *arg)
 	while (1) {
 		struct ptlrpc_sec *sec;
 
-		thread_clear_flags(thread, SVC_SIGNAL);
 		sec_process_ctx_list();
 again:
 		/* go through sec list do gc.
@@ -184,8 +183,7 @@ static int sec_gc_main(void *arg)
 		lwi = LWI_TIMEOUT(msecs_to_jiffies(SEC_GC_INTERVAL * MSEC_PER_SEC),
 				  NULL, NULL);
 		l_wait_event(thread->t_ctl_waitq,
-			     thread_is_stopping(thread) ||
-			     thread_is_signal(thread),
+			     thread_is_stopping(thread),
 			     &lwi);
 
 		if (thread_test_and_clear_flags(thread, SVC_STOPPING))

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 01/19] sched/wait: add wait_event_idle() functions.
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 21:22   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

The new TASK_IDLE state (TASK_UNINTERRUPTIBLE | __TASK_NOLOAD)
is not much used.  One way to make it easier to use is to
add wait_event*() family functions that make use of it.
This patch adds:
  wait_event_idle()
  wait_event_idle_timeout()
  wait_event_idle_exclusive()
  wait_event_idle_exclusive_timeout()

This set was chosen because lustre needs them before
it can discard its own l_wait_event() macro.

Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 include/linux/wait.h |  114 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/include/linux/wait.h b/include/linux/wait.h
index 55a611486bac..d9f131ecf708 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -599,6 +599,120 @@ do {										\
 	__ret;									\
 })
 
+/**
+ * wait_event_idle - wait for a condition without contributing to system load
+ * @wq_head: the waitqueue to wait on
+ * @condition: a C expression for the event to wait for
+ *
+ * The process is put to sleep (TASK_IDLE) until the
+ * @condition evaluates to true.
+ * The @condition is checked each time the waitqueue @wq_head is woken up.
+ *
+ * wake_up() has to be called after changing any variable that could
+ * change the result of the wait condition.
+ *
+ */
+#define wait_event_idle(wq_head, condition)					\
+do {										\
+	might_sleep();								\
+	if (!(condition))							\
+		___wait_event(wq_head, condition, TASK_IDLE, 0, 0, schedule());	\
+} while (0)
+
+/**
+ * wait_event_idle_exclusive - wait for a condition with contributing to system load
+ * @wq_head: the waitqueue to wait on
+ * @condition: a C expression for the event to wait for
+ *
+ * The process is put to sleep (TASK_IDLE) until the
+ * @condition evaluates to true.
+ * The @condition is checked each time the waitqueue @wq_head is woken up.
+ *
+ * The process is put on the wait queue with an WQ_FLAG_EXCLUSIVE flag
+ * set thus if other processes wait on the same list, when this
+ * process is woken further processes are not considered.
+ *
+ * wake_up() has to be called after changing any variable that could
+ * change the result of the wait condition.
+ *
+ */
+#define wait_event_idle_exclusive(wq_head, condition)				\
+do {										\
+	might_sleep();								\
+	if (!(condition))							\
+		___wait_event(wq_head, condition, TASK_IDLE, 1, 0, schedule());	\
+} while (0)
+
+#define __wait_event_idle_timeout(wq_head, condition, timeout)			\
+	___wait_event(wq_head, ___wait_cond_timeout(condition),			\
+		      TASK_IDLE, 0, timeout,					\
+		      __ret = schedule_timeout(__ret))
+
+/**
+ * wait_event_idle_timeout - sleep without load until a condition becomes true or a timeout elapses
+ * @wq_head: the waitqueue to wait on
+ * @condition: a C expression for the event to wait for
+ * @timeout: timeout, in jiffies
+ *
+ * The process is put to sleep (TASK_IDLE) until the
+ * @condition evaluates to true. The @condition is checked each time
+ * the waitqueue @wq_head is woken up.
+ *
+ * wake_up() has to be called after changing any variable that could
+ * change the result of the wait condition.
+ *
+ * Returns:
+ * 0 if the @condition evaluated to %false after the @timeout elapsed,
+ * 1 if the @condition evaluated to %true after the @timeout elapsed,
+ * or the remaining jiffies (at least 1) if the @condition evaluated
+ * to %true before the @timeout elapsed.
+ */
+#define wait_event_idle_timeout(wq_head, condition, timeout)			\
+({										\
+	long __ret = timeout;							\
+	might_sleep();								\
+	if (!___wait_cond_timeout(condition))					\
+		__ret = __wait_event_idle_timeout(wq_head, condition, timeout);	\
+	__ret;									\
+})
+
+#define __wait_event_idle_exclusive_timeout(wq_head, condition, timeout)	\
+	___wait_event(wq_head, ___wait_cond_timeout(condition),			\
+		      TASK_IDLE, 1, timeout,					\
+		      __ret = schedule_timeout(__ret))
+
+/**
+ * wait_event_idle_exclusive_timeout - sleep without load until a condition becomes true or a timeout elapses
+ * @wq_head: the waitqueue to wait on
+ * @condition: a C expression for the event to wait for
+ * @timeout: timeout, in jiffies
+ *
+ * The process is put to sleep (TASK_IDLE) until the
+ * @condition evaluates to true. The @condition is checked each time
+ * the waitqueue @wq_head is woken up.
+ *
+ * The process is put on the wait queue with an WQ_FLAG_EXCLUSIVE flag
+ * set thus if other processes wait on the same list, when this
+ * process is woken further processes are not considered.
+ *
+ * wake_up() has to be called after changing any variable that could
+ * change the result of the wait condition.
+ *
+ * Returns:
+ * 0 if the @condition evaluated to %false after the @timeout elapsed,
+ * 1 if the @condition evaluated to %true after the @timeout elapsed,
+ * or the remaining jiffies (at least 1) if the @condition evaluated
+ * to %true before the @timeout elapsed.
+ */
+#define wait_event_idle_exclusive_timeout(wq_head, condition, timeout)		\
+({										\
+	long __ret = timeout;							\
+	might_sleep();								\
+	if (!___wait_cond_timeout(condition))					\
+		__ret = __wait_event_idle_exclusive_timeout(wq_head, condition, timeout);\
+	__ret;									\
+})
+
 extern int do_wait_intr(wait_queue_head_t *, wait_queue_entry_t *);
 extern int do_wait_intr_irq(wait_queue_head_t *, wait_queue_entry_t *);
 

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 00/19] RESEND staging: lustre: use standard wait_event macros
@ 2018-02-12 21:22 ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

Hi,
 this is a resend of patch series that I sent a little over a month
 ago.  Since then I've recieved Reviewed-By:from James Simmons
 (thanks) and confirmation that it passes his testing.
 I cannot quite say that all tests pass for me with these patch,
 but the tests produce the same results both with and without the
 patches.

 No non-trivial changes - a couple of typos in change descriptions
 fixes, and reviewed-by's added.

Previous intro text:
Hi,
 this is a revised version of the patch series I sent under a similar
 subject in mid December.
 Improvements are:
   - new wait_event_idle* macros are now in include/linux/wait.h which
     Ack from peterz.
   - *all* waits are now TASK_IDLE or TASK_INTERRUPTIBLE and so don't
     affect the load average.  There is no need to choose whether load
     is appropriate or not in each case.
   - all l_wait_event() users are handled so l_wait_event() is
     removed.  The one case I had left out before uses
     wait_event_idle_exclusive() with and option of using
     wait_event_idle_exclusive_lifo() is that ever gets approved.

 I think this set is ready to go.
 If you only review two patches, please review

    staging: lustre: simplify waiting in ldlm_completion_ast()
and
    staging: lustre: remove back_to_sleep()

 as in both of those, the actual behaviour of the current code (as I
 understand it) doesn't seem to agree with comments/debug message, or
 just generally looks odd.

Thanks,
NeilBrown

---

NeilBrown (19):
      sched/wait: add wait_event_idle() functions.
      staging: lustre: discard SVC_SIGNAL and related functions
      staging: lustre: replace simple cases of l_wait_event() with wait_event().
      staging: lustre: discard cfs_time_seconds()
      staging: lustre: use wait_event_idle_timeout() where appropriate.
      staging: lustre: introduce and use l_wait_event_abortable()
      staging: lustre: simplify l_wait_event when intr handler but no timeout.
      staging: lustre: simplify waiting in ldlm_completion_ast()
      staging: lustre: open code polling loop instead of using l_wait_event()
      staging: lustre: simplify waiting in ptlrpc_invalidate_import()
      staging: lustre: remove back_to_sleep()
      staging: lustre: make polling loop in ptlrpc_unregister_bulk more obvious
      staging: lustre: use wait_event_idle_timeout in ptlrpcd()
      staging: lustre: improve waiting in sptlrpc_req_refresh_ctx
      staging: lustre: use explicit poll loop in ptlrpc_service_unlink_rqbd
      staging: lustre: use explicit poll loop in ptlrpc_unregister_reply
      staging: lustre: remove l_wait_event from ptlrpc_set_wait
      staging: lustre: replace l_wait_event_exclusive_head() with wait_event_idle_exclusive
      staging: lustre: remove l_wait_event() and related code


 .../lustre/include/linux/libcfs/libcfs_debug.h     |    4 
 .../lustre/include/linux/libcfs/libcfs_time.h      |    2 
 .../lustre/include/linux/libcfs/linux/linux-time.h |    7 
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c    |    8 -
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c |    4 
 .../staging/lustre/lnet/klnds/socklnd/socklnd.c    |    6 
 .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c |   22 +
 drivers/staging/lustre/lnet/libcfs/debug.c         |    2 
 drivers/staging/lustre/lnet/libcfs/fail.c          |    2 
 drivers/staging/lustre/lnet/libcfs/tracefile.c     |    4 
 drivers/staging/lustre/lnet/lnet/acceptor.c        |    2 
 drivers/staging/lustre/lnet/lnet/api-ni.c          |    4 
 drivers/staging/lustre/lnet/lnet/lib-move.c        |    4 
 drivers/staging/lustre/lnet/lnet/net_fault.c       |   14 -
 drivers/staging/lustre/lnet/lnet/peer.c            |    2 
 drivers/staging/lustre/lnet/lnet/router.c          |    8 -
 drivers/staging/lustre/lnet/selftest/conrpc.c      |    4 
 drivers/staging/lustre/lnet/selftest/rpc.c         |    2 
 drivers/staging/lustre/lnet/selftest/selftest.h    |    2 
 drivers/staging/lustre/lnet/selftest/timer.c       |    2 
 drivers/staging/lustre/lustre/include/lustre_dlm.h |    2 
 drivers/staging/lustre/lustre/include/lustre_lib.h |  296 ++------------------
 drivers/staging/lustre/lustre/include/lustre_mdc.h |    2 
 drivers/staging/lustre/lustre/include/lustre_net.h |    8 -
 drivers/staging/lustre/lustre/ldlm/ldlm_flock.c    |   30 --
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c     |   14 -
 drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c    |   12 -
 drivers/staging/lustre/lustre/ldlm/ldlm_pool.c     |   17 -
 drivers/staging/lustre/lustre/ldlm/ldlm_request.c  |   55 +---
 drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |   14 -
 drivers/staging/lustre/lustre/llite/llite_lib.c    |   23 +-
 drivers/staging/lustre/lustre/llite/statahead.c    |   60 ++--
 drivers/staging/lustre/lustre/lov/lov_object.c     |    6 
 drivers/staging/lustre/lustre/lov/lov_request.c    |   12 -
 drivers/staging/lustre/lustre/mdc/mdc_request.c    |    5 
 drivers/staging/lustre/lustre/mgc/mgc_request.c    |   19 -
 drivers/staging/lustre/lustre/obdclass/cl_io.c     |   23 +-
 drivers/staging/lustre/lustre/obdclass/genops.c    |   24 +-
 drivers/staging/lustre/lustre/obdclass/llog_obd.c  |    5 
 .../staging/lustre/lustre/obdecho/echo_client.c    |    2 
 drivers/staging/lustre/lustre/osc/osc_cache.c      |   28 +-
 drivers/staging/lustre/lustre/osc/osc_object.c     |    6 
 drivers/staging/lustre/lustre/osc/osc_page.c       |    6 
 drivers/staging/lustre/lustre/osc/osc_request.c    |    6 
 drivers/staging/lustre/lustre/ptlrpc/client.c      |  101 +++----
 drivers/staging/lustre/lustre/ptlrpc/events.c      |    7 
 drivers/staging/lustre/lustre/ptlrpc/import.c      |   51 +--
 drivers/staging/lustre/lustre/ptlrpc/niobuf.c      |   15 +
 .../staging/lustre/lustre/ptlrpc/pack_generic.c    |    9 -
 drivers/staging/lustre/lustre/ptlrpc/pinger.c      |   28 +-
 .../staging/lustre/lustre/ptlrpc/ptlrpc_internal.h |    2 
 drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c     |   18 +
 drivers/staging/lustre/lustre/ptlrpc/recover.c     |   12 -
 drivers/staging/lustre/lustre/ptlrpc/sec.c         |   34 ++
 drivers/staging/lustre/lustre/ptlrpc/sec_gc.c      |   23 --
 drivers/staging/lustre/lustre/ptlrpc/service.c     |   84 +++---
 include/linux/wait.h                               |  114 ++++++++
 57 files changed, 516 insertions(+), 762 deletions(-)

--
Signature

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 02/19] staging: lustre: discard SVC_SIGNAL and related functions
@ 2018-02-12 21:22   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

This flag is never set, so remove checks and remove
the flag.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/include/lustre_net.h |    6 ------
 drivers/staging/lustre/lustre/ptlrpc/sec_gc.c      |    4 +---
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h
index 3ff5de4770e8..4c665eca2467 100644
--- a/drivers/staging/lustre/lustre/include/lustre_net.h
+++ b/drivers/staging/lustre/lustre/include/lustre_net.h
@@ -1260,7 +1260,6 @@ enum {
 	SVC_STARTING    = 1 << 2,
 	SVC_RUNNING     = 1 << 3,
 	SVC_EVENT       = 1 << 4,
-	SVC_SIGNAL      = 1 << 5,
 };
 
 #define PTLRPC_THR_NAME_LEN		32
@@ -1333,11 +1332,6 @@ static inline int thread_is_event(struct ptlrpc_thread *thread)
 	return !!(thread->t_flags & SVC_EVENT);
 }
 
-static inline int thread_is_signal(struct ptlrpc_thread *thread)
-{
-	return !!(thread->t_flags & SVC_SIGNAL);
-}
-
 static inline void thread_clear_flags(struct ptlrpc_thread *thread, __u32 flags)
 {
 	thread->t_flags &= ~flags;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
index 8d1e0edfcede..d85c8638c009 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
@@ -153,7 +153,6 @@ static int sec_gc_main(void *arg)
 	while (1) {
 		struct ptlrpc_sec *sec;
 
-		thread_clear_flags(thread, SVC_SIGNAL);
 		sec_process_ctx_list();
 again:
 		/* go through sec list do gc.
@@ -184,8 +183,7 @@ static int sec_gc_main(void *arg)
 		lwi = LWI_TIMEOUT(msecs_to_jiffies(SEC_GC_INTERVAL * MSEC_PER_SEC),
 				  NULL, NULL);
 		l_wait_event(thread->t_ctl_waitq,
-			     thread_is_stopping(thread) ||
-			     thread_is_signal(thread),
+			     thread_is_stopping(thread),
 			     &lwi);
 
 		if (thread_test_and_clear_flags(thread, SVC_STOPPING))

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 03/19] staging: lustre: replace simple cases of l_wait_event() with wait_event().
@ 2018-02-12 21:22   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

When the lwi arg is full of zeros, l_wait_event() behaves almost
identically to the standard wait_event_idle() interface, so use that
instead.

l_wait_event() uses TASK_INTERRUPTIBLE, but blocks all signals.
wait_event_idle() uses the new TASK_IDLE and so avoids adding
to the load average without needing to block signals.

In one case, wait_event_idle_exclusive() is needed.

Also remove all l_wait_condition*() macros which were short-cuts
for setting lwi to {0}.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |   19 --------
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c     |    4 --
 drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c    |    8 +--
 drivers/staging/lustre/lustre/ldlm/ldlm_pool.c     |    5 +-
 drivers/staging/lustre/lustre/llite/statahead.c    |   50 ++++++++------------
 drivers/staging/lustre/lustre/lov/lov_object.c     |    6 +-
 drivers/staging/lustre/lustre/mgc/mgc_request.c    |    4 --
 drivers/staging/lustre/lustre/obdclass/cl_io.c     |    6 +-
 drivers/staging/lustre/lustre/obdclass/genops.c    |   15 ++----
 drivers/staging/lustre/lustre/osc/osc_cache.c      |    5 +-
 drivers/staging/lustre/lustre/osc/osc_object.c     |    4 --
 drivers/staging/lustre/lustre/ptlrpc/pinger.c      |   10 ++--
 drivers/staging/lustre/lustre/ptlrpc/sec_gc.c      |   11 ++--
 drivers/staging/lustre/lustre/ptlrpc/service.c     |   13 ++---
 14 files changed, 53 insertions(+), 107 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
index ca1dce15337e..7d950c53e962 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -333,24 +333,7 @@ do {									   \
 	__ret;						  \
 })
 
-#define l_wait_condition(wq, condition)			 \
-({							      \
-	struct l_wait_info lwi = { 0 };			 \
-	l_wait_event(wq, condition, &lwi);		      \
-})
-
-#define l_wait_condition_exclusive(wq, condition)	       \
-({							      \
-	struct l_wait_info lwi = { 0 };			 \
-	l_wait_event_exclusive(wq, condition, &lwi);	    \
-})
-
-#define l_wait_condition_exclusive_head(wq, condition)	  \
-({							      \
-	struct l_wait_info lwi = { 0 };			 \
-	l_wait_event_exclusive_head(wq, condition, &lwi);       \
-})
-
 /** @} lib */
 
+
 #endif /* _LUSTRE_LIB_H */
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
index 7cbc6a06afec..4f700ddb47c6 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
@@ -1913,14 +1913,12 @@ void ldlm_cancel_callback(struct ldlm_lock *lock)
 		ldlm_set_bl_done(lock);
 		wake_up_all(&lock->l_waitq);
 	} else if (!ldlm_is_bl_done(lock)) {
-		struct l_wait_info lwi = { 0 };
-
 		/*
 		 * The lock is guaranteed to have been canceled once
 		 * returning from this function.
 		 */
 		unlock_res_and_lock(lock);
-		l_wait_event(lock->l_waitq, is_bl_done(lock), &lwi);
+		wait_event_idle(lock->l_waitq, is_bl_done(lock));
 		lock_res_and_lock(lock);
 	}
 }
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
index 5f6e7c933b81..6c7c4b19a0a0 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
@@ -833,17 +833,15 @@ static int ldlm_bl_thread_main(void *arg)
 	/* cannot use bltd after this, it is only on caller's stack */
 
 	while (1) {
-		struct l_wait_info lwi = { 0 };
 		struct ldlm_bl_work_item *blwi = NULL;
 		struct obd_export *exp = NULL;
 		int rc;
 
 		rc = ldlm_bl_get_work(blp, &blwi, &exp);
 		if (!rc)
-			l_wait_event_exclusive(blp->blp_waitq,
-					       ldlm_bl_get_work(blp, &blwi,
-								&exp),
-					       &lwi);
+			wait_event_idle_exclusive(blp->blp_waitq,
+						  ldlm_bl_get_work(blp, &blwi,
+								   &exp));
 		atomic_inc(&blp->blp_busy_threads);
 
 		if (ldlm_bl_thread_need_create(blp, blwi))
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
index 8563bd32befa..f27c2694793a 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
@@ -1031,7 +1031,6 @@ static int ldlm_pools_thread_main(void *arg)
 
 static int ldlm_pools_thread_start(void)
 {
-	struct l_wait_info lwi = { 0 };
 	struct task_struct *task;
 
 	if (ldlm_pools_thread)
@@ -1052,8 +1051,8 @@ static int ldlm_pools_thread_start(void)
 		ldlm_pools_thread = NULL;
 		return PTR_ERR(task);
 	}
-	l_wait_event(ldlm_pools_thread->t_ctl_waitq,
-		     thread_is_running(ldlm_pools_thread), &lwi);
+	wait_event_idle(ldlm_pools_thread->t_ctl_waitq,
+			thread_is_running(ldlm_pools_thread));
 	return 0;
 }
 
diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c
index 90c7324575e4..78005cc6e831 100644
--- a/drivers/staging/lustre/lustre/llite/statahead.c
+++ b/drivers/staging/lustre/lustre/llite/statahead.c
@@ -864,7 +864,6 @@ static int ll_agl_thread(void *arg)
 	struct ll_sb_info	*sbi    = ll_i2sbi(dir);
 	struct ll_statahead_info *sai;
 	struct ptlrpc_thread *thread;
-	struct l_wait_info	lwi    = { 0 };
 
 	sai = ll_sai_get(dir);
 	thread = &sai->sai_agl_thread;
@@ -885,10 +884,9 @@ static int ll_agl_thread(void *arg)
 	wake_up(&thread->t_ctl_waitq);
 
 	while (1) {
-		l_wait_event(thread->t_ctl_waitq,
-			     !list_empty(&sai->sai_agls) ||
-			     !thread_is_running(thread),
-			     &lwi);
+		wait_event_idle(thread->t_ctl_waitq,
+				!list_empty(&sai->sai_agls) ||
+				!thread_is_running(thread));
 
 		if (!thread_is_running(thread))
 			break;
@@ -932,7 +930,6 @@ static int ll_agl_thread(void *arg)
 static void ll_start_agl(struct dentry *parent, struct ll_statahead_info *sai)
 {
 	struct ptlrpc_thread *thread = &sai->sai_agl_thread;
-	struct l_wait_info    lwi    = { 0 };
 	struct ll_inode_info  *plli;
 	struct task_struct *task;
 
@@ -948,9 +945,8 @@ static void ll_start_agl(struct dentry *parent, struct ll_statahead_info *sai)
 		return;
 	}
 
-	l_wait_event(thread->t_ctl_waitq,
-		     thread_is_running(thread) || thread_is_stopped(thread),
-		     &lwi);
+	wait_event_idle(thread->t_ctl_waitq,
+			thread_is_running(thread) || thread_is_stopped(thread));
 }
 
 /* statahead thread main function */
@@ -968,7 +964,6 @@ static int ll_statahead_thread(void *arg)
 	int		       first  = 0;
 	int		       rc     = 0;
 	struct md_op_data *op_data;
-	struct l_wait_info	lwi    = { 0 };
 
 	sai = ll_sai_get(dir);
 	sa_thread = &sai->sai_thread;
@@ -1069,12 +1064,11 @@ static int ll_statahead_thread(void *arg)
 
 			/* wait for spare statahead window */
 			do {
-				l_wait_event(sa_thread->t_ctl_waitq,
-					     !sa_sent_full(sai) ||
-					     sa_has_callback(sai) ||
-					     !list_empty(&sai->sai_agls) ||
-					     !thread_is_running(sa_thread),
-					     &lwi);
+				wait_event_idle(sa_thread->t_ctl_waitq,
+						!sa_sent_full(sai) ||
+						sa_has_callback(sai) ||
+						!list_empty(&sai->sai_agls) ||
+						!thread_is_running(sa_thread));
 				sa_handle_callback(sai);
 
 				spin_lock(&lli->lli_agl_lock);
@@ -1128,11 +1122,10 @@ static int ll_statahead_thread(void *arg)
 	 * for file release to stop me.
 	 */
 	while (thread_is_running(sa_thread)) {
-		l_wait_event(sa_thread->t_ctl_waitq,
-			     sa_has_callback(sai) ||
-			     !agl_list_empty(sai) ||
-			     !thread_is_running(sa_thread),
-			     &lwi);
+		wait_event_idle(sa_thread->t_ctl_waitq,
+				sa_has_callback(sai) ||
+				!agl_list_empty(sai) ||
+				!thread_is_running(sa_thread));
 
 		sa_handle_callback(sai);
 	}
@@ -1145,9 +1138,8 @@ static int ll_statahead_thread(void *arg)
 
 		CDEBUG(D_READA, "stop agl thread: sai %p pid %u\n",
 		       sai, (unsigned int)agl_thread->t_pid);
-		l_wait_event(agl_thread->t_ctl_waitq,
-			     thread_is_stopped(agl_thread),
-			     &lwi);
+		wait_event_idle(agl_thread->t_ctl_waitq,
+				thread_is_stopped(agl_thread));
 	} else {
 		/* Set agl_thread flags anyway. */
 		thread_set_flags(agl_thread, SVC_STOPPED);
@@ -1159,8 +1151,8 @@ static int ll_statahead_thread(void *arg)
 	 */
 	while (sai->sai_sent != sai->sai_replied) {
 		/* in case we're not woken up, timeout wait */
-		lwi = LWI_TIMEOUT(msecs_to_jiffies(MSEC_PER_SEC >> 3),
-				  NULL, NULL);
+		struct l_wait_info lwi = LWI_TIMEOUT(msecs_to_jiffies(MSEC_PER_SEC >> 3),
+						     NULL, NULL);
 		l_wait_event(sa_thread->t_ctl_waitq,
 			     sai->sai_sent == sai->sai_replied, &lwi);
 	}
@@ -1520,7 +1512,6 @@ static int start_statahead_thread(struct inode *dir, struct dentry *dentry)
 {
 	struct ll_inode_info *lli = ll_i2info(dir);
 	struct ll_statahead_info *sai = NULL;
-	struct l_wait_info lwi = { 0 };
 	struct ptlrpc_thread *thread;
 	struct task_struct *task;
 	struct dentry *parent = dentry->d_parent;
@@ -1570,9 +1561,8 @@ static int start_statahead_thread(struct inode *dir, struct dentry *dentry)
 		goto out;
 	}
 
-	l_wait_event(thread->t_ctl_waitq,
-		     thread_is_running(thread) || thread_is_stopped(thread),
-		     &lwi);
+	wait_event_idle(thread->t_ctl_waitq,
+			thread_is_running(thread) || thread_is_stopped(thread));
 	ll_sai_put(sai);
 
 	/*
diff --git a/drivers/staging/lustre/lustre/lov/lov_object.c b/drivers/staging/lustre/lustre/lov/lov_object.c
index 897cf2cd4a24..86cd4f9fbd0c 100644
--- a/drivers/staging/lustre/lustre/lov/lov_object.c
+++ b/drivers/staging/lustre/lustre/lov/lov_object.c
@@ -723,15 +723,13 @@ static void lov_conf_unlock(struct lov_object *lov)
 
 static int lov_layout_wait(const struct lu_env *env, struct lov_object *lov)
 {
-	struct l_wait_info lwi = { 0 };
-
 	while (atomic_read(&lov->lo_active_ios) > 0) {
 		CDEBUG(D_INODE, "file:" DFID " wait for active IO, now: %d.\n",
 		       PFID(lu_object_fid(lov2lu(lov))),
 		       atomic_read(&lov->lo_active_ios));
 
-		l_wait_event(lov->lo_waitq,
-			     atomic_read(&lov->lo_active_ios) == 0, &lwi);
+		wait_event_idle(lov->lo_waitq,
+				atomic_read(&lov->lo_active_ios) == 0);
 	}
 	return 0;
 }
diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c
index 79ff85feab64..b743aee62349 100644
--- a/drivers/staging/lustre/lustre/mgc/mgc_request.c
+++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c
@@ -601,9 +601,7 @@ static int mgc_requeue_thread(void *data)
 			config_log_put(cld_prev);
 
 		/* Wait a bit to see if anyone else needs a requeue */
-		lwi = (struct l_wait_info) { 0 };
-		l_wait_event(rq_waitq, rq_state & (RQ_NOW | RQ_STOP),
-			     &lwi);
+		wait_event_idle(rq_waitq, rq_state & (RQ_NOW | RQ_STOP));
 		spin_lock(&config_list_lock);
 	}
 
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
index 6ec5218a18c1..902bad22013b 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -1110,10 +1110,8 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
 		CERROR("IO failed: %d, still wait for %d remaining entries\n",
 		       rc, atomic_read(&anchor->csi_sync_nr));
 
-		lwi = (struct l_wait_info) { 0 };
-		(void)l_wait_event(anchor->csi_waitq,
-				   atomic_read(&anchor->csi_sync_nr) == 0,
-				   &lwi);
+		wait_event_idle(anchor->csi_waitq,
+				atomic_read(&anchor->csi_sync_nr) == 0);
 	} else {
 		rc = anchor->csi_sync_rc;
 	}
diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
index b1d6ba4a3190..3ff25b8d3b48 100644
--- a/drivers/staging/lustre/lustre/obdclass/genops.c
+++ b/drivers/staging/lustre/lustre/obdclass/genops.c
@@ -1237,12 +1237,10 @@ static int obd_zombie_is_idle(void)
  */
 void obd_zombie_barrier(void)
 {
-	struct l_wait_info lwi = { 0 };
-
 	if (obd_zombie_pid == current_pid())
 		/* don't wait for myself */
 		return;
-	l_wait_event(obd_zombie_waitq, obd_zombie_is_idle(), &lwi);
+	wait_event_idle(obd_zombie_waitq, obd_zombie_is_idle());
 }
 EXPORT_SYMBOL(obd_zombie_barrier);
 
@@ -1257,10 +1255,8 @@ static int obd_zombie_impexp_thread(void *unused)
 	obd_zombie_pid = current_pid();
 
 	while (!test_bit(OBD_ZOMBIE_STOP, &obd_zombie_flags)) {
-		struct l_wait_info lwi = { 0 };
-
-		l_wait_event(obd_zombie_waitq,
-			     !obd_zombie_impexp_check(NULL), &lwi);
+		wait_event_idle(obd_zombie_waitq,
+				!obd_zombie_impexp_check(NULL));
 		obd_zombie_impexp_cull();
 
 		/*
@@ -1593,7 +1589,6 @@ static inline bool obd_mod_rpc_slot_avail(struct client_obd *cli,
 u16 obd_get_mod_rpc_slot(struct client_obd *cli, __u32 opc,
 			 struct lookup_intent *it)
 {
-	struct l_wait_info lwi = LWI_INTR(NULL, NULL);
 	bool close_req = false;
 	u16 i, max;
 
@@ -1631,8 +1626,8 @@ u16 obd_get_mod_rpc_slot(struct client_obd *cli, __u32 opc,
 		CDEBUG(D_RPCTRACE, "%s: sleeping for a modify RPC slot opc %u, max %hu\n",
 		       cli->cl_import->imp_obd->obd_name, opc, max);
 
-		l_wait_event(cli->cl_mod_rpcs_waitq,
-			     obd_mod_rpc_slot_avail(cli, close_req), &lwi);
+		wait_event_idle(cli->cl_mod_rpcs_waitq,
+				obd_mod_rpc_slot_avail(cli, close_req));
 	} while (true);
 }
 EXPORT_SYMBOL(obd_get_mod_rpc_slot);
diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c
index 5767ac2a7d16..b8d5adca94e1 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cache.c
+++ b/drivers/staging/lustre/lustre/osc/osc_cache.c
@@ -964,9 +964,8 @@ static int osc_extent_wait(const struct lu_env *env, struct osc_extent *ext,
 				"%s: wait ext to %u timedout, recovery in progress?\n",
 				cli_name(osc_cli(obj)), state);
 
-		lwi = LWI_INTR(NULL, NULL);
-		rc = l_wait_event(ext->oe_waitq, extent_wait_cb(ext, state),
-				  &lwi);
+		wait_event_idle(ext->oe_waitq, extent_wait_cb(ext, state));
+		rc = 0;
 	}
 	if (rc == 0 && ext->oe_rc < 0)
 		rc = ext->oe_rc;
diff --git a/drivers/staging/lustre/lustre/osc/osc_object.c b/drivers/staging/lustre/lustre/osc/osc_object.c
index f82c87a77550..6c424f0290bb 100644
--- a/drivers/staging/lustre/lustre/osc/osc_object.c
+++ b/drivers/staging/lustre/lustre/osc/osc_object.c
@@ -454,12 +454,10 @@ struct lu_object *osc_object_alloc(const struct lu_env *env,
 
 int osc_object_invalidate(const struct lu_env *env, struct osc_object *osc)
 {
-	struct l_wait_info lwi = { 0 };
-
 	CDEBUG(D_INODE, "Invalidate osc object: %p, # of active IOs: %d\n",
 	       osc, atomic_read(&osc->oo_nr_ios));
 
-	l_wait_event(osc->oo_io_waitq, !atomic_read(&osc->oo_nr_ios), &lwi);
+	wait_event_idle(osc->oo_io_waitq, !atomic_read(&osc->oo_nr_ios));
 
 	/* Discard all dirty pages of this object. */
 	osc_cache_truncate_start(env, osc, 0, NULL);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
index fe6b47bfe8be..af707cb2b62b 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
@@ -291,7 +291,6 @@ static struct ptlrpc_thread pinger_thread;
 
 int ptlrpc_start_pinger(void)
 {
-	struct l_wait_info lwi = { 0 };
 	struct task_struct *task;
 	int rc;
 
@@ -310,8 +309,8 @@ int ptlrpc_start_pinger(void)
 		CERROR("cannot start pinger thread: rc = %d\n", rc);
 		return rc;
 	}
-	l_wait_event(pinger_thread.t_ctl_waitq,
-		     thread_is_running(&pinger_thread), &lwi);
+	wait_event_idle(pinger_thread.t_ctl_waitq,
+			thread_is_running(&pinger_thread));
 
 	return 0;
 }
@@ -320,7 +319,6 @@ static int ptlrpc_pinger_remove_timeouts(void);
 
 int ptlrpc_stop_pinger(void)
 {
-	struct l_wait_info lwi = { 0 };
 	int rc = 0;
 
 	if (thread_is_init(&pinger_thread) ||
@@ -331,8 +329,8 @@ int ptlrpc_stop_pinger(void)
 	thread_set_flags(&pinger_thread, SVC_STOPPING);
 	wake_up(&pinger_thread.t_ctl_waitq);
 
-	l_wait_event(pinger_thread.t_ctl_waitq,
-		     thread_is_stopped(&pinger_thread), &lwi);
+	wait_event_idle(pinger_thread.t_ctl_waitq,
+			thread_is_stopped(&pinger_thread));
 
 	return rc;
 }
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
index d85c8638c009..b61e1aa25e8c 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
@@ -197,7 +197,6 @@ static int sec_gc_main(void *arg)
 
 int sptlrpc_gc_init(void)
 {
-	struct l_wait_info lwi = { 0 };
 	struct task_struct *task;
 
 	mutex_init(&sec_gc_mutex);
@@ -214,18 +213,16 @@ int sptlrpc_gc_init(void)
 		return PTR_ERR(task);
 	}
 
-	l_wait_event(sec_gc_thread.t_ctl_waitq,
-		     thread_is_running(&sec_gc_thread), &lwi);
+	wait_event_idle(sec_gc_thread.t_ctl_waitq,
+			thread_is_running(&sec_gc_thread));
 	return 0;
 }
 
 void sptlrpc_gc_fini(void)
 {
-	struct l_wait_info lwi = { 0 };
-
 	thread_set_flags(&sec_gc_thread, SVC_STOPPING);
 	wake_up(&sec_gc_thread.t_ctl_waitq);
 
-	l_wait_event(sec_gc_thread.t_ctl_waitq,
-		     thread_is_stopped(&sec_gc_thread), &lwi);
+	wait_event_idle(sec_gc_thread.t_ctl_waitq,
+			thread_is_stopped(&sec_gc_thread));
 }
diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
index 63be6e7273f3..1f22926c1355 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -2233,7 +2233,7 @@ static int ptlrpc_hr_main(void *arg)
 	wake_up(&ptlrpc_hr.hr_waitq);
 
 	while (!ptlrpc_hr.hr_stopping) {
-		l_wait_condition(hrt->hrt_waitq, hrt_dont_sleep(hrt, &replies));
+		wait_event_idle(hrt->hrt_waitq, hrt_dont_sleep(hrt, &replies));
 
 		while (!list_empty(&replies)) {
 			struct ptlrpc_reply_state *rs;
@@ -2312,7 +2312,6 @@ static int ptlrpc_start_hr_threads(void)
 
 static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt)
 {
-	struct l_wait_info lwi = { 0 };
 	struct ptlrpc_thread *thread;
 	LIST_HEAD(zombie);
 
@@ -2341,8 +2340,8 @@ static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt)
 
 		CDEBUG(D_INFO, "waiting for stopping-thread %s #%u\n",
 		       svcpt->scp_service->srv_thread_name, thread->t_id);
-		l_wait_event(thread->t_ctl_waitq,
-			     thread_is_stopped(thread), &lwi);
+		wait_event_idle(thread->t_ctl_waitq,
+				thread_is_stopped(thread));
 
 		spin_lock(&svcpt->scp_lock);
 	}
@@ -2403,7 +2402,6 @@ int ptlrpc_start_threads(struct ptlrpc_service *svc)
 
 int ptlrpc_start_thread(struct ptlrpc_service_part *svcpt, int wait)
 {
-	struct l_wait_info lwi = { 0 };
 	struct ptlrpc_thread *thread;
 	struct ptlrpc_service *svc;
 	struct task_struct *task;
@@ -2499,9 +2497,8 @@ int ptlrpc_start_thread(struct ptlrpc_service_part *svcpt, int wait)
 	if (!wait)
 		return 0;
 
-	l_wait_event(thread->t_ctl_waitq,
-		     thread_is_running(thread) || thread_is_stopped(thread),
-		     &lwi);
+	wait_event_idle(thread->t_ctl_waitq,
+			thread_is_running(thread) || thread_is_stopped(thread));
 
 	rc = thread_is_stopped(thread) ? thread->t_id : 0;
 	return rc;

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 01/19] sched/wait: add wait_event_idle() functions.
@ 2018-02-12 21:22   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

The new TASK_IDLE state (TASK_UNINTERRUPTIBLE | __TASK_NOLOAD)
is not much used.  One way to make it easier to use is to
add wait_event*() family functions that make use of it.
This patch adds:
  wait_event_idle()
  wait_event_idle_timeout()
  wait_event_idle_exclusive()
  wait_event_idle_exclusive_timeout()

This set was chosen because lustre needs them before
it can discard its own l_wait_event() macro.

Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 include/linux/wait.h |  114 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/include/linux/wait.h b/include/linux/wait.h
index 55a611486bac..d9f131ecf708 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -599,6 +599,120 @@ do {										\
 	__ret;									\
 })
 
+/**
+ * wait_event_idle - wait for a condition without contributing to system load
+ * @wq_head: the waitqueue to wait on
+ * @condition: a C expression for the event to wait for
+ *
+ * The process is put to sleep (TASK_IDLE) until the
+ * @condition evaluates to true.
+ * The @condition is checked each time the waitqueue @wq_head is woken up.
+ *
+ * wake_up() has to be called after changing any variable that could
+ * change the result of the wait condition.
+ *
+ */
+#define wait_event_idle(wq_head, condition)					\
+do {										\
+	might_sleep();								\
+	if (!(condition))							\
+		___wait_event(wq_head, condition, TASK_IDLE, 0, 0, schedule());	\
+} while (0)
+
+/**
+ * wait_event_idle_exclusive - wait for a condition with contributing to system load
+ * @wq_head: the waitqueue to wait on
+ * @condition: a C expression for the event to wait for
+ *
+ * The process is put to sleep (TASK_IDLE) until the
+ * @condition evaluates to true.
+ * The @condition is checked each time the waitqueue @wq_head is woken up.
+ *
+ * The process is put on the wait queue with an WQ_FLAG_EXCLUSIVE flag
+ * set thus if other processes wait on the same list, when this
+ * process is woken further processes are not considered.
+ *
+ * wake_up() has to be called after changing any variable that could
+ * change the result of the wait condition.
+ *
+ */
+#define wait_event_idle_exclusive(wq_head, condition)				\
+do {										\
+	might_sleep();								\
+	if (!(condition))							\
+		___wait_event(wq_head, condition, TASK_IDLE, 1, 0, schedule());	\
+} while (0)
+
+#define __wait_event_idle_timeout(wq_head, condition, timeout)			\
+	___wait_event(wq_head, ___wait_cond_timeout(condition),			\
+		      TASK_IDLE, 0, timeout,					\
+		      __ret = schedule_timeout(__ret))
+
+/**
+ * wait_event_idle_timeout - sleep without load until a condition becomes true or a timeout elapses
+ * @wq_head: the waitqueue to wait on
+ * @condition: a C expression for the event to wait for
+ * @timeout: timeout, in jiffies
+ *
+ * The process is put to sleep (TASK_IDLE) until the
+ * @condition evaluates to true. The @condition is checked each time
+ * the waitqueue @wq_head is woken up.
+ *
+ * wake_up() has to be called after changing any variable that could
+ * change the result of the wait condition.
+ *
+ * Returns:
+ * 0 if the @condition evaluated to %false after the @timeout elapsed,
+ * 1 if the @condition evaluated to %true after the @timeout elapsed,
+ * or the remaining jiffies (at least 1) if the @condition evaluated
+ * to %true before the @timeout elapsed.
+ */
+#define wait_event_idle_timeout(wq_head, condition, timeout)			\
+({										\
+	long __ret = timeout;							\
+	might_sleep();								\
+	if (!___wait_cond_timeout(condition))					\
+		__ret = __wait_event_idle_timeout(wq_head, condition, timeout);	\
+	__ret;									\
+})
+
+#define __wait_event_idle_exclusive_timeout(wq_head, condition, timeout)	\
+	___wait_event(wq_head, ___wait_cond_timeout(condition),			\
+		      TASK_IDLE, 1, timeout,					\
+		      __ret = schedule_timeout(__ret))
+
+/**
+ * wait_event_idle_exclusive_timeout - sleep without load until a condition becomes true or a timeout elapses
+ * @wq_head: the waitqueue to wait on
+ * @condition: a C expression for the event to wait for
+ * @timeout: timeout, in jiffies
+ *
+ * The process is put to sleep (TASK_IDLE) until the
+ * @condition evaluates to true. The @condition is checked each time
+ * the waitqueue @wq_head is woken up.
+ *
+ * The process is put on the wait queue with an WQ_FLAG_EXCLUSIVE flag
+ * set thus if other processes wait on the same list, when this
+ * process is woken further processes are not considered.
+ *
+ * wake_up() has to be called after changing any variable that could
+ * change the result of the wait condition.
+ *
+ * Returns:
+ * 0 if the @condition evaluated to %false after the @timeout elapsed,
+ * 1 if the @condition evaluated to %true after the @timeout elapsed,
+ * or the remaining jiffies (at least 1) if the @condition evaluated
+ * to %true before the @timeout elapsed.
+ */
+#define wait_event_idle_exclusive_timeout(wq_head, condition, timeout)		\
+({										\
+	long __ret = timeout;							\
+	might_sleep();								\
+	if (!___wait_cond_timeout(condition))					\
+		__ret = __wait_event_idle_exclusive_timeout(wq_head, condition, timeout);\
+	__ret;									\
+})
+
 extern int do_wait_intr(wait_queue_head_t *, wait_queue_entry_t *);
 extern int do_wait_intr_irq(wait_queue_head_t *, wait_queue_entry_t *);
 

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 04/19] staging: lustre: discard cfs_time_seconds()
@ 2018-02-12 21:22   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

cfs_time_seconds() converts a number of seconds to the
matching number of jiffies.
The standard way to do this in Linux is  "* HZ".
So discard cfs_time_seconds() and use "* HZ" instead.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 .../lustre/include/linux/libcfs/libcfs_debug.h     |    4 ++--
 .../lustre/include/linux/libcfs/libcfs_time.h      |    2 +-
 .../lustre/include/linux/libcfs/linux/linux-time.h |    7 +-----
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c    |    8 ++++---
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c |    4 ++--
 .../staging/lustre/lnet/klnds/socklnd/socklnd.c    |    6 +++--
 .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c |   22 ++++++++++----------
 drivers/staging/lustre/lnet/libcfs/debug.c         |    2 +-
 drivers/staging/lustre/lnet/libcfs/fail.c          |    2 +-
 drivers/staging/lustre/lnet/libcfs/tracefile.c     |    4 ++--
 drivers/staging/lustre/lnet/lnet/acceptor.c        |    2 +-
 drivers/staging/lustre/lnet/lnet/api-ni.c          |    4 ++--
 drivers/staging/lustre/lnet/lnet/lib-move.c        |    4 ++--
 drivers/staging/lustre/lnet/lnet/net_fault.c       |   14 +++++--------
 drivers/staging/lustre/lnet/lnet/peer.c            |    2 +-
 drivers/staging/lustre/lnet/lnet/router.c          |    8 ++++---
 drivers/staging/lustre/lnet/selftest/conrpc.c      |    4 ++--
 drivers/staging/lustre/lnet/selftest/rpc.c         |    2 +-
 drivers/staging/lustre/lnet/selftest/selftest.h    |    2 +-
 drivers/staging/lustre/lnet/selftest/timer.c       |    2 +-
 drivers/staging/lustre/lustre/include/lustre_dlm.h |    2 +-
 drivers/staging/lustre/lustre/include/lustre_mdc.h |    2 +-
 drivers/staging/lustre/lustre/include/lustre_net.h |    2 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c     |    2 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c    |    4 ++--
 drivers/staging/lustre/lustre/ldlm/ldlm_pool.c     |    2 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_request.c  |    2 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |    2 +-
 drivers/staging/lustre/lustre/llite/llite_lib.c    |    4 ++--
 drivers/staging/lustre/lustre/llite/statahead.c    |    2 +-
 drivers/staging/lustre/lustre/lov/lov_request.c    |    4 ++--
 drivers/staging/lustre/lustre/mdc/mdc_request.c    |    2 +-
 drivers/staging/lustre/lustre/mgc/mgc_request.c    |    2 +-
 drivers/staging/lustre/lustre/obdclass/cl_io.c     |    2 +-
 .../staging/lustre/lustre/obdecho/echo_client.c    |    2 +-
 drivers/staging/lustre/lustre/osc/osc_cache.c      |    4 ++--
 drivers/staging/lustre/lustre/osc/osc_object.c     |    2 +-
 drivers/staging/lustre/lustre/ptlrpc/client.c      |   10 +++++----
 drivers/staging/lustre/lustre/ptlrpc/events.c      |    2 +-
 drivers/staging/lustre/lustre/ptlrpc/import.c      |   15 ++++++--------
 drivers/staging/lustre/lustre/ptlrpc/niobuf.c      |    4 ++--
 .../staging/lustre/lustre/ptlrpc/pack_generic.c    |    2 +-
 drivers/staging/lustre/lustre/ptlrpc/pinger.c      |    8 ++++---
 drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c     |    4 ++--
 drivers/staging/lustre/lustre/ptlrpc/recover.c     |    2 +-
 drivers/staging/lustre/lustre/ptlrpc/service.c     |    8 ++++---
 46 files changed, 96 insertions(+), 106 deletions(-)

diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
index 1b98f0953afb..9290a19429e7 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_debug.h
@@ -66,8 +66,8 @@ extern unsigned int libcfs_panic_on_lbug;
 # define DEBUG_SUBSYSTEM S_UNDEFINED
 #endif
 
-#define CDEBUG_DEFAULT_MAX_DELAY (cfs_time_seconds(600))	 /* jiffies */
-#define CDEBUG_DEFAULT_MIN_DELAY ((cfs_time_seconds(1) + 1) / 2) /* jiffies */
+#define CDEBUG_DEFAULT_MAX_DELAY (600 * HZ)	 /* jiffies */
+#define CDEBUG_DEFAULT_MIN_DELAY ((HZ + 1) / 2) /* jiffies */
 #define CDEBUG_DEFAULT_BACKOFF   2
 struct cfs_debug_limit_state {
 	unsigned long   cdls_next;
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h
index 9699646decb9..c4f25be78268 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_time.h
@@ -62,7 +62,7 @@ static inline int cfs_time_aftereq(unsigned long t1, unsigned long t2)
 
 static inline unsigned long cfs_time_shift(int seconds)
 {
-	return cfs_time_add(cfs_time_current(), cfs_time_seconds(seconds));
+	return cfs_time_add(cfs_time_current(), seconds * HZ);
 }
 
 /*
diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h
index aece13698eb4..805cb326af86 100644
--- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h
+++ b/drivers/staging/lustre/include/linux/libcfs/linux/linux-time.h
@@ -65,11 +65,6 @@ static inline unsigned long cfs_time_current(void)
 	return jiffies;
 }
 
-static inline long cfs_time_seconds(int seconds)
-{
-	return ((long)seconds) * msecs_to_jiffies(MSEC_PER_SEC);
-}
-
 static inline long cfs_duration_sec(long d)
 {
 	return d / msecs_to_jiffies(MSEC_PER_SEC);
@@ -85,7 +80,7 @@ static inline u64 cfs_time_add_64(u64 t, u64 d)
 static inline u64 cfs_time_shift_64(int seconds)
 {
 	return cfs_time_add_64(cfs_time_current_64(),
-			       cfs_time_seconds(seconds));
+			       seconds * HZ);
 }
 
 static inline int cfs_time_before_64(u64 t1, u64 t2)
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
index ec84edfda271..7ae2955c4db6 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
@@ -1211,7 +1211,7 @@ static struct kib_hca_dev *kiblnd_current_hdev(struct kib_dev *dev)
 			CDEBUG(D_NET, "%s: Wait for failover\n",
 			       dev->ibd_ifname);
 		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1) / 100);
+		schedule_timeout(HZ / 100);
 
 		read_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
 	}
@@ -1921,7 +1921,7 @@ struct list_head *kiblnd_pool_alloc_node(struct kib_poolset *ps)
 
 		set_current_state(TASK_INTERRUPTIBLE);
 		schedule_timeout(interval);
-		if (interval < cfs_time_seconds(1))
+		if (interval < HZ)
 			interval *= 2;
 
 		goto again;
@@ -2541,7 +2541,7 @@ static void kiblnd_base_shutdown(void)
 			       "Waiting for %d threads to terminate\n",
 			       atomic_read(&kiblnd_data.kib_nthreads));
 			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(cfs_time_seconds(1));
+			schedule_timeout(HZ);
 		}
 
 		/* fall through */
@@ -2592,7 +2592,7 @@ static void kiblnd_shutdown(struct lnet_ni *ni)
 			       libcfs_nid2str(ni->ni_nid),
 			       atomic_read(&net->ibn_npeers));
 			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(cfs_time_seconds(1));
+			schedule_timeout(HZ);
 		}
 
 		kiblnd_net_fini_pools(net);
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
index b3e7f28eb978..ca094555e04b 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
@@ -3728,8 +3728,8 @@ kiblnd_failover_thread(void *arg)
 		add_wait_queue(&kiblnd_data.kib_failover_waitq, &wait);
 		write_unlock_irqrestore(glock, flags);
 
-		rc = schedule_timeout(long_sleep ? cfs_time_seconds(10) :
-						   cfs_time_seconds(1));
+		rc = schedule_timeout(long_sleep ? 10 * HZ :
+						   HZ);
 		remove_wait_queue(&kiblnd_data.kib_failover_waitq, &wait);
 		write_lock_irqsave(glock, flags);
 
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
index ff292216290d..7086678e1c3e 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
@@ -1677,7 +1677,7 @@ ksocknal_destroy_conn(struct ksock_conn *conn)
 	switch (conn->ksnc_rx_state) {
 	case SOCKNAL_RX_LNET_PAYLOAD:
 		last_rcv = conn->ksnc_rx_deadline -
-			   cfs_time_seconds(*ksocknal_tunables.ksnd_timeout);
+			   *ksocknal_tunables.ksnd_timeout * HZ;
 		CERROR("Completing partial receive from %s[%d], ip %pI4h:%d, with error, wanted: %zd, left: %d, last alive is %ld secs ago\n",
 		       libcfs_id2str(conn->ksnc_peer->ksnp_id), conn->ksnc_type,
 		       &conn->ksnc_ipaddr, conn->ksnc_port,
@@ -2356,7 +2356,7 @@ ksocknal_base_shutdown(void)
 				ksocknal_data.ksnd_nthreads);
 			read_unlock(&ksocknal_data.ksnd_global_lock);
 			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(cfs_time_seconds(1));
+			schedule_timeout(HZ);
 			read_lock(&ksocknal_data.ksnd_global_lock);
 		}
 		read_unlock(&ksocknal_data.ksnd_global_lock);
@@ -2599,7 +2599,7 @@ ksocknal_shutdown(struct lnet_ni *ni)
 		       "waiting for %d peers to disconnect\n",
 		       net->ksnn_npeers);
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1));
+		schedule_timeout(HZ);
 
 		ksocknal_debug_peerhash(ni);
 
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
index 11fd3a36424f..63e452f666bf 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
@@ -189,7 +189,7 @@ ksocknal_transmit(struct ksock_conn *conn, struct ksock_tx *tx)
 
 	if (ksocknal_data.ksnd_stall_tx) {
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(ksocknal_data.ksnd_stall_tx));
+		schedule_timeout(ksocknal_data.ksnd_stall_tx * HZ);
 	}
 
 	LASSERT(tx->tx_resid);
@@ -294,7 +294,7 @@ ksocknal_receive(struct ksock_conn *conn)
 
 	if (ksocknal_data.ksnd_stall_rx) {
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(ksocknal_data.ksnd_stall_rx));
+		schedule_timeout(ksocknal_data.ksnd_stall_rx * HZ);
 	}
 
 	rc = ksocknal_connsock_addref(conn);
@@ -1780,7 +1780,7 @@ ksocknal_connect(struct ksock_route *route)
 	int rc = 0;
 
 	deadline = cfs_time_add(cfs_time_current(),
-				cfs_time_seconds(*ksocknal_tunables.ksnd_timeout));
+				*ksocknal_tunables.ksnd_timeout * HZ);
 
 	write_lock_bh(&ksocknal_data.ksnd_global_lock);
 
@@ -1878,7 +1878,7 @@ ksocknal_connect(struct ksock_route *route)
 			 * so min_reconnectms should be good heuristic
 			 */
 			route->ksnr_retry_interval =
-				cfs_time_seconds(*ksocknal_tunables.ksnd_min_reconnectms) / 1000;
+				*ksocknal_tunables.ksnd_min_reconnectms * HZ / 1000;
 			route->ksnr_timeout = cfs_time_add(cfs_time_current(),
 							   route->ksnr_retry_interval);
 		}
@@ -1899,10 +1899,10 @@ ksocknal_connect(struct ksock_route *route)
 	route->ksnr_retry_interval *= 2;
 	route->ksnr_retry_interval =
 		max(route->ksnr_retry_interval,
-		    cfs_time_seconds(*ksocknal_tunables.ksnd_min_reconnectms) / 1000);
+		    (long)*ksocknal_tunables.ksnd_min_reconnectms * HZ / 1000);
 	route->ksnr_retry_interval =
 		min(route->ksnr_retry_interval,
-		    cfs_time_seconds(*ksocknal_tunables.ksnd_max_reconnectms) / 1000);
+		    (long)*ksocknal_tunables.ksnd_max_reconnectms * HZ / 1000);
 
 	LASSERT(route->ksnr_retry_interval);
 	route->ksnr_timeout = cfs_time_add(cfs_time_current(),
@@ -1972,7 +1972,7 @@ ksocknal_connd_check_start(time64_t sec, long *timeout)
 
 	if (sec - ksocknal_data.ksnd_connd_failed_stamp <= 1) {
 		/* may run out of resource, retry later */
-		*timeout = cfs_time_seconds(1);
+		*timeout = HZ;
 		return 0;
 	}
 
@@ -2031,8 +2031,8 @@ ksocknal_connd_check_stop(time64_t sec, long *timeout)
 	val = (int)(ksocknal_data.ksnd_connd_starting_stamp +
 		    SOCKNAL_CONND_TIMEOUT - sec);
 
-	*timeout = (val > 0) ? cfs_time_seconds(val) :
-			       cfs_time_seconds(SOCKNAL_CONND_TIMEOUT);
+	*timeout = (val > 0) ? val * HZ :
+			       SOCKNAL_CONND_TIMEOUT * HZ;
 	if (val > 0)
 		return 0;
 
@@ -2307,7 +2307,7 @@ ksocknal_send_keepalive_locked(struct ksock_peer *peer)
 	if (*ksocknal_tunables.ksnd_keepalive <= 0 ||
 	    time_before(cfs_time_current(),
 			cfs_time_add(peer->ksnp_last_alive,
-				     cfs_time_seconds(*ksocknal_tunables.ksnd_keepalive))))
+				     *ksocknal_tunables.ksnd_keepalive * HZ)))
 		return 0;
 
 	if (time_before(cfs_time_current(), peer->ksnp_send_keepalive))
@@ -2563,7 +2563,7 @@ ksocknal_reaper(void *arg)
 					     ksocknal_data.ksnd_peer_hash_size;
 			}
 
-			deadline = cfs_time_add(deadline, cfs_time_seconds(p));
+			deadline = cfs_time_add(deadline, p * HZ);
 		}
 
 		if (nenomem_conns) {
diff --git a/drivers/staging/lustre/lnet/libcfs/debug.c b/drivers/staging/lustre/lnet/libcfs/debug.c
index 551c45bf4108..c70d2ae29b11 100644
--- a/drivers/staging/lustre/lnet/libcfs/debug.c
+++ b/drivers/staging/lustre/lnet/libcfs/debug.c
@@ -113,7 +113,7 @@ static int param_set_delay_minmax(const char *val,
 	if (rc)
 		return -EINVAL;
 
-	d = cfs_time_seconds(sec) / 100;
+	d = sec * HZ / 100;
 	if (d < min || d > max)
 		return -EINVAL;
 
diff --git a/drivers/staging/lustre/lnet/libcfs/fail.c b/drivers/staging/lustre/lnet/libcfs/fail.c
index 39439b303d65..d3f1e866c6a7 100644
--- a/drivers/staging/lustre/lnet/libcfs/fail.c
+++ b/drivers/staging/lustre/lnet/libcfs/fail.c
@@ -134,7 +134,7 @@ int __cfs_fail_timeout_set(u32 id, u32 value, int ms, int set)
 		CERROR("cfs_fail_timeout id %x sleeping for %dms\n",
 		       id, ms);
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(ms) / 1000);
+		schedule_timeout(ms * HZ / 1000);
 		CERROR("cfs_fail_timeout id %x awake\n", id);
 	}
 	return ret;
diff --git a/drivers/staging/lustre/lnet/libcfs/tracefile.c b/drivers/staging/lustre/lnet/libcfs/tracefile.c
index 57913aae1d88..4affca750bc5 100644
--- a/drivers/staging/lustre/lnet/libcfs/tracefile.c
+++ b/drivers/staging/lustre/lnet/libcfs/tracefile.c
@@ -441,7 +441,7 @@ int libcfs_debug_vmsg2(struct libcfs_debug_msg_data *msgdata,
 
 		if (cfs_time_after(cfs_time_current(),
 				   cdls->cdls_next + libcfs_console_max_delay +
-				   cfs_time_seconds(10))) {
+				   10 * HZ)) {
 			/* last timeout was a long time ago */
 			cdls->cdls_delay /= libcfs_console_backoff * 4;
 		} else {
@@ -1071,7 +1071,7 @@ static int tracefiled(void *arg)
 		init_waitqueue_entry(&__wait, current);
 		add_wait_queue(&tctl->tctl_waitq, &__wait);
 		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1));
+		schedule_timeout(HZ);
 		remove_wait_queue(&tctl->tctl_waitq, &__wait);
 	}
 	complete(&tctl->tctl_stop);
diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c
index ee85cab6f437..6c1f4941d4ba 100644
--- a/drivers/staging/lustre/lnet/lnet/acceptor.c
+++ b/drivers/staging/lustre/lnet/lnet/acceptor.c
@@ -365,7 +365,7 @@ lnet_acceptor(void *arg)
 			if (rc != -EAGAIN) {
 				CWARN("Accept error %d: pausing...\n", rc);
 				set_current_state(TASK_UNINTERRUPTIBLE);
-				schedule_timeout(cfs_time_seconds(1));
+				schedule_timeout(HZ);
 			}
 			continue;
 		}
diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c
index 2c7abad57104..93e6274e9dac 100644
--- a/drivers/staging/lustre/lnet/lnet/api-ni.c
+++ b/drivers/staging/lustre/lnet/lnet/api-ni.c
@@ -970,7 +970,7 @@ lnet_ping_md_unlink(struct lnet_ping_info *pinfo,
 	while (pinfo->pi_features != LNET_PING_FEAT_INVAL) {
 		CDEBUG(D_NET, "Still waiting for ping MD to unlink\n");
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1));
+		schedule_timeout(HZ);
 	}
 
 	cfs_restore_sigs(blocked);
@@ -1109,7 +1109,7 @@ lnet_clear_zombies_nis_locked(void)
 				       libcfs_nid2str(ni->ni_nid));
 			}
 			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(cfs_time_seconds(1));
+			schedule_timeout(HZ);
 			lnet_net_lock(LNET_LOCK_EX);
 			continue;
 		}
diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c
index c673037dbce4..ed43b3f4b114 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-move.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-move.c
@@ -524,7 +524,7 @@ lnet_peer_is_alive(struct lnet_peer *lp, unsigned long now)
 		return 0;
 
 	deadline = cfs_time_add(lp->lp_last_alive,
-				cfs_time_seconds(lp->lp_ni->ni_peertimeout));
+				lp->lp_ni->ni_peertimeout * HZ);
 	alive = cfs_time_after(deadline, now);
 
 	/* Update obsolete lp_alive except for routers assumed to be dead
@@ -562,7 +562,7 @@ lnet_peer_alive_locked(struct lnet_peer *lp)
 
 		unsigned long next_query =
 			   cfs_time_add(lp->lp_last_query,
-					cfs_time_seconds(lnet_queryinterval));
+					lnet_queryinterval * HZ);
 
 		if (time_before(now, next_query)) {
 			if (lp->lp_alive)
diff --git a/drivers/staging/lustre/lnet/lnet/net_fault.c b/drivers/staging/lustre/lnet/lnet/net_fault.c
index e3468cef273b..a63b7941d435 100644
--- a/drivers/staging/lustre/lnet/lnet/net_fault.c
+++ b/drivers/staging/lustre/lnet/lnet/net_fault.c
@@ -315,9 +315,8 @@ drop_rule_match(struct lnet_drop_rule *rule, lnet_nid_t src,
 				rule->dr_time_base = now;
 
 			rule->dr_drop_time = rule->dr_time_base +
-				cfs_time_seconds(
-					prandom_u32_max(attr->u.drop.da_interval));
-			rule->dr_time_base += cfs_time_seconds(attr->u.drop.da_interval);
+				prandom_u32_max(attr->u.drop.da_interval) * HZ;
+			rule->dr_time_base += attr->u.drop.da_interval * HZ;
 
 			CDEBUG(D_NET, "Drop Rule %s->%s: next drop : %lu\n",
 			       libcfs_nid2str(attr->fa_src),
@@ -440,8 +439,7 @@ static struct delay_daemon_data	delay_dd;
 static unsigned long
 round_timeout(unsigned long timeout)
 {
-	return cfs_time_seconds((unsigned int)
-			cfs_duration_sec(cfs_time_sub(timeout, 0)) + 1);
+	return (unsigned int)rounddown(timeout, HZ) + HZ;
 }
 
 static void
@@ -483,10 +481,8 @@ delay_rule_match(struct lnet_delay_rule *rule, lnet_nid_t src,
 				rule->dl_time_base = now;
 
 			rule->dl_delay_time = rule->dl_time_base +
-				cfs_time_seconds(
-					prandom_u32_max(
-						attr->u.delay.la_interval));
-			rule->dl_time_base += cfs_time_seconds(attr->u.delay.la_interval);
+				prandom_u32_max(attr->u.delay.la_interval) * HZ;
+			rule->dl_time_base += attr->u.delay.la_interval * HZ;
 
 			CDEBUG(D_NET, "Delay Rule %s->%s: next delay : %lu\n",
 			       libcfs_nid2str(attr->fa_src),
diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c
index 3e157c10fec4..3d4caa609c83 100644
--- a/drivers/staging/lustre/lnet/lnet/peer.c
+++ b/drivers/staging/lustre/lnet/lnet/peer.c
@@ -137,7 +137,7 @@ lnet_peer_table_deathrow_wait_locked(struct lnet_peer_table *ptable,
 			       ptable->pt_zombies);
 		}
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1) >> 1);
+		schedule_timeout(HZ >> 1);
 		lnet_net_lock(cpt_locked);
 	}
 }
diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c
index 6504761ca598..ec1d3e58519a 100644
--- a/drivers/staging/lustre/lnet/lnet/router.c
+++ b/drivers/staging/lustre/lnet/lnet/router.c
@@ -808,7 +808,7 @@ lnet_wait_known_routerstate(void)
 			return;
 
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1));
+		schedule_timeout(HZ);
 	}
 }
 
@@ -1011,7 +1011,7 @@ lnet_ping_router_locked(struct lnet_peer *rtr)
 
 	if (secs && !rtr->lp_ping_notsent &&
 	    cfs_time_after(now, cfs_time_add(rtr->lp_ping_timestamp,
-					     cfs_time_seconds(secs)))) {
+					     secs * HZ))) {
 		int rc;
 		struct lnet_process_id id;
 		struct lnet_handle_md mdh;
@@ -1185,7 +1185,7 @@ lnet_prune_rc_data(int wait_unlink)
 		CDEBUG(((i & (-i)) == i) ? D_WARNING : D_NET,
 		       "Waiting for rc buffers to unlink\n");
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1) / 4);
+		schedule_timeout(HZ / 4);
 
 		lnet_net_lock(LNET_LOCK_EX);
 	}
@@ -1282,7 +1282,7 @@ lnet_router_checker(void *arg)
 		else
 			wait_event_interruptible_timeout(the_lnet.ln_rc_waitq,
 							 false,
-							 cfs_time_seconds(1));
+							 HZ);
 	}
 
 	lnet_prune_rc_data(1); /* wait for UNLINK */
diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c
index 7aa515c34594..6dcc966b293b 100644
--- a/drivers/staging/lustre/lnet/selftest/conrpc.c
+++ b/drivers/staging/lustre/lnet/selftest/conrpc.c
@@ -359,7 +359,7 @@ lstcon_rpc_trans_postwait(struct lstcon_rpc_trans *trans, int timeout)
 
 	rc = wait_event_interruptible_timeout(trans->tas_waitq,
 					      lstcon_rpc_trans_check(trans),
-					      cfs_time_seconds(timeout));
+					      timeout * HZ);
 	rc = (rc > 0) ? 0 : ((rc < 0) ? -EINTR : -ETIMEDOUT);
 
 	mutex_lock(&console_session.ses_mutex);
@@ -1350,7 +1350,7 @@ lstcon_rpc_cleanup_wait(void)
 
 		CWARN("Session is shutting down, waiting for termination of transactions\n");
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1));
+		schedule_timeout(HZ);
 
 		mutex_lock(&console_session.ses_mutex);
 	}
diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c
index f8198ad1046e..9613b0a77007 100644
--- a/drivers/staging/lustre/lnet/selftest/rpc.c
+++ b/drivers/staging/lustre/lnet/selftest/rpc.c
@@ -1604,7 +1604,7 @@ srpc_startup(void)
 
 	/* 1 second pause to avoid timestamp reuse */
 	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(cfs_time_seconds(1));
+	schedule_timeout(HZ);
 	srpc_data.rpc_matchbits = ((__u64)ktime_get_real_seconds()) << 48;
 
 	srpc_data.rpc_state = SRPC_STATE_NONE;
diff --git a/drivers/staging/lustre/lnet/selftest/selftest.h b/drivers/staging/lustre/lnet/selftest/selftest.h
index ad04534f000c..05466b85e1c0 100644
--- a/drivers/staging/lustre/lnet/selftest/selftest.h
+++ b/drivers/staging/lustre/lnet/selftest/selftest.h
@@ -575,7 +575,7 @@ swi_state2str(int state)
 #define selftest_wait_events()					\
 	do {							\
 		set_current_state(TASK_UNINTERRUPTIBLE);	\
-		schedule_timeout(cfs_time_seconds(1) / 10);	\
+		schedule_timeout(HZ / 10);	\
 	} while (0)
 
 #define lst_wait_until(cond, lock, fmt, ...)				\
diff --git a/drivers/staging/lustre/lnet/selftest/timer.c b/drivers/staging/lustre/lnet/selftest/timer.c
index ab125a8524c5..9716afeb3c94 100644
--- a/drivers/staging/lustre/lnet/selftest/timer.c
+++ b/drivers/staging/lustre/lnet/selftest/timer.c
@@ -177,7 +177,7 @@ stt_timer_main(void *arg)
 
 		rc = wait_event_timeout(stt_data.stt_waitq,
 					stt_data.stt_shuttingdown,
-					cfs_time_seconds(STTIMER_SLOTTIME));
+					STTIMER_SLOTTIME * HZ);
 	}
 
 	spin_lock(&stt_data.stt_lock);
diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm.h b/drivers/staging/lustre/lustre/include/lustre_dlm.h
index e0b17052b2ea..239aa2b1268f 100644
--- a/drivers/staging/lustre/lustre/include/lustre_dlm.h
+++ b/drivers/staging/lustre/lustre/include/lustre_dlm.h
@@ -60,7 +60,7 @@ struct obd_device;
 #define OBD_LDLM_DEVICENAME  "ldlm"
 
 #define LDLM_DEFAULT_LRU_SIZE (100 * num_online_cpus())
-#define LDLM_DEFAULT_MAX_ALIVE (cfs_time_seconds(3900)) /* 65 min */
+#define LDLM_DEFAULT_MAX_ALIVE (65 * 60 * HZ) /* 65 min */
 #define LDLM_DEFAULT_PARALLEL_AST_LIMIT 1024
 
 /**
diff --git a/drivers/staging/lustre/lustre/include/lustre_mdc.h b/drivers/staging/lustre/lustre/include/lustre_mdc.h
index 007e1ec3f0f4..a9c9992a2502 100644
--- a/drivers/staging/lustre/lustre/include/lustre_mdc.h
+++ b/drivers/staging/lustre/lustre/include/lustre_mdc.h
@@ -124,7 +124,7 @@ static inline void mdc_get_rpc_lock(struct mdc_rpc_lock *lck,
 	 */
 	while (unlikely(lck->rpcl_it == MDC_FAKE_RPCL_IT)) {
 		mutex_unlock(&lck->rpcl_mutex);
-		schedule_timeout(cfs_time_seconds(1) / 4);
+		schedule_timeout(HZ / 4);
 		goto again;
 	}
 
diff --git a/drivers/staging/lustre/lustre/include/lustre_net.h b/drivers/staging/lustre/lustre/include/lustre_net.h
index 4c665eca2467..5a4434e7c85a 100644
--- a/drivers/staging/lustre/lustre/include/lustre_net.h
+++ b/drivers/staging/lustre/lustre/include/lustre_net.h
@@ -2262,7 +2262,7 @@ static inline int ptlrpc_send_limit_expired(struct ptlrpc_request *req)
 {
 	if (req->rq_delay_limit != 0 &&
 	    time_before(cfs_time_add(req->rq_queued_time,
-				     cfs_time_seconds(req->rq_delay_limit)),
+				     req->rq_delay_limit * HZ),
 			cfs_time_current())) {
 		return 1;
 	}
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
index 4f700ddb47c6..773abe78708a 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
@@ -1366,7 +1366,7 @@ enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags,
 				}
 			}
 
-			lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(obd_timeout),
+			lwi = LWI_TIMEOUT_INTR(obd_timeout * HZ,
 					       NULL, LWI_ON_SIGNAL_NOOP, NULL);
 
 			/* XXX FIXME see comment on CAN_MATCH in lustre_dlm.h */
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
index 6c7c4b19a0a0..58913e628124 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
@@ -163,7 +163,7 @@ static void ldlm_handle_cp_callback(struct ptlrpc_request *req,
 	LDLM_DEBUG(lock, "client completion callback handler START");
 
 	if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_CANCEL_BL_CB_RACE)) {
-		int to = cfs_time_seconds(1);
+		int to = HZ;
 
 		while (to > 0) {
 			set_current_state(TASK_INTERRUPTIBLE);
@@ -327,7 +327,7 @@ static void ldlm_handle_gl_callback(struct ptlrpc_request *req,
 	    !lock->l_readers && !lock->l_writers &&
 	    cfs_time_after(cfs_time_current(),
 			   cfs_time_add(lock->l_last_used,
-					cfs_time_seconds(10)))) {
+					10 * HZ))) {
 		unlock_res_and_lock(lock);
 		if (ldlm_bl_to_thread_lock(ns, NULL, lock))
 			ldlm_handle_bl_callback(ns, NULL, lock);
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
index f27c2694793a..622245a5f049 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
@@ -1008,7 +1008,7 @@ static int ldlm_pools_thread_main(void *arg)
 		 * Wait until the next check time, or until we're
 		 * stopped.
 		 */
-		lwi = LWI_TIMEOUT(cfs_time_seconds(c_time),
+		lwi = LWI_TIMEOUT(c_time * HZ,
 				  NULL, NULL);
 		l_wait_event(thread->t_ctl_waitq,
 			     thread_is_stopping(thread) ||
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index 6aa37463db46..a244fa717134 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -288,7 +288,7 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 		LDLM_DEBUG(lock, "waiting indefinitely because of NO_TIMEOUT");
 		lwi = LWI_INTR(interrupted_completion_wait, &lwd);
 	} else {
-		lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(timeout),
+		lwi = LWI_TIMEOUT_INTR(timeout * HZ,
 				       ldlm_expired_completion_wait,
 				       interrupted_completion_wait, &lwd);
 	}
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
index 9958533cc227..2e66825c8f4b 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
@@ -799,7 +799,7 @@ static void cleanup_resource(struct ldlm_resource *res, struct list_head *q,
 			LDLM_DEBUG(lock, "setting FL_LOCAL_ONLY");
 			if (lock->l_flags & LDLM_FL_FAIL_LOC) {
 				set_current_state(TASK_UNINTERRUPTIBLE);
-				schedule_timeout(cfs_time_seconds(4));
+				schedule_timeout(4 * HZ);
 				set_current_state(TASK_RUNNING);
 			}
 			if (lock->l_completion_ast)
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
index 020f0faeb750..c820b201af71 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -2026,8 +2026,8 @@ void ll_umount_begin(struct super_block *sb)
 	 * to decrement mnt_cnt and hope to finish it within 10sec.
 	 */
 	init_waitqueue_head(&waitq);
-	lwi = LWI_TIMEOUT_INTERVAL(cfs_time_seconds(10),
-				   cfs_time_seconds(1), NULL, NULL);
+	lwi = LWI_TIMEOUT_INTERVAL(10 * HZ,
+				   HZ, NULL, NULL);
 	l_wait_event(waitq, may_umount(sbi->ll_mnt.mnt), &lwi);
 
 	schedule();
diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c
index 78005cc6e831..96360f104b92 100644
--- a/drivers/staging/lustre/lustre/llite/statahead.c
+++ b/drivers/staging/lustre/lustre/llite/statahead.c
@@ -1424,7 +1424,7 @@ static int revalidate_statahead_dentry(struct inode *dir,
 		spin_lock(&lli->lli_sa_lock);
 		sai->sai_index_wait = entry->se_index;
 		spin_unlock(&lli->lli_sa_lock);
-		lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(30), NULL,
+		lwi = LWI_TIMEOUT_INTR(30 * HZ, NULL,
 				       LWI_ON_SIGNAL_NOOP, NULL);
 		rc = l_wait_event(sai->sai_waitq, sa_ready(entry), &lwi);
 		if (rc < 0) {
diff --git a/drivers/staging/lustre/lustre/lov/lov_request.c b/drivers/staging/lustre/lustre/lov/lov_request.c
index cfa1d7f92b0f..fb3b7a7fa32a 100644
--- a/drivers/staging/lustre/lustre/lov/lov_request.c
+++ b/drivers/staging/lustre/lustre/lov/lov_request.c
@@ -126,8 +126,8 @@ static int lov_check_and_wait_active(struct lov_obd *lov, int ost_idx)
 	mutex_unlock(&lov->lov_lock);
 
 	init_waitqueue_head(&waitq);
-	lwi = LWI_TIMEOUT_INTERVAL(cfs_time_seconds(obd_timeout),
-				   cfs_time_seconds(1), NULL, NULL);
+	lwi = LWI_TIMEOUT_INTERVAL(obd_timeout * HZ,
+				   HZ, NULL, NULL);
 
 	rc = l_wait_event(waitq, lov_check_set(lov, ost_idx), &lwi);
 	if (tgt->ltd_active)
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c
index 03e55bca4ada..b12518ba5ae9 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_request.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c
@@ -888,7 +888,7 @@ static int mdc_getpage(struct obd_export *exp, const struct lu_fid *fid,
 			       exp->exp_obd->obd_name, -EIO);
 			return -EIO;
 		}
-		lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(resends), NULL, NULL,
+		lwi = LWI_TIMEOUT_INTR(resends * HZ, NULL, NULL,
 				       NULL);
 		l_wait_event(waitq, 0, &lwi);
 
diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c
index b743aee62349..a01d13bde102 100644
--- a/drivers/staging/lustre/lustre/mgc/mgc_request.c
+++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c
@@ -1628,7 +1628,7 @@ int mgc_process_log(struct obd_device *mgc, struct config_llog_data *cld)
 
 		if (rcl == -ESHUTDOWN &&
 		    atomic_read(&mgc->u.cli.cl_mgc_refcount) > 0 && !retry) {
-			int secs = cfs_time_seconds(obd_timeout);
+			int secs = obd_timeout * HZ;
 			struct obd_import *imp;
 			struct l_wait_info lwi;
 
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
index 902bad22013b..ce5e7bdda692 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -1097,7 +1097,7 @@ EXPORT_SYMBOL(cl_sync_io_init);
 int cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
 		    long timeout)
 {
-	struct l_wait_info lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(timeout),
+	struct l_wait_info lwi = LWI_TIMEOUT_INTR(timeout * HZ,
 						  NULL, NULL, NULL);
 	int rc;
 
diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c
index b9c1dc7e61b0..9c5ce5074b66 100644
--- a/drivers/staging/lustre/lustre/obdecho/echo_client.c
+++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c
@@ -752,7 +752,7 @@ static struct lu_device *echo_device_free(const struct lu_env *env,
 		spin_unlock(&ec->ec_lock);
 		CERROR("echo_client still has objects at cleanup time, wait for 1 second\n");
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(cfs_time_seconds(1));
+		schedule_timeout(HZ);
 		lu_site_purge(env, ed->ed_site, -1);
 		spin_lock(&ec->ec_lock);
 	}
diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c
index b8d5adca94e1..0797e671f667 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cache.c
+++ b/drivers/staging/lustre/lustre/osc/osc_cache.c
@@ -934,7 +934,7 @@ static int osc_extent_wait(const struct lu_env *env, struct osc_extent *ext,
 			   enum osc_extent_state state)
 {
 	struct osc_object *obj = ext->oe_obj;
-	struct l_wait_info lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(600), NULL,
+	struct l_wait_info lwi = LWI_TIMEOUT_INTR(600 * HZ, NULL,
 						  LWI_ON_SIGNAL_NOOP, NULL);
 	int rc = 0;
 
@@ -1571,7 +1571,7 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli,
 	struct l_wait_info lwi;
 	int rc = -EDQUOT;
 
-	lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(AT_OFF ? obd_timeout : at_max),
+	lwi = LWI_TIMEOUT_INTR((AT_OFF ? obd_timeout : at_max) * HZ,
 			       NULL, LWI_ON_SIGNAL_NOOP, NULL);
 
 	OSC_DUMP_GRANT(D_CACHE, cli, "need:%d\n", bytes);
diff --git a/drivers/staging/lustre/lustre/osc/osc_object.c b/drivers/staging/lustre/lustre/osc/osc_object.c
index 6c424f0290bb..6baa8e2e00c9 100644
--- a/drivers/staging/lustre/lustre/osc/osc_object.c
+++ b/drivers/staging/lustre/lustre/osc/osc_object.c
@@ -328,7 +328,7 @@ int osc_object_is_contended(struct osc_object *obj)
 	 * ll_file_is_contended.
 	 */
 	retry_time = cfs_time_add(obj->oo_contention_time,
-				  cfs_time_seconds(osc_contention_time));
+				  osc_contention_time * HZ);
 	if (cfs_time_after(cur_time, retry_time)) {
 		osc_object_clear_contended(obj);
 		return 0;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index bac4b2304bad..0ab13f8e5993 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -766,7 +766,7 @@ int ptlrpc_request_bufs_pack(struct ptlrpc_request *request,
 			 * fail_loc
 			 */
 			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(cfs_time_seconds(2));
+			schedule_timeout(2 * HZ);
 			set_current_state(TASK_RUNNING);
 		}
 	}
@@ -2284,7 +2284,7 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 			 * We still want to block for a limited time,
 			 * so we allow interrupts during the timeout.
 			 */
-			lwi = LWI_TIMEOUT_INTR_ALL(cfs_time_seconds(1),
+			lwi = LWI_TIMEOUT_INTR_ALL(HZ,
 						   ptlrpc_expired_set,
 						   ptlrpc_interrupted_set, set);
 		else
@@ -2293,7 +2293,7 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 			 * interrupts are allowed. Wait until all
 			 * complete, or an in-flight req times out.
 			 */
-			lwi = LWI_TIMEOUT(cfs_time_seconds(timeout ? timeout : 1),
+			lwi = LWI_TIMEOUT((timeout ? timeout : 1) * HZ,
 					  ptlrpc_expired_set, set);
 
 		rc = l_wait_event(set->set_waitq, ptlrpc_check_set(NULL, set), &lwi);
@@ -2538,8 +2538,8 @@ static int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async)
 		 * Network access will complete in finite time but the HUGE
 		 * timeout lets us CWARN for visibility of sluggish NALs
 		 */
-		lwi = LWI_TIMEOUT_INTERVAL(cfs_time_seconds(LONG_UNLINK),
-					   cfs_time_seconds(1), NULL, NULL);
+		lwi = LWI_TIMEOUT_INTERVAL(LONG_UNLINK * HZ,
+					   HZ, NULL, NULL);
 		rc = l_wait_event(*wq, !ptlrpc_client_recv_or_unlink(request),
 				  &lwi);
 		if (rc == 0) {
diff --git a/drivers/staging/lustre/lustre/ptlrpc/events.c b/drivers/staging/lustre/lustre/ptlrpc/events.c
index 811b7ab3a582..71f7588570ef 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/events.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/events.c
@@ -517,7 +517,7 @@ static void ptlrpc_ni_fini(void)
 
 			/* Wait for a bit */
 			init_waitqueue_head(&waitq);
-			lwi = LWI_TIMEOUT(cfs_time_seconds(2), NULL, NULL);
+			lwi = LWI_TIMEOUT(2 * HZ, NULL, NULL);
 			l_wait_event(waitq, 0, &lwi);
 			break;
 		}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c
index 5b0f65536c29..0eba5f18bd3b 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/import.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/import.c
@@ -307,9 +307,9 @@ void ptlrpc_invalidate_import(struct obd_import *imp)
 		 * have been locally cancelled by ptlrpc_abort_inflight.
 		 */
 		lwi = LWI_TIMEOUT_INTERVAL(
-			cfs_timeout_cap(cfs_time_seconds(timeout)),
-			(timeout > 1) ? cfs_time_seconds(1) :
-			cfs_time_seconds(1) / 2,
+			cfs_timeout_cap(timeout * HZ),
+			(timeout > 1) ? HZ :
+			HZ / 2,
 			NULL, NULL);
 		rc = l_wait_event(imp->imp_recovery_waitq,
 				  (atomic_read(&imp->imp_inflight) == 0),
@@ -431,7 +431,7 @@ void ptlrpc_fail_import(struct obd_import *imp, __u32 conn_cnt)
 int ptlrpc_reconnect_import(struct obd_import *imp)
 {
 	struct l_wait_info lwi;
-	int secs = cfs_time_seconds(obd_timeout);
+	int secs = obd_timeout * HZ;
 	int rc;
 
 	ptlrpc_pinger_force(imp);
@@ -1508,14 +1508,13 @@ int ptlrpc_disconnect_import(struct obd_import *imp, int noclose)
 
 		if (AT_OFF) {
 			if (imp->imp_server_timeout)
-				timeout = cfs_time_seconds(obd_timeout / 2);
+				timeout = obd_timeout * HZ / 2;
 			else
-				timeout = cfs_time_seconds(obd_timeout);
+				timeout = obd_timeout * HZ;
 		} else {
 			int idx = import_at_get_index(imp,
 				imp->imp_client->cli_request_portal);
-			timeout = cfs_time_seconds(
-				at_get(&imp->imp_at.iat_service_estimate[idx]));
+			timeout = at_get(&imp->imp_at.iat_service_estimate[idx]) * HZ;
 		}
 
 		lwi = LWI_TIMEOUT_INTR(cfs_timeout_cap(timeout),
diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
index 047d712e850c..0c2ded721c49 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
@@ -270,8 +270,8 @@ int ptlrpc_unregister_bulk(struct ptlrpc_request *req, int async)
 		/* Network access will complete in finite time but the HUGE
 		 * timeout lets us CWARN for visibility of sluggish LNDs
 		 */
-		lwi = LWI_TIMEOUT_INTERVAL(cfs_time_seconds(LONG_UNLINK),
-					   cfs_time_seconds(1), NULL, NULL);
+		lwi = LWI_TIMEOUT_INTERVAL(LONG_UNLINK * HZ,
+					   HZ, NULL, NULL);
 		rc = l_wait_event(*wq, !ptlrpc_client_bulk_active(req), &lwi);
 		if (rc == 0) {
 			ptlrpc_rqphase_move(req, req->rq_next_phase);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
index a64e125df95f..c060d6f5015a 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
@@ -267,7 +267,7 @@ lustre_get_emerg_rs(struct ptlrpc_service_part *svcpt)
 		/* If we cannot get anything for some long time, we better
 		 * bail out instead of waiting infinitely
 		 */
-		lwi = LWI_TIMEOUT(cfs_time_seconds(10), NULL, NULL);
+		lwi = LWI_TIMEOUT(10 * HZ, NULL, NULL);
 		rc = l_wait_event(svcpt->scp_rep_waitq,
 				  !list_empty(&svcpt->scp_rep_idle), &lwi);
 		if (rc != 0)
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
index af707cb2b62b..010a1cdf05fa 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
@@ -141,7 +141,7 @@ static long pinger_check_timeout(unsigned long time)
 	}
 	mutex_unlock(&pinger_mutex);
 
-	return cfs_time_sub(cfs_time_add(time, cfs_time_seconds(timeout)),
+	return cfs_time_sub(cfs_time_add(time, timeout * HZ),
 					 cfs_time_current());
 }
 
@@ -247,7 +247,7 @@ static int ptlrpc_pinger_main(void *arg)
 			if (imp->imp_pingable && imp->imp_next_ping &&
 			    cfs_time_after(imp->imp_next_ping,
 					   cfs_time_add(this_ping,
-							cfs_time_seconds(PING_INTERVAL))))
+							PING_INTERVAL * HZ)))
 				ptlrpc_update_next_ping(imp, 0);
 		}
 		mutex_unlock(&pinger_mutex);
@@ -264,10 +264,10 @@ static int ptlrpc_pinger_main(void *arg)
 		CDEBUG(D_INFO, "next wakeup in " CFS_DURATION_T " (%ld)\n",
 		       time_to_next_wake,
 		       cfs_time_add(this_ping,
-				    cfs_time_seconds(PING_INTERVAL)));
+				    PING_INTERVAL * HZ));
 		if (time_to_next_wake > 0) {
 			lwi = LWI_TIMEOUT(max_t(long, time_to_next_wake,
-						cfs_time_seconds(1)),
+						HZ),
 					  NULL, NULL);
 			l_wait_event(thread->t_ctl_waitq,
 				     thread_is_stopping(thread) ||
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
index 8b865294d933..dad2f9290f70 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
@@ -230,7 +230,7 @@ void ptlrpcd_add_req(struct ptlrpc_request *req)
 
 	spin_lock(&req->rq_lock);
 	if (req->rq_invalid_rqset) {
-		struct l_wait_info lwi = LWI_TIMEOUT(cfs_time_seconds(5),
+		struct l_wait_info lwi = LWI_TIMEOUT(5 * HZ,
 						     back_to_sleep, NULL);
 
 		req->rq_invalid_rqset = 0;
@@ -438,7 +438,7 @@ static int ptlrpcd(void *arg)
 		int timeout;
 
 		timeout = ptlrpc_set_next_timeout(set);
-		lwi = LWI_TIMEOUT(cfs_time_seconds(timeout ? timeout : 1),
+		lwi = LWI_TIMEOUT((timeout ? timeout : 1) * HZ,
 				  ptlrpc_expired_set, set);
 
 		lu_context_enter(&env.le_ctx);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/recover.c b/drivers/staging/lustre/lustre/ptlrpc/recover.c
index e4d3f23e9f3a..5bbd23eebfa6 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/recover.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/recover.c
@@ -347,7 +347,7 @@ int ptlrpc_recover_import(struct obd_import *imp, char *new_uuid, int async)
 
 	if (!async) {
 		struct l_wait_info lwi;
-		int secs = cfs_time_seconds(obd_timeout);
+		int secs = obd_timeout * HZ;
 
 		CDEBUG(D_HA, "%s: recovery started, waiting %u seconds\n",
 		       obd2cli_tgt(imp->imp_obd), secs);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
index 1f22926c1355..6d4229ebc9d9 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -2149,7 +2149,7 @@ static int ptlrpc_main(void *arg)
 			 * Wait for a timeout (unless something else
 			 * happens) before I try again
 			 */
-			svcpt->scp_rqbd_timeout = cfs_time_seconds(1) / 10;
+			svcpt->scp_rqbd_timeout = HZ / 10;
 			CDEBUG(D_RPCTRACE, "Posted buffers: %d\n",
 			       svcpt->scp_nrqbds_posted);
 		}
@@ -2588,7 +2588,7 @@ static void ptlrpc_wait_replies(struct ptlrpc_service_part *svcpt)
 {
 	while (1) {
 		int rc;
-		struct l_wait_info lwi = LWI_TIMEOUT(cfs_time_seconds(10),
+		struct l_wait_info lwi = LWI_TIMEOUT(10 * HZ,
 						     NULL, NULL);
 
 		rc = l_wait_event(svcpt->scp_waitq,
@@ -2660,8 +2660,8 @@ ptlrpc_service_unlink_rqbd(struct ptlrpc_service *svc)
 			 * of sluggish LNDs
 			 */
 			lwi = LWI_TIMEOUT_INTERVAL(
-					cfs_time_seconds(LONG_UNLINK),
-					cfs_time_seconds(1), NULL, NULL);
+					LONG_UNLINK * HZ,
+					HZ, NULL, NULL);
 			rc = l_wait_event(svcpt->scp_waitq,
 					  svcpt->scp_nrqbds_posted == 0, &lwi);
 			if (rc == -ETIMEDOUT) {

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 05/19] staging: lustre: use wait_event_idle_timeout() where appropriate.
@ 2018-02-12 21:22   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

When the lwi arg has a timeout, but no timeout
callback function, l_wait_event() acts much the same as
wait_event_idle_timeout() - the wait is not interruptible and
simply waits for the event or the timeouts.

The most noticable difference is that the return value is
-ETIMEDOUT or 0, rather than 0 or non-zero.

Another difference is that if the timeout is zero, l_wait_event()
will not time out at all.  In the one case where that is possible
we need to conditionally use wait_event_idle().

So replace all such calls with wait_event_idle_timeout(), being
careful of the return value.

In one case, there is no event expected, only the timeout
is needed.  So use schedule_timeout_uninterruptible().

Note that the presence or absence of LWI_ON_SIGNAL_NOOP
has no effect in these cases.  It only has effect if the timeout
callback is non-NULL, or the timeout is zero, or
LWI_TIMEOUT_INTR_ALL() is used.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c     |   10 ++------
 drivers/staging/lustre/lustre/ldlm/ldlm_pool.c     |   12 +++-------
 drivers/staging/lustre/lustre/llite/statahead.c    |   14 ++++-------
 drivers/staging/lustre/lustre/mdc/mdc_request.c    |    5 +---
 drivers/staging/lustre/lustre/mgc/mgc_request.c    |   15 +++++-------
 drivers/staging/lustre/lustre/obdclass/cl_io.c     |   17 ++++++++------
 drivers/staging/lustre/lustre/osc/osc_cache.c      |   25 ++++++++++----------
 drivers/staging/lustre/lustre/ptlrpc/events.c      |    7 +-----
 drivers/staging/lustre/lustre/ptlrpc/import.c      |   12 ++++------
 .../staging/lustre/lustre/ptlrpc/pack_generic.c    |    9 +++----
 drivers/staging/lustre/lustre/ptlrpc/pinger.c      |   12 +++-------
 drivers/staging/lustre/lustre/ptlrpc/recover.c     |   12 ++++------
 drivers/staging/lustre/lustre/ptlrpc/sec_gc.c      |   10 ++------
 drivers/staging/lustre/lustre/ptlrpc/service.c     |   11 ++++-----
 14 files changed, 68 insertions(+), 103 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
index 773abe78708a..95bea351d21d 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
@@ -1349,7 +1349,6 @@ enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags,
 		if ((flags & LDLM_FL_LVB_READY) && !ldlm_is_lvb_ready(lock)) {
 			__u64 wait_flags = LDLM_FL_LVB_READY |
 				LDLM_FL_DESTROYED | LDLM_FL_FAIL_NOTIFIED;
-			struct l_wait_info lwi;
 
 			if (lock->l_completion_ast) {
 				int err = lock->l_completion_ast(lock,
@@ -1366,13 +1365,10 @@ enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags,
 				}
 			}
 
-			lwi = LWI_TIMEOUT_INTR(obd_timeout * HZ,
-					       NULL, LWI_ON_SIGNAL_NOOP, NULL);
-
 			/* XXX FIXME see comment on CAN_MATCH in lustre_dlm.h */
-			l_wait_event(lock->l_waitq,
-				     lock->l_flags & wait_flags,
-				     &lwi);
+			wait_event_idle_timeout(lock->l_waitq,
+						lock->l_flags & wait_flags,
+						obd_timeout * HZ);
 			if (!ldlm_is_lvb_ready(lock)) {
 				if (flags & LDLM_FL_TEST_LOCK)
 					LDLM_LOCK_RELEASE(lock);
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
index 622245a5f049..a0e486b57e08 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
@@ -997,8 +997,6 @@ static int ldlm_pools_thread_main(void *arg)
 	       "ldlm_poold", current_pid());
 
 	while (1) {
-		struct l_wait_info lwi;
-
 		/*
 		 * Recal all pools on this tick.
 		 */
@@ -1008,12 +1006,10 @@ static int ldlm_pools_thread_main(void *arg)
 		 * Wait until the next check time, or until we're
 		 * stopped.
 		 */
-		lwi = LWI_TIMEOUT(c_time * HZ,
-				  NULL, NULL);
-		l_wait_event(thread->t_ctl_waitq,
-			     thread_is_stopping(thread) ||
-			     thread_is_event(thread),
-			     &lwi);
+		wait_event_idle_timeout(thread->t_ctl_waitq,
+					thread_is_stopping(thread) ||
+					thread_is_event(thread),
+					c_time * HZ);
 
 		if (thread_test_and_clear_flags(thread, SVC_STOPPING))
 			break;
diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c
index 96360f104b92..6052bfd7ff05 100644
--- a/drivers/staging/lustre/lustre/llite/statahead.c
+++ b/drivers/staging/lustre/lustre/llite/statahead.c
@@ -1151,10 +1151,9 @@ static int ll_statahead_thread(void *arg)
 	 */
 	while (sai->sai_sent != sai->sai_replied) {
 		/* in case we're not woken up, timeout wait */
-		struct l_wait_info lwi = LWI_TIMEOUT(msecs_to_jiffies(MSEC_PER_SEC >> 3),
-						     NULL, NULL);
-		l_wait_event(sa_thread->t_ctl_waitq,
-			     sai->sai_sent == sai->sai_replied, &lwi);
+		wait_event_idle_timeout(sa_thread->t_ctl_waitq,
+					sai->sai_sent == sai->sai_replied,
+					HZ>>3);
 	}
 
 	/* release resources held by statahead RPCs */
@@ -1374,7 +1373,6 @@ static int revalidate_statahead_dentry(struct inode *dir,
 {
 	struct ll_inode_info *lli = ll_i2info(dir);
 	struct sa_entry *entry = NULL;
-	struct l_wait_info lwi = { 0 };
 	struct ll_dentry_data *ldd;
 	int rc = 0;
 
@@ -1424,10 +1422,8 @@ static int revalidate_statahead_dentry(struct inode *dir,
 		spin_lock(&lli->lli_sa_lock);
 		sai->sai_index_wait = entry->se_index;
 		spin_unlock(&lli->lli_sa_lock);
-		lwi = LWI_TIMEOUT_INTR(30 * HZ, NULL,
-				       LWI_ON_SIGNAL_NOOP, NULL);
-		rc = l_wait_event(sai->sai_waitq, sa_ready(entry), &lwi);
-		if (rc < 0) {
+		if (0 == wait_event_idle_timeout(sai->sai_waitq,
+						 sa_ready(entry), 30 * HZ)) {
 			/*
 			 * entry may not be ready, so it may be used by inflight
 			 * statahead RPC, don't free it.
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c
index b12518ba5ae9..ab48746ce433 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_request.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c
@@ -838,7 +838,6 @@ static int mdc_getpage(struct obd_export *exp, const struct lu_fid *fid,
 	struct ptlrpc_bulk_desc *desc;
 	struct ptlrpc_request *req;
 	wait_queue_head_t waitq;
-	struct l_wait_info lwi;
 	int resends = 0;
 	int rc;
 	int i;
@@ -888,9 +887,7 @@ static int mdc_getpage(struct obd_export *exp, const struct lu_fid *fid,
 			       exp->exp_obd->obd_name, -EIO);
 			return -EIO;
 		}
-		lwi = LWI_TIMEOUT_INTR(resends * HZ, NULL, NULL,
-				       NULL);
-		l_wait_event(waitq, 0, &lwi);
+		wait_event_idle_timeout(waitq, 0, resends * HZ);
 
 		goto restart_bulk;
 	}
diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c
index a01d13bde102..c61cd23a96df 100644
--- a/drivers/staging/lustre/lustre/mgc/mgc_request.c
+++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c
@@ -535,7 +535,6 @@ static int mgc_requeue_thread(void *data)
 	spin_lock(&config_list_lock);
 	rq_state |= RQ_RUNNING;
 	while (!(rq_state & RQ_STOP)) {
-		struct l_wait_info lwi;
 		struct config_llog_data *cld, *cld_prev;
 		int rand = prandom_u32_max(MGC_TIMEOUT_RAND_CENTISEC);
 		int to;
@@ -556,9 +555,9 @@ static int mgc_requeue_thread(void *data)
 		to = msecs_to_jiffies(MGC_TIMEOUT_MIN_SECONDS * MSEC_PER_SEC);
 		/* rand is centi-seconds */
 		to += msecs_to_jiffies(rand * MSEC_PER_SEC / 100);
-		lwi = LWI_TIMEOUT(to, NULL, NULL);
-		l_wait_event(rq_waitq, rq_state & (RQ_STOP | RQ_PRECLEANUP),
-			     &lwi);
+		wait_event_idle_timeout(rq_waitq,
+					rq_state & (RQ_STOP | RQ_PRECLEANUP),
+					to);
 
 		/*
 		 * iterate & processing through the list. for each cld, process
@@ -1628,9 +1627,7 @@ int mgc_process_log(struct obd_device *mgc, struct config_llog_data *cld)
 
 		if (rcl == -ESHUTDOWN &&
 		    atomic_read(&mgc->u.cli.cl_mgc_refcount) > 0 && !retry) {
-			int secs = obd_timeout * HZ;
 			struct obd_import *imp;
-			struct l_wait_info lwi;
 
 			mutex_unlock(&cld->cld_lock);
 			imp = class_exp2cliimp(mgc->u.cli.cl_mgc_mgsexp);
@@ -1645,9 +1642,9 @@ int mgc_process_log(struct obd_device *mgc, struct config_llog_data *cld)
 			 */
 			ptlrpc_pinger_force(imp);
 
-			lwi = LWI_TIMEOUT(secs, NULL, NULL);
-			l_wait_event(imp->imp_recovery_waitq,
-				     !mgc_import_in_recovery(imp), &lwi);
+			wait_event_idle_timeout(imp->imp_recovery_waitq,
+						!mgc_import_in_recovery(imp),
+						obd_timeout * HZ);
 
 			if (imp->imp_state == LUSTRE_IMP_FULL) {
 				retry = true;
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
index ce5e7bdda692..ab84e011b560 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -1097,16 +1097,19 @@ EXPORT_SYMBOL(cl_sync_io_init);
 int cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
 		    long timeout)
 {
-	struct l_wait_info lwi = LWI_TIMEOUT_INTR(timeout * HZ,
-						  NULL, NULL, NULL);
-	int rc;
+	int rc = 1;
 
 	LASSERT(timeout >= 0);
 
-	rc = l_wait_event(anchor->csi_waitq,
-			  atomic_read(&anchor->csi_sync_nr) == 0,
-			  &lwi);
-	if (rc < 0) {
+	if (timeout == 0)
+		wait_event_idle(anchor->csi_waitq,
+				atomic_read(&anchor->csi_sync_nr) == 0);
+	else
+		rc = wait_event_idle_timeout(anchor->csi_waitq,
+					     atomic_read(&anchor->csi_sync_nr) == 0,
+					     timeout * HZ);
+	if (rc == 0) {
+		rc = -ETIMEDOUT;
 		CERROR("IO failed: %d, still wait for %d remaining entries\n",
 		       rc, atomic_read(&anchor->csi_sync_nr));
 
diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c
index 0797e671f667..dacfab12c501 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cache.c
+++ b/drivers/staging/lustre/lustre/osc/osc_cache.c
@@ -934,8 +934,6 @@ static int osc_extent_wait(const struct lu_env *env, struct osc_extent *ext,
 			   enum osc_extent_state state)
 {
 	struct osc_object *obj = ext->oe_obj;
-	struct l_wait_info lwi = LWI_TIMEOUT_INTR(600 * HZ, NULL,
-						  LWI_ON_SIGNAL_NOOP, NULL);
 	int rc = 0;
 
 	osc_object_lock(obj);
@@ -958,17 +956,19 @@ static int osc_extent_wait(const struct lu_env *env, struct osc_extent *ext,
 		osc_extent_release(env, ext);
 
 	/* wait for the extent until its state becomes @state */
-	rc = l_wait_event(ext->oe_waitq, extent_wait_cb(ext, state), &lwi);
-	if (rc == -ETIMEDOUT) {
+	rc = wait_event_idle_timeout(ext->oe_waitq,
+				     extent_wait_cb(ext, state), 600 * HZ);
+	if (rc == 0) {
 		OSC_EXTENT_DUMP(D_ERROR, ext,
 				"%s: wait ext to %u timedout, recovery in progress?\n",
 				cli_name(osc_cli(obj)), state);
 
 		wait_event_idle(ext->oe_waitq, extent_wait_cb(ext, state));
-		rc = 0;
 	}
-	if (rc == 0 && ext->oe_rc < 0)
+	if (ext->oe_rc < 0)
 		rc = ext->oe_rc;
+	else
+		rc = 0;
 	return rc;
 }
 
@@ -1568,12 +1568,9 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli,
 	struct osc_object *osc = oap->oap_obj;
 	struct lov_oinfo *loi = osc->oo_oinfo;
 	struct osc_cache_waiter ocw;
-	struct l_wait_info lwi;
+	unsigned long timeout = (AT_OFF ? obd_timeout : at_max) * HZ;
 	int rc = -EDQUOT;
 
-	lwi = LWI_TIMEOUT_INTR((AT_OFF ? obd_timeout : at_max) * HZ,
-			       NULL, LWI_ON_SIGNAL_NOOP, NULL);
-
 	OSC_DUMP_GRANT(D_CACHE, cli, "need:%d\n", bytes);
 
 	spin_lock(&cli->cl_loi_list_lock);
@@ -1616,13 +1613,15 @@ static int osc_enter_cache(const struct lu_env *env, struct client_obd *cli,
 		CDEBUG(D_CACHE, "%s: sleeping for cache space @ %p for %p\n",
 		       cli_name(cli), &ocw, oap);
 
-		rc = l_wait_event(ocw.ocw_waitq, ocw_granted(cli, &ocw), &lwi);
+		rc = wait_event_idle_timeout(ocw.ocw_waitq,
+					     ocw_granted(cli, &ocw), timeout);
 
 		spin_lock(&cli->cl_loi_list_lock);
 
-		if (rc < 0) {
-			/* l_wait_event is interrupted by signal, or timed out */
+		if (rc == 0) {
+			/* wait_event is interrupted by signal, or timed out */
 			list_del_init(&ocw.ocw_entry);
+			rc = -ETIMEDOUT;
 			break;
 		}
 		LASSERT(list_empty(&ocw.ocw_entry));
diff --git a/drivers/staging/lustre/lustre/ptlrpc/events.c b/drivers/staging/lustre/lustre/ptlrpc/events.c
index 71f7588570ef..130bacc2c891 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/events.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/events.c
@@ -490,8 +490,6 @@ int ptlrpc_uuid_to_peer(struct obd_uuid *uuid,
 
 static void ptlrpc_ni_fini(void)
 {
-	wait_queue_head_t waitq;
-	struct l_wait_info lwi;
 	int rc;
 	int retries;
 
@@ -515,10 +513,7 @@ static void ptlrpc_ni_fini(void)
 			if (retries != 0)
 				CWARN("Event queue still busy\n");
 
-			/* Wait for a bit */
-			init_waitqueue_head(&waitq);
-			lwi = LWI_TIMEOUT(2 * HZ, NULL, NULL);
-			l_wait_event(waitq, 0, &lwi);
+			schedule_timeout_uninterruptible(2 * HZ);
 			break;
 		}
 	}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c
index 0eba5f18bd3b..ed210550f61f 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/import.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/import.c
@@ -430,21 +430,19 @@ void ptlrpc_fail_import(struct obd_import *imp, __u32 conn_cnt)
 
 int ptlrpc_reconnect_import(struct obd_import *imp)
 {
-	struct l_wait_info lwi;
-	int secs = obd_timeout * HZ;
 	int rc;
 
 	ptlrpc_pinger_force(imp);
 
 	CDEBUG(D_HA, "%s: recovery started, waiting %u seconds\n",
-	       obd2cli_tgt(imp->imp_obd), secs);
+	       obd2cli_tgt(imp->imp_obd), obd_timeout);
 
-	lwi = LWI_TIMEOUT(secs, NULL, NULL);
-	rc = l_wait_event(imp->imp_recovery_waitq,
-			  !ptlrpc_import_in_recovery(imp), &lwi);
+	rc = wait_event_idle_timeout(imp->imp_recovery_waitq,
+				     !ptlrpc_import_in_recovery(imp),
+				     obd_timeout * HZ);
 	CDEBUG(D_HA, "%s: recovery finished s:%s\n", obd2cli_tgt(imp->imp_obd),
 	       ptlrpc_import_state_name(imp->imp_state));
-	return rc;
+	return rc == 0 ? -ETIMEDOUT : 0;
 }
 EXPORT_SYMBOL(ptlrpc_reconnect_import);
 
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
index c060d6f5015a..f73463ac401f 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
@@ -260,17 +260,16 @@ lustre_get_emerg_rs(struct ptlrpc_service_part *svcpt)
 
 	/* See if we have anything in a pool, and wait if nothing */
 	while (list_empty(&svcpt->scp_rep_idle)) {
-		struct l_wait_info lwi;
 		int rc;
 
 		spin_unlock(&svcpt->scp_rep_lock);
 		/* If we cannot get anything for some long time, we better
 		 * bail out instead of waiting infinitely
 		 */
-		lwi = LWI_TIMEOUT(10 * HZ, NULL, NULL);
-		rc = l_wait_event(svcpt->scp_rep_waitq,
-				  !list_empty(&svcpt->scp_rep_idle), &lwi);
-		if (rc != 0)
+		rc = wait_event_idle_timeout(svcpt->scp_rep_waitq,
+					     !list_empty(&svcpt->scp_rep_idle),
+					     10 * HZ);
+		if (rc == 0)
 			goto out;
 		spin_lock(&svcpt->scp_rep_lock);
 	}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pinger.c b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
index 010a1cdf05fa..639070f6e68e 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pinger.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pinger.c
@@ -228,7 +228,6 @@ static int ptlrpc_pinger_main(void *arg)
 	/* And now, loop forever, pinging as needed. */
 	while (1) {
 		unsigned long this_ping = cfs_time_current();
-		struct l_wait_info lwi;
 		long time_to_next_wake;
 		struct timeout_item *item;
 		struct list_head *iter;
@@ -266,13 +265,10 @@ static int ptlrpc_pinger_main(void *arg)
 		       cfs_time_add(this_ping,
 				    PING_INTERVAL * HZ));
 		if (time_to_next_wake > 0) {
-			lwi = LWI_TIMEOUT(max_t(long, time_to_next_wake,
-						HZ),
-					  NULL, NULL);
-			l_wait_event(thread->t_ctl_waitq,
-				     thread_is_stopping(thread) ||
-				     thread_is_event(thread),
-				     &lwi);
+			wait_event_idle_timeout(thread->t_ctl_waitq,
+						thread_is_stopping(thread) ||
+						thread_is_event(thread),
+						max_t(long, time_to_next_wake, HZ));
 			if (thread_test_and_clear_flags(thread, SVC_STOPPING))
 				break;
 			/* woken after adding import to reset timer */
diff --git a/drivers/staging/lustre/lustre/ptlrpc/recover.c b/drivers/staging/lustre/lustre/ptlrpc/recover.c
index 5bbd23eebfa6..7b5f2429d144 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/recover.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/recover.c
@@ -346,17 +346,15 @@ int ptlrpc_recover_import(struct obd_import *imp, char *new_uuid, int async)
 		goto out;
 
 	if (!async) {
-		struct l_wait_info lwi;
-		int secs = obd_timeout * HZ;
-
 		CDEBUG(D_HA, "%s: recovery started, waiting %u seconds\n",
-		       obd2cli_tgt(imp->imp_obd), secs);
+		       obd2cli_tgt(imp->imp_obd), obd_timeout);
 
-		lwi = LWI_TIMEOUT(secs, NULL, NULL);
-		rc = l_wait_event(imp->imp_recovery_waitq,
-				  !ptlrpc_import_in_recovery(imp), &lwi);
+		rc = wait_event_idle_timeout(imp->imp_recovery_waitq,
+					     !ptlrpc_import_in_recovery(imp),
+					     obd_timeout * HZ);
 		CDEBUG(D_HA, "%s: recovery finished\n",
 		       obd2cli_tgt(imp->imp_obd));
+		rc = rc? 0 : -ETIMEDOUT;
 	}
 
 out:
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
index b61e1aa25e8c..48f1a72afd77 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
@@ -142,7 +142,6 @@ static void sec_do_gc(struct ptlrpc_sec *sec)
 static int sec_gc_main(void *arg)
 {
 	struct ptlrpc_thread *thread = arg;
-	struct l_wait_info lwi;
 
 	unshare_fs_struct();
 
@@ -179,12 +178,9 @@ static int sec_gc_main(void *arg)
 
 		/* check ctx list again before sleep */
 		sec_process_ctx_list();
-
-		lwi = LWI_TIMEOUT(msecs_to_jiffies(SEC_GC_INTERVAL * MSEC_PER_SEC),
-				  NULL, NULL);
-		l_wait_event(thread->t_ctl_waitq,
-			     thread_is_stopping(thread),
-			     &lwi);
+		wait_event_idle_timeout(thread->t_ctl_waitq,
+					thread_is_stopping(thread),
+					SEC_GC_INTERVAL * HZ);
 
 		if (thread_test_and_clear_flags(thread, SVC_STOPPING))
 			break;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
index 6d4229ebc9d9..5c41297d23d2 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -2588,13 +2588,12 @@ static void ptlrpc_wait_replies(struct ptlrpc_service_part *svcpt)
 {
 	while (1) {
 		int rc;
-		struct l_wait_info lwi = LWI_TIMEOUT(10 * HZ,
-						     NULL, NULL);
 
-		rc = l_wait_event(svcpt->scp_waitq,
-				  atomic_read(&svcpt->scp_nreps_difficult) == 0,
-				  &lwi);
-		if (rc == 0)
+		rc = wait_event_idle_timeout(
+			svcpt->scp_waitq,
+			atomic_read(&svcpt->scp_nreps_difficult) == 0,
+			10 * HZ);
+		if (rc > 0)
 			break;
 		CWARN("Unexpectedly long timeout %s %p\n",
 		      svcpt->scp_service->srv_name, svcpt->scp_service);

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 06/19] staging: lustre: introduce and use l_wait_event_abortable()
@ 2018-02-12 21:22   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

lustre sometimes wants to wait for an event, but abort if
one of a specific list of signals arrives.  This is a little
bit like wait_event_killable(), except that the signals are
identified a different way.

So introduce l_wait_event_abortable() which provides this
functionality.
Having separate functions for separate needs is more in line
with the pattern set by include/linux/wait.h, than having a
single function which tries to include all possible needs.

Also introduce l_wait_event_abortable_exclusive().

Note that l_wait_event() return -EINTR on a signal, while
Linux wait_event functions return -ERESTARTSYS.
l_wait_event_{abortable_,}exclusive follow the Linux pattern.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |   24 ++++++++++++++++++++
 drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |   12 +++++-----
 drivers/staging/lustre/lustre/llite/llite_lib.c    |   12 +++-------
 drivers/staging/lustre/lustre/obdclass/genops.c    |    9 +++-----
 drivers/staging/lustre/lustre/obdclass/llog_obd.c  |    5 ++--
 drivers/staging/lustre/lustre/osc/osc_page.c       |    6 ++---
 drivers/staging/lustre/lustre/osc/osc_request.c    |    6 ++---
 7 files changed, 43 insertions(+), 31 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
index 7d950c53e962..b2a64d0e682c 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -336,4 +336,28 @@ do {									   \
 /** @} lib */
 
 
+
+/* l_wait_event_abortable() is a bit like wait_event_killable()
+ * except there is a fixed set of signals which will abort:
+ * LUSTRE_FATAL_SIGS
+ */
+#define l_wait_event_abortable(wq, condition)				\
+({									\
+	sigset_t __blocked;						\
+	int __ret = 0;							\
+	__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);		\
+	__ret = wait_event_interruptible(wq, condition);		\
+	cfs_restore_sigs(__blocked);					\
+	__ret;								\
+})
+
+#define l_wait_event_abortable_exclusive(wq, condition)			\
+({									\
+	sigset_t __blocked;						\
+	int __ret = 0;							\
+	__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);		\
+	__ret = wait_event_interruptible_exclusive(wq, condition);	\
+	cfs_restore_sigs(__blocked);					\
+	__ret;								\
+})
 #endif /* _LUSTRE_LIB_H */
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
index 2e66825c8f4b..4c44603ab6f9 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
@@ -879,7 +879,6 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, int force)
 	ldlm_namespace_cleanup(ns, force ? LDLM_FL_LOCAL_ONLY : 0);
 
 	if (atomic_read(&ns->ns_bref) > 0) {
-		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
 		int rc;
 
 		CDEBUG(D_DLMTRACE,
@@ -887,11 +886,12 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, int force)
 		       ldlm_ns_name(ns), atomic_read(&ns->ns_bref));
 force_wait:
 		if (force)
-			lwi = LWI_TIMEOUT(msecs_to_jiffies(obd_timeout *
-					  MSEC_PER_SEC) / 4, NULL, NULL);
-
-		rc = l_wait_event(ns->ns_waitq,
-				  atomic_read(&ns->ns_bref) == 0, &lwi);
+			rc = wait_event_idle_timeout(ns->ns_waitq,
+						     atomic_read(&ns->ns_bref) == 0,
+						     obd_timeout * HZ / 4) ? 0 : -ETIMEDOUT;
+		else
+			rc = l_wait_event_abortable(ns->ns_waitq,
+						    atomic_read(&ns->ns_bref) == 0);
 
 		/* Forced cleanups should be able to reclaim all references,
 		 * so it's safe to wait forever... we can't leak locks...
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
index c820b201af71..ccb614bd7f53 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -986,16 +986,12 @@ void ll_put_super(struct super_block *sb)
 	}
 
 	/* Wait for unstable pages to be committed to stable storage */
-	if (!force) {
-		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
-
-		rc = l_wait_event(sbi->ll_cache->ccc_unstable_waitq,
-				  !atomic_long_read(&sbi->ll_cache->ccc_unstable_nr),
-				  &lwi);
-	}
+	if (!force)
+		rc = l_wait_event_abortable(sbi->ll_cache->ccc_unstable_waitq,
+					    !atomic_long_read(&sbi->ll_cache->ccc_unstable_nr));
 
 	ccc_count = atomic_long_read(&sbi->ll_cache->ccc_unstable_nr);
-	if (!force && rc != -EINTR)
+	if (!force && rc != -ERESTARTSYS)
 		LASSERTF(!ccc_count, "count: %li\n", ccc_count);
 
 	/* We need to set force before the lov_disconnect in
diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
index 3ff25b8d3b48..8f776a4058a9 100644
--- a/drivers/staging/lustre/lustre/obdclass/genops.c
+++ b/drivers/staging/lustre/lustre/obdclass/genops.c
@@ -1332,7 +1332,6 @@ static bool obd_request_slot_avail(struct client_obd *cli,
 int obd_get_request_slot(struct client_obd *cli)
 {
 	struct obd_request_slot_waiter orsw;
-	struct l_wait_info lwi;
 	int rc;
 
 	spin_lock(&cli->cl_loi_list_lock);
@@ -1347,11 +1346,9 @@ int obd_get_request_slot(struct client_obd *cli)
 	orsw.orsw_signaled = false;
 	spin_unlock(&cli->cl_loi_list_lock);
 
-	lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
-	rc = l_wait_event(orsw.orsw_waitq,
-			  obd_request_slot_avail(cli, &orsw) ||
-			  orsw.orsw_signaled,
-			  &lwi);
+	rc = l_wait_event_abortable(orsw.orsw_waitq,
+				    obd_request_slot_avail(cli, &orsw) ||
+				    orsw.orsw_signaled);
 
 	/*
 	 * Here, we must take the lock to avoid the on-stack 'orsw' to be
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_obd.c b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
index 28bbaa2136ac..26aea114a29b 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_obd.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
@@ -104,7 +104,6 @@ EXPORT_SYMBOL(__llog_ctxt_put);
 
 int llog_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt)
 {
-	struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
 	struct obd_llog_group *olg;
 	int rc, idx;
 
@@ -129,8 +128,8 @@ int llog_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt)
 		CERROR("Error %d while cleaning up ctxt %p\n",
 		       rc, ctxt);
 
-	l_wait_event(olg->olg_waitq,
-		     llog_group_ctxt_null(olg, idx), &lwi);
+	l_wait_event_abortable(olg->olg_waitq,
+			     llog_group_ctxt_null(olg, idx));
 
 	return rc;
 }
diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c
index 20094b6309f9..6fdd521feb21 100644
--- a/drivers/staging/lustre/lustre/osc/osc_page.c
+++ b/drivers/staging/lustre/lustre/osc/osc_page.c
@@ -759,7 +759,6 @@ static long osc_lru_reclaim(struct client_obd *cli, unsigned long npages)
 static int osc_lru_alloc(const struct lu_env *env, struct client_obd *cli,
 			 struct osc_page *opg)
 {
-	struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
 	struct osc_io *oio = osc_env_io(env);
 	int rc = 0;
 
@@ -782,9 +781,8 @@ static int osc_lru_alloc(const struct lu_env *env, struct client_obd *cli,
 
 		cond_resched();
 
-		rc = l_wait_event(osc_lru_waitq,
-				  atomic_long_read(cli->cl_lru_left) > 0,
-				  &lwi);
+		rc = l_wait_event_abortable(osc_lru_waitq,
+					    atomic_long_read(cli->cl_lru_left) > 0);
 
 		if (rc < 0)
 			break;
diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
index 45b1ebf33363..074b5ce6284c 100644
--- a/drivers/staging/lustre/lustre/osc/osc_request.c
+++ b/drivers/staging/lustre/lustre/osc/osc_request.c
@@ -552,14 +552,12 @@ static int osc_destroy(const struct lu_env *env, struct obd_export *exp,
 
 	req->rq_interpret_reply = osc_destroy_interpret;
 	if (!osc_can_send_destroy(cli)) {
-		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
-
 		/*
 		 * Wait until the number of on-going destroy RPCs drops
 		 * under max_rpc_in_flight
 		 */
-		l_wait_event_exclusive(cli->cl_destroy_waitq,
-				       osc_can_send_destroy(cli), &lwi);
+		l_wait_event_abortable_exclusive(cli->cl_destroy_waitq,
+					       osc_can_send_destroy(cli));
 	}
 
 	/* Do not wait for response */

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 08/19] staging: lustre: simplify waiting in ldlm_completion_ast()
@ 2018-02-12 21:22   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

If a signal-callback (lwi_on_signal) is set without lwi_allow_intr, as
is the case in ldlm_completion_ast(), the behavior depends on the
timeout set.

If a timeout is set, then signals are ignored.  If the timeout is
reached, the timeout handler is called.  If the timeout handler
return 0, which ldlm_expired_completion_wait() always does, the
l_wait_event() switches to exactly the behavior if no timeout was set.

If no timeout is set, then "fatal" signals are not ignored.  If one
arrives the callback is run, but as the callback is empty in this
case, that is not relevant.

This can be simplified to:
 if a timeout is wanted
     wait_event_idle_timeout()
     if that timed out, call the timeout handler
 l_wait_event_abortable()

i.e. the code always waits indefinitely.  Sometimes it performs a
non-abortable wait first.  Sometimes it doesn't.  But it only
aborts before the condition is true if it is signaled.
This doesn't quite agree with the comments and debug messages.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/ldlm/ldlm_request.c |   55 +++++++--------------
 1 file changed, 18 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index a244fa717134..f1233d844bbd 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -72,15 +72,6 @@ MODULE_PARM_DESC(ldlm_enqueue_min, "lock enqueue timeout minimum");
 /* in client side, whether the cached locks will be canceled before replay */
 unsigned int ldlm_cancel_unused_locks_before_replay = 1;
 
-static void interrupted_completion_wait(void *data)
-{
-}
-
-struct lock_wait_data {
-	struct ldlm_lock *lwd_lock;
-	__u32	     lwd_conn_cnt;
-};
-
 struct ldlm_async_args {
 	struct lustre_handle lock_handle;
 };
@@ -112,10 +103,8 @@ static int ldlm_request_bufsize(int count, int type)
 	return sizeof(struct ldlm_request) + avail;
 }
 
-static int ldlm_expired_completion_wait(void *data)
+static void ldlm_expired_completion_wait(struct ldlm_lock *lock, struct obd_import *imp2)
 {
-	struct lock_wait_data *lwd = data;
-	struct ldlm_lock *lock = lwd->lwd_lock;
 	struct obd_import *imp;
 	struct obd_device *obd;
 
@@ -135,19 +124,17 @@ static int ldlm_expired_completion_wait(void *data)
 			if (last_dump == 0)
 				libcfs_debug_dumplog();
 		}
-		return 0;
+		return;
 	}
 
 	obd = lock->l_conn_export->exp_obd;
 	imp = obd->u.cli.cl_import;
-	ptlrpc_fail_import(imp, lwd->lwd_conn_cnt);
+	ptlrpc_fail_import(imp, imp2 ? imp2->imp_conn_cnt : 0);
 	LDLM_ERROR(lock,
 		   "lock timed out (enqueued at %lld, %llds ago), entering recovery for %s@%s",
 		   (s64)lock->l_last_activity,
 		   (s64)(ktime_get_real_seconds() - lock->l_last_activity),
 		   obd2cli_tgt(obd), imp->imp_connection->c_remote_uuid.uuid);
-
-	return 0;
 }
 
 /**
@@ -251,10 +238,8 @@ EXPORT_SYMBOL(ldlm_completion_ast_async);
 int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 {
 	/* XXX ALLOCATE - 160 bytes */
-	struct lock_wait_data lwd;
 	struct obd_device *obd;
 	struct obd_import *imp = NULL;
-	struct l_wait_info lwi;
 	__u32 timeout;
 	int rc = 0;
 
@@ -281,32 +266,28 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 
 	timeout = ldlm_cp_timeout(lock);
 
-	lwd.lwd_lock = lock;
 	lock->l_last_activity = ktime_get_real_seconds();
 
-	if (ldlm_is_no_timeout(lock)) {
-		LDLM_DEBUG(lock, "waiting indefinitely because of NO_TIMEOUT");
-		lwi = LWI_INTR(interrupted_completion_wait, &lwd);
-	} else {
-		lwi = LWI_TIMEOUT_INTR(timeout * HZ,
-				       ldlm_expired_completion_wait,
-				       interrupted_completion_wait, &lwd);
-	}
-
-	if (imp) {
-		spin_lock(&imp->imp_lock);
-		lwd.lwd_conn_cnt = imp->imp_conn_cnt;
-		spin_unlock(&imp->imp_lock);
-	}
-
 	if (OBD_FAIL_CHECK_RESET(OBD_FAIL_LDLM_INTR_CP_AST,
 				 OBD_FAIL_LDLM_CP_BL_RACE | OBD_FAIL_ONCE)) {
 		ldlm_set_fail_loc(lock);
 		rc = -EINTR;
 	} else {
-		/* Go to sleep until the lock is granted or cancelled. */
-		rc = l_wait_event(lock->l_waitq,
-				  is_granted_or_cancelled(lock), &lwi);
+		/* Go to sleep until the lock is granted or canceled. */
+		if (!ldlm_is_no_timeout(lock)) {
+			/* Wait uninterruptible for a while first */
+			rc = wait_event_idle_timeout(lock->l_waitq,
+						     is_granted_or_cancelled(lock),
+						     timeout * HZ);
+			if (rc == 0)
+				ldlm_expired_completion_wait(lock, imp);
+		}
+		/* Now wait abortable */
+		if (rc == 0)
+			rc = l_wait_event_abortable(lock->l_waitq,
+						    is_granted_or_cancelled(lock));
+		else
+			rc = 0;
 	}
 
 	if (rc) {

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 07/19] staging: lustre: simplify l_wait_event when intr handler but no timeout.
@ 2018-02-12 21:22   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 21:22 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

If l_wait_event() is given a function to be called on a signal,
but no timeout or timeout handler, then the intr function is simply
called at the end if the wait was aborted by a signal.
So a simpler way to write the code (in the one place this case is
used) it to open-code the body of the function after the
wait_event, if -ERESTARTSYS was returned.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/ldlm/ldlm_flock.c |   30 +++++------------------
 1 file changed, 7 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
index 657ab95091a0..411b540b96d9 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
@@ -310,24 +310,6 @@ static int ldlm_process_flock_lock(struct ldlm_lock *req)
 	return LDLM_ITER_CONTINUE;
 }
 
-struct ldlm_flock_wait_data {
-	struct ldlm_lock *fwd_lock;
-};
-
-static void
-ldlm_flock_interrupted_wait(void *data)
-{
-	struct ldlm_lock *lock;
-
-	lock = ((struct ldlm_flock_wait_data *)data)->fwd_lock;
-
-	lock_res_and_lock(lock);
-
-	/* client side - set flag to prevent lock from being put on LRU list */
-	ldlm_set_cbpending(lock);
-	unlock_res_and_lock(lock);
-}
-
 /**
  * Flock completion callback function.
  *
@@ -342,8 +324,6 @@ int
 ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 {
 	struct file_lock		*getlk = lock->l_ast_data;
-	struct ldlm_flock_wait_data	fwd;
-	struct l_wait_info		lwi;
 	int				rc = 0;
 
 	OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_CP_CB_WAIT2, 4);
@@ -372,13 +352,17 @@ ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 
 	LDLM_DEBUG(lock,
 		   "client-side enqueue returned a blocked lock, sleeping");
-	fwd.fwd_lock = lock;
-	lwi = LWI_TIMEOUT_INTR(0, NULL, ldlm_flock_interrupted_wait, &fwd);
 
 	/* Go to sleep until the lock is granted. */
-	rc = l_wait_event(lock->l_waitq, is_granted_or_cancelled(lock), &lwi);
+	rc = l_wait_event_abortable(lock->l_waitq, is_granted_or_cancelled(lock));
 
 	if (rc) {
+		lock_res_and_lock(lock);
+
+		/* client side - set flag to prevent lock from being put on LRU list */
+		ldlm_set_cbpending(lock);
+		unlock_res_and_lock(lock);
+
 		LDLM_DEBUG(lock, "client-side enqueue waking up: failed (%d)",
 			   rc);
 		return rc;

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [lustre-devel] [PATCH 06/19] staging: lustre: introduce and use l_wait_event_abortable()
  2018-02-12 21:22   ` [lustre-devel] " NeilBrown
@ 2018-02-12 21:36     ` Patrick Farrell
  -1 siblings, 0 replies; 58+ messages in thread
From: Patrick Farrell @ 2018-02-12 21:36 UTC (permalink / raw)
  To: NeilBrown, Oleg Drokin, Andreas Dilger, James Simmons,
	Greg Kroah-Hartman
  Cc: lkml, lustre

It's worth noting that the change from -EINTR to -ERESTARTSYS will modify the behavior of userspace slightly.  Specifically, when a signal handler is setup with retry set (SA_RESTART flag set), the syscall will be restarted rather than aborted.

This should be fine.  It may eventually shake out some stuble bugs in Lustre when we abort an operation and then restart it from a point where we didn't in the past - past instances where we changed from -EINTR to -ERESTARTSYS certainly have - but it's for the best.  As I understand it from past conversations with Andreas and others, Lustre is not really intending to claim it's not restartable, it's just an artifact of people copying older code that was written without awareness of the difference in EINTR vs ERESTARTSYS.

Ideally someone should go through and audit the remaining uses of -EINTR and replace most of them with -ERESTARTSYS.

James, maybe you want to add that to the TODO list?

On 2/12/18, 3:24 PM, "lustre-devel on behalf of NeilBrown" <lustre-devel-bounces@lists.lustre.org on behalf of neilb@suse.com> wrote:

    lustre sometimes wants to wait for an event, but abort if
    one of a specific list of signals arrives.  This is a little
    bit like wait_event_killable(), except that the signals are
    identified a different way.
    
    So introduce l_wait_event_abortable() which provides this
    functionality.
    Having separate functions for separate needs is more in line
    with the pattern set by include/linux/wait.h, than having a
    single function which tries to include all possible needs.
    
    Also introduce l_wait_event_abortable_exclusive().
    
    Note that l_wait_event() return -EINTR on a signal, while
    Linux wait_event functions return -ERESTARTSYS.
    l_wait_event_{abortable_,}exclusive follow the Linux pattern.
    
    Reviewed-by: James Simmons <jsimmons@infradead.org>
    Signed-off-by: NeilBrown <neilb@suse.com>
    ---
     drivers/staging/lustre/lustre/include/lustre_lib.h |   24 ++++++++++++++++++++
     drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |   12 +++++-----
     drivers/staging/lustre/lustre/llite/llite_lib.c    |   12 +++-------
     drivers/staging/lustre/lustre/obdclass/genops.c    |    9 +++-----
     drivers/staging/lustre/lustre/obdclass/llog_obd.c  |    5 ++--
     drivers/staging/lustre/lustre/osc/osc_page.c       |    6 ++---
     drivers/staging/lustre/lustre/osc/osc_request.c    |    6 ++---
     7 files changed, 43 insertions(+), 31 deletions(-)
    
    diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
    index 7d950c53e962..b2a64d0e682c 100644
    --- a/drivers/staging/lustre/lustre/include/lustre_lib.h
    +++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
    @@ -336,4 +336,28 @@ do {									   \
     /** @} lib */
     
     
    +
    +/* l_wait_event_abortable() is a bit like wait_event_killable()
    + * except there is a fixed set of signals which will abort:
    + * LUSTRE_FATAL_SIGS
    + */
    +#define l_wait_event_abortable(wq, condition)				\
    +({									\
    +	sigset_t __blocked;						\
    +	int __ret = 0;							\
    +	__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);		\
    +	__ret = wait_event_interruptible(wq, condition);		\
    +	cfs_restore_sigs(__blocked);					\
    +	__ret;								\
    +})
    +
    +#define l_wait_event_abortable_exclusive(wq, condition)			\
    +({									\
    +	sigset_t __blocked;						\
    +	int __ret = 0;							\
    +	__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);		\
    +	__ret = wait_event_interruptible_exclusive(wq, condition);	\
    +	cfs_restore_sigs(__blocked);					\
    +	__ret;								\
    +})
     #endif /* _LUSTRE_LIB_H */
    diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
    index 2e66825c8f4b..4c44603ab6f9 100644
    --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
    +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
    @@ -879,7 +879,6 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, int force)
     	ldlm_namespace_cleanup(ns, force ? LDLM_FL_LOCAL_ONLY : 0);
     
     	if (atomic_read(&ns->ns_bref) > 0) {
    -		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
     		int rc;
     
     		CDEBUG(D_DLMTRACE,
    @@ -887,11 +886,12 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, int force)
     		       ldlm_ns_name(ns), atomic_read(&ns->ns_bref));
     force_wait:
     		if (force)
    -			lwi = LWI_TIMEOUT(msecs_to_jiffies(obd_timeout *
    -					  MSEC_PER_SEC) / 4, NULL, NULL);
    -
    -		rc = l_wait_event(ns->ns_waitq,
    -				  atomic_read(&ns->ns_bref) == 0, &lwi);
    +			rc = wait_event_idle_timeout(ns->ns_waitq,
    +						     atomic_read(&ns->ns_bref) == 0,
    +						     obd_timeout * HZ / 4) ? 0 : -ETIMEDOUT;
    +		else
    +			rc = l_wait_event_abortable(ns->ns_waitq,
    +						    atomic_read(&ns->ns_bref) == 0);
     
     		/* Forced cleanups should be able to reclaim all references,
     		 * so it's safe to wait forever... we can't leak locks...
    diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
    index c820b201af71..ccb614bd7f53 100644
    --- a/drivers/staging/lustre/lustre/llite/llite_lib.c
    +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
    @@ -986,16 +986,12 @@ void ll_put_super(struct super_block *sb)
     	}
     
     	/* Wait for unstable pages to be committed to stable storage */
    -	if (!force) {
    -		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
    -
    -		rc = l_wait_event(sbi->ll_cache->ccc_unstable_waitq,
    -				  !atomic_long_read(&sbi->ll_cache->ccc_unstable_nr),
    -				  &lwi);
    -	}
    +	if (!force)
    +		rc = l_wait_event_abortable(sbi->ll_cache->ccc_unstable_waitq,
    +					    !atomic_long_read(&sbi->ll_cache->ccc_unstable_nr));
     
     	ccc_count = atomic_long_read(&sbi->ll_cache->ccc_unstable_nr);
    -	if (!force && rc != -EINTR)
    +	if (!force && rc != -ERESTARTSYS)
     		LASSERTF(!ccc_count, "count: %li\n", ccc_count);
     
     	/* We need to set force before the lov_disconnect in
    diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
    index 3ff25b8d3b48..8f776a4058a9 100644
    --- a/drivers/staging/lustre/lustre/obdclass/genops.c
    +++ b/drivers/staging/lustre/lustre/obdclass/genops.c
    @@ -1332,7 +1332,6 @@ static bool obd_request_slot_avail(struct client_obd *cli,
     int obd_get_request_slot(struct client_obd *cli)
     {
     	struct obd_request_slot_waiter orsw;
    -	struct l_wait_info lwi;
     	int rc;
     
     	spin_lock(&cli->cl_loi_list_lock);
    @@ -1347,11 +1346,9 @@ int obd_get_request_slot(struct client_obd *cli)
     	orsw.orsw_signaled = false;
     	spin_unlock(&cli->cl_loi_list_lock);
     
    -	lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
    -	rc = l_wait_event(orsw.orsw_waitq,
    -			  obd_request_slot_avail(cli, &orsw) ||
    -			  orsw.orsw_signaled,
    -			  &lwi);
    +	rc = l_wait_event_abortable(orsw.orsw_waitq,
    +				    obd_request_slot_avail(cli, &orsw) ||
    +				    orsw.orsw_signaled);
     
     	/*
     	 * Here, we must take the lock to avoid the on-stack 'orsw' to be
    diff --git a/drivers/staging/lustre/lustre/obdclass/llog_obd.c b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
    index 28bbaa2136ac..26aea114a29b 100644
    --- a/drivers/staging/lustre/lustre/obdclass/llog_obd.c
    +++ b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
    @@ -104,7 +104,6 @@ EXPORT_SYMBOL(__llog_ctxt_put);
     
     int llog_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt)
     {
    -	struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
     	struct obd_llog_group *olg;
     	int rc, idx;
     
    @@ -129,8 +128,8 @@ int llog_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt)
     		CERROR("Error %d while cleaning up ctxt %p\n",
     		       rc, ctxt);
     
    -	l_wait_event(olg->olg_waitq,
    -		     llog_group_ctxt_null(olg, idx), &lwi);
    +	l_wait_event_abortable(olg->olg_waitq,
    +			     llog_group_ctxt_null(olg, idx));
     
     	return rc;
     }
    diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c
    index 20094b6309f9..6fdd521feb21 100644
    --- a/drivers/staging/lustre/lustre/osc/osc_page.c
    +++ b/drivers/staging/lustre/lustre/osc/osc_page.c
    @@ -759,7 +759,6 @@ static long osc_lru_reclaim(struct client_obd *cli, unsigned long npages)
     static int osc_lru_alloc(const struct lu_env *env, struct client_obd *cli,
     			 struct osc_page *opg)
     {
    -	struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
     	struct osc_io *oio = osc_env_io(env);
     	int rc = 0;
     
    @@ -782,9 +781,8 @@ static int osc_lru_alloc(const struct lu_env *env, struct client_obd *cli,
     
     		cond_resched();
     
    -		rc = l_wait_event(osc_lru_waitq,
    -				  atomic_long_read(cli->cl_lru_left) > 0,
    -				  &lwi);
    +		rc = l_wait_event_abortable(osc_lru_waitq,
    +					    atomic_long_read(cli->cl_lru_left) > 0);
     
     		if (rc < 0)
     			break;
    diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
    index 45b1ebf33363..074b5ce6284c 100644
    --- a/drivers/staging/lustre/lustre/osc/osc_request.c
    +++ b/drivers/staging/lustre/lustre/osc/osc_request.c
    @@ -552,14 +552,12 @@ static int osc_destroy(const struct lu_env *env, struct obd_export *exp,
     
     	req->rq_interpret_reply = osc_destroy_interpret;
     	if (!osc_can_send_destroy(cli)) {
    -		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
    -
     		/*
     		 * Wait until the number of on-going destroy RPCs drops
     		 * under max_rpc_in_flight
     		 */
    -		l_wait_event_exclusive(cli->cl_destroy_waitq,
    -				       osc_can_send_destroy(cli), &lwi);
    +		l_wait_event_abortable_exclusive(cli->cl_destroy_waitq,
    +					       osc_can_send_destroy(cli));
     	}
     
     	/* Do not wait for response */
    
    
    _______________________________________________
    lustre-devel mailing list
    lustre-devel@lists.lustre.org
    http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org
    


^ permalink raw reply	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 06/19] staging: lustre: introduce and use l_wait_event_abortable()
@ 2018-02-12 21:36     ` Patrick Farrell
  0 siblings, 0 replies; 58+ messages in thread
From: Patrick Farrell @ 2018-02-12 21:36 UTC (permalink / raw)
  To: NeilBrown, Oleg Drokin, Andreas Dilger, James Simmons,
	Greg Kroah-Hartman
  Cc: lkml, lustre

It's worth noting that the change from -EINTR to -ERESTARTSYS will modify the behavior of userspace slightly.  Specifically, when a signal handler is setup with retry set (SA_RESTART flag set), the syscall will be restarted rather than aborted.

This should be fine.  It may eventually shake out some stuble bugs in Lustre when we abort an operation and then restart it from a point where we didn't in the past - past instances where we changed from -EINTR to -ERESTARTSYS certainly have - but it's for the best.  As I understand it from past conversations with Andreas and others, Lustre is not really intending to claim it's not restartable, it's just an artifact of people copying older code that was written without awareness of the difference in EINTR vs ERESTARTSYS.

Ideally someone should go through and audit the remaining uses of -EINTR and replace most of them with -ERESTARTSYS.

James, maybe you want to add that to the TODO list?

?On 2/12/18, 3:24 PM, "lustre-devel on behalf of NeilBrown" <lustre-devel-bounces at lists.lustre.org on behalf of neilb@suse.com> wrote:

    lustre sometimes wants to wait for an event, but abort if
    one of a specific list of signals arrives.  This is a little
    bit like wait_event_killable(), except that the signals are
    identified a different way.
    
    So introduce l_wait_event_abortable() which provides this
    functionality.
    Having separate functions for separate needs is more in line
    with the pattern set by include/linux/wait.h, than having a
    single function which tries to include all possible needs.
    
    Also introduce l_wait_event_abortable_exclusive().
    
    Note that l_wait_event() return -EINTR on a signal, while
    Linux wait_event functions return -ERESTARTSYS.
    l_wait_event_{abortable_,}exclusive follow the Linux pattern.
    
    Reviewed-by: James Simmons <jsimmons@infradead.org>
    Signed-off-by: NeilBrown <neilb@suse.com>
    ---
     drivers/staging/lustre/lustre/include/lustre_lib.h |   24 ++++++++++++++++++++
     drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |   12 +++++-----
     drivers/staging/lustre/lustre/llite/llite_lib.c    |   12 +++-------
     drivers/staging/lustre/lustre/obdclass/genops.c    |    9 +++-----
     drivers/staging/lustre/lustre/obdclass/llog_obd.c  |    5 ++--
     drivers/staging/lustre/lustre/osc/osc_page.c       |    6 ++---
     drivers/staging/lustre/lustre/osc/osc_request.c    |    6 ++---
     7 files changed, 43 insertions(+), 31 deletions(-)
    
    diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
    index 7d950c53e962..b2a64d0e682c 100644
    --- a/drivers/staging/lustre/lustre/include/lustre_lib.h
    +++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
    @@ -336,4 +336,28 @@ do {									   \
     /** @} lib */
     
     
    +
    +/* l_wait_event_abortable() is a bit like wait_event_killable()
    + * except there is a fixed set of signals which will abort:
    + * LUSTRE_FATAL_SIGS
    + */
    +#define l_wait_event_abortable(wq, condition)				\
    +({									\
    +	sigset_t __blocked;						\
    +	int __ret = 0;							\
    +	__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);		\
    +	__ret = wait_event_interruptible(wq, condition);		\
    +	cfs_restore_sigs(__blocked);					\
    +	__ret;								\
    +})
    +
    +#define l_wait_event_abortable_exclusive(wq, condition)			\
    +({									\
    +	sigset_t __blocked;						\
    +	int __ret = 0;							\
    +	__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);		\
    +	__ret = wait_event_interruptible_exclusive(wq, condition);	\
    +	cfs_restore_sigs(__blocked);					\
    +	__ret;								\
    +})
     #endif /* _LUSTRE_LIB_H */
    diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
    index 2e66825c8f4b..4c44603ab6f9 100644
    --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
    +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
    @@ -879,7 +879,6 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, int force)
     	ldlm_namespace_cleanup(ns, force ? LDLM_FL_LOCAL_ONLY : 0);
     
     	if (atomic_read(&ns->ns_bref) > 0) {
    -		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
     		int rc;
     
     		CDEBUG(D_DLMTRACE,
    @@ -887,11 +886,12 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, int force)
     		       ldlm_ns_name(ns), atomic_read(&ns->ns_bref));
     force_wait:
     		if (force)
    -			lwi = LWI_TIMEOUT(msecs_to_jiffies(obd_timeout *
    -					  MSEC_PER_SEC) / 4, NULL, NULL);
    -
    -		rc = l_wait_event(ns->ns_waitq,
    -				  atomic_read(&ns->ns_bref) == 0, &lwi);
    +			rc = wait_event_idle_timeout(ns->ns_waitq,
    +						     atomic_read(&ns->ns_bref) == 0,
    +						     obd_timeout * HZ / 4) ? 0 : -ETIMEDOUT;
    +		else
    +			rc = l_wait_event_abortable(ns->ns_waitq,
    +						    atomic_read(&ns->ns_bref) == 0);
     
     		/* Forced cleanups should be able to reclaim all references,
     		 * so it's safe to wait forever... we can't leak locks...
    diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
    index c820b201af71..ccb614bd7f53 100644
    --- a/drivers/staging/lustre/lustre/llite/llite_lib.c
    +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
    @@ -986,16 +986,12 @@ void ll_put_super(struct super_block *sb)
     	}
     
     	/* Wait for unstable pages to be committed to stable storage */
    -	if (!force) {
    -		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
    -
    -		rc = l_wait_event(sbi->ll_cache->ccc_unstable_waitq,
    -				  !atomic_long_read(&sbi->ll_cache->ccc_unstable_nr),
    -				  &lwi);
    -	}
    +	if (!force)
    +		rc = l_wait_event_abortable(sbi->ll_cache->ccc_unstable_waitq,
    +					    !atomic_long_read(&sbi->ll_cache->ccc_unstable_nr));
     
     	ccc_count = atomic_long_read(&sbi->ll_cache->ccc_unstable_nr);
    -	if (!force && rc != -EINTR)
    +	if (!force && rc != -ERESTARTSYS)
     		LASSERTF(!ccc_count, "count: %li\n", ccc_count);
     
     	/* We need to set force before the lov_disconnect in
    diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
    index 3ff25b8d3b48..8f776a4058a9 100644
    --- a/drivers/staging/lustre/lustre/obdclass/genops.c
    +++ b/drivers/staging/lustre/lustre/obdclass/genops.c
    @@ -1332,7 +1332,6 @@ static bool obd_request_slot_avail(struct client_obd *cli,
     int obd_get_request_slot(struct client_obd *cli)
     {
     	struct obd_request_slot_waiter orsw;
    -	struct l_wait_info lwi;
     	int rc;
     
     	spin_lock(&cli->cl_loi_list_lock);
    @@ -1347,11 +1346,9 @@ int obd_get_request_slot(struct client_obd *cli)
     	orsw.orsw_signaled = false;
     	spin_unlock(&cli->cl_loi_list_lock);
     
    -	lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
    -	rc = l_wait_event(orsw.orsw_waitq,
    -			  obd_request_slot_avail(cli, &orsw) ||
    -			  orsw.orsw_signaled,
    -			  &lwi);
    +	rc = l_wait_event_abortable(orsw.orsw_waitq,
    +				    obd_request_slot_avail(cli, &orsw) ||
    +				    orsw.orsw_signaled);
     
     	/*
     	 * Here, we must take the lock to avoid the on-stack 'orsw' to be
    diff --git a/drivers/staging/lustre/lustre/obdclass/llog_obd.c b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
    index 28bbaa2136ac..26aea114a29b 100644
    --- a/drivers/staging/lustre/lustre/obdclass/llog_obd.c
    +++ b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
    @@ -104,7 +104,6 @@ EXPORT_SYMBOL(__llog_ctxt_put);
     
     int llog_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt)
     {
    -	struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
     	struct obd_llog_group *olg;
     	int rc, idx;
     
    @@ -129,8 +128,8 @@ int llog_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt)
     		CERROR("Error %d while cleaning up ctxt %p\n",
     		       rc, ctxt);
     
    -	l_wait_event(olg->olg_waitq,
    -		     llog_group_ctxt_null(olg, idx), &lwi);
    +	l_wait_event_abortable(olg->olg_waitq,
    +			     llog_group_ctxt_null(olg, idx));
     
     	return rc;
     }
    diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c
    index 20094b6309f9..6fdd521feb21 100644
    --- a/drivers/staging/lustre/lustre/osc/osc_page.c
    +++ b/drivers/staging/lustre/lustre/osc/osc_page.c
    @@ -759,7 +759,6 @@ static long osc_lru_reclaim(struct client_obd *cli, unsigned long npages)
     static int osc_lru_alloc(const struct lu_env *env, struct client_obd *cli,
     			 struct osc_page *opg)
     {
    -	struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
     	struct osc_io *oio = osc_env_io(env);
     	int rc = 0;
     
    @@ -782,9 +781,8 @@ static int osc_lru_alloc(const struct lu_env *env, struct client_obd *cli,
     
     		cond_resched();
     
    -		rc = l_wait_event(osc_lru_waitq,
    -				  atomic_long_read(cli->cl_lru_left) > 0,
    -				  &lwi);
    +		rc = l_wait_event_abortable(osc_lru_waitq,
    +					    atomic_long_read(cli->cl_lru_left) > 0);
     
     		if (rc < 0)
     			break;
    diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
    index 45b1ebf33363..074b5ce6284c 100644
    --- a/drivers/staging/lustre/lustre/osc/osc_request.c
    +++ b/drivers/staging/lustre/lustre/osc/osc_request.c
    @@ -552,14 +552,12 @@ static int osc_destroy(const struct lu_env *env, struct obd_export *exp,
     
     	req->rq_interpret_reply = osc_destroy_interpret;
     	if (!osc_can_send_destroy(cli)) {
    -		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
    -
     		/*
     		 * Wait until the number of on-going destroy RPCs drops
     		 * under max_rpc_in_flight
     		 */
    -		l_wait_event_exclusive(cli->cl_destroy_waitq,
    -				       osc_can_send_destroy(cli), &lwi);
    +		l_wait_event_abortable_exclusive(cli->cl_destroy_waitq,
    +					       osc_can_send_destroy(cli));
     	}
     
     	/* Do not wait for response */
    
    
    _______________________________________________
    lustre-devel mailing list
    lustre-devel at lists.lustre.org
    http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org
    

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [lustre-devel] [PATCH 08/19] staging: lustre: simplify waiting in ldlm_completion_ast()
  2018-02-12 21:22   ` [lustre-devel] " NeilBrown
@ 2018-02-12 22:08     ` Patrick Farrell
  -1 siblings, 0 replies; 58+ messages in thread
From: Patrick Farrell @ 2018-02-12 22:08 UTC (permalink / raw)
  To: NeilBrown, Oleg Drokin, Andreas Dilger, James Simmons,
	Greg Kroah-Hartman
  Cc: lkml, lustre

Neil,

I didn't get anything after 8/19 in this series.  Is this just me?  (I'd keep waiting, except I also found a few things in this patch.)

Minor:
The line XXX ALLOCATE is out of date and could go.  (It refers to a mix of things you eliminated and things that were already gone.)

Less minor:
You remove use of the imp_lock when reading the connection count.  While that'll work on x86, it's probably wrong on some architecture to read that without taking the lock...?

Bug:
The existing code uses the imp_conn_cnt from *before* the wait, rather than after.  I think that's quite important.  So you'll want to read it out before the wait.  I think the main reason we'd hit the timeout is a disconnect, which should cause a reconnect, so it's very important to use the value from *before* the wait.  (See comment on ptlrpc_set_import_discon for more of an explanation.  Basically it's tracking a connection 'epoch', if it's changed, someone else already went through the reconnect code for this 'connection epoch' and we shouldn't start that process.)

- Patrick

On 2/12/18, 3:24 PM, "lustre-devel on behalf of NeilBrown" <lustre-devel-bounces@lists.lustre.org on behalf of neilb@suse.com> wrote:

    If a signal-callback (lwi_on_signal) is set without lwi_allow_intr, as
    is the case in ldlm_completion_ast(), the behavior depends on the
    timeout set.
    
    If a timeout is set, then signals are ignored.  If the timeout is
    reached, the timeout handler is called.  If the timeout handler
    return 0, which ldlm_expired_completion_wait() always does, the
    l_wait_event() switches to exactly the behavior if no timeout was set.
    
    If no timeout is set, then "fatal" signals are not ignored.  If one
    arrives the callback is run, but as the callback is empty in this
    case, that is not relevant.
    
    This can be simplified to:
     if a timeout is wanted
         wait_event_idle_timeout()
         if that timed out, call the timeout handler
     l_wait_event_abortable()
    
    i.e. the code always waits indefinitely.  Sometimes it performs a
    non-abortable wait first.  Sometimes it doesn't.  But it only
    aborts before the condition is true if it is signaled.
    This doesn't quite agree with the comments and debug messages.
    
    Reviewed-by: James Simmons <jsimmons@infradead.org>
    Signed-off-by: NeilBrown <neilb@suse.com>
    ---
     drivers/staging/lustre/lustre/ldlm/ldlm_request.c |   55 +++++++--------------
     1 file changed, 18 insertions(+), 37 deletions(-)
    
    diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
    index a244fa717134..f1233d844bbd 100644
    --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
    +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
    @@ -72,15 +72,6 @@ MODULE_PARM_DESC(ldlm_enqueue_min, "lock enqueue timeout minimum");
     /* in client side, whether the cached locks will be canceled before replay */
     unsigned int ldlm_cancel_unused_locks_before_replay = 1;
     
    -static void interrupted_completion_wait(void *data)
    -{
    -}
    -
    -struct lock_wait_data {
    -	struct ldlm_lock *lwd_lock;
    -	__u32	     lwd_conn_cnt;
    -};
    -
     struct ldlm_async_args {
     	struct lustre_handle lock_handle;
     };
    @@ -112,10 +103,8 @@ static int ldlm_request_bufsize(int count, int type)
     	return sizeof(struct ldlm_request) + avail;
     }
     
    -static int ldlm_expired_completion_wait(void *data)
    +static void ldlm_expired_completion_wait(struct ldlm_lock *lock, struct obd_import *imp2)
     {
    -	struct lock_wait_data *lwd = data;
    -	struct ldlm_lock *lock = lwd->lwd_lock;
     	struct obd_import *imp;
     	struct obd_device *obd;
     
    @@ -135,19 +124,17 @@ static int ldlm_expired_completion_wait(void *data)
     			if (last_dump == 0)
     				libcfs_debug_dumplog();
     		}
    -		return 0;
    +		return;
     	}
     
     	obd = lock->l_conn_export->exp_obd;
     	imp = obd->u.cli.cl_import;
    -	ptlrpc_fail_import(imp, lwd->lwd_conn_cnt);
    +	ptlrpc_fail_import(imp, imp2 ? imp2->imp_conn_cnt : 0);
     	LDLM_ERROR(lock,
     		   "lock timed out (enqueued at %lld, %llds ago), entering recovery for %s@%s",
     		   (s64)lock->l_last_activity,
     		   (s64)(ktime_get_real_seconds() - lock->l_last_activity),
     		   obd2cli_tgt(obd), imp->imp_connection->c_remote_uuid.uuid);
    -
    -	return 0;
     }
     
     /**
    @@ -251,10 +238,8 @@ EXPORT_SYMBOL(ldlm_completion_ast_async);
     int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
     {
     	/* XXX ALLOCATE - 160 bytes */
    -	struct lock_wait_data lwd;
     	struct obd_device *obd;
     	struct obd_import *imp = NULL;
    -	struct l_wait_info lwi;
     	__u32 timeout;
     	int rc = 0;
     
    @@ -281,32 +266,28 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
     
     	timeout = ldlm_cp_timeout(lock);
     
    -	lwd.lwd_lock = lock;
     	lock->l_last_activity = ktime_get_real_seconds();
     
    -	if (ldlm_is_no_timeout(lock)) {
    -		LDLM_DEBUG(lock, "waiting indefinitely because of NO_TIMEOUT");
    -		lwi = LWI_INTR(interrupted_completion_wait, &lwd);
    -	} else {
    -		lwi = LWI_TIMEOUT_INTR(timeout * HZ,
    -				       ldlm_expired_completion_wait,
    -				       interrupted_completion_wait, &lwd);
    -	}
    -
    -	if (imp) {
    -		spin_lock(&imp->imp_lock);
    -		lwd.lwd_conn_cnt = imp->imp_conn_cnt;
    -		spin_unlock(&imp->imp_lock);
    -	}
    -
     	if (OBD_FAIL_CHECK_RESET(OBD_FAIL_LDLM_INTR_CP_AST,
     				 OBD_FAIL_LDLM_CP_BL_RACE | OBD_FAIL_ONCE)) {
     		ldlm_set_fail_loc(lock);
     		rc = -EINTR;
     	} else {
    -		/* Go to sleep until the lock is granted or cancelled. */
    -		rc = l_wait_event(lock->l_waitq,
    -				  is_granted_or_cancelled(lock), &lwi);
    +		/* Go to sleep until the lock is granted or canceled. */
    +		if (!ldlm_is_no_timeout(lock)) {
    +			/* Wait uninterruptible for a while first */
    +			rc = wait_event_idle_timeout(lock->l_waitq,
    +						     is_granted_or_cancelled(lock),
    +						     timeout * HZ);
    +			if (rc == 0)
    +				ldlm_expired_completion_wait(lock, imp);
    +		}
    +		/* Now wait abortable */
    +		if (rc == 0)
    +			rc = l_wait_event_abortable(lock->l_waitq,
    +						    is_granted_or_cancelled(lock));
    +		else
    +			rc = 0;
     	}
     
     	if (rc) {
    
    
    _______________________________________________
    lustre-devel mailing list
    lustre-devel@lists.lustre.org
    http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org
    


^ permalink raw reply	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 08/19] staging: lustre: simplify waiting in ldlm_completion_ast()
@ 2018-02-12 22:08     ` Patrick Farrell
  0 siblings, 0 replies; 58+ messages in thread
From: Patrick Farrell @ 2018-02-12 22:08 UTC (permalink / raw)
  To: NeilBrown, Oleg Drokin, Andreas Dilger, James Simmons,
	Greg Kroah-Hartman
  Cc: lkml, lustre

Neil,

I didn't get anything after 8/19 in this series.  Is this just me?  (I'd keep waiting, except I also found a few things in this patch.)

Minor:
The line XXX ALLOCATE is out of date and could go.  (It refers to a mix of things you eliminated and things that were already gone.)

Less minor:
You remove use of the imp_lock when reading the connection count.  While that'll work on x86, it's probably wrong on some architecture to read that without taking the lock...?

Bug:
The existing code uses the imp_conn_cnt from *before* the wait, rather than after.  I think that's quite important.  So you'll want to read it out before the wait.  I think the main reason we'd hit the timeout is a disconnect, which should cause a reconnect, so it's very important to use the value from *before* the wait.  (See comment on ptlrpc_set_import_discon for more of an explanation.  Basically it's tracking a connection 'epoch', if it's changed, someone else already went through the reconnect code for this 'connection epoch' and we shouldn't start that process.)

- Patrick

?On 2/12/18, 3:24 PM, "lustre-devel on behalf of NeilBrown" <lustre-devel-bounces at lists.lustre.org on behalf of neilb@suse.com> wrote:

    If a signal-callback (lwi_on_signal) is set without lwi_allow_intr, as
    is the case in ldlm_completion_ast(), the behavior depends on the
    timeout set.
    
    If a timeout is set, then signals are ignored.  If the timeout is
    reached, the timeout handler is called.  If the timeout handler
    return 0, which ldlm_expired_completion_wait() always does, the
    l_wait_event() switches to exactly the behavior if no timeout was set.
    
    If no timeout is set, then "fatal" signals are not ignored.  If one
    arrives the callback is run, but as the callback is empty in this
    case, that is not relevant.
    
    This can be simplified to:
     if a timeout is wanted
         wait_event_idle_timeout()
         if that timed out, call the timeout handler
     l_wait_event_abortable()
    
    i.e. the code always waits indefinitely.  Sometimes it performs a
    non-abortable wait first.  Sometimes it doesn't.  But it only
    aborts before the condition is true if it is signaled.
    This doesn't quite agree with the comments and debug messages.
    
    Reviewed-by: James Simmons <jsimmons@infradead.org>
    Signed-off-by: NeilBrown <neilb@suse.com>
    ---
     drivers/staging/lustre/lustre/ldlm/ldlm_request.c |   55 +++++++--------------
     1 file changed, 18 insertions(+), 37 deletions(-)
    
    diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
    index a244fa717134..f1233d844bbd 100644
    --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
    +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
    @@ -72,15 +72,6 @@ MODULE_PARM_DESC(ldlm_enqueue_min, "lock enqueue timeout minimum");
     /* in client side, whether the cached locks will be canceled before replay */
     unsigned int ldlm_cancel_unused_locks_before_replay = 1;
     
    -static void interrupted_completion_wait(void *data)
    -{
    -}
    -
    -struct lock_wait_data {
    -	struct ldlm_lock *lwd_lock;
    -	__u32	     lwd_conn_cnt;
    -};
    -
     struct ldlm_async_args {
     	struct lustre_handle lock_handle;
     };
    @@ -112,10 +103,8 @@ static int ldlm_request_bufsize(int count, int type)
     	return sizeof(struct ldlm_request) + avail;
     }
     
    -static int ldlm_expired_completion_wait(void *data)
    +static void ldlm_expired_completion_wait(struct ldlm_lock *lock, struct obd_import *imp2)
     {
    -	struct lock_wait_data *lwd = data;
    -	struct ldlm_lock *lock = lwd->lwd_lock;
     	struct obd_import *imp;
     	struct obd_device *obd;
     
    @@ -135,19 +124,17 @@ static int ldlm_expired_completion_wait(void *data)
     			if (last_dump == 0)
     				libcfs_debug_dumplog();
     		}
    -		return 0;
    +		return;
     	}
     
     	obd = lock->l_conn_export->exp_obd;
     	imp = obd->u.cli.cl_import;
    -	ptlrpc_fail_import(imp, lwd->lwd_conn_cnt);
    +	ptlrpc_fail_import(imp, imp2 ? imp2->imp_conn_cnt : 0);
     	LDLM_ERROR(lock,
     		   "lock timed out (enqueued at %lld, %llds ago), entering recovery for %s@%s",
     		   (s64)lock->l_last_activity,
     		   (s64)(ktime_get_real_seconds() - lock->l_last_activity),
     		   obd2cli_tgt(obd), imp->imp_connection->c_remote_uuid.uuid);
    -
    -	return 0;
     }
     
     /**
    @@ -251,10 +238,8 @@ EXPORT_SYMBOL(ldlm_completion_ast_async);
     int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
     {
     	/* XXX ALLOCATE - 160 bytes */
    -	struct lock_wait_data lwd;
     	struct obd_device *obd;
     	struct obd_import *imp = NULL;
    -	struct l_wait_info lwi;
     	__u32 timeout;
     	int rc = 0;
     
    @@ -281,32 +266,28 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
     
     	timeout = ldlm_cp_timeout(lock);
     
    -	lwd.lwd_lock = lock;
     	lock->l_last_activity = ktime_get_real_seconds();
     
    -	if (ldlm_is_no_timeout(lock)) {
    -		LDLM_DEBUG(lock, "waiting indefinitely because of NO_TIMEOUT");
    -		lwi = LWI_INTR(interrupted_completion_wait, &lwd);
    -	} else {
    -		lwi = LWI_TIMEOUT_INTR(timeout * HZ,
    -				       ldlm_expired_completion_wait,
    -				       interrupted_completion_wait, &lwd);
    -	}
    -
    -	if (imp) {
    -		spin_lock(&imp->imp_lock);
    -		lwd.lwd_conn_cnt = imp->imp_conn_cnt;
    -		spin_unlock(&imp->imp_lock);
    -	}
    -
     	if (OBD_FAIL_CHECK_RESET(OBD_FAIL_LDLM_INTR_CP_AST,
     				 OBD_FAIL_LDLM_CP_BL_RACE | OBD_FAIL_ONCE)) {
     		ldlm_set_fail_loc(lock);
     		rc = -EINTR;
     	} else {
    -		/* Go to sleep until the lock is granted or cancelled. */
    -		rc = l_wait_event(lock->l_waitq,
    -				  is_granted_or_cancelled(lock), &lwi);
    +		/* Go to sleep until the lock is granted or canceled. */
    +		if (!ldlm_is_no_timeout(lock)) {
    +			/* Wait uninterruptible for a while first */
    +			rc = wait_event_idle_timeout(lock->l_waitq,
    +						     is_granted_or_cancelled(lock),
    +						     timeout * HZ);
    +			if (rc == 0)
    +				ldlm_expired_completion_wait(lock, imp);
    +		}
    +		/* Now wait abortable */
    +		if (rc == 0)
    +			rc = l_wait_event_abortable(lock->l_waitq,
    +						    is_granted_or_cancelled(lock));
    +		else
    +			rc = 0;
     	}
     
     	if (rc) {
    
    
    _______________________________________________
    lustre-devel mailing list
    lustre-devel at lists.lustre.org
    http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org
    

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH 19/19] staging: lustre: remove l_wait_event() and related code
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 23:47   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

These macros are no longer used, so they can
be removed.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Patrick Farrell <paf@cray.com>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |  249 --------------------
 1 file changed, 249 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
index ccc1a329e42b..1efd86f18c1f 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -76,123 +76,6 @@ int do_set_info_async(struct obd_import *imp,
 
 void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id);
 
-/*
- * l_wait_event is a flexible sleeping function, permitting simple caller
- * configuration of interrupt and timeout sensitivity along with actions to
- * be performed in the event of either exception.
- *
- * The first form of usage looks like this:
- *
- * struct l_wait_info lwi = LWI_TIMEOUT_INTR(timeout, timeout_handler,
- *					   intr_handler, callback_data);
- * rc = l_wait_event(waitq, condition, &lwi);
- *
- * l_wait_event() makes the current process wait on 'waitq' until 'condition'
- * is TRUE or a "killable" signal (SIGTERM, SIKGILL, SIGINT) is pending.  It
- * returns 0 to signify 'condition' is TRUE, but if a signal wakes it before
- * 'condition' becomes true, it optionally calls the specified 'intr_handler'
- * if not NULL, and returns -EINTR.
- *
- * If a non-zero timeout is specified, signals are ignored until the timeout
- * has expired.  At this time, if 'timeout_handler' is not NULL it is called.
- * If it returns FALSE l_wait_event() continues to wait as described above with
- * signals enabled.  Otherwise it returns -ETIMEDOUT.
- *
- * LWI_INTR(intr_handler, callback_data) is shorthand for
- * LWI_TIMEOUT_INTR(0, NULL, intr_handler, callback_data)
- *
- * The second form of usage looks like this:
- *
- * struct l_wait_info lwi = LWI_TIMEOUT(timeout, timeout_handler);
- * rc = l_wait_event(waitq, condition, &lwi);
- *
- * This form is the same as the first except that it COMPLETELY IGNORES
- * SIGNALS.  The caller must therefore beware that if 'timeout' is zero, or if
- * 'timeout_handler' is not NULL and returns FALSE, then the ONLY thing that
- * can unblock the current process is 'condition' becoming TRUE.
- *
- * Another form of usage is:
- * struct l_wait_info lwi = LWI_TIMEOUT_INTERVAL(timeout, interval,
- *					       timeout_handler);
- * rc = l_wait_event(waitq, condition, &lwi);
- * This is the same as previous case, but condition is checked once every
- * 'interval' jiffies (if non-zero).
- *
- * Subtle synchronization point: this macro does *not* necessary takes
- * wait-queue spin-lock before returning, and, hence, following idiom is safe
- * ONLY when caller provides some external locking:
- *
- *	     Thread1			    Thread2
- *
- *   l_wait_event(&obj->wq, ....);				       (1)
- *
- *				    wake_up(&obj->wq):		 (2)
- *					 spin_lock(&q->lock);	  (2.1)
- *					 __wake_up_common(q, ...);     (2.2)
- *					 spin_unlock(&q->lock, flags); (2.3)
- *
- *   kfree(obj);						  (3)
- *
- * As l_wait_event() may "short-cut" execution and return without taking
- * wait-queue spin-lock, some additional synchronization is necessary to
- * guarantee that step (3) can begin only after (2.3) finishes.
- *
- * XXX nikita: some ptlrpc daemon threads have races of that sort.
- *
- */
-
-#define LWI_ON_SIGNAL_NOOP ((void (*)(void *))(-1))
-
-struct l_wait_info {
-	long lwi_timeout;
-	long lwi_interval;
-	int	    lwi_allow_intr;
-	int  (*lwi_on_timeout)(void *);
-	void (*lwi_on_signal)(void *);
-	void  *lwi_cb_data;
-};
-
-/* NB: LWI_TIMEOUT ignores signals completely */
-#define LWI_TIMEOUT(time, cb, data)	     \
-((struct l_wait_info) {			 \
-	.lwi_timeout    = time,		 \
-	.lwi_on_timeout = cb,		   \
-	.lwi_cb_data    = data,		 \
-	.lwi_interval   = 0,		    \
-	.lwi_allow_intr = 0		     \
-})
-
-#define LWI_TIMEOUT_INTERVAL(time, interval, cb, data)  \
-((struct l_wait_info) {				 \
-	.lwi_timeout    = time,			 \
-	.lwi_on_timeout = cb,			   \
-	.lwi_cb_data    = data,			 \
-	.lwi_interval   = interval,		     \
-	.lwi_allow_intr = 0			     \
-})
-
-#define LWI_TIMEOUT_INTR(time, time_cb, sig_cb, data)   \
-((struct l_wait_info) {				 \
-	.lwi_timeout    = time,			 \
-	.lwi_on_timeout = time_cb,		      \
-	.lwi_on_signal  = sig_cb,		       \
-	.lwi_cb_data    = data,			 \
-	.lwi_interval   = 0,			    \
-	.lwi_allow_intr = 0			     \
-})
-
-#define LWI_TIMEOUT_INTR_ALL(time, time_cb, sig_cb, data)       \
-((struct l_wait_info) {					 \
-	.lwi_timeout    = time,				 \
-	.lwi_on_timeout = time_cb,			      \
-	.lwi_on_signal  = sig_cb,			       \
-	.lwi_cb_data    = data,				 \
-	.lwi_interval   = 0,				    \
-	.lwi_allow_intr = 1				     \
-})
-
-#define LWI_INTR(cb, data)  LWI_TIMEOUT_INTR(0, NULL, cb, data)
-
 #define LUSTRE_FATAL_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) |		\
 			   sigmask(SIGTERM) | sigmask(SIGQUIT) |	\
 			   sigmask(SIGALRM))
@@ -201,138 +84,6 @@ static inline int l_fatal_signal_pending(struct task_struct *p)
 	return signal_pending(p) && sigtestsetmask(&p->pending.signal, LUSTRE_FATAL_SIGS);
 }
 
-/**
- * wait_queue_entry_t of Linux (version < 2.6.34) is a FIFO list for exclusively
- * waiting threads, which is not always desirable because all threads will
- * be waken up again and again, even user only needs a few of them to be
- * active most time. This is not good for performance because cache can
- * be polluted by different threads.
- *
- * LIFO list can resolve this problem because we always wakeup the most
- * recent active thread by default.
- *
- * NB: please don't call non-exclusive & exclusive wait on the same
- * waitq if add_wait_queue_exclusive_head is used.
- */
-#define add_wait_queue_exclusive_head(waitq, link)		\
-{								\
-	unsigned long flags;					\
-								\
-	spin_lock_irqsave(&((waitq)->lock), flags);		\
-	__add_wait_queue_exclusive(waitq, link);		\
-	spin_unlock_irqrestore(&((waitq)->lock), flags);	\
-}
-
-/*
- * wait for @condition to become true, but no longer than timeout, specified
- * by @info.
- */
-#define __l_wait_event(wq, condition, info, ret, l_add_wait)		   \
-do {									   \
-	wait_queue_entry_t __wait;						 \
-	long __timeout = info->lwi_timeout;			  \
-	sigset_t   __blocked;					      \
-	int   __allow_intr = info->lwi_allow_intr;			     \
-									       \
-	ret = 0;							       \
-	if (condition)							 \
-		break;							 \
-									       \
-	init_waitqueue_entry(&__wait, current);					    \
-	l_add_wait(&wq, &__wait);					      \
-									       \
-	/* Block all signals (just the non-fatal ones if no timeout). */       \
-	if (info->lwi_on_signal && (__timeout == 0 || __allow_intr))   \
-		__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);	      \
-	else								   \
-		__blocked = cfs_block_sigsinv(0);			      \
-									       \
-	for (;;) {							     \
-		if (condition)						 \
-			break;						 \
-									       \
-		set_current_state(TASK_INTERRUPTIBLE);			       \
-									       \
-		if (__timeout == 0) {					  \
-			schedule();					       \
-		} else {						       \
-			long interval = info->lwi_interval ?	  \
-					     min_t(long,	     \
-						 info->lwi_interval, __timeout) : \
-					     __timeout;			\
-			long remaining = schedule_timeout(interval);\
-			__timeout = cfs_time_sub(__timeout,		    \
-					    cfs_time_sub(interval, remaining));\
-			if (__timeout == 0) {				  \
-				if (!info->lwi_on_timeout ||		      \
-				    info->lwi_on_timeout(info->lwi_cb_data)) { \
-					ret = -ETIMEDOUT;		      \
-					break;				 \
-				}					      \
-				/* Take signals after the timeout expires. */  \
-				if (info->lwi_on_signal)		       \
-				    (void)cfs_block_sigsinv(LUSTRE_FATAL_SIGS);\
-			}						      \
-		}							      \
-									       \
-		set_current_state(TASK_RUNNING);			       \
-									       \
-		if (condition)						 \
-			break;						 \
-		if (signal_pending(current)) {				    \
-			if (info->lwi_on_signal &&		     \
-			    (__timeout == 0 || __allow_intr)) {		\
-				if (info->lwi_on_signal != LWI_ON_SIGNAL_NOOP) \
-					info->lwi_on_signal(info->lwi_cb_data);\
-				ret = -EINTR;				  \
-				break;					 \
-			}						      \
-			/* We have to do this here because some signals */     \
-			/* are not blockable - ie from strace(1).       */     \
-			/* In these cases we want to schedule_timeout() */     \
-			/* again, because we don't want that to return  */     \
-			/* -EINTR when the RPC actually succeeded.      */     \
-			/* the recalc_sigpending() below will deliver the */     \
-			/* signal properly.			     */     \
-			cfs_clear_sigpending();				\
-		}							      \
-	}								      \
-									       \
-	cfs_restore_sigs(__blocked);					   \
-									       \
-	remove_wait_queue(&wq, &__wait);					   \
-} while (0)
-
-#define l_wait_event(wq, condition, info)		       \
-({							      \
-	int		 __ret;			      \
-	struct l_wait_info *__info = (info);		    \
-								\
-	__l_wait_event(wq, condition, __info,		   \
-		       __ret, add_wait_queue);		   \
-	__ret;						  \
-})
-
-#define l_wait_event_exclusive(wq, condition, info)	     \
-({							      \
-	int		 __ret;			      \
-	struct l_wait_info *__info = (info);		    \
-								\
-	__l_wait_event(wq, condition, __info,		   \
-		       __ret, add_wait_queue_exclusive);	 \
-	__ret;						  \
-})
-
-#define l_wait_event_exclusive_head(wq, condition, info)	\
-({							      \
-	int		 __ret;			      \
-	struct l_wait_info *__info = (info);		    \
-								\
-	__l_wait_event(wq, condition, __info,		   \
-		       __ret, add_wait_queue_exclusive_head);    \
-	__ret;						  \
-})
-
 /** @} lib */
 
 

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 18/19] staging: lustre: replace l_wait_event_exclusive_head() with wait_event_idle_exclusive
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 23:47   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

This l_wait_event_exclusive_head() will wait indefinitely
if the timeout is zero.  If it does wait with a timeout
and times out, the timeout for next time is set to zero.

The can be mapped to a call to either
 wait_event_idle_exclusive()
or
 wait_event_idle_exclusive_timeout()
depending in the timeout setting.

The current code arranges for LIFO queuing of waiters,
but include/event.h doesn't support that yet.
Until it does, fall back on FIFO with
wait_event_idle_exclusive{,_timeout}().

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 drivers/staging/lustre/lustre/ptlrpc/service.c |   43 ++++++++++++++----------
 1 file changed, 25 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
index 6e3403417434..29fdb54f16ca 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -1897,15 +1897,6 @@ ptlrpc_check_rqbd_pool(struct ptlrpc_service_part *svcpt)
 	}
 }
 
-static int
-ptlrpc_retry_rqbds(void *arg)
-{
-	struct ptlrpc_service_part *svcpt = arg;
-
-	svcpt->scp_rqbd_timeout = 0;
-	return -ETIMEDOUT;
-}
-
 static inline int
 ptlrpc_threads_enough(struct ptlrpc_service_part *svcpt)
 {
@@ -1968,13 +1959,17 @@ ptlrpc_server_request_incoming(struct ptlrpc_service_part *svcpt)
 	return !list_empty(&svcpt->scp_req_incoming);
 }
 
+/* We perfer lifo queuing, but kernel doesn't provide that yet. */
+#ifndef wait_event_idle_exclusive_lifo
+#define wait_event_idle_exclusive_lifo wait_event_idle_exclusive
+#define wait_event_idle_exclusive_lifo_timeout wait_event_idle_exclusive_timeout
+#endif
+
 static __attribute__((__noinline__)) int
 ptlrpc_wait_event(struct ptlrpc_service_part *svcpt,
 		  struct ptlrpc_thread *thread)
 {
 	/* Don't exit while there are replies to be handled */
-	struct l_wait_info lwi = LWI_TIMEOUT(svcpt->scp_rqbd_timeout,
-					     ptlrpc_retry_rqbds, svcpt);
 
 	/* XXX: Add this back when libcfs watchdog is merged upstream
 	lc_watchdog_disable(thread->t_watchdog);
@@ -1982,13 +1977,25 @@ ptlrpc_wait_event(struct ptlrpc_service_part *svcpt,
 
 	cond_resched();
 
-	l_wait_event_exclusive_head(svcpt->scp_waitq,
-				    ptlrpc_thread_stopping(thread) ||
-				    ptlrpc_server_request_incoming(svcpt) ||
-				    ptlrpc_server_request_pending(svcpt,
-								  false) ||
-				    ptlrpc_rqbd_pending(svcpt) ||
-				    ptlrpc_at_check(svcpt), &lwi);
+	if (svcpt->scp_rqbd_timeout == 0)
+		wait_event_idle_exclusive_lifo(
+			svcpt->scp_waitq,
+			ptlrpc_thread_stopping(thread) ||
+			ptlrpc_server_request_incoming(svcpt) ||
+			ptlrpc_server_request_pending(svcpt,
+						      false) ||
+			ptlrpc_rqbd_pending(svcpt) ||
+			ptlrpc_at_check(svcpt));
+	else if (0 == wait_event_idle_exclusive_lifo_timeout(
+			 svcpt->scp_waitq,
+			 ptlrpc_thread_stopping(thread) ||
+			 ptlrpc_server_request_incoming(svcpt) ||
+			 ptlrpc_server_request_pending(svcpt,
+						       false) ||
+			 ptlrpc_rqbd_pending(svcpt) ||
+			 ptlrpc_at_check(svcpt),
+			 svcpt->scp_rqbd_timeout))
+		svcpt->scp_rqbd_timeout = 0;
 
 	if (ptlrpc_thread_stopping(thread))
 		return -EINTR;

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 17/19] staging: lustre: remove l_wait_event from ptlrpc_set_wait
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 23:47   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

This is the last remaining use of l_wait_event().
It is the only use of LWI_TIMEOUT_INTR_ALL() which
has a meaning that timeouts can be interrupted.
Only interrupts by "fatal" signals are allowed, so
introduce l_wait_event_abortable_timeout() to
support this.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |   14 +++
 drivers/staging/lustre/lustre/ptlrpc/client.c      |   84 ++++++++------------
 2 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
index 1939e959b92a..ccc1a329e42b 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -196,6 +196,10 @@ struct l_wait_info {
 #define LUSTRE_FATAL_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) |		\
 			   sigmask(SIGTERM) | sigmask(SIGQUIT) |	\
 			   sigmask(SIGALRM))
+static inline int l_fatal_signal_pending(struct task_struct *p)
+{
+	return signal_pending(p) && sigtestsetmask(&p->pending.signal, LUSTRE_FATAL_SIGS);
+}
 
 /**
  * wait_queue_entry_t of Linux (version < 2.6.34) is a FIFO list for exclusively
@@ -347,6 +351,16 @@ do {									   \
 	__ret;								\
 })
 
+#define l_wait_event_abortable_timeout(wq, condition, timeout)		\
+({									\
+	sigset_t __blocked;						\
+	int __ret = 0;							\
+	__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);		\
+	__ret = wait_event_interruptible_timeout(wq, condition, timeout);\
+	cfs_restore_sigs(__blocked);					\
+	__ret;								\
+})
+
 #define l_wait_event_abortable_exclusive(wq, condition)			\
 ({									\
 	sigset_t __blocked;						\
diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index ffdd3ffd62c6..3d689d6100bc 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -1774,7 +1774,7 @@ int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set)
 		}
 
 		/*
-		 * ptlrpc_set_wait->l_wait_event sets lwi_allow_intr
+		 * ptlrpc_set_wait allow signal to abort the timeout
 		 * so it sets rq_intr regardless of individual rpc
 		 * timeouts. The synchronous IO waiting path sets
 		 * rq_intr irrespective of whether ptlrpcd
@@ -2122,8 +2122,7 @@ int ptlrpc_expire_one_request(struct ptlrpc_request *req, int async_unlink)
 
 /**
  * Time out all uncompleted requests in request set pointed by \a data
- * Callback used when waiting on sets with l_wait_event.
- * Always returns 1.
+ * Called when wait_event_idle_timeout times out.
  */
 void ptlrpc_expired_set(struct ptlrpc_request_set *set)
 {
@@ -2156,18 +2155,6 @@ void ptlrpc_expired_set(struct ptlrpc_request_set *set)
 		ptlrpc_expire_one_request(req, 1);
 	}
 }
-static int ptlrpc_expired_set_void(void *data)
-{
-	struct ptlrpc_request_set *set = data;
-
-	ptlrpc_expired_set(set);
-	/*
-	 * When waiting for a whole set, we always break out of the
-	 * sleep so we can recalculate the timeout, or enable interrupts
-	 * if everyone's timed out.
-	 */
-	return 1;
-}
 
 /**
  * Sets rq_intr flag in \a req under spinlock.
@@ -2182,11 +2169,10 @@ EXPORT_SYMBOL(ptlrpc_mark_interrupted);
 
 /**
  * Interrupts (sets interrupted flag) all uncompleted requests in
- * a set \a data. Callback for l_wait_event for interruptible waits.
+ * a set \a data. Called when l_wait_event_abortable_timeout receives signal.
  */
-static void ptlrpc_interrupted_set(void *data)
+static void ptlrpc_interrupted_set(struct ptlrpc_request_set *set)
 {
-	struct ptlrpc_request_set *set = data;
 	struct list_head *tmp;
 
 	CDEBUG(D_RPCTRACE, "INTERRUPTED SET %p\n", set);
@@ -2256,7 +2242,6 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 {
 	struct list_head *tmp;
 	struct ptlrpc_request *req;
-	struct l_wait_info lwi;
 	int rc, timeout;
 
 	if (set->set_producer)
@@ -2282,46 +2267,47 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 		CDEBUG(D_RPCTRACE, "set %p going to sleep for %d seconds\n",
 		       set, timeout);
 
-		if (timeout == 0 && !signal_pending(current))
+		if (timeout == 0 && !signal_pending(current)) {
 			/*
 			 * No requests are in-flight (ether timed out
 			 * or delayed), so we can allow interrupts.
 			 * We still want to block for a limited time,
 			 * so we allow interrupts during the timeout.
 			 */
-			lwi = LWI_TIMEOUT_INTR_ALL(HZ,
-						   ptlrpc_expired_set_void,
-						   ptlrpc_interrupted_set, set);
-		else
+			rc = l_wait_event_abortable_timeout(set->set_waitq,
+							    ptlrpc_check_set(NULL, set),
+							    HZ);
+			if (rc == 0) {
+				rc = -ETIMEDOUT;
+				ptlrpc_expired_set(set);
+			} else if (rc < 0) {
+				rc = -EINTR;
+				ptlrpc_interrupted_set(set);
+			} else
+				rc = 0;
+		} else {
 			/*
 			 * At least one request is in flight, so no
 			 * interrupts are allowed. Wait until all
 			 * complete, or an in-flight req times out.
 			 */
-			lwi = LWI_TIMEOUT((timeout ? timeout : 1) * HZ,
-					  ptlrpc_expired_set_void, set);
-
-		rc = l_wait_event(set->set_waitq, ptlrpc_check_set(NULL, set), &lwi);
-
-		/*
-		 * LU-769 - if we ignored the signal because it was already
-		 * pending when we started, we need to handle it now or we risk
-		 * it being ignored forever
-		 */
-		if (rc == -ETIMEDOUT && !lwi.lwi_allow_intr &&
-		    signal_pending(current)) {
-			sigset_t blocked_sigs =
-					   cfs_block_sigsinv(LUSTRE_FATAL_SIGS);
-
-			/*
-			 * In fact we only interrupt for the "fatal" signals
-			 * like SIGINT or SIGKILL. We still ignore less
-			 * important signals since ptlrpc set is not easily
-			 * reentrant from userspace again
-			 */
-			if (signal_pending(current))
-				ptlrpc_interrupted_set(set);
-			cfs_restore_sigs(blocked_sigs);
+			rc = wait_event_idle_timeout(set->set_waitq,
+						     ptlrpc_check_set(NULL, set),
+						     (timeout ? timeout : 1) * HZ);
+			if (rc == 0) {
+				ptlrpc_expired_set(set);
+				rc = -ETIMEDOUT;
+				/*
+				 * LU-769 - if we ignored the signal
+				 * because it was already pending when
+				 * we started, we need to handle it
+				 * now or we risk it being ignored
+				 * forever
+				 */
+				if (l_fatal_signal_pending(current))
+					ptlrpc_interrupted_set(set);
+			} else
+				rc = 0;
 		}
 
 		LASSERT(rc == 0 || rc == -EINTR || rc == -ETIMEDOUT);
@@ -2528,7 +2514,7 @@ static int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async)
 		return 0;
 
 	/*
-	 * We have to l_wait_event() whatever the result, to give liblustre
+	 * We have to wait_event_idle_timeout() whatever the result, to give liblustre
 	 * a chance to run reply_in_callback(), and to make sure we've
 	 * unlinked before returning a req to the pool.
 	 */

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 16/19] staging: lustre: use explicit poll loop in ptlrpc_unregister_reply
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 23:47   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

replace l_wait_event() with wait_event_idle_timeout() and explicit
loop.  This approach is easier to understand.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 drivers/staging/lustre/lustre/ptlrpc/client.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index f70176c6db08..ffdd3ffd62c6 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -2500,7 +2500,6 @@ static int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async)
 {
 	int rc;
 	wait_queue_head_t *wq;
-	struct l_wait_info lwi;
 
 	/* Might sleep. */
 	LASSERT(!in_interrupt());
@@ -2543,16 +2542,17 @@ static int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async)
 		 * Network access will complete in finite time but the HUGE
 		 * timeout lets us CWARN for visibility of sluggish NALs
 		 */
-		lwi = LWI_TIMEOUT_INTERVAL(LONG_UNLINK * HZ,
-					   HZ, NULL, NULL);
-		rc = l_wait_event(*wq, !ptlrpc_client_recv_or_unlink(request),
-				  &lwi);
-		if (rc == 0) {
+		int cnt = 0;
+		while (cnt < LONG_UNLINK &&
+		       (rc = wait_event_idle_timeout(*wq,
+						     !ptlrpc_client_recv_or_unlink(request),
+						     HZ)) == 0)
+			cnt += 1;
+		if (rc > 0) {
 			ptlrpc_rqphase_move(request, request->rq_next_phase);
 			return 1;
 		}
 
-		LASSERT(rc == -ETIMEDOUT);
 		DEBUG_REQ(D_WARNING, request,
 			  "Unexpectedly long timeout receiving_reply=%d req_ulinked=%d reply_unlinked=%d",
 			  request->rq_receiving_reply,

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 15/19] staging: lustre: use explicit poll loop in ptlrpc_service_unlink_rqbd
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 23:47   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

Rather an using l_wait_event(), use wait_event_idle_timeout()
with an explicit loop so it is easier to see what is happening.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 drivers/staging/lustre/lustre/ptlrpc/service.c |   15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
index 5c41297d23d2..6e3403417434 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -2618,7 +2618,7 @@ ptlrpc_service_unlink_rqbd(struct ptlrpc_service *svc)
 {
 	struct ptlrpc_service_part *svcpt;
 	struct ptlrpc_request_buffer_desc *rqbd;
-	struct l_wait_info lwi;
+	int cnt;
 	int rc;
 	int i;
 
@@ -2658,12 +2658,13 @@ ptlrpc_service_unlink_rqbd(struct ptlrpc_service *svc)
 			 * the HUGE timeout lets us CWARN for visibility
 			 * of sluggish LNDs
 			 */
-			lwi = LWI_TIMEOUT_INTERVAL(
-					LONG_UNLINK * HZ,
-					HZ, NULL, NULL);
-			rc = l_wait_event(svcpt->scp_waitq,
-					  svcpt->scp_nrqbds_posted == 0, &lwi);
-			if (rc == -ETIMEDOUT) {
+			cnt = 0;
+			while (cnt < LONG_UNLINK &&
+			       (rc = wait_event_idle_timeout(svcpt->scp_waitq,
+							     svcpt->scp_nrqbds_posted == 0,
+							     HZ)) == 0)
+				cnt ++;
+			if (rc == 0) {
 				CWARN("Service %s waiting for request buffers\n",
 				      svcpt->scp_service->srv_name);
 			}

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 14/19] staging: lustre: improve waiting in sptlrpc_req_refresh_ctx
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 23:47   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

Replace l_wait_event with wait_event_idle_timeout() and call the
handler function explicitly.  This makes it more clear
what is happening.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 drivers/staging/lustre/lustre/ptlrpc/sec.c |   34 ++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec.c b/drivers/staging/lustre/lustre/ptlrpc/sec.c
index 617e004d00f8..90e3b3022106 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec.c
@@ -554,9 +554,8 @@ int ctx_check_refresh(struct ptlrpc_cli_ctx *ctx)
 }
 
 static
-int ctx_refresh_timeout(void *data)
+int ctx_refresh_timeout(struct ptlrpc_request *req)
 {
-	struct ptlrpc_request *req = data;
 	int rc;
 
 	/* conn_cnt is needed in expire_one_request */
@@ -575,10 +574,8 @@ int ctx_refresh_timeout(void *data)
 }
 
 static
-void ctx_refresh_interrupt(void *data)
+void ctx_refresh_interrupt(struct ptlrpc_request *req)
 {
-	struct ptlrpc_request *req = data;
-
 	spin_lock(&req->rq_lock);
 	req->rq_intr = 1;
 	spin_unlock(&req->rq_lock);
@@ -611,7 +608,6 @@ int sptlrpc_req_refresh_ctx(struct ptlrpc_request *req, long timeout)
 {
 	struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx;
 	struct ptlrpc_sec *sec;
-	struct l_wait_info lwi;
 	int rc;
 
 	LASSERT(ctx);
@@ -743,10 +739,28 @@ int sptlrpc_req_refresh_ctx(struct ptlrpc_request *req, long timeout)
 	req->rq_restart = 0;
 	spin_unlock(&req->rq_lock);
 
-	lwi = LWI_TIMEOUT_INTR(msecs_to_jiffies(timeout * MSEC_PER_SEC),
-			       ctx_refresh_timeout, ctx_refresh_interrupt,
-			       req);
-	rc = l_wait_event(req->rq_reply_waitq, ctx_check_refresh(ctx), &lwi);
+	rc = wait_event_idle_timeout(req->rq_reply_waitq,
+				     ctx_check_refresh(ctx),
+				     timeout * HZ);
+	if (rc == 0 && ctx_refresh_timeout(req) == 0) {
+		/* Keep waiting, but enable some signals */
+		rc = l_wait_event_abortable(req->rq_reply_waitq,
+					    ctx_check_refresh(ctx));
+		if (rc == 0)
+			rc = 1;
+	}
+
+	if (rc > 0)
+		/* condition is true */
+		rc = 0;
+	else if (rc == 0)
+		/* Timed out */
+		rc = -ETIMEDOUT;
+	else {
+		/* Aborted by signal */
+		rc = -EINTR;
+		ctx_refresh_interrupt(req);
+	}
 
 	/*
 	 * following cases could lead us here:

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 13/19] staging: lustre: use wait_event_idle_timeout in ptlrpcd()
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 23:47   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

We can replace l_wait_event() with
wait_event_idle_timeout() here providing we call the
timeout function when wait_event_idle_timeout() returns zero.

As ptlrpc_expired_set() returns 1, the l_wait_event() aborts of the
first timeout.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 drivers/staging/lustre/lustre/ptlrpc/client.c      |   12 ++++++++----
 .../staging/lustre/lustre/ptlrpc/ptlrpc_internal.h |    2 +-
 drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c     |    9 +++++----
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index 81b7a7046d82..f70176c6db08 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -2125,9 +2125,8 @@ int ptlrpc_expire_one_request(struct ptlrpc_request *req, int async_unlink)
  * Callback used when waiting on sets with l_wait_event.
  * Always returns 1.
  */
-int ptlrpc_expired_set(void *data)
+void ptlrpc_expired_set(struct ptlrpc_request_set *set)
 {
-	struct ptlrpc_request_set *set = data;
 	struct list_head *tmp;
 	time64_t now = ktime_get_real_seconds();
 
@@ -2156,7 +2155,12 @@ int ptlrpc_expired_set(void *data)
 		 */
 		ptlrpc_expire_one_request(req, 1);
 	}
+}
+static int ptlrpc_expired_set_void(void *data)
+{
+	struct ptlrpc_request_set *set = data;
 
+	ptlrpc_expired_set(set);
 	/*
 	 * When waiting for a whole set, we always break out of the
 	 * sleep so we can recalculate the timeout, or enable interrupts
@@ -2286,7 +2290,7 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 			 * so we allow interrupts during the timeout.
 			 */
 			lwi = LWI_TIMEOUT_INTR_ALL(HZ,
-						   ptlrpc_expired_set,
+						   ptlrpc_expired_set_void,
 						   ptlrpc_interrupted_set, set);
 		else
 			/*
@@ -2295,7 +2299,7 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 			 * complete, or an in-flight req times out.
 			 */
 			lwi = LWI_TIMEOUT((timeout ? timeout : 1) * HZ,
-					  ptlrpc_expired_set, set);
+					  ptlrpc_expired_set_void, set);
 
 		rc = l_wait_event(set->set_waitq, ptlrpc_check_set(NULL, set), &lwi);
 
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
index f9decbd1459d..b7a8d7537a66 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
@@ -68,7 +68,7 @@ void ptlrpc_request_cache_free(struct ptlrpc_request *req);
 void ptlrpc_init_xid(void);
 void ptlrpc_set_add_new_req(struct ptlrpcd_ctl *pc,
 			    struct ptlrpc_request *req);
-int ptlrpc_expired_set(void *data);
+void ptlrpc_expired_set(struct ptlrpc_request_set *set);
 int ptlrpc_set_next_timeout(struct ptlrpc_request_set *set);
 void ptlrpc_resend_req(struct ptlrpc_request *request);
 void ptlrpc_set_bulk_mbits(struct ptlrpc_request *req);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
index 437b4b2a9072..6ed77521d025 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
@@ -435,16 +435,17 @@ static int ptlrpcd(void *arg)
 	 * new_req_list and ptlrpcd_check() moves them into the set.
 	 */
 	do {
-		struct l_wait_info lwi;
 		int timeout;
 
 		timeout = ptlrpc_set_next_timeout(set);
-		lwi = LWI_TIMEOUT((timeout ? timeout : 1) * HZ,
-				  ptlrpc_expired_set, set);
 
 		lu_context_enter(&env.le_ctx);
 		lu_context_enter(env.le_ses);
-		l_wait_event(set->set_waitq, ptlrpcd_check(&env, pc), &lwi);
+		if (wait_event_idle_timeout(set->set_waitq,
+					    ptlrpcd_check(&env, pc),
+					    (timeout ? timeout : 1) * HZ) == 0)
+			ptlrpc_expired_set(set);
+
 		lu_context_exit(&env.le_ctx);
 		lu_context_exit(env.le_ses);
 

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 12/19] staging: lustre: make polling loop in ptlrpc_unregister_bulk more obvious
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 23:47   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

This use of l_wait_event() is a polling loop that re-checks
every second.  Make this more obvious with a while loop
and wait_event_idle_timeout().

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 drivers/staging/lustre/lustre/ptlrpc/niobuf.c |   15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
index 0c2ded721c49..86883abaad2c 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
@@ -229,7 +229,6 @@ int ptlrpc_unregister_bulk(struct ptlrpc_request *req, int async)
 {
 	struct ptlrpc_bulk_desc *desc = req->rq_bulk;
 	wait_queue_head_t *wq;
-	struct l_wait_info lwi;
 	int rc;
 
 	LASSERT(!in_interrupt());     /* might sleep */
@@ -246,7 +245,7 @@ int ptlrpc_unregister_bulk(struct ptlrpc_request *req, int async)
 
 	/* the unlink ensures the callback happens ASAP and is the last
 	 * one.  If it fails, it must be because completion just happened,
-	 * but we must still l_wait_event() in this case to give liblustre
+	 * but we must still wait_event() in this case to give liblustre
 	 * a chance to run client_bulk_callback()
 	 */
 	mdunlink_iterate_helper(desc->bd_mds, desc->bd_md_max_brw);
@@ -270,15 +269,17 @@ int ptlrpc_unregister_bulk(struct ptlrpc_request *req, int async)
 		/* Network access will complete in finite time but the HUGE
 		 * timeout lets us CWARN for visibility of sluggish LNDs
 		 */
-		lwi = LWI_TIMEOUT_INTERVAL(LONG_UNLINK * HZ,
-					   HZ, NULL, NULL);
-		rc = l_wait_event(*wq, !ptlrpc_client_bulk_active(req), &lwi);
-		if (rc == 0) {
+		int cnt = 0;
+		while (cnt < LONG_UNLINK &&
+		       (rc = wait_event_idle_timeout(*wq,
+						     !ptlrpc_client_bulk_active(req),
+						     HZ)) == 0)
+			cnt += 1;
+		if (rc > 0) {
 			ptlrpc_rqphase_move(req, req->rq_next_phase);
 			return 1;
 		}
 
-		LASSERT(rc == -ETIMEDOUT);
 		DEBUG_REQ(D_WARNING, req, "Unexpectedly long timeout: desc %p",
 			  desc);
 	}

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 11/19] staging: lustre: remove back_to_sleep()
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 23:47   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

When 'back_to_sleep()' is passed as the 'timeout' function,
the effect is to wait indefinitely for the event, polling
once after the timeout.
If LWI_ON_SIGNAL_NOOP is given, then after the timeout
we allow fatal signals to interrupt the wait.

Make this more obvious in both places "back_to_sleep()" is
used but using two explicit sleeps.

The code in ptlrpcd_add_req() looks odd - why not just have one
wait_event_idle()?  However I believe this is a faithful
transformation of the existing code.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |    4 ----
 drivers/staging/lustre/lustre/ptlrpc/import.c      |   11 ++++++-----
 drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c     |    9 +++++----
 3 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
index b2a64d0e682c..1939e959b92a 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -140,10 +140,6 @@ void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id);
  * XXX nikita: some ptlrpc daemon threads have races of that sort.
  *
  */
-static inline int back_to_sleep(void *arg)
-{
-	return 0;
-}
 
 #define LWI_ON_SIGNAL_NOOP ((void (*)(void *))(-1))
 
diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c
index 5d62c9de27eb..faf0f606f013 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/import.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/import.c
@@ -1496,7 +1496,6 @@ int ptlrpc_disconnect_import(struct obd_import *imp, int noclose)
 	}
 
 	if (ptlrpc_import_in_recovery(imp)) {
-		struct l_wait_info lwi;
 		long timeout;
 
 		if (AT_OFF) {
@@ -1510,10 +1509,12 @@ int ptlrpc_disconnect_import(struct obd_import *imp, int noclose)
 			timeout = at_get(&imp->imp_at.iat_service_estimate[idx]) * HZ;
 		}
 
-		lwi = LWI_TIMEOUT_INTR(cfs_timeout_cap(timeout),
-				       back_to_sleep, LWI_ON_SIGNAL_NOOP, NULL);
-		rc = l_wait_event(imp->imp_recovery_waitq,
-				  !ptlrpc_import_in_recovery(imp), &lwi);
+		if (wait_event_idle_timeout(imp->imp_recovery_waitq,
+					    !ptlrpc_import_in_recovery(imp),
+					    cfs_timeout_cap(timeout)) == 0)
+			l_wait_event_abortable(
+				imp->imp_recovery_waitq,
+				!ptlrpc_import_in_recovery(imp));
 	}
 
 	spin_lock(&imp->imp_lock);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
index dad2f9290f70..437b4b2a9072 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
@@ -230,12 +230,13 @@ void ptlrpcd_add_req(struct ptlrpc_request *req)
 
 	spin_lock(&req->rq_lock);
 	if (req->rq_invalid_rqset) {
-		struct l_wait_info lwi = LWI_TIMEOUT(5 * HZ,
-						     back_to_sleep, NULL);
-
 		req->rq_invalid_rqset = 0;
 		spin_unlock(&req->rq_lock);
-		l_wait_event(req->rq_set_waitq, !req->rq_set, &lwi);
+		if (wait_event_idle_timeout(req->rq_set_waitq,
+					    !req->rq_set,
+					    5 * HZ) == 0)
+			wait_event_idle(req->rq_set_waitq,
+					!req->rq_set);
 	} else if (req->rq_set) {
 		/* If we have a valid "rq_set", just reuse it to avoid double
 		 * linked.

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 10/19] staging: lustre: simplify waiting in ptlrpc_invalidate_import()
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 23:47   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

This waiter currently wakes up every second to re-test if
imp_flight is zero.  If we ensure wakeup is called whenever
imp_flight is decremented to zero, we can just have a simple
wait_event_idle_timeout().

So add a wake_up_all to the one place it is missing, and simplify
the wait_event.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 drivers/staging/lustre/lustre/ptlrpc/client.c |    3 ++-
 drivers/staging/lustre/lustre/ptlrpc/import.c |   21 ++++++++-------------
 2 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index 0ab13f8e5993..81b7a7046d82 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -1588,7 +1588,8 @@ static int ptlrpc_send_new_req(struct ptlrpc_request *req)
 		spin_lock(&imp->imp_lock);
 		if (!list_empty(&req->rq_list)) {
 			list_del_init(&req->rq_list);
-			atomic_dec(&req->rq_import->imp_inflight);
+			if (atomic_dec_and_test(&req->rq_import->imp_inflight))
+				wake_up_all(&req->rq_import->imp_recovery_waitq);
 		}
 		spin_unlock(&imp->imp_lock);
 		ptlrpc_rqphase_move(req, RQ_PHASE_NEW);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c
index ed210550f61f..5d62c9de27eb 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/import.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/import.c
@@ -265,7 +265,6 @@ void ptlrpc_invalidate_import(struct obd_import *imp)
 {
 	struct list_head *tmp, *n;
 	struct ptlrpc_request *req;
-	struct l_wait_info lwi;
 	unsigned int timeout;
 	int rc;
 
@@ -306,19 +305,15 @@ void ptlrpc_invalidate_import(struct obd_import *imp)
 		 * callbacks. Cap it at obd_timeout -- these should all
 		 * have been locally cancelled by ptlrpc_abort_inflight.
 		 */
-		lwi = LWI_TIMEOUT_INTERVAL(
-			cfs_timeout_cap(timeout * HZ),
-			(timeout > 1) ? HZ :
-			HZ / 2,
-			NULL, NULL);
-		rc = l_wait_event(imp->imp_recovery_waitq,
-				  (atomic_read(&imp->imp_inflight) == 0),
-				  &lwi);
-		if (rc) {
+		rc = wait_event_idle_timeout(imp->imp_recovery_waitq,
+					     atomic_read(&imp->imp_inflight) == 0,
+					     obd_timeout * HZ);
+
+		if (rc == 0) {
 			const char *cli_tgt = obd2cli_tgt(imp->imp_obd);
 
-			CERROR("%s: rc = %d waiting for callback (%d != 0)\n",
-			       cli_tgt, rc,
+			CERROR("%s: timeout waiting for callback (%d != 0)\n",
+			       cli_tgt,
 			       atomic_read(&imp->imp_inflight));
 
 			spin_lock(&imp->imp_lock);
@@ -365,7 +360,7 @@ void ptlrpc_invalidate_import(struct obd_import *imp)
 			}
 			spin_unlock(&imp->imp_lock);
 		}
-	} while (rc != 0);
+	} while (rc == 0);
 
 	/*
 	 * Let's additionally check that no new rpcs added to import in

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 09/19] staging: lustre: open code polling loop instead of using l_wait_event()
  2018-02-12 21:22 ` [lustre-devel] " NeilBrown
@ 2018-02-12 23:47   ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

Two places that LWI_TIMEOUT_INTERVAL() is used, the outcome is a
simple polling loop that polls every second for some event (with a
limit).

So write a simple loop to make this more apparent.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
Reviewed-by: Patrick Farrell <paf@cray.com>
---
 drivers/staging/lustre/lustre/llite/llite_lib.c |   11 +++++------
 drivers/staging/lustre/lustre/lov/lov_request.c |   12 +++++-------
 2 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
index ccb614bd7f53..9e96a8ee1783 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -1984,8 +1984,7 @@ void ll_umount_begin(struct super_block *sb)
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 	struct obd_device *obd;
 	struct obd_ioctl_data *ioc_data;
-	wait_queue_head_t waitq;
-	struct l_wait_info lwi;
+	int cnt = 0;
 
 	CDEBUG(D_VFSTRACE, "VFS Op: superblock %p count %d active %d\n", sb,
 	       sb->s_count, atomic_read(&sb->s_active));
@@ -2021,10 +2020,10 @@ void ll_umount_begin(struct super_block *sb)
 	 * and then continue. For now, we just periodically checking for vfs
 	 * to decrement mnt_cnt and hope to finish it within 10sec.
 	 */
-	init_waitqueue_head(&waitq);
-	lwi = LWI_TIMEOUT_INTERVAL(10 * HZ,
-				   HZ, NULL, NULL);
-	l_wait_event(waitq, may_umount(sbi->ll_mnt.mnt), &lwi);
+	while (cnt < 10 && !may_umount(sbi->ll_mnt.mnt)) {
+		schedule_timeout_uninterruptible(HZ);
+		cnt ++;
+	}
 
 	schedule();
 }
diff --git a/drivers/staging/lustre/lustre/lov/lov_request.c b/drivers/staging/lustre/lustre/lov/lov_request.c
index fb3b7a7fa32a..c1e58fcc30b3 100644
--- a/drivers/staging/lustre/lustre/lov/lov_request.c
+++ b/drivers/staging/lustre/lustre/lov/lov_request.c
@@ -99,8 +99,7 @@ static int lov_check_set(struct lov_obd *lov, int idx)
  */
 static int lov_check_and_wait_active(struct lov_obd *lov, int ost_idx)
 {
-	wait_queue_head_t waitq;
-	struct l_wait_info lwi;
+	int cnt = 0;
 	struct lov_tgt_desc *tgt;
 	int rc = 0;
 
@@ -125,11 +124,10 @@ static int lov_check_and_wait_active(struct lov_obd *lov, int ost_idx)
 
 	mutex_unlock(&lov->lov_lock);
 
-	init_waitqueue_head(&waitq);
-	lwi = LWI_TIMEOUT_INTERVAL(obd_timeout * HZ,
-				   HZ, NULL, NULL);
-
-	rc = l_wait_event(waitq, lov_check_set(lov, ost_idx), &lwi);
+	while (cnt < obd_timeout && !lov_check_set(lov, ost_idx)) {
+		schedule_timeout_uninterruptible(HZ);
+		cnt ++;
+	}
 	if (tgt->ltd_active)
 		return 1;
 

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 09/19] staging: lustre: open code polling loop instead of using l_wait_event()
@ 2018-02-12 23:47   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

Two places that LWI_TIMEOUT_INTERVAL() is used, the outcome is a
simple polling loop that polls every second for some event (with a
limit).

So write a simple loop to make this more apparent.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/llite/llite_lib.c |   11 +++++------
 drivers/staging/lustre/lustre/lov/lov_request.c |   12 +++++-------
 2 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
index ccb614bd7f53..9e96a8ee1783 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -1984,8 +1984,7 @@ void ll_umount_begin(struct super_block *sb)
 	struct ll_sb_info *sbi = ll_s2sbi(sb);
 	struct obd_device *obd;
 	struct obd_ioctl_data *ioc_data;
-	wait_queue_head_t waitq;
-	struct l_wait_info lwi;
+	int cnt = 0;
 
 	CDEBUG(D_VFSTRACE, "VFS Op: superblock %p count %d active %d\n", sb,
 	       sb->s_count, atomic_read(&sb->s_active));
@@ -2021,10 +2020,10 @@ void ll_umount_begin(struct super_block *sb)
 	 * and then continue. For now, we just periodically checking for vfs
 	 * to decrement mnt_cnt and hope to finish it within 10sec.
 	 */
-	init_waitqueue_head(&waitq);
-	lwi = LWI_TIMEOUT_INTERVAL(10 * HZ,
-				   HZ, NULL, NULL);
-	l_wait_event(waitq, may_umount(sbi->ll_mnt.mnt), &lwi);
+	while (cnt < 10 && !may_umount(sbi->ll_mnt.mnt)) {
+		schedule_timeout_uninterruptible(HZ);
+		cnt ++;
+	}
 
 	schedule();
 }
diff --git a/drivers/staging/lustre/lustre/lov/lov_request.c b/drivers/staging/lustre/lustre/lov/lov_request.c
index fb3b7a7fa32a..c1e58fcc30b3 100644
--- a/drivers/staging/lustre/lustre/lov/lov_request.c
+++ b/drivers/staging/lustre/lustre/lov/lov_request.c
@@ -99,8 +99,7 @@ static int lov_check_set(struct lov_obd *lov, int idx)
  */
 static int lov_check_and_wait_active(struct lov_obd *lov, int ost_idx)
 {
-	wait_queue_head_t waitq;
-	struct l_wait_info lwi;
+	int cnt = 0;
 	struct lov_tgt_desc *tgt;
 	int rc = 0;
 
@@ -125,11 +124,10 @@ static int lov_check_and_wait_active(struct lov_obd *lov, int ost_idx)
 
 	mutex_unlock(&lov->lov_lock);
 
-	init_waitqueue_head(&waitq);
-	lwi = LWI_TIMEOUT_INTERVAL(obd_timeout * HZ,
-				   HZ, NULL, NULL);
-
-	rc = l_wait_event(waitq, lov_check_set(lov, ost_idx), &lwi);
+	while (cnt < obd_timeout && !lov_check_set(lov, ost_idx)) {
+		schedule_timeout_uninterruptible(HZ);
+		cnt ++;
+	}
 	if (tgt->ltd_active)
 		return 1;
 

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 10/19] staging: lustre: simplify waiting in ptlrpc_invalidate_import()
@ 2018-02-12 23:47   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

This waiter currently wakes up every second to re-test if
imp_flight is zero.  If we ensure wakeup is called whenever
imp_flight is decremented to zero, we can just have a simple
wait_event_idle_timeout().

So add a wake_up_all to the one place it is missing, and simplify
the wait_event.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/ptlrpc/client.c |    3 ++-
 drivers/staging/lustre/lustre/ptlrpc/import.c |   21 ++++++++-------------
 2 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index 0ab13f8e5993..81b7a7046d82 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -1588,7 +1588,8 @@ static int ptlrpc_send_new_req(struct ptlrpc_request *req)
 		spin_lock(&imp->imp_lock);
 		if (!list_empty(&req->rq_list)) {
 			list_del_init(&req->rq_list);
-			atomic_dec(&req->rq_import->imp_inflight);
+			if (atomic_dec_and_test(&req->rq_import->imp_inflight))
+				wake_up_all(&req->rq_import->imp_recovery_waitq);
 		}
 		spin_unlock(&imp->imp_lock);
 		ptlrpc_rqphase_move(req, RQ_PHASE_NEW);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c
index ed210550f61f..5d62c9de27eb 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/import.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/import.c
@@ -265,7 +265,6 @@ void ptlrpc_invalidate_import(struct obd_import *imp)
 {
 	struct list_head *tmp, *n;
 	struct ptlrpc_request *req;
-	struct l_wait_info lwi;
 	unsigned int timeout;
 	int rc;
 
@@ -306,19 +305,15 @@ void ptlrpc_invalidate_import(struct obd_import *imp)
 		 * callbacks. Cap it at obd_timeout -- these should all
 		 * have been locally cancelled by ptlrpc_abort_inflight.
 		 */
-		lwi = LWI_TIMEOUT_INTERVAL(
-			cfs_timeout_cap(timeout * HZ),
-			(timeout > 1) ? HZ :
-			HZ / 2,
-			NULL, NULL);
-		rc = l_wait_event(imp->imp_recovery_waitq,
-				  (atomic_read(&imp->imp_inflight) == 0),
-				  &lwi);
-		if (rc) {
+		rc = wait_event_idle_timeout(imp->imp_recovery_waitq,
+					     atomic_read(&imp->imp_inflight) == 0,
+					     obd_timeout * HZ);
+
+		if (rc == 0) {
 			const char *cli_tgt = obd2cli_tgt(imp->imp_obd);
 
-			CERROR("%s: rc = %d waiting for callback (%d != 0)\n",
-			       cli_tgt, rc,
+			CERROR("%s: timeout waiting for callback (%d != 0)\n",
+			       cli_tgt,
 			       atomic_read(&imp->imp_inflight));
 
 			spin_lock(&imp->imp_lock);
@@ -365,7 +360,7 @@ void ptlrpc_invalidate_import(struct obd_import *imp)
 			}
 			spin_unlock(&imp->imp_lock);
 		}
-	} while (rc != 0);
+	} while (rc == 0);
 
 	/*
 	 * Let's additionally check that no new rpcs added to import in

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 12/19] staging: lustre: make polling loop in ptlrpc_unregister_bulk more obvious
@ 2018-02-12 23:47   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

This use of l_wait_event() is a polling loop that re-checks
every second.  Make this more obvious with a while loop
and wait_event_idle_timeout().

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/ptlrpc/niobuf.c |   15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
index 0c2ded721c49..86883abaad2c 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/niobuf.c
@@ -229,7 +229,6 @@ int ptlrpc_unregister_bulk(struct ptlrpc_request *req, int async)
 {
 	struct ptlrpc_bulk_desc *desc = req->rq_bulk;
 	wait_queue_head_t *wq;
-	struct l_wait_info lwi;
 	int rc;
 
 	LASSERT(!in_interrupt());     /* might sleep */
@@ -246,7 +245,7 @@ int ptlrpc_unregister_bulk(struct ptlrpc_request *req, int async)
 
 	/* the unlink ensures the callback happens ASAP and is the last
 	 * one.  If it fails, it must be because completion just happened,
-	 * but we must still l_wait_event() in this case to give liblustre
+	 * but we must still wait_event() in this case to give liblustre
 	 * a chance to run client_bulk_callback()
 	 */
 	mdunlink_iterate_helper(desc->bd_mds, desc->bd_md_max_brw);
@@ -270,15 +269,17 @@ int ptlrpc_unregister_bulk(struct ptlrpc_request *req, int async)
 		/* Network access will complete in finite time but the HUGE
 		 * timeout lets us CWARN for visibility of sluggish LNDs
 		 */
-		lwi = LWI_TIMEOUT_INTERVAL(LONG_UNLINK * HZ,
-					   HZ, NULL, NULL);
-		rc = l_wait_event(*wq, !ptlrpc_client_bulk_active(req), &lwi);
-		if (rc == 0) {
+		int cnt = 0;
+		while (cnt < LONG_UNLINK &&
+		       (rc = wait_event_idle_timeout(*wq,
+						     !ptlrpc_client_bulk_active(req),
+						     HZ)) == 0)
+			cnt += 1;
+		if (rc > 0) {
 			ptlrpc_rqphase_move(req, req->rq_next_phase);
 			return 1;
 		}
 
-		LASSERT(rc == -ETIMEDOUT);
 		DEBUG_REQ(D_WARNING, req, "Unexpectedly long timeout: desc %p",
 			  desc);
 	}

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 11/19] staging: lustre: remove back_to_sleep()
@ 2018-02-12 23:47   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

When 'back_to_sleep()' is passed as the 'timeout' function,
the effect is to wait indefinitely for the event, polling
once after the timeout.
If LWI_ON_SIGNAL_NOOP is given, then after the timeout
we allow fatal signals to interrupt the wait.

Make this more obvious in both places "back_to_sleep()" is
used but using two explicit sleeps.

The code in ptlrpcd_add_req() looks odd - why not just have one
wait_event_idle()?  However I believe this is a faithful
transformation of the existing code.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |    4 ----
 drivers/staging/lustre/lustre/ptlrpc/import.c      |   11 ++++++-----
 drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c     |    9 +++++----
 3 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
index b2a64d0e682c..1939e959b92a 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -140,10 +140,6 @@ void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id);
  * XXX nikita: some ptlrpc daemon threads have races of that sort.
  *
  */
-static inline int back_to_sleep(void *arg)
-{
-	return 0;
-}
 
 #define LWI_ON_SIGNAL_NOOP ((void (*)(void *))(-1))
 
diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c
index 5d62c9de27eb..faf0f606f013 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/import.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/import.c
@@ -1496,7 +1496,6 @@ int ptlrpc_disconnect_import(struct obd_import *imp, int noclose)
 	}
 
 	if (ptlrpc_import_in_recovery(imp)) {
-		struct l_wait_info lwi;
 		long timeout;
 
 		if (AT_OFF) {
@@ -1510,10 +1509,12 @@ int ptlrpc_disconnect_import(struct obd_import *imp, int noclose)
 			timeout = at_get(&imp->imp_at.iat_service_estimate[idx]) * HZ;
 		}
 
-		lwi = LWI_TIMEOUT_INTR(cfs_timeout_cap(timeout),
-				       back_to_sleep, LWI_ON_SIGNAL_NOOP, NULL);
-		rc = l_wait_event(imp->imp_recovery_waitq,
-				  !ptlrpc_import_in_recovery(imp), &lwi);
+		if (wait_event_idle_timeout(imp->imp_recovery_waitq,
+					    !ptlrpc_import_in_recovery(imp),
+					    cfs_timeout_cap(timeout)) == 0)
+			l_wait_event_abortable(
+				imp->imp_recovery_waitq,
+				!ptlrpc_import_in_recovery(imp));
 	}
 
 	spin_lock(&imp->imp_lock);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
index dad2f9290f70..437b4b2a9072 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
@@ -230,12 +230,13 @@ void ptlrpcd_add_req(struct ptlrpc_request *req)
 
 	spin_lock(&req->rq_lock);
 	if (req->rq_invalid_rqset) {
-		struct l_wait_info lwi = LWI_TIMEOUT(5 * HZ,
-						     back_to_sleep, NULL);
-
 		req->rq_invalid_rqset = 0;
 		spin_unlock(&req->rq_lock);
-		l_wait_event(req->rq_set_waitq, !req->rq_set, &lwi);
+		if (wait_event_idle_timeout(req->rq_set_waitq,
+					    !req->rq_set,
+					    5 * HZ) == 0)
+			wait_event_idle(req->rq_set_waitq,
+					!req->rq_set);
 	} else if (req->rq_set) {
 		/* If we have a valid "rq_set", just reuse it to avoid double
 		 * linked.

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 13/19] staging: lustre: use wait_event_idle_timeout in ptlrpcd()
@ 2018-02-12 23:47   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

We can replace l_wait_event() with
wait_event_idle_timeout() here providing we call the
timeout function when wait_event_idle_timeout() returns zero.

As ptlrpc_expired_set() returns 1, the l_wait_event() aborts of the
first timeout.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/ptlrpc/client.c      |   12 ++++++++----
 .../staging/lustre/lustre/ptlrpc/ptlrpc_internal.h |    2 +-
 drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c     |    9 +++++----
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index 81b7a7046d82..f70176c6db08 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -2125,9 +2125,8 @@ int ptlrpc_expire_one_request(struct ptlrpc_request *req, int async_unlink)
  * Callback used when waiting on sets with l_wait_event.
  * Always returns 1.
  */
-int ptlrpc_expired_set(void *data)
+void ptlrpc_expired_set(struct ptlrpc_request_set *set)
 {
-	struct ptlrpc_request_set *set = data;
 	struct list_head *tmp;
 	time64_t now = ktime_get_real_seconds();
 
@@ -2156,7 +2155,12 @@ int ptlrpc_expired_set(void *data)
 		 */
 		ptlrpc_expire_one_request(req, 1);
 	}
+}
+static int ptlrpc_expired_set_void(void *data)
+{
+	struct ptlrpc_request_set *set = data;
 
+	ptlrpc_expired_set(set);
 	/*
 	 * When waiting for a whole set, we always break out of the
 	 * sleep so we can recalculate the timeout, or enable interrupts
@@ -2286,7 +2290,7 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 			 * so we allow interrupts during the timeout.
 			 */
 			lwi = LWI_TIMEOUT_INTR_ALL(HZ,
-						   ptlrpc_expired_set,
+						   ptlrpc_expired_set_void,
 						   ptlrpc_interrupted_set, set);
 		else
 			/*
@@ -2295,7 +2299,7 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 			 * complete, or an in-flight req times out.
 			 */
 			lwi = LWI_TIMEOUT((timeout ? timeout : 1) * HZ,
-					  ptlrpc_expired_set, set);
+					  ptlrpc_expired_set_void, set);
 
 		rc = l_wait_event(set->set_waitq, ptlrpc_check_set(NULL, set), &lwi);
 
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
index f9decbd1459d..b7a8d7537a66 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
@@ -68,7 +68,7 @@ void ptlrpc_request_cache_free(struct ptlrpc_request *req);
 void ptlrpc_init_xid(void);
 void ptlrpc_set_add_new_req(struct ptlrpcd_ctl *pc,
 			    struct ptlrpc_request *req);
-int ptlrpc_expired_set(void *data);
+void ptlrpc_expired_set(struct ptlrpc_request_set *set);
 int ptlrpc_set_next_timeout(struct ptlrpc_request_set *set);
 void ptlrpc_resend_req(struct ptlrpc_request *request);
 void ptlrpc_set_bulk_mbits(struct ptlrpc_request *req);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
index 437b4b2a9072..6ed77521d025 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
@@ -435,16 +435,17 @@ static int ptlrpcd(void *arg)
 	 * new_req_list and ptlrpcd_check() moves them into the set.
 	 */
 	do {
-		struct l_wait_info lwi;
 		int timeout;
 
 		timeout = ptlrpc_set_next_timeout(set);
-		lwi = LWI_TIMEOUT((timeout ? timeout : 1) * HZ,
-				  ptlrpc_expired_set, set);
 
 		lu_context_enter(&env.le_ctx);
 		lu_context_enter(env.le_ses);
-		l_wait_event(set->set_waitq, ptlrpcd_check(&env, pc), &lwi);
+		if (wait_event_idle_timeout(set->set_waitq,
+					    ptlrpcd_check(&env, pc),
+					    (timeout ? timeout : 1) * HZ) == 0)
+			ptlrpc_expired_set(set);
+
 		lu_context_exit(&env.le_ctx);
 		lu_context_exit(env.le_ses);
 

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 14/19] staging: lustre: improve waiting in sptlrpc_req_refresh_ctx
@ 2018-02-12 23:47   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

Replace l_wait_event with wait_event_idle_timeout() and call the
handler function explicitly.  This makes it more clear
what is happening.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/ptlrpc/sec.c |   34 ++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec.c b/drivers/staging/lustre/lustre/ptlrpc/sec.c
index 617e004d00f8..90e3b3022106 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec.c
@@ -554,9 +554,8 @@ int ctx_check_refresh(struct ptlrpc_cli_ctx *ctx)
 }
 
 static
-int ctx_refresh_timeout(void *data)
+int ctx_refresh_timeout(struct ptlrpc_request *req)
 {
-	struct ptlrpc_request *req = data;
 	int rc;
 
 	/* conn_cnt is needed in expire_one_request */
@@ -575,10 +574,8 @@ int ctx_refresh_timeout(void *data)
 }
 
 static
-void ctx_refresh_interrupt(void *data)
+void ctx_refresh_interrupt(struct ptlrpc_request *req)
 {
-	struct ptlrpc_request *req = data;
-
 	spin_lock(&req->rq_lock);
 	req->rq_intr = 1;
 	spin_unlock(&req->rq_lock);
@@ -611,7 +608,6 @@ int sptlrpc_req_refresh_ctx(struct ptlrpc_request *req, long timeout)
 {
 	struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx;
 	struct ptlrpc_sec *sec;
-	struct l_wait_info lwi;
 	int rc;
 
 	LASSERT(ctx);
@@ -743,10 +739,28 @@ int sptlrpc_req_refresh_ctx(struct ptlrpc_request *req, long timeout)
 	req->rq_restart = 0;
 	spin_unlock(&req->rq_lock);
 
-	lwi = LWI_TIMEOUT_INTR(msecs_to_jiffies(timeout * MSEC_PER_SEC),
-			       ctx_refresh_timeout, ctx_refresh_interrupt,
-			       req);
-	rc = l_wait_event(req->rq_reply_waitq, ctx_check_refresh(ctx), &lwi);
+	rc = wait_event_idle_timeout(req->rq_reply_waitq,
+				     ctx_check_refresh(ctx),
+				     timeout * HZ);
+	if (rc == 0 && ctx_refresh_timeout(req) == 0) {
+		/* Keep waiting, but enable some signals */
+		rc = l_wait_event_abortable(req->rq_reply_waitq,
+					    ctx_check_refresh(ctx));
+		if (rc == 0)
+			rc = 1;
+	}
+
+	if (rc > 0)
+		/* condition is true */
+		rc = 0;
+	else if (rc == 0)
+		/* Timed out */
+		rc = -ETIMEDOUT;
+	else {
+		/* Aborted by signal */
+		rc = -EINTR;
+		ctx_refresh_interrupt(req);
+	}
 
 	/*
 	 * following cases could lead us here:

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 17/19] staging: lustre: remove l_wait_event from ptlrpc_set_wait
@ 2018-02-12 23:47   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

This is the last remaining use of l_wait_event().
It is the only use of LWI_TIMEOUT_INTR_ALL() which
has a meaning that timeouts can be interrupted.
Only interrupts by "fatal" signals are allowed, so
introduce l_wait_event_abortable_timeout() to
support this.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |   14 +++
 drivers/staging/lustre/lustre/ptlrpc/client.c      |   84 ++++++++------------
 2 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
index 1939e959b92a..ccc1a329e42b 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -196,6 +196,10 @@ struct l_wait_info {
 #define LUSTRE_FATAL_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) |		\
 			   sigmask(SIGTERM) | sigmask(SIGQUIT) |	\
 			   sigmask(SIGALRM))
+static inline int l_fatal_signal_pending(struct task_struct *p)
+{
+	return signal_pending(p) && sigtestsetmask(&p->pending.signal, LUSTRE_FATAL_SIGS);
+}
 
 /**
  * wait_queue_entry_t of Linux (version < 2.6.34) is a FIFO list for exclusively
@@ -347,6 +351,16 @@ do {									   \
 	__ret;								\
 })
 
+#define l_wait_event_abortable_timeout(wq, condition, timeout)		\
+({									\
+	sigset_t __blocked;						\
+	int __ret = 0;							\
+	__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);		\
+	__ret = wait_event_interruptible_timeout(wq, condition, timeout);\
+	cfs_restore_sigs(__blocked);					\
+	__ret;								\
+})
+
 #define l_wait_event_abortable_exclusive(wq, condition)			\
 ({									\
 	sigset_t __blocked;						\
diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index ffdd3ffd62c6..3d689d6100bc 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -1774,7 +1774,7 @@ int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set)
 		}
 
 		/*
-		 * ptlrpc_set_wait->l_wait_event sets lwi_allow_intr
+		 * ptlrpc_set_wait allow signal to abort the timeout
 		 * so it sets rq_intr regardless of individual rpc
 		 * timeouts. The synchronous IO waiting path sets
 		 * rq_intr irrespective of whether ptlrpcd
@@ -2122,8 +2122,7 @@ int ptlrpc_expire_one_request(struct ptlrpc_request *req, int async_unlink)
 
 /**
  * Time out all uncompleted requests in request set pointed by \a data
- * Callback used when waiting on sets with l_wait_event.
- * Always returns 1.
+ * Called when wait_event_idle_timeout times out.
  */
 void ptlrpc_expired_set(struct ptlrpc_request_set *set)
 {
@@ -2156,18 +2155,6 @@ void ptlrpc_expired_set(struct ptlrpc_request_set *set)
 		ptlrpc_expire_one_request(req, 1);
 	}
 }
-static int ptlrpc_expired_set_void(void *data)
-{
-	struct ptlrpc_request_set *set = data;
-
-	ptlrpc_expired_set(set);
-	/*
-	 * When waiting for a whole set, we always break out of the
-	 * sleep so we can recalculate the timeout, or enable interrupts
-	 * if everyone's timed out.
-	 */
-	return 1;
-}
 
 /**
  * Sets rq_intr flag in \a req under spinlock.
@@ -2182,11 +2169,10 @@ EXPORT_SYMBOL(ptlrpc_mark_interrupted);
 
 /**
  * Interrupts (sets interrupted flag) all uncompleted requests in
- * a set \a data. Callback for l_wait_event for interruptible waits.
+ * a set \a data. Called when l_wait_event_abortable_timeout receives signal.
  */
-static void ptlrpc_interrupted_set(void *data)
+static void ptlrpc_interrupted_set(struct ptlrpc_request_set *set)
 {
-	struct ptlrpc_request_set *set = data;
 	struct list_head *tmp;
 
 	CDEBUG(D_RPCTRACE, "INTERRUPTED SET %p\n", set);
@@ -2256,7 +2242,6 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 {
 	struct list_head *tmp;
 	struct ptlrpc_request *req;
-	struct l_wait_info lwi;
 	int rc, timeout;
 
 	if (set->set_producer)
@@ -2282,46 +2267,47 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set)
 		CDEBUG(D_RPCTRACE, "set %p going to sleep for %d seconds\n",
 		       set, timeout);
 
-		if (timeout == 0 && !signal_pending(current))
+		if (timeout == 0 && !signal_pending(current)) {
 			/*
 			 * No requests are in-flight (ether timed out
 			 * or delayed), so we can allow interrupts.
 			 * We still want to block for a limited time,
 			 * so we allow interrupts during the timeout.
 			 */
-			lwi = LWI_TIMEOUT_INTR_ALL(HZ,
-						   ptlrpc_expired_set_void,
-						   ptlrpc_interrupted_set, set);
-		else
+			rc = l_wait_event_abortable_timeout(set->set_waitq,
+							    ptlrpc_check_set(NULL, set),
+							    HZ);
+			if (rc == 0) {
+				rc = -ETIMEDOUT;
+				ptlrpc_expired_set(set);
+			} else if (rc < 0) {
+				rc = -EINTR;
+				ptlrpc_interrupted_set(set);
+			} else
+				rc = 0;
+		} else {
 			/*
 			 * At least one request is in flight, so no
 			 * interrupts are allowed. Wait until all
 			 * complete, or an in-flight req times out.
 			 */
-			lwi = LWI_TIMEOUT((timeout ? timeout : 1) * HZ,
-					  ptlrpc_expired_set_void, set);
-
-		rc = l_wait_event(set->set_waitq, ptlrpc_check_set(NULL, set), &lwi);
-
-		/*
-		 * LU-769 - if we ignored the signal because it was already
-		 * pending when we started, we need to handle it now or we risk
-		 * it being ignored forever
-		 */
-		if (rc == -ETIMEDOUT && !lwi.lwi_allow_intr &&
-		    signal_pending(current)) {
-			sigset_t blocked_sigs =
-					   cfs_block_sigsinv(LUSTRE_FATAL_SIGS);
-
-			/*
-			 * In fact we only interrupt for the "fatal" signals
-			 * like SIGINT or SIGKILL. We still ignore less
-			 * important signals since ptlrpc set is not easily
-			 * reentrant from userspace again
-			 */
-			if (signal_pending(current))
-				ptlrpc_interrupted_set(set);
-			cfs_restore_sigs(blocked_sigs);
+			rc = wait_event_idle_timeout(set->set_waitq,
+						     ptlrpc_check_set(NULL, set),
+						     (timeout ? timeout : 1) * HZ);
+			if (rc == 0) {
+				ptlrpc_expired_set(set);
+				rc = -ETIMEDOUT;
+				/*
+				 * LU-769 - if we ignored the signal
+				 * because it was already pending when
+				 * we started, we need to handle it
+				 * now or we risk it being ignored
+				 * forever
+				 */
+				if (l_fatal_signal_pending(current))
+					ptlrpc_interrupted_set(set);
+			} else
+				rc = 0;
 		}
 
 		LASSERT(rc == 0 || rc == -EINTR || rc == -ETIMEDOUT);
@@ -2528,7 +2514,7 @@ static int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async)
 		return 0;
 
 	/*
-	 * We have to l_wait_event() whatever the result, to give liblustre
+	 * We have to wait_event_idle_timeout() whatever the result, to give liblustre
 	 * a chance to run reply_in_callback(), and to make sure we've
 	 * unlinked before returning a req to the pool.
 	 */

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 16/19] staging: lustre: use explicit poll loop in ptlrpc_unregister_reply
@ 2018-02-12 23:47   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

replace l_wait_event() with wait_event_idle_timeout() and explicit
loop.  This approach is easier to understand.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/ptlrpc/client.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index f70176c6db08..ffdd3ffd62c6 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -2500,7 +2500,6 @@ static int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async)
 {
 	int rc;
 	wait_queue_head_t *wq;
-	struct l_wait_info lwi;
 
 	/* Might sleep. */
 	LASSERT(!in_interrupt());
@@ -2543,16 +2542,17 @@ static int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async)
 		 * Network access will complete in finite time but the HUGE
 		 * timeout lets us CWARN for visibility of sluggish NALs
 		 */
-		lwi = LWI_TIMEOUT_INTERVAL(LONG_UNLINK * HZ,
-					   HZ, NULL, NULL);
-		rc = l_wait_event(*wq, !ptlrpc_client_recv_or_unlink(request),
-				  &lwi);
-		if (rc == 0) {
+		int cnt = 0;
+		while (cnt < LONG_UNLINK &&
+		       (rc = wait_event_idle_timeout(*wq,
+						     !ptlrpc_client_recv_or_unlink(request),
+						     HZ)) == 0)
+			cnt += 1;
+		if (rc > 0) {
 			ptlrpc_rqphase_move(request, request->rq_next_phase);
 			return 1;
 		}
 
-		LASSERT(rc == -ETIMEDOUT);
 		DEBUG_REQ(D_WARNING, request,
 			  "Unexpectedly long timeout receiving_reply=%d req_ulinked=%d reply_unlinked=%d",
 			  request->rq_receiving_reply,

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 18/19] staging: lustre: replace l_wait_event_exclusive_head() with wait_event_idle_exclusive
@ 2018-02-12 23:47   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

This l_wait_event_exclusive_head() will wait indefinitely
if the timeout is zero.  If it does wait with a timeout
and times out, the timeout for next time is set to zero.

The can be mapped to a call to either
 wait_event_idle_exclusive()
or
 wait_event_idle_exclusive_timeout()
depending in the timeout setting.

The current code arranges for LIFO queuing of waiters,
but include/event.h doesn't support that yet.
Until it does, fall back on FIFO with
wait_event_idle_exclusive{,_timeout}().

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/ptlrpc/service.c |   43 ++++++++++++++----------
 1 file changed, 25 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
index 6e3403417434..29fdb54f16ca 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -1897,15 +1897,6 @@ ptlrpc_check_rqbd_pool(struct ptlrpc_service_part *svcpt)
 	}
 }
 
-static int
-ptlrpc_retry_rqbds(void *arg)
-{
-	struct ptlrpc_service_part *svcpt = arg;
-
-	svcpt->scp_rqbd_timeout = 0;
-	return -ETIMEDOUT;
-}
-
 static inline int
 ptlrpc_threads_enough(struct ptlrpc_service_part *svcpt)
 {
@@ -1968,13 +1959,17 @@ ptlrpc_server_request_incoming(struct ptlrpc_service_part *svcpt)
 	return !list_empty(&svcpt->scp_req_incoming);
 }
 
+/* We perfer lifo queuing, but kernel doesn't provide that yet. */
+#ifndef wait_event_idle_exclusive_lifo
+#define wait_event_idle_exclusive_lifo wait_event_idle_exclusive
+#define wait_event_idle_exclusive_lifo_timeout wait_event_idle_exclusive_timeout
+#endif
+
 static __attribute__((__noinline__)) int
 ptlrpc_wait_event(struct ptlrpc_service_part *svcpt,
 		  struct ptlrpc_thread *thread)
 {
 	/* Don't exit while there are replies to be handled */
-	struct l_wait_info lwi = LWI_TIMEOUT(svcpt->scp_rqbd_timeout,
-					     ptlrpc_retry_rqbds, svcpt);
 
 	/* XXX: Add this back when libcfs watchdog is merged upstream
 	lc_watchdog_disable(thread->t_watchdog);
@@ -1982,13 +1977,25 @@ ptlrpc_wait_event(struct ptlrpc_service_part *svcpt,
 
 	cond_resched();
 
-	l_wait_event_exclusive_head(svcpt->scp_waitq,
-				    ptlrpc_thread_stopping(thread) ||
-				    ptlrpc_server_request_incoming(svcpt) ||
-				    ptlrpc_server_request_pending(svcpt,
-								  false) ||
-				    ptlrpc_rqbd_pending(svcpt) ||
-				    ptlrpc_at_check(svcpt), &lwi);
+	if (svcpt->scp_rqbd_timeout == 0)
+		wait_event_idle_exclusive_lifo(
+			svcpt->scp_waitq,
+			ptlrpc_thread_stopping(thread) ||
+			ptlrpc_server_request_incoming(svcpt) ||
+			ptlrpc_server_request_pending(svcpt,
+						      false) ||
+			ptlrpc_rqbd_pending(svcpt) ||
+			ptlrpc_at_check(svcpt));
+	else if (0 == wait_event_idle_exclusive_lifo_timeout(
+			 svcpt->scp_waitq,
+			 ptlrpc_thread_stopping(thread) ||
+			 ptlrpc_server_request_incoming(svcpt) ||
+			 ptlrpc_server_request_pending(svcpt,
+						       false) ||
+			 ptlrpc_rqbd_pending(svcpt) ||
+			 ptlrpc_at_check(svcpt),
+			 svcpt->scp_rqbd_timeout))
+		svcpt->scp_rqbd_timeout = 0;
 
 	if (ptlrpc_thread_stopping(thread))
 		return -EINTR;

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 15/19] staging: lustre: use explicit poll loop in ptlrpc_service_unlink_rqbd
@ 2018-02-12 23:47   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

Rather an using l_wait_event(), use wait_event_idle_timeout()
with an explicit loop so it is easier to see what is happening.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/ptlrpc/service.c |   15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
index 5c41297d23d2..6e3403417434 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -2618,7 +2618,7 @@ ptlrpc_service_unlink_rqbd(struct ptlrpc_service *svc)
 {
 	struct ptlrpc_service_part *svcpt;
 	struct ptlrpc_request_buffer_desc *rqbd;
-	struct l_wait_info lwi;
+	int cnt;
 	int rc;
 	int i;
 
@@ -2658,12 +2658,13 @@ ptlrpc_service_unlink_rqbd(struct ptlrpc_service *svc)
 			 * the HUGE timeout lets us CWARN for visibility
 			 * of sluggish LNDs
 			 */
-			lwi = LWI_TIMEOUT_INTERVAL(
-					LONG_UNLINK * HZ,
-					HZ, NULL, NULL);
-			rc = l_wait_event(svcpt->scp_waitq,
-					  svcpt->scp_nrqbds_posted == 0, &lwi);
-			if (rc == -ETIMEDOUT) {
+			cnt = 0;
+			while (cnt < LONG_UNLINK &&
+			       (rc = wait_event_idle_timeout(svcpt->scp_waitq,
+							     svcpt->scp_nrqbds_posted == 0,
+							     HZ)) == 0)
+				cnt ++;
+			if (rc == 0) {
 				CWARN("Service %s waiting for request buffers\n",
 				      svcpt->scp_service->srv_name);
 			}

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 19/19] staging: lustre: remove l_wait_event() and related code
@ 2018-02-12 23:47   ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:47 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

These macros are no longer used, so they can
be removed.

Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/include/lustre_lib.h |  249 --------------------
 1 file changed, 249 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
index ccc1a329e42b..1efd86f18c1f 100644
--- a/drivers/staging/lustre/lustre/include/lustre_lib.h
+++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
@@ -76,123 +76,6 @@ int do_set_info_async(struct obd_import *imp,
 
 void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id);
 
-/*
- * l_wait_event is a flexible sleeping function, permitting simple caller
- * configuration of interrupt and timeout sensitivity along with actions to
- * be performed in the event of either exception.
- *
- * The first form of usage looks like this:
- *
- * struct l_wait_info lwi = LWI_TIMEOUT_INTR(timeout, timeout_handler,
- *					   intr_handler, callback_data);
- * rc = l_wait_event(waitq, condition, &lwi);
- *
- * l_wait_event() makes the current process wait on 'waitq' until 'condition'
- * is TRUE or a "killable" signal (SIGTERM, SIKGILL, SIGINT) is pending.  It
- * returns 0 to signify 'condition' is TRUE, but if a signal wakes it before
- * 'condition' becomes true, it optionally calls the specified 'intr_handler'
- * if not NULL, and returns -EINTR.
- *
- * If a non-zero timeout is specified, signals are ignored until the timeout
- * has expired.  At this time, if 'timeout_handler' is not NULL it is called.
- * If it returns FALSE l_wait_event() continues to wait as described above with
- * signals enabled.  Otherwise it returns -ETIMEDOUT.
- *
- * LWI_INTR(intr_handler, callback_data) is shorthand for
- * LWI_TIMEOUT_INTR(0, NULL, intr_handler, callback_data)
- *
- * The second form of usage looks like this:
- *
- * struct l_wait_info lwi = LWI_TIMEOUT(timeout, timeout_handler);
- * rc = l_wait_event(waitq, condition, &lwi);
- *
- * This form is the same as the first except that it COMPLETELY IGNORES
- * SIGNALS.  The caller must therefore beware that if 'timeout' is zero, or if
- * 'timeout_handler' is not NULL and returns FALSE, then the ONLY thing that
- * can unblock the current process is 'condition' becoming TRUE.
- *
- * Another form of usage is:
- * struct l_wait_info lwi = LWI_TIMEOUT_INTERVAL(timeout, interval,
- *					       timeout_handler);
- * rc = l_wait_event(waitq, condition, &lwi);
- * This is the same as previous case, but condition is checked once every
- * 'interval' jiffies (if non-zero).
- *
- * Subtle synchronization point: this macro does *not* necessary takes
- * wait-queue spin-lock before returning, and, hence, following idiom is safe
- * ONLY when caller provides some external locking:
- *
- *	     Thread1			    Thread2
- *
- *   l_wait_event(&obj->wq, ....);				       (1)
- *
- *				    wake_up(&obj->wq):		 (2)
- *					 spin_lock(&q->lock);	  (2.1)
- *					 __wake_up_common(q, ...);     (2.2)
- *					 spin_unlock(&q->lock, flags); (2.3)
- *
- *   kfree(obj);						  (3)
- *
- * As l_wait_event() may "short-cut" execution and return without taking
- * wait-queue spin-lock, some additional synchronization is necessary to
- * guarantee that step (3) can begin only after (2.3) finishes.
- *
- * XXX nikita: some ptlrpc daemon threads have races of that sort.
- *
- */
-
-#define LWI_ON_SIGNAL_NOOP ((void (*)(void *))(-1))
-
-struct l_wait_info {
-	long lwi_timeout;
-	long lwi_interval;
-	int	    lwi_allow_intr;
-	int  (*lwi_on_timeout)(void *);
-	void (*lwi_on_signal)(void *);
-	void  *lwi_cb_data;
-};
-
-/* NB: LWI_TIMEOUT ignores signals completely */
-#define LWI_TIMEOUT(time, cb, data)	     \
-((struct l_wait_info) {			 \
-	.lwi_timeout    = time,		 \
-	.lwi_on_timeout = cb,		   \
-	.lwi_cb_data    = data,		 \
-	.lwi_interval   = 0,		    \
-	.lwi_allow_intr = 0		     \
-})
-
-#define LWI_TIMEOUT_INTERVAL(time, interval, cb, data)  \
-((struct l_wait_info) {				 \
-	.lwi_timeout    = time,			 \
-	.lwi_on_timeout = cb,			   \
-	.lwi_cb_data    = data,			 \
-	.lwi_interval   = interval,		     \
-	.lwi_allow_intr = 0			     \
-})
-
-#define LWI_TIMEOUT_INTR(time, time_cb, sig_cb, data)   \
-((struct l_wait_info) {				 \
-	.lwi_timeout    = time,			 \
-	.lwi_on_timeout = time_cb,		      \
-	.lwi_on_signal  = sig_cb,		       \
-	.lwi_cb_data    = data,			 \
-	.lwi_interval   = 0,			    \
-	.lwi_allow_intr = 0			     \
-})
-
-#define LWI_TIMEOUT_INTR_ALL(time, time_cb, sig_cb, data)       \
-((struct l_wait_info) {					 \
-	.lwi_timeout    = time,				 \
-	.lwi_on_timeout = time_cb,			      \
-	.lwi_on_signal  = sig_cb,			       \
-	.lwi_cb_data    = data,				 \
-	.lwi_interval   = 0,				    \
-	.lwi_allow_intr = 1				     \
-})
-
-#define LWI_INTR(cb, data)  LWI_TIMEOUT_INTR(0, NULL, cb, data)
-
 #define LUSTRE_FATAL_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) |		\
 			   sigmask(SIGTERM) | sigmask(SIGQUIT) |	\
 			   sigmask(SIGALRM))
@@ -201,138 +84,6 @@ static inline int l_fatal_signal_pending(struct task_struct *p)
 	return signal_pending(p) && sigtestsetmask(&p->pending.signal, LUSTRE_FATAL_SIGS);
 }
 
-/**
- * wait_queue_entry_t of Linux (version < 2.6.34) is a FIFO list for exclusively
- * waiting threads, which is not always desirable because all threads will
- * be waken up again and again, even user only needs a few of them to be
- * active most time. This is not good for performance because cache can
- * be polluted by different threads.
- *
- * LIFO list can resolve this problem because we always wakeup the most
- * recent active thread by default.
- *
- * NB: please don't call non-exclusive & exclusive wait on the same
- * waitq if add_wait_queue_exclusive_head is used.
- */
-#define add_wait_queue_exclusive_head(waitq, link)		\
-{								\
-	unsigned long flags;					\
-								\
-	spin_lock_irqsave(&((waitq)->lock), flags);		\
-	__add_wait_queue_exclusive(waitq, link);		\
-	spin_unlock_irqrestore(&((waitq)->lock), flags);	\
-}
-
-/*
- * wait for @condition to become true, but no longer than timeout, specified
- * by @info.
- */
-#define __l_wait_event(wq, condition, info, ret, l_add_wait)		   \
-do {									   \
-	wait_queue_entry_t __wait;						 \
-	long __timeout = info->lwi_timeout;			  \
-	sigset_t   __blocked;					      \
-	int   __allow_intr = info->lwi_allow_intr;			     \
-									       \
-	ret = 0;							       \
-	if (condition)							 \
-		break;							 \
-									       \
-	init_waitqueue_entry(&__wait, current);					    \
-	l_add_wait(&wq, &__wait);					      \
-									       \
-	/* Block all signals (just the non-fatal ones if no timeout). */       \
-	if (info->lwi_on_signal && (__timeout == 0 || __allow_intr))   \
-		__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);	      \
-	else								   \
-		__blocked = cfs_block_sigsinv(0);			      \
-									       \
-	for (;;) {							     \
-		if (condition)						 \
-			break;						 \
-									       \
-		set_current_state(TASK_INTERRUPTIBLE);			       \
-									       \
-		if (__timeout == 0) {					  \
-			schedule();					       \
-		} else {						       \
-			long interval = info->lwi_interval ?	  \
-					     min_t(long,	     \
-						 info->lwi_interval, __timeout) : \
-					     __timeout;			\
-			long remaining = schedule_timeout(interval);\
-			__timeout = cfs_time_sub(__timeout,		    \
-					    cfs_time_sub(interval, remaining));\
-			if (__timeout == 0) {				  \
-				if (!info->lwi_on_timeout ||		      \
-				    info->lwi_on_timeout(info->lwi_cb_data)) { \
-					ret = -ETIMEDOUT;		      \
-					break;				 \
-				}					      \
-				/* Take signals after the timeout expires. */  \
-				if (info->lwi_on_signal)		       \
-				    (void)cfs_block_sigsinv(LUSTRE_FATAL_SIGS);\
-			}						      \
-		}							      \
-									       \
-		set_current_state(TASK_RUNNING);			       \
-									       \
-		if (condition)						 \
-			break;						 \
-		if (signal_pending(current)) {				    \
-			if (info->lwi_on_signal &&		     \
-			    (__timeout == 0 || __allow_intr)) {		\
-				if (info->lwi_on_signal != LWI_ON_SIGNAL_NOOP) \
-					info->lwi_on_signal(info->lwi_cb_data);\
-				ret = -EINTR;				  \
-				break;					 \
-			}						      \
-			/* We have to do this here because some signals */     \
-			/* are not blockable - ie from strace(1).       */     \
-			/* In these cases we want to schedule_timeout() */     \
-			/* again, because we don't want that to return  */     \
-			/* -EINTR when the RPC actually succeeded.      */     \
-			/* the recalc_sigpending() below will deliver the */     \
-			/* signal properly.			     */     \
-			cfs_clear_sigpending();				\
-		}							      \
-	}								      \
-									       \
-	cfs_restore_sigs(__blocked);					   \
-									       \
-	remove_wait_queue(&wq, &__wait);					   \
-} while (0)
-
-#define l_wait_event(wq, condition, info)		       \
-({							      \
-	int		 __ret;			      \
-	struct l_wait_info *__info = (info);		    \
-								\
-	__l_wait_event(wq, condition, __info,		   \
-		       __ret, add_wait_queue);		   \
-	__ret;						  \
-})
-
-#define l_wait_event_exclusive(wq, condition, info)	     \
-({							      \
-	int		 __ret;			      \
-	struct l_wait_info *__info = (info);		    \
-								\
-	__l_wait_event(wq, condition, __info,		   \
-		       __ret, add_wait_queue_exclusive);	 \
-	__ret;						  \
-})
-
-#define l_wait_event_exclusive_head(wq, condition, info)	\
-({							      \
-	int		 __ret;			      \
-	struct l_wait_info *__info = (info);		    \
-								\
-	__l_wait_event(wq, condition, __info,		   \
-		       __ret, add_wait_queue_exclusive_head);    \
-	__ret;						  \
-})
-
 /** @} lib */
 
 

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [lustre-devel] [PATCH 06/19] staging: lustre: introduce and use l_wait_event_abortable()
  2018-02-12 21:36     ` Patrick Farrell
@ 2018-02-12 23:58       ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:58 UTC (permalink / raw)
  To: Patrick Farrell, Oleg Drokin, Andreas Dilger, James Simmons,
	Greg Kroah-Hartman
  Cc: lkml, lustre

[-- Attachment #1: Type: text/plain, Size: 11656 bytes --]

On Mon, Feb 12 2018, Patrick Farrell wrote:

> It's worth noting that the change from -EINTR to -ERESTARTSYS will
> modify the behavior of userspace slightly.  Specifically, when a
> signal handler is setup with retry set (SA_RESTART flag set), the
> syscall will be restarted rather than aborted.

Thanks for the review.
This state is true if the error status ever gets all the way up to user
space.  I don't think it does, though I haven't carefully audited every
l_wait_event_abortable() call site.  I did look at a few and the return
value is only used locally in the same function.
I suspect I would have checked for error codes escaping when I wrote
the patch, but I don't have a clear memory.

Some sort of audit wouldn't hurt of course.

Thanks,
NeilBrown


>
> This should be fine.  It may eventually shake out some stuble bugs in Lustre when we abort an operation and then restart it from a point where we didn't in the past - past instances where we changed from -EINTR to -ERESTARTSYS certainly have - but it's for the best.  As I understand it from past conversations with Andreas and others, Lustre is not really intending to claim it's not restartable, it's just an artifact of people copying older code that was written without awareness of the difference in EINTR vs ERESTARTSYS.
>
> Ideally someone should go through and audit the remaining uses of -EINTR and replace most of them with -ERESTARTSYS.
>
> James, maybe you want to add that to the TODO list?
>
> On 2/12/18, 3:24 PM, "lustre-devel on behalf of NeilBrown" <lustre-devel-bounces@lists.lustre.org on behalf of neilb@suse.com> wrote:
>
>     lustre sometimes wants to wait for an event, but abort if
>     one of a specific list of signals arrives.  This is a little
>     bit like wait_event_killable(), except that the signals are
>     identified a different way.
>     
>     So introduce l_wait_event_abortable() which provides this
>     functionality.
>     Having separate functions for separate needs is more in line
>     with the pattern set by include/linux/wait.h, than having a
>     single function which tries to include all possible needs.
>     
>     Also introduce l_wait_event_abortable_exclusive().
>     
>     Note that l_wait_event() return -EINTR on a signal, while
>     Linux wait_event functions return -ERESTARTSYS.
>     l_wait_event_{abortable_,}exclusive follow the Linux pattern.
>     
>     Reviewed-by: James Simmons <jsimmons@infradead.org>
>     Signed-off-by: NeilBrown <neilb@suse.com>
>     ---
>      drivers/staging/lustre/lustre/include/lustre_lib.h |   24 ++++++++++++++++++++
>      drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |   12 +++++-----
>      drivers/staging/lustre/lustre/llite/llite_lib.c    |   12 +++-------
>      drivers/staging/lustre/lustre/obdclass/genops.c    |    9 +++-----
>      drivers/staging/lustre/lustre/obdclass/llog_obd.c  |    5 ++--
>      drivers/staging/lustre/lustre/osc/osc_page.c       |    6 ++---
>      drivers/staging/lustre/lustre/osc/osc_request.c    |    6 ++---
>      7 files changed, 43 insertions(+), 31 deletions(-)
>     
>     diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
>     index 7d950c53e962..b2a64d0e682c 100644
>     --- a/drivers/staging/lustre/lustre/include/lustre_lib.h
>     +++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
>     @@ -336,4 +336,28 @@ do {									   \
>      /** @} lib */
>      
>      
>     +
>     +/* l_wait_event_abortable() is a bit like wait_event_killable()
>     + * except there is a fixed set of signals which will abort:
>     + * LUSTRE_FATAL_SIGS
>     + */
>     +#define l_wait_event_abortable(wq, condition)				\
>     +({									\
>     +	sigset_t __blocked;						\
>     +	int __ret = 0;							\
>     +	__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);		\
>     +	__ret = wait_event_interruptible(wq, condition);		\
>     +	cfs_restore_sigs(__blocked);					\
>     +	__ret;								\
>     +})
>     +
>     +#define l_wait_event_abortable_exclusive(wq, condition)			\
>     +({									\
>     +	sigset_t __blocked;						\
>     +	int __ret = 0;							\
>     +	__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);		\
>     +	__ret = wait_event_interruptible_exclusive(wq, condition);	\
>     +	cfs_restore_sigs(__blocked);					\
>     +	__ret;								\
>     +})
>      #endif /* _LUSTRE_LIB_H */
>     diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
>     index 2e66825c8f4b..4c44603ab6f9 100644
>     --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
>     +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
>     @@ -879,7 +879,6 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, int force)
>      	ldlm_namespace_cleanup(ns, force ? LDLM_FL_LOCAL_ONLY : 0);
>      
>      	if (atomic_read(&ns->ns_bref) > 0) {
>     -		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
>      		int rc;
>      
>      		CDEBUG(D_DLMTRACE,
>     @@ -887,11 +886,12 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, int force)
>      		       ldlm_ns_name(ns), atomic_read(&ns->ns_bref));
>      force_wait:
>      		if (force)
>     -			lwi = LWI_TIMEOUT(msecs_to_jiffies(obd_timeout *
>     -					  MSEC_PER_SEC) / 4, NULL, NULL);
>     -
>     -		rc = l_wait_event(ns->ns_waitq,
>     -				  atomic_read(&ns->ns_bref) == 0, &lwi);
>     +			rc = wait_event_idle_timeout(ns->ns_waitq,
>     +						     atomic_read(&ns->ns_bref) == 0,
>     +						     obd_timeout * HZ / 4) ? 0 : -ETIMEDOUT;
>     +		else
>     +			rc = l_wait_event_abortable(ns->ns_waitq,
>     +						    atomic_read(&ns->ns_bref) == 0);
>      
>      		/* Forced cleanups should be able to reclaim all references,
>      		 * so it's safe to wait forever... we can't leak locks...
>     diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
>     index c820b201af71..ccb614bd7f53 100644
>     --- a/drivers/staging/lustre/lustre/llite/llite_lib.c
>     +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
>     @@ -986,16 +986,12 @@ void ll_put_super(struct super_block *sb)
>      	}
>      
>      	/* Wait for unstable pages to be committed to stable storage */
>     -	if (!force) {
>     -		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
>     -
>     -		rc = l_wait_event(sbi->ll_cache->ccc_unstable_waitq,
>     -				  !atomic_long_read(&sbi->ll_cache->ccc_unstable_nr),
>     -				  &lwi);
>     -	}
>     +	if (!force)
>     +		rc = l_wait_event_abortable(sbi->ll_cache->ccc_unstable_waitq,
>     +					    !atomic_long_read(&sbi->ll_cache->ccc_unstable_nr));
>      
>      	ccc_count = atomic_long_read(&sbi->ll_cache->ccc_unstable_nr);
>     -	if (!force && rc != -EINTR)
>     +	if (!force && rc != -ERESTARTSYS)
>      		LASSERTF(!ccc_count, "count: %li\n", ccc_count);
>      
>      	/* We need to set force before the lov_disconnect in
>     diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
>     index 3ff25b8d3b48..8f776a4058a9 100644
>     --- a/drivers/staging/lustre/lustre/obdclass/genops.c
>     +++ b/drivers/staging/lustre/lustre/obdclass/genops.c
>     @@ -1332,7 +1332,6 @@ static bool obd_request_slot_avail(struct client_obd *cli,
>      int obd_get_request_slot(struct client_obd *cli)
>      {
>      	struct obd_request_slot_waiter orsw;
>     -	struct l_wait_info lwi;
>      	int rc;
>      
>      	spin_lock(&cli->cl_loi_list_lock);
>     @@ -1347,11 +1346,9 @@ int obd_get_request_slot(struct client_obd *cli)
>      	orsw.orsw_signaled = false;
>      	spin_unlock(&cli->cl_loi_list_lock);
>      
>     -	lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
>     -	rc = l_wait_event(orsw.orsw_waitq,
>     -			  obd_request_slot_avail(cli, &orsw) ||
>     -			  orsw.orsw_signaled,
>     -			  &lwi);
>     +	rc = l_wait_event_abortable(orsw.orsw_waitq,
>     +				    obd_request_slot_avail(cli, &orsw) ||
>     +				    orsw.orsw_signaled);
>      
>      	/*
>      	 * Here, we must take the lock to avoid the on-stack 'orsw' to be
>     diff --git a/drivers/staging/lustre/lustre/obdclass/llog_obd.c b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
>     index 28bbaa2136ac..26aea114a29b 100644
>     --- a/drivers/staging/lustre/lustre/obdclass/llog_obd.c
>     +++ b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
>     @@ -104,7 +104,6 @@ EXPORT_SYMBOL(__llog_ctxt_put);
>      
>      int llog_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt)
>      {
>     -	struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
>      	struct obd_llog_group *olg;
>      	int rc, idx;
>      
>     @@ -129,8 +128,8 @@ int llog_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt)
>      		CERROR("Error %d while cleaning up ctxt %p\n",
>      		       rc, ctxt);
>      
>     -	l_wait_event(olg->olg_waitq,
>     -		     llog_group_ctxt_null(olg, idx), &lwi);
>     +	l_wait_event_abortable(olg->olg_waitq,
>     +			     llog_group_ctxt_null(olg, idx));
>      
>      	return rc;
>      }
>     diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c
>     index 20094b6309f9..6fdd521feb21 100644
>     --- a/drivers/staging/lustre/lustre/osc/osc_page.c
>     +++ b/drivers/staging/lustre/lustre/osc/osc_page.c
>     @@ -759,7 +759,6 @@ static long osc_lru_reclaim(struct client_obd *cli, unsigned long npages)
>      static int osc_lru_alloc(const struct lu_env *env, struct client_obd *cli,
>      			 struct osc_page *opg)
>      {
>     -	struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
>      	struct osc_io *oio = osc_env_io(env);
>      	int rc = 0;
>      
>     @@ -782,9 +781,8 @@ static int osc_lru_alloc(const struct lu_env *env, struct client_obd *cli,
>      
>      		cond_resched();
>      
>     -		rc = l_wait_event(osc_lru_waitq,
>     -				  atomic_long_read(cli->cl_lru_left) > 0,
>     -				  &lwi);
>     +		rc = l_wait_event_abortable(osc_lru_waitq,
>     +					    atomic_long_read(cli->cl_lru_left) > 0);
>      
>      		if (rc < 0)
>      			break;
>     diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
>     index 45b1ebf33363..074b5ce6284c 100644
>     --- a/drivers/staging/lustre/lustre/osc/osc_request.c
>     +++ b/drivers/staging/lustre/lustre/osc/osc_request.c
>     @@ -552,14 +552,12 @@ static int osc_destroy(const struct lu_env *env, struct obd_export *exp,
>      
>      	req->rq_interpret_reply = osc_destroy_interpret;
>      	if (!osc_can_send_destroy(cli)) {
>     -		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
>     -
>      		/*
>      		 * Wait until the number of on-going destroy RPCs drops
>      		 * under max_rpc_in_flight
>      		 */
>     -		l_wait_event_exclusive(cli->cl_destroy_waitq,
>     -				       osc_can_send_destroy(cli), &lwi);
>     +		l_wait_event_abortable_exclusive(cli->cl_destroy_waitq,
>     +					       osc_can_send_destroy(cli));
>      	}
>      
>      	/* Do not wait for response */
>     
>     
>     _______________________________________________
>     lustre-devel mailing list
>     lustre-devel@lists.lustre.org
>     http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org
>     

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 06/19] staging: lustre: introduce and use l_wait_event_abortable()
@ 2018-02-12 23:58       ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-12 23:58 UTC (permalink / raw)
  To: Patrick Farrell, Oleg Drokin, Andreas Dilger, James Simmons,
	Greg Kroah-Hartman
  Cc: lkml, lustre

On Mon, Feb 12 2018, Patrick Farrell wrote:

> It's worth noting that the change from -EINTR to -ERESTARTSYS will
> modify the behavior of userspace slightly.  Specifically, when a
> signal handler is setup with retry set (SA_RESTART flag set), the
> syscall will be restarted rather than aborted.

Thanks for the review.
This state is true if the error status ever gets all the way up to user
space.  I don't think it does, though I haven't carefully audited every
l_wait_event_abortable() call site.  I did look at a few and the return
value is only used locally in the same function.
I suspect I would have checked for error codes escaping when I wrote
the patch, but I don't have a clear memory.

Some sort of audit wouldn't hurt of course.

Thanks,
NeilBrown


>
> This should be fine.  It may eventually shake out some stuble bugs in Lustre when we abort an operation and then restart it from a point where we didn't in the past - past instances where we changed from -EINTR to -ERESTARTSYS certainly have - but it's for the best.  As I understand it from past conversations with Andreas and others, Lustre is not really intending to claim it's not restartable, it's just an artifact of people copying older code that was written without awareness of the difference in EINTR vs ERESTARTSYS.
>
> Ideally someone should go through and audit the remaining uses of -EINTR and replace most of them with -ERESTARTSYS.
>
> James, maybe you want to add that to the TODO list?
>
> ?On 2/12/18, 3:24 PM, "lustre-devel on behalf of NeilBrown" <lustre-devel-bounces at lists.lustre.org on behalf of neilb@suse.com> wrote:
>
>     lustre sometimes wants to wait for an event, but abort if
>     one of a specific list of signals arrives.  This is a little
>     bit like wait_event_killable(), except that the signals are
>     identified a different way.
>     
>     So introduce l_wait_event_abortable() which provides this
>     functionality.
>     Having separate functions for separate needs is more in line
>     with the pattern set by include/linux/wait.h, than having a
>     single function which tries to include all possible needs.
>     
>     Also introduce l_wait_event_abortable_exclusive().
>     
>     Note that l_wait_event() return -EINTR on a signal, while
>     Linux wait_event functions return -ERESTARTSYS.
>     l_wait_event_{abortable_,}exclusive follow the Linux pattern.
>     
>     Reviewed-by: James Simmons <jsimmons@infradead.org>
>     Signed-off-by: NeilBrown <neilb@suse.com>
>     ---
>      drivers/staging/lustre/lustre/include/lustre_lib.h |   24 ++++++++++++++++++++
>      drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |   12 +++++-----
>      drivers/staging/lustre/lustre/llite/llite_lib.c    |   12 +++-------
>      drivers/staging/lustre/lustre/obdclass/genops.c    |    9 +++-----
>      drivers/staging/lustre/lustre/obdclass/llog_obd.c  |    5 ++--
>      drivers/staging/lustre/lustre/osc/osc_page.c       |    6 ++---
>      drivers/staging/lustre/lustre/osc/osc_request.c    |    6 ++---
>      7 files changed, 43 insertions(+), 31 deletions(-)
>     
>     diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
>     index 7d950c53e962..b2a64d0e682c 100644
>     --- a/drivers/staging/lustre/lustre/include/lustre_lib.h
>     +++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
>     @@ -336,4 +336,28 @@ do {									   \
>      /** @} lib */
>      
>      
>     +
>     +/* l_wait_event_abortable() is a bit like wait_event_killable()
>     + * except there is a fixed set of signals which will abort:
>     + * LUSTRE_FATAL_SIGS
>     + */
>     +#define l_wait_event_abortable(wq, condition)				\
>     +({									\
>     +	sigset_t __blocked;						\
>     +	int __ret = 0;							\
>     +	__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);		\
>     +	__ret = wait_event_interruptible(wq, condition);		\
>     +	cfs_restore_sigs(__blocked);					\
>     +	__ret;								\
>     +})
>     +
>     +#define l_wait_event_abortable_exclusive(wq, condition)			\
>     +({									\
>     +	sigset_t __blocked;						\
>     +	int __ret = 0;							\
>     +	__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);		\
>     +	__ret = wait_event_interruptible_exclusive(wq, condition);	\
>     +	cfs_restore_sigs(__blocked);					\
>     +	__ret;								\
>     +})
>      #endif /* _LUSTRE_LIB_H */
>     diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
>     index 2e66825c8f4b..4c44603ab6f9 100644
>     --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
>     +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
>     @@ -879,7 +879,6 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, int force)
>      	ldlm_namespace_cleanup(ns, force ? LDLM_FL_LOCAL_ONLY : 0);
>      
>      	if (atomic_read(&ns->ns_bref) > 0) {
>     -		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
>      		int rc;
>      
>      		CDEBUG(D_DLMTRACE,
>     @@ -887,11 +886,12 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, int force)
>      		       ldlm_ns_name(ns), atomic_read(&ns->ns_bref));
>      force_wait:
>      		if (force)
>     -			lwi = LWI_TIMEOUT(msecs_to_jiffies(obd_timeout *
>     -					  MSEC_PER_SEC) / 4, NULL, NULL);
>     -
>     -		rc = l_wait_event(ns->ns_waitq,
>     -				  atomic_read(&ns->ns_bref) == 0, &lwi);
>     +			rc = wait_event_idle_timeout(ns->ns_waitq,
>     +						     atomic_read(&ns->ns_bref) == 0,
>     +						     obd_timeout * HZ / 4) ? 0 : -ETIMEDOUT;
>     +		else
>     +			rc = l_wait_event_abortable(ns->ns_waitq,
>     +						    atomic_read(&ns->ns_bref) == 0);
>      
>      		/* Forced cleanups should be able to reclaim all references,
>      		 * so it's safe to wait forever... we can't leak locks...
>     diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
>     index c820b201af71..ccb614bd7f53 100644
>     --- a/drivers/staging/lustre/lustre/llite/llite_lib.c
>     +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
>     @@ -986,16 +986,12 @@ void ll_put_super(struct super_block *sb)
>      	}
>      
>      	/* Wait for unstable pages to be committed to stable storage */
>     -	if (!force) {
>     -		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
>     -
>     -		rc = l_wait_event(sbi->ll_cache->ccc_unstable_waitq,
>     -				  !atomic_long_read(&sbi->ll_cache->ccc_unstable_nr),
>     -				  &lwi);
>     -	}
>     +	if (!force)
>     +		rc = l_wait_event_abortable(sbi->ll_cache->ccc_unstable_waitq,
>     +					    !atomic_long_read(&sbi->ll_cache->ccc_unstable_nr));
>      
>      	ccc_count = atomic_long_read(&sbi->ll_cache->ccc_unstable_nr);
>     -	if (!force && rc != -EINTR)
>     +	if (!force && rc != -ERESTARTSYS)
>      		LASSERTF(!ccc_count, "count: %li\n", ccc_count);
>      
>      	/* We need to set force before the lov_disconnect in
>     diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
>     index 3ff25b8d3b48..8f776a4058a9 100644
>     --- a/drivers/staging/lustre/lustre/obdclass/genops.c
>     +++ b/drivers/staging/lustre/lustre/obdclass/genops.c
>     @@ -1332,7 +1332,6 @@ static bool obd_request_slot_avail(struct client_obd *cli,
>      int obd_get_request_slot(struct client_obd *cli)
>      {
>      	struct obd_request_slot_waiter orsw;
>     -	struct l_wait_info lwi;
>      	int rc;
>      
>      	spin_lock(&cli->cl_loi_list_lock);
>     @@ -1347,11 +1346,9 @@ int obd_get_request_slot(struct client_obd *cli)
>      	orsw.orsw_signaled = false;
>      	spin_unlock(&cli->cl_loi_list_lock);
>      
>     -	lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
>     -	rc = l_wait_event(orsw.orsw_waitq,
>     -			  obd_request_slot_avail(cli, &orsw) ||
>     -			  orsw.orsw_signaled,
>     -			  &lwi);
>     +	rc = l_wait_event_abortable(orsw.orsw_waitq,
>     +				    obd_request_slot_avail(cli, &orsw) ||
>     +				    orsw.orsw_signaled);
>      
>      	/*
>      	 * Here, we must take the lock to avoid the on-stack 'orsw' to be
>     diff --git a/drivers/staging/lustre/lustre/obdclass/llog_obd.c b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
>     index 28bbaa2136ac..26aea114a29b 100644
>     --- a/drivers/staging/lustre/lustre/obdclass/llog_obd.c
>     +++ b/drivers/staging/lustre/lustre/obdclass/llog_obd.c
>     @@ -104,7 +104,6 @@ EXPORT_SYMBOL(__llog_ctxt_put);
>      
>      int llog_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt)
>      {
>     -	struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
>      	struct obd_llog_group *olg;
>      	int rc, idx;
>      
>     @@ -129,8 +128,8 @@ int llog_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt)
>      		CERROR("Error %d while cleaning up ctxt %p\n",
>      		       rc, ctxt);
>      
>     -	l_wait_event(olg->olg_waitq,
>     -		     llog_group_ctxt_null(olg, idx), &lwi);
>     +	l_wait_event_abortable(olg->olg_waitq,
>     +			     llog_group_ctxt_null(olg, idx));
>      
>      	return rc;
>      }
>     diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c
>     index 20094b6309f9..6fdd521feb21 100644
>     --- a/drivers/staging/lustre/lustre/osc/osc_page.c
>     +++ b/drivers/staging/lustre/lustre/osc/osc_page.c
>     @@ -759,7 +759,6 @@ static long osc_lru_reclaim(struct client_obd *cli, unsigned long npages)
>      static int osc_lru_alloc(const struct lu_env *env, struct client_obd *cli,
>      			 struct osc_page *opg)
>      {
>     -	struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
>      	struct osc_io *oio = osc_env_io(env);
>      	int rc = 0;
>      
>     @@ -782,9 +781,8 @@ static int osc_lru_alloc(const struct lu_env *env, struct client_obd *cli,
>      
>      		cond_resched();
>      
>     -		rc = l_wait_event(osc_lru_waitq,
>     -				  atomic_long_read(cli->cl_lru_left) > 0,
>     -				  &lwi);
>     +		rc = l_wait_event_abortable(osc_lru_waitq,
>     +					    atomic_long_read(cli->cl_lru_left) > 0);
>      
>      		if (rc < 0)
>      			break;
>     diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
>     index 45b1ebf33363..074b5ce6284c 100644
>     --- a/drivers/staging/lustre/lustre/osc/osc_request.c
>     +++ b/drivers/staging/lustre/lustre/osc/osc_request.c
>     @@ -552,14 +552,12 @@ static int osc_destroy(const struct lu_env *env, struct obd_export *exp,
>      
>      	req->rq_interpret_reply = osc_destroy_interpret;
>      	if (!osc_can_send_destroy(cli)) {
>     -		struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
>     -
>      		/*
>      		 * Wait until the number of on-going destroy RPCs drops
>      		 * under max_rpc_in_flight
>      		 */
>     -		l_wait_event_exclusive(cli->cl_destroy_waitq,
>     -				       osc_can_send_destroy(cli), &lwi);
>     +		l_wait_event_abortable_exclusive(cli->cl_destroy_waitq,
>     +					       osc_can_send_destroy(cli));
>      	}
>      
>      	/* Do not wait for response */
>     
>     
>     _______________________________________________
>     lustre-devel mailing list
>     lustre-devel at lists.lustre.org
>     http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org
>     
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 832 bytes
Desc: not available
URL: <http://lists.lustre.org/pipermail/lustre-devel-lustre.org/attachments/20180213/71244c1c/attachment-0001.sig>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [lustre-devel] [PATCH 08/19] staging: lustre: simplify waiting in ldlm_completion_ast()
  2018-02-12 22:08     ` Patrick Farrell
@ 2018-02-13  0:17       ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-13  0:17 UTC (permalink / raw)
  To: Patrick Farrell, Oleg Drokin, Andreas Dilger, James Simmons,
	Greg Kroah-Hartman
  Cc: lkml, lustre

[-- Attachment #1: Type: text/plain, Size: 4026 bytes --]

On Mon, Feb 12 2018, Patrick Farrell wrote:

> Neil,
>
> I didn't get anything after 8/19 in this series.  Is this just me?  (I'd keep waiting, except I also found a few things in this patch.)

Not just you.  My fault.  They are appearing now.

>
> Minor:
> The line XXX ALLOCATE is out of date and could go.  (It refers to a
> mix of things you eliminated and things that were already gone.)

What does the line even mean?  Some comment about stack usage?
I think we have a look that looks for large stack frames.  I wonder how
to run it...

>
> Less minor:
> You remove use of the imp_lock when reading the connection count.  While that'll work on x86, it's probably wrong on some architecture to read that without taking the lock...?

It was my understanding that on all architectures which Linux support, a
32bit aligned read is atomic wrt any 32bit write.  I have trouble imagining how
it could be otherwise.

I probably should have highlighted the removal of the spinlock in the
patch description though - it was intentional.

>
> Bug:
> The existing code uses the imp_conn_cnt from *before* the wait, rather
> than after.  I think that's quite important.  So you'll want to read
> it out before the wait.  I think the main reason we'd hit the timeout
> is a disconnect, which should cause a reconnect, so it's very
> important to use the value from *before* the wait.  (See comment on
> ptlrpc_set_import_discon for more of an explanation.  Basically it's
> tracking a connection 'epoch', if it's changed, someone else already
> went through the reconnect code for this 'connection epoch' and we
> shouldn't start that process.) 
>

That wasn't intentional though - thanks for catching!
Looking at  ptlrpc_set_import_discon(), which is where the number
eventually gets used, it is only used to compare with the new value of
imp->imp_conn_cnt. 

This would fix both (assuming the locking issue needs fixing).

Thanks,
NeilBrown

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index f1233d844bbd..c3c9186b74ce 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -103,7 +103,7 @@ static int ldlm_request_bufsize(int count, int type)
 	return sizeof(struct ldlm_request) + avail;
 }
 
-static void ldlm_expired_completion_wait(struct ldlm_lock *lock, struct obd_import *imp2)
+static void ldlm_expired_completion_wait(struct ldlm_lock *lock, __u32 conn_cnt)
 {
 	struct obd_import *imp;
 	struct obd_device *obd;
@@ -129,7 +129,7 @@ static void ldlm_expired_completion_wait(struct ldlm_lock *lock, struct obd_impo
 
 	obd = lock->l_conn_export->exp_obd;
 	imp = obd->u.cli.cl_import;
-	ptlrpc_fail_import(imp, imp2 ? imp2->imp_conn_cnt : 0);
+	ptlrpc_fail_import(imp, conn_cnt);
 	LDLM_ERROR(lock,
 		   "lock timed out (enqueued at %lld, %llds ago), entering recovery for %s@%s",
 		   (s64)lock->l_last_activity,
@@ -241,6 +241,7 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 	struct obd_device *obd;
 	struct obd_import *imp = NULL;
 	__u32 timeout;
+	__u32 conn_cnt = 0;
 	int rc = 0;
 
 	if (flags == LDLM_FL_WAIT_NOREPROC) {
@@ -268,6 +269,11 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 
 	lock->l_last_activity = ktime_get_real_seconds();
 
+	if (imp) {
+		spin_lock(&imp->imp_lock);
+		conn_cnt = imp->imp_conn_cnt;
+		spin_unlock(&imp->imp_lock);
+	}
 	if (OBD_FAIL_CHECK_RESET(OBD_FAIL_LDLM_INTR_CP_AST,
 				 OBD_FAIL_LDLM_CP_BL_RACE | OBD_FAIL_ONCE)) {
 		ldlm_set_fail_loc(lock);
@@ -280,7 +286,7 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 						     is_granted_or_cancelled(lock),
 						     timeout * HZ);
 			if (rc == 0)
-				ldlm_expired_completion_wait(lock, imp);
+				ldlm_expired_completion_wait(lock, conn_cnt);
 		}
 		/* Now wait abortable */
 		if (rc == 0)

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 08/19] staging: lustre: simplify waiting in ldlm_completion_ast()
@ 2018-02-13  0:17       ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-13  0:17 UTC (permalink / raw)
  To: Patrick Farrell, Oleg Drokin, Andreas Dilger, James Simmons,
	Greg Kroah-Hartman
  Cc: lkml, lustre

On Mon, Feb 12 2018, Patrick Farrell wrote:

> Neil,
>
> I didn't get anything after 8/19 in this series.  Is this just me?  (I'd keep waiting, except I also found a few things in this patch.)

Not just you.  My fault.  They are appearing now.

>
> Minor:
> The line XXX ALLOCATE is out of date and could go.  (It refers to a
> mix of things you eliminated and things that were already gone.)

What does the line even mean?  Some comment about stack usage?
I think we have a look that looks for large stack frames.  I wonder how
to run it...

>
> Less minor:
> You remove use of the imp_lock when reading the connection count.  While that'll work on x86, it's probably wrong on some architecture to read that without taking the lock...?

It was my understanding that on all architectures which Linux support, a
32bit aligned read is atomic wrt any 32bit write.  I have trouble imagining how
it could be otherwise.

I probably should have highlighted the removal of the spinlock in the
patch description though - it was intentional.

>
> Bug:
> The existing code uses the imp_conn_cnt from *before* the wait, rather
> than after.  I think that's quite important.  So you'll want to read
> it out before the wait.  I think the main reason we'd hit the timeout
> is a disconnect, which should cause a reconnect, so it's very
> important to use the value from *before* the wait.  (See comment on
> ptlrpc_set_import_discon for more of an explanation.  Basically it's
> tracking a connection 'epoch', if it's changed, someone else already
> went through the reconnect code for this 'connection epoch' and we
> shouldn't start that process.) 
>

That wasn't intentional though - thanks for catching!
Looking at  ptlrpc_set_import_discon(), which is where the number
eventually gets used, it is only used to compare with the new value of
imp->imp_conn_cnt. 

This would fix both (assuming the locking issue needs fixing).

Thanks,
NeilBrown

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index f1233d844bbd..c3c9186b74ce 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -103,7 +103,7 @@ static int ldlm_request_bufsize(int count, int type)
 	return sizeof(struct ldlm_request) + avail;
 }
 
-static void ldlm_expired_completion_wait(struct ldlm_lock *lock, struct obd_import *imp2)
+static void ldlm_expired_completion_wait(struct ldlm_lock *lock, __u32 conn_cnt)
 {
 	struct obd_import *imp;
 	struct obd_device *obd;
@@ -129,7 +129,7 @@ static void ldlm_expired_completion_wait(struct ldlm_lock *lock, struct obd_impo
 
 	obd = lock->l_conn_export->exp_obd;
 	imp = obd->u.cli.cl_import;
-	ptlrpc_fail_import(imp, imp2 ? imp2->imp_conn_cnt : 0);
+	ptlrpc_fail_import(imp, conn_cnt);
 	LDLM_ERROR(lock,
 		   "lock timed out (enqueued at %lld, %llds ago), entering recovery for %s@%s",
 		   (s64)lock->l_last_activity,
@@ -241,6 +241,7 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 	struct obd_device *obd;
 	struct obd_import *imp = NULL;
 	__u32 timeout;
+	__u32 conn_cnt = 0;
 	int rc = 0;
 
 	if (flags == LDLM_FL_WAIT_NOREPROC) {
@@ -268,6 +269,11 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 
 	lock->l_last_activity = ktime_get_real_seconds();
 
+	if (imp) {
+		spin_lock(&imp->imp_lock);
+		conn_cnt = imp->imp_conn_cnt;
+		spin_unlock(&imp->imp_lock);
+	}
 	if (OBD_FAIL_CHECK_RESET(OBD_FAIL_LDLM_INTR_CP_AST,
 				 OBD_FAIL_LDLM_CP_BL_RACE | OBD_FAIL_ONCE)) {
 		ldlm_set_fail_loc(lock);
@@ -280,7 +286,7 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 						     is_granted_or_cancelled(lock),
 						     timeout * HZ);
 			if (rc == 0)
-				ldlm_expired_completion_wait(lock, imp);
+				ldlm_expired_completion_wait(lock, conn_cnt);
 		}
 		/* Now wait abortable */
 		if (rc == 0)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 832 bytes
Desc: not available
URL: <http://lists.lustre.org/pipermail/lustre-devel-lustre.org/attachments/20180213/94cb2c06/attachment.sig>

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [lustre-devel] [PATCH 08/19] staging: lustre: simplify waiting in ldlm_completion_ast()
  2018-02-13  0:17       ` NeilBrown
@ 2018-02-13  0:46         ` Patrick Farrell
  -1 siblings, 0 replies; 58+ messages in thread
From: Patrick Farrell @ 2018-02-13  0:46 UTC (permalink / raw)
  To: NeilBrown, Oleg Drokin, Andreas Dilger, James Simmons,
	Greg Kroah-Hartman
  Cc: lkml, lustre

[-- Attachment #1: Type: text/plain, Size: 5157 bytes --]

Yes, I assume it’s a comment about stack usage (or even more out of date and unrelated to the current code entirely. :p)  Like you, I can’t imagine what else it would be...

You’re probably right about the locking issue, I’m happy to defer.  (In any case, this timed out path should be very far from hot...)

Otherwise that fix looks good.  I’ll review the rest of these tomorrow.

________________________________
From: NeilBrown <neilb@suse.com>
Sent: Monday, February 12, 2018 6:17:22 PM
To: Patrick Farrell; Oleg Drokin; Andreas Dilger; James Simmons; Greg Kroah-Hartman
Cc: lkml; lustre
Subject: Re: [lustre-devel] [PATCH 08/19] staging: lustre: simplify waiting in ldlm_completion_ast()

On Mon, Feb 12 2018, Patrick Farrell wrote:

> Neil,
>
> I didn't get anything after 8/19 in this series.  Is this just me?  (I'd keep waiting, except I also found a few things in this patch.)

Not just you.  My fault.  They are appearing now.

>
> Minor:
> The line XXX ALLOCATE is out of date and could go.  (It refers to a
> mix of things you eliminated and things that were already gone.)

What does the line even mean?  Some comment about stack usage?
I think we have a look that looks for large stack frames.  I wonder how
to run it...

>
> Less minor:
> You remove use of the imp_lock when reading the connection count.  While that'll work on x86, it's probably wrong on some architecture to read that without taking the lock...?

It was my understanding that on all architectures which Linux support, a
32bit aligned read is atomic wrt any 32bit write.  I have trouble imagining how
it could be otherwise.

I probably should have highlighted the removal of the spinlock in the
patch description though - it was intentional.

>
> Bug:
> The existing code uses the imp_conn_cnt from *before* the wait, rather
> than after.  I think that's quite important.  So you'll want to read
> it out before the wait.  I think the main reason we'd hit the timeout
> is a disconnect, which should cause a reconnect, so it's very
> important to use the value from *before* the wait.  (See comment on
> ptlrpc_set_import_discon for more of an explanation.  Basically it's
> tracking a connection 'epoch', if it's changed, someone else already
> went through the reconnect code for this 'connection epoch' and we
> shouldn't start that process.)
>

That wasn't intentional though - thanks for catching!
Looking at  ptlrpc_set_import_discon(), which is where the number
eventually gets used, it is only used to compare with the new value of
imp->imp_conn_cnt.

This would fix both (assuming the locking issue needs fixing).

Thanks,
NeilBrown

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index f1233d844bbd..c3c9186b74ce 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -103,7 +103,7 @@ static int ldlm_request_bufsize(int count, int type)
         return sizeof(struct ldlm_request) + avail;
 }

-static void ldlm_expired_completion_wait(struct ldlm_lock *lock, struct obd_import *imp2)
+static void ldlm_expired_completion_wait(struct ldlm_lock *lock, __u32 conn_cnt)
 {
         struct obd_import *imp;
         struct obd_device *obd;
@@ -129,7 +129,7 @@ static void ldlm_expired_completion_wait(struct ldlm_lock *lock, struct obd_impo

         obd = lock->l_conn_export->exp_obd;
         imp = obd->u.cli.cl_import;
-       ptlrpc_fail_import(imp, imp2 ? imp2->imp_conn_cnt : 0);
+       ptlrpc_fail_import(imp, conn_cnt);
         LDLM_ERROR(lock,
                    "lock timed out (enqueued at %lld, %llds ago), entering recovery for %s@%s",
                    (s64)lock->l_last_activity,
@@ -241,6 +241,7 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
         struct obd_device *obd;
         struct obd_import *imp = NULL;
         __u32 timeout;
+       __u32 conn_cnt = 0;
         int rc = 0;

         if (flags == LDLM_FL_WAIT_NOREPROC) {
@@ -268,6 +269,11 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)

         lock->l_last_activity = ktime_get_real_seconds();

+       if (imp) {
+               spin_lock(&imp->imp_lock);
+               conn_cnt = imp->imp_conn_cnt;
+               spin_unlock(&imp->imp_lock);
+       }
         if (OBD_FAIL_CHECK_RESET(OBD_FAIL_LDLM_INTR_CP_AST,
                                  OBD_FAIL_LDLM_CP_BL_RACE | OBD_FAIL_ONCE)) {
                 ldlm_set_fail_loc(lock);
@@ -280,7 +286,7 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
                                                      is_granted_or_cancelled(lock),
                                                      timeout * HZ);
                         if (rc == 0)
-                               ldlm_expired_completion_wait(lock, imp);
+                               ldlm_expired_completion_wait(lock, conn_cnt);
                 }
                 /* Now wait abortable */
                 if (rc == 0)

[-- Attachment #2: Type: text/html, Size: 8885 bytes --]

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 08/19] staging: lustre: simplify waiting in ldlm_completion_ast()
@ 2018-02-13  0:46         ` Patrick Farrell
  0 siblings, 0 replies; 58+ messages in thread
From: Patrick Farrell @ 2018-02-13  0:46 UTC (permalink / raw)
  To: NeilBrown, Oleg Drokin, Andreas Dilger, James Simmons,
	Greg Kroah-Hartman
  Cc: lkml, lustre

Yes, I assume it?s a comment about stack usage (or even more out of date and unrelated to the current code entirely. :p)  Like you, I can?t imagine what else it would be...

You?re probably right about the locking issue, I?m happy to defer.  (In any case, this timed out path should be very far from hot...)

Otherwise that fix looks good.  I?ll review the rest of these tomorrow.

________________________________
From: NeilBrown <neilb@suse.com>
Sent: Monday, February 12, 2018 6:17:22 PM
To: Patrick Farrell; Oleg Drokin; Andreas Dilger; James Simmons; Greg Kroah-Hartman
Cc: lkml; lustre
Subject: Re: [lustre-devel] [PATCH 08/19] staging: lustre: simplify waiting in ldlm_completion_ast()

On Mon, Feb 12 2018, Patrick Farrell wrote:

> Neil,
>
> I didn't get anything after 8/19 in this series.  Is this just me?  (I'd keep waiting, except I also found a few things in this patch.)

Not just you.  My fault.  They are appearing now.

>
> Minor:
> The line XXX ALLOCATE is out of date and could go.  (It refers to a
> mix of things you eliminated and things that were already gone.)

What does the line even mean?  Some comment about stack usage?
I think we have a look that looks for large stack frames.  I wonder how
to run it...

>
> Less minor:
> You remove use of the imp_lock when reading the connection count.  While that'll work on x86, it's probably wrong on some architecture to read that without taking the lock...?

It was my understanding that on all architectures which Linux support, a
32bit aligned read is atomic wrt any 32bit write.  I have trouble imagining how
it could be otherwise.

I probably should have highlighted the removal of the spinlock in the
patch description though - it was intentional.

>
> Bug:
> The existing code uses the imp_conn_cnt from *before* the wait, rather
> than after.  I think that's quite important.  So you'll want to read
> it out before the wait.  I think the main reason we'd hit the timeout
> is a disconnect, which should cause a reconnect, so it's very
> important to use the value from *before* the wait.  (See comment on
> ptlrpc_set_import_discon for more of an explanation.  Basically it's
> tracking a connection 'epoch', if it's changed, someone else already
> went through the reconnect code for this 'connection epoch' and we
> shouldn't start that process.)
>

That wasn't intentional though - thanks for catching!
Looking at  ptlrpc_set_import_discon(), which is where the number
eventually gets used, it is only used to compare with the new value of
imp->imp_conn_cnt.

This would fix both (assuming the locking issue needs fixing).

Thanks,
NeilBrown

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index f1233d844bbd..c3c9186b74ce 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -103,7 +103,7 @@ static int ldlm_request_bufsize(int count, int type)
         return sizeof(struct ldlm_request) + avail;
 }

-static void ldlm_expired_completion_wait(struct ldlm_lock *lock, struct obd_import *imp2)
+static void ldlm_expired_completion_wait(struct ldlm_lock *lock, __u32 conn_cnt)
 {
         struct obd_import *imp;
         struct obd_device *obd;
@@ -129,7 +129,7 @@ static void ldlm_expired_completion_wait(struct ldlm_lock *lock, struct obd_impo

         obd = lock->l_conn_export->exp_obd;
         imp = obd->u.cli.cl_import;
-       ptlrpc_fail_import(imp, imp2 ? imp2->imp_conn_cnt : 0);
+       ptlrpc_fail_import(imp, conn_cnt);
         LDLM_ERROR(lock,
                    "lock timed out (enqueued at %lld, %llds ago), entering recovery for %s@%s",
                    (s64)lock->l_last_activity,
@@ -241,6 +241,7 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
         struct obd_device *obd;
         struct obd_import *imp = NULL;
         __u32 timeout;
+       __u32 conn_cnt = 0;
         int rc = 0;

         if (flags == LDLM_FL_WAIT_NOREPROC) {
@@ -268,6 +269,11 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)

         lock->l_last_activity = ktime_get_real_seconds();

+       if (imp) {
+               spin_lock(&imp->imp_lock);
+               conn_cnt = imp->imp_conn_cnt;
+               spin_unlock(&imp->imp_lock);
+       }
         if (OBD_FAIL_CHECK_RESET(OBD_FAIL_LDLM_INTR_CP_AST,
                                  OBD_FAIL_LDLM_CP_BL_RACE | OBD_FAIL_ONCE)) {
                 ldlm_set_fail_loc(lock);
@@ -280,7 +286,7 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
                                                      is_granted_or_cancelled(lock),
                                                      timeout * HZ);
                         if (rc == 0)
-                               ldlm_expired_completion_wait(lock, imp);
+                               ldlm_expired_completion_wait(lock, conn_cnt);
                 }
                 /* Now wait abortable */
                 if (rc == 0)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lustre.org/pipermail/lustre-devel-lustre.org/attachments/20180213/004b9baa/attachment.html>

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [lustre-devel] [PATCH 19/19] staging: lustre: remove l_wait_event() and related code
  2018-02-12 23:47   ` [lustre-devel] " NeilBrown
@ 2018-02-13 18:15     ` Patrick Farrell
  -1 siblings, 0 replies; 58+ messages in thread
From: Patrick Farrell @ 2018-02-13 18:15 UTC (permalink / raw)
  To: NeilBrown, Oleg Drokin, Andreas Dilger, James Simmons,
	Greg Kroah-Hartman
  Cc: lkml, lustre

With the fix from yesterday, these look good.  Thanks, Neil.

Reviewed-by: Patrick Farrell <paf@cray.com>

- Patrick

On 2/12/18, 5:52 PM, "lustre-devel on behalf of NeilBrown" <lustre-devel-bounces@lists.lustre.org on behalf of neilb@suse.com> wrote:

    These macros are no longer used, so they can
    be removed.
    
    Reviewed-by: James Simmons <jsimmons@infradead.org>
    Signed-off-by: NeilBrown <neilb@suse.com>
    ---
     drivers/staging/lustre/lustre/include/lustre_lib.h |  249 --------------------
     1 file changed, 249 deletions(-)
    
    diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
    index ccc1a329e42b..1efd86f18c1f 100644
    --- a/drivers/staging/lustre/lustre/include/lustre_lib.h
    +++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
    @@ -76,123 +76,6 @@ int do_set_info_async(struct obd_import *imp,
     
     void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id);
     
    -/*
    - * l_wait_event is a flexible sleeping function, permitting simple caller
    - * configuration of interrupt and timeout sensitivity along with actions to
    - * be performed in the event of either exception.
    - *
    - * The first form of usage looks like this:
    - *
    - * struct l_wait_info lwi = LWI_TIMEOUT_INTR(timeout, timeout_handler,
    - *					   intr_handler, callback_data);
    - * rc = l_wait_event(waitq, condition, &lwi);
    - *
    - * l_wait_event() makes the current process wait on 'waitq' until 'condition'
    - * is TRUE or a "killable" signal (SIGTERM, SIKGILL, SIGINT) is pending.  It
    - * returns 0 to signify 'condition' is TRUE, but if a signal wakes it before
    - * 'condition' becomes true, it optionally calls the specified 'intr_handler'
    - * if not NULL, and returns -EINTR.
    - *
    - * If a non-zero timeout is specified, signals are ignored until the timeout
    - * has expired.  At this time, if 'timeout_handler' is not NULL it is called.
    - * If it returns FALSE l_wait_event() continues to wait as described above with
    - * signals enabled.  Otherwise it returns -ETIMEDOUT.
    - *
    - * LWI_INTR(intr_handler, callback_data) is shorthand for
    - * LWI_TIMEOUT_INTR(0, NULL, intr_handler, callback_data)
    - *
    - * The second form of usage looks like this:
    - *
    - * struct l_wait_info lwi = LWI_TIMEOUT(timeout, timeout_handler);
    - * rc = l_wait_event(waitq, condition, &lwi);
    - *
    - * This form is the same as the first except that it COMPLETELY IGNORES
    - * SIGNALS.  The caller must therefore beware that if 'timeout' is zero, or if
    - * 'timeout_handler' is not NULL and returns FALSE, then the ONLY thing that
    - * can unblock the current process is 'condition' becoming TRUE.
    - *
    - * Another form of usage is:
    - * struct l_wait_info lwi = LWI_TIMEOUT_INTERVAL(timeout, interval,
    - *					       timeout_handler);
    - * rc = l_wait_event(waitq, condition, &lwi);
    - * This is the same as previous case, but condition is checked once every
    - * 'interval' jiffies (if non-zero).
    - *
    - * Subtle synchronization point: this macro does *not* necessary takes
    - * wait-queue spin-lock before returning, and, hence, following idiom is safe
    - * ONLY when caller provides some external locking:
    - *
    - *	     Thread1			    Thread2
    - *
    - *   l_wait_event(&obj->wq, ....);				       (1)
    - *
    - *				    wake_up(&obj->wq):		 (2)
    - *					 spin_lock(&q->lock);	  (2.1)
    - *					 __wake_up_common(q, ...);     (2.2)
    - *					 spin_unlock(&q->lock, flags); (2.3)
    - *
    - *   kfree(obj);						  (3)
    - *
    - * As l_wait_event() may "short-cut" execution and return without taking
    - * wait-queue spin-lock, some additional synchronization is necessary to
    - * guarantee that step (3) can begin only after (2.3) finishes.
    - *
    - * XXX nikita: some ptlrpc daemon threads have races of that sort.
    - *
    - */
    -
    -#define LWI_ON_SIGNAL_NOOP ((void (*)(void *))(-1))
    -
    -struct l_wait_info {
    -	long lwi_timeout;
    -	long lwi_interval;
    -	int	    lwi_allow_intr;
    -	int  (*lwi_on_timeout)(void *);
    -	void (*lwi_on_signal)(void *);
    -	void  *lwi_cb_data;
    -};
    -
    -/* NB: LWI_TIMEOUT ignores signals completely */
    -#define LWI_TIMEOUT(time, cb, data)	     \
    -((struct l_wait_info) {			 \
    -	.lwi_timeout    = time,		 \
    -	.lwi_on_timeout = cb,		   \
    -	.lwi_cb_data    = data,		 \
    -	.lwi_interval   = 0,		    \
    -	.lwi_allow_intr = 0		     \
    -})
    -
    -#define LWI_TIMEOUT_INTERVAL(time, interval, cb, data)  \
    -((struct l_wait_info) {				 \
    -	.lwi_timeout    = time,			 \
    -	.lwi_on_timeout = cb,			   \
    -	.lwi_cb_data    = data,			 \
    -	.lwi_interval   = interval,		     \
    -	.lwi_allow_intr = 0			     \
    -})
    -
    -#define LWI_TIMEOUT_INTR(time, time_cb, sig_cb, data)   \
    -((struct l_wait_info) {				 \
    -	.lwi_timeout    = time,			 \
    -	.lwi_on_timeout = time_cb,		      \
    -	.lwi_on_signal  = sig_cb,		       \
    -	.lwi_cb_data    = data,			 \
    -	.lwi_interval   = 0,			    \
    -	.lwi_allow_intr = 0			     \
    -})
    -
    -#define LWI_TIMEOUT_INTR_ALL(time, time_cb, sig_cb, data)       \
    -((struct l_wait_info) {					 \
    -	.lwi_timeout    = time,				 \
    -	.lwi_on_timeout = time_cb,			      \
    -	.lwi_on_signal  = sig_cb,			       \
    -	.lwi_cb_data    = data,				 \
    -	.lwi_interval   = 0,				    \
    -	.lwi_allow_intr = 1				     \
    -})
    -
    -#define LWI_INTR(cb, data)  LWI_TIMEOUT_INTR(0, NULL, cb, data)
    -
     #define LUSTRE_FATAL_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) |		\
     			   sigmask(SIGTERM) | sigmask(SIGQUIT) |	\
     			   sigmask(SIGALRM))
    @@ -201,138 +84,6 @@ static inline int l_fatal_signal_pending(struct task_struct *p)
     	return signal_pending(p) && sigtestsetmask(&p->pending.signal, LUSTRE_FATAL_SIGS);
     }
     
    -/**
    - * wait_queue_entry_t of Linux (version < 2.6.34) is a FIFO list for exclusively
    - * waiting threads, which is not always desirable because all threads will
    - * be waken up again and again, even user only needs a few of them to be
    - * active most time. This is not good for performance because cache can
    - * be polluted by different threads.
    - *
    - * LIFO list can resolve this problem because we always wakeup the most
    - * recent active thread by default.
    - *
    - * NB: please don't call non-exclusive & exclusive wait on the same
    - * waitq if add_wait_queue_exclusive_head is used.
    - */
    -#define add_wait_queue_exclusive_head(waitq, link)		\
    -{								\
    -	unsigned long flags;					\
    -								\
    -	spin_lock_irqsave(&((waitq)->lock), flags);		\
    -	__add_wait_queue_exclusive(waitq, link);		\
    -	spin_unlock_irqrestore(&((waitq)->lock), flags);	\
    -}
    -
    -/*
    - * wait for @condition to become true, but no longer than timeout, specified
    - * by @info.
    - */
    -#define __l_wait_event(wq, condition, info, ret, l_add_wait)		   \
    -do {									   \
    -	wait_queue_entry_t __wait;						 \
    -	long __timeout = info->lwi_timeout;			  \
    -	sigset_t   __blocked;					      \
    -	int   __allow_intr = info->lwi_allow_intr;			     \
    -									       \
    -	ret = 0;							       \
    -	if (condition)							 \
    -		break;							 \
    -									       \
    -	init_waitqueue_entry(&__wait, current);					    \
    -	l_add_wait(&wq, &__wait);					      \
    -									       \
    -	/* Block all signals (just the non-fatal ones if no timeout). */       \
    -	if (info->lwi_on_signal && (__timeout == 0 || __allow_intr))   \
    -		__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);	      \
    -	else								   \
    -		__blocked = cfs_block_sigsinv(0);			      \
    -									       \
    -	for (;;) {							     \
    -		if (condition)						 \
    -			break;						 \
    -									       \
    -		set_current_state(TASK_INTERRUPTIBLE);			       \
    -									       \
    -		if (__timeout == 0) {					  \
    -			schedule();					       \
    -		} else {						       \
    -			long interval = info->lwi_interval ?	  \
    -					     min_t(long,	     \
    -						 info->lwi_interval, __timeout) : \
    -					     __timeout;			\
    -			long remaining = schedule_timeout(interval);\
    -			__timeout = cfs_time_sub(__timeout,		    \
    -					    cfs_time_sub(interval, remaining));\
    -			if (__timeout == 0) {				  \
    -				if (!info->lwi_on_timeout ||		      \
    -				    info->lwi_on_timeout(info->lwi_cb_data)) { \
    -					ret = -ETIMEDOUT;		      \
    -					break;				 \
    -				}					      \
    -				/* Take signals after the timeout expires. */  \
    -				if (info->lwi_on_signal)		       \
    -				    (void)cfs_block_sigsinv(LUSTRE_FATAL_SIGS);\
    -			}						      \
    -		}							      \
    -									       \
    -		set_current_state(TASK_RUNNING);			       \
    -									       \
    -		if (condition)						 \
    -			break;						 \
    -		if (signal_pending(current)) {				    \
    -			if (info->lwi_on_signal &&		     \
    -			    (__timeout == 0 || __allow_intr)) {		\
    -				if (info->lwi_on_signal != LWI_ON_SIGNAL_NOOP) \
    -					info->lwi_on_signal(info->lwi_cb_data);\
    -				ret = -EINTR;				  \
    -				break;					 \
    -			}						      \
    -			/* We have to do this here because some signals */     \
    -			/* are not blockable - ie from strace(1).       */     \
    -			/* In these cases we want to schedule_timeout() */     \
    -			/* again, because we don't want that to return  */     \
    -			/* -EINTR when the RPC actually succeeded.      */     \
    -			/* the recalc_sigpending() below will deliver the */     \
    -			/* signal properly.			     */     \
    -			cfs_clear_sigpending();				\
    -		}							      \
    -	}								      \
    -									       \
    -	cfs_restore_sigs(__blocked);					   \
    -									       \
    -	remove_wait_queue(&wq, &__wait);					   \
    -} while (0)
    -
    -#define l_wait_event(wq, condition, info)		       \
    -({							      \
    -	int		 __ret;			      \
    -	struct l_wait_info *__info = (info);		    \
    -								\
    -	__l_wait_event(wq, condition, __info,		   \
    -		       __ret, add_wait_queue);		   \
    -	__ret;						  \
    -})
    -
    -#define l_wait_event_exclusive(wq, condition, info)	     \
    -({							      \
    -	int		 __ret;			      \
    -	struct l_wait_info *__info = (info);		    \
    -								\
    -	__l_wait_event(wq, condition, __info,		   \
    -		       __ret, add_wait_queue_exclusive);	 \
    -	__ret;						  \
    -})
    -
    -#define l_wait_event_exclusive_head(wq, condition, info)	\
    -({							      \
    -	int		 __ret;			      \
    -	struct l_wait_info *__info = (info);		    \
    -								\
    -	__l_wait_event(wq, condition, __info,		   \
    -		       __ret, add_wait_queue_exclusive_head);    \
    -	__ret;						  \
    -})
    -
     /** @} lib */
     
     
    
    
    _______________________________________________
    lustre-devel mailing list
    lustre-devel@lists.lustre.org
    http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org
    


^ permalink raw reply	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 19/19] staging: lustre: remove l_wait_event() and related code
@ 2018-02-13 18:15     ` Patrick Farrell
  0 siblings, 0 replies; 58+ messages in thread
From: Patrick Farrell @ 2018-02-13 18:15 UTC (permalink / raw)
  To: NeilBrown, Oleg Drokin, Andreas Dilger, James Simmons,
	Greg Kroah-Hartman
  Cc: lkml, lustre

With the fix from yesterday, these look good.  Thanks, Neil.

Reviewed-by: Patrick Farrell <paf@cray.com>

- Patrick

?On 2/12/18, 5:52 PM, "lustre-devel on behalf of NeilBrown" <lustre-devel-bounces at lists.lustre.org on behalf of neilb@suse.com> wrote:

    These macros are no longer used, so they can
    be removed.
    
    Reviewed-by: James Simmons <jsimmons@infradead.org>
    Signed-off-by: NeilBrown <neilb@suse.com>
    ---
     drivers/staging/lustre/lustre/include/lustre_lib.h |  249 --------------------
     1 file changed, 249 deletions(-)
    
    diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h
    index ccc1a329e42b..1efd86f18c1f 100644
    --- a/drivers/staging/lustre/lustre/include/lustre_lib.h
    +++ b/drivers/staging/lustre/lustre/include/lustre_lib.h
    @@ -76,123 +76,6 @@ int do_set_info_async(struct obd_import *imp,
     
     void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id);
     
    -/*
    - * l_wait_event is a flexible sleeping function, permitting simple caller
    - * configuration of interrupt and timeout sensitivity along with actions to
    - * be performed in the event of either exception.
    - *
    - * The first form of usage looks like this:
    - *
    - * struct l_wait_info lwi = LWI_TIMEOUT_INTR(timeout, timeout_handler,
    - *					   intr_handler, callback_data);
    - * rc = l_wait_event(waitq, condition, &lwi);
    - *
    - * l_wait_event() makes the current process wait on 'waitq' until 'condition'
    - * is TRUE or a "killable" signal (SIGTERM, SIKGILL, SIGINT) is pending.  It
    - * returns 0 to signify 'condition' is TRUE, but if a signal wakes it before
    - * 'condition' becomes true, it optionally calls the specified 'intr_handler'
    - * if not NULL, and returns -EINTR.
    - *
    - * If a non-zero timeout is specified, signals are ignored until the timeout
    - * has expired.  At this time, if 'timeout_handler' is not NULL it is called.
    - * If it returns FALSE l_wait_event() continues to wait as described above with
    - * signals enabled.  Otherwise it returns -ETIMEDOUT.
    - *
    - * LWI_INTR(intr_handler, callback_data) is shorthand for
    - * LWI_TIMEOUT_INTR(0, NULL, intr_handler, callback_data)
    - *
    - * The second form of usage looks like this:
    - *
    - * struct l_wait_info lwi = LWI_TIMEOUT(timeout, timeout_handler);
    - * rc = l_wait_event(waitq, condition, &lwi);
    - *
    - * This form is the same as the first except that it COMPLETELY IGNORES
    - * SIGNALS.  The caller must therefore beware that if 'timeout' is zero, or if
    - * 'timeout_handler' is not NULL and returns FALSE, then the ONLY thing that
    - * can unblock the current process is 'condition' becoming TRUE.
    - *
    - * Another form of usage is:
    - * struct l_wait_info lwi = LWI_TIMEOUT_INTERVAL(timeout, interval,
    - *					       timeout_handler);
    - * rc = l_wait_event(waitq, condition, &lwi);
    - * This is the same as previous case, but condition is checked once every
    - * 'interval' jiffies (if non-zero).
    - *
    - * Subtle synchronization point: this macro does *not* necessary takes
    - * wait-queue spin-lock before returning, and, hence, following idiom is safe
    - * ONLY when caller provides some external locking:
    - *
    - *	     Thread1			    Thread2
    - *
    - *   l_wait_event(&obj->wq, ....);				       (1)
    - *
    - *				    wake_up(&obj->wq):		 (2)
    - *					 spin_lock(&q->lock);	  (2.1)
    - *					 __wake_up_common(q, ...);     (2.2)
    - *					 spin_unlock(&q->lock, flags); (2.3)
    - *
    - *   kfree(obj);						  (3)
    - *
    - * As l_wait_event() may "short-cut" execution and return without taking
    - * wait-queue spin-lock, some additional synchronization is necessary to
    - * guarantee that step (3) can begin only after (2.3) finishes.
    - *
    - * XXX nikita: some ptlrpc daemon threads have races of that sort.
    - *
    - */
    -
    -#define LWI_ON_SIGNAL_NOOP ((void (*)(void *))(-1))
    -
    -struct l_wait_info {
    -	long lwi_timeout;
    -	long lwi_interval;
    -	int	    lwi_allow_intr;
    -	int  (*lwi_on_timeout)(void *);
    -	void (*lwi_on_signal)(void *);
    -	void  *lwi_cb_data;
    -};
    -
    -/* NB: LWI_TIMEOUT ignores signals completely */
    -#define LWI_TIMEOUT(time, cb, data)	     \
    -((struct l_wait_info) {			 \
    -	.lwi_timeout    = time,		 \
    -	.lwi_on_timeout = cb,		   \
    -	.lwi_cb_data    = data,		 \
    -	.lwi_interval   = 0,		    \
    -	.lwi_allow_intr = 0		     \
    -})
    -
    -#define LWI_TIMEOUT_INTERVAL(time, interval, cb, data)  \
    -((struct l_wait_info) {				 \
    -	.lwi_timeout    = time,			 \
    -	.lwi_on_timeout = cb,			   \
    -	.lwi_cb_data    = data,			 \
    -	.lwi_interval   = interval,		     \
    -	.lwi_allow_intr = 0			     \
    -})
    -
    -#define LWI_TIMEOUT_INTR(time, time_cb, sig_cb, data)   \
    -((struct l_wait_info) {				 \
    -	.lwi_timeout    = time,			 \
    -	.lwi_on_timeout = time_cb,		      \
    -	.lwi_on_signal  = sig_cb,		       \
    -	.lwi_cb_data    = data,			 \
    -	.lwi_interval   = 0,			    \
    -	.lwi_allow_intr = 0			     \
    -})
    -
    -#define LWI_TIMEOUT_INTR_ALL(time, time_cb, sig_cb, data)       \
    -((struct l_wait_info) {					 \
    -	.lwi_timeout    = time,				 \
    -	.lwi_on_timeout = time_cb,			      \
    -	.lwi_on_signal  = sig_cb,			       \
    -	.lwi_cb_data    = data,				 \
    -	.lwi_interval   = 0,				    \
    -	.lwi_allow_intr = 1				     \
    -})
    -
    -#define LWI_INTR(cb, data)  LWI_TIMEOUT_INTR(0, NULL, cb, data)
    -
     #define LUSTRE_FATAL_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) |		\
     			   sigmask(SIGTERM) | sigmask(SIGQUIT) |	\
     			   sigmask(SIGALRM))
    @@ -201,138 +84,6 @@ static inline int l_fatal_signal_pending(struct task_struct *p)
     	return signal_pending(p) && sigtestsetmask(&p->pending.signal, LUSTRE_FATAL_SIGS);
     }
     
    -/**
    - * wait_queue_entry_t of Linux (version < 2.6.34) is a FIFO list for exclusively
    - * waiting threads, which is not always desirable because all threads will
    - * be waken up again and again, even user only needs a few of them to be
    - * active most time. This is not good for performance because cache can
    - * be polluted by different threads.
    - *
    - * LIFO list can resolve this problem because we always wakeup the most
    - * recent active thread by default.
    - *
    - * NB: please don't call non-exclusive & exclusive wait on the same
    - * waitq if add_wait_queue_exclusive_head is used.
    - */
    -#define add_wait_queue_exclusive_head(waitq, link)		\
    -{								\
    -	unsigned long flags;					\
    -								\
    -	spin_lock_irqsave(&((waitq)->lock), flags);		\
    -	__add_wait_queue_exclusive(waitq, link);		\
    -	spin_unlock_irqrestore(&((waitq)->lock), flags);	\
    -}
    -
    -/*
    - * wait for @condition to become true, but no longer than timeout, specified
    - * by @info.
    - */
    -#define __l_wait_event(wq, condition, info, ret, l_add_wait)		   \
    -do {									   \
    -	wait_queue_entry_t __wait;						 \
    -	long __timeout = info->lwi_timeout;			  \
    -	sigset_t   __blocked;					      \
    -	int   __allow_intr = info->lwi_allow_intr;			     \
    -									       \
    -	ret = 0;							       \
    -	if (condition)							 \
    -		break;							 \
    -									       \
    -	init_waitqueue_entry(&__wait, current);					    \
    -	l_add_wait(&wq, &__wait);					      \
    -									       \
    -	/* Block all signals (just the non-fatal ones if no timeout). */       \
    -	if (info->lwi_on_signal && (__timeout == 0 || __allow_intr))   \
    -		__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS);	      \
    -	else								   \
    -		__blocked = cfs_block_sigsinv(0);			      \
    -									       \
    -	for (;;) {							     \
    -		if (condition)						 \
    -			break;						 \
    -									       \
    -		set_current_state(TASK_INTERRUPTIBLE);			       \
    -									       \
    -		if (__timeout == 0) {					  \
    -			schedule();					       \
    -		} else {						       \
    -			long interval = info->lwi_interval ?	  \
    -					     min_t(long,	     \
    -						 info->lwi_interval, __timeout) : \
    -					     __timeout;			\
    -			long remaining = schedule_timeout(interval);\
    -			__timeout = cfs_time_sub(__timeout,		    \
    -					    cfs_time_sub(interval, remaining));\
    -			if (__timeout == 0) {				  \
    -				if (!info->lwi_on_timeout ||		      \
    -				    info->lwi_on_timeout(info->lwi_cb_data)) { \
    -					ret = -ETIMEDOUT;		      \
    -					break;				 \
    -				}					      \
    -				/* Take signals after the timeout expires. */  \
    -				if (info->lwi_on_signal)		       \
    -				    (void)cfs_block_sigsinv(LUSTRE_FATAL_SIGS);\
    -			}						      \
    -		}							      \
    -									       \
    -		set_current_state(TASK_RUNNING);			       \
    -									       \
    -		if (condition)						 \
    -			break;						 \
    -		if (signal_pending(current)) {				    \
    -			if (info->lwi_on_signal &&		     \
    -			    (__timeout == 0 || __allow_intr)) {		\
    -				if (info->lwi_on_signal != LWI_ON_SIGNAL_NOOP) \
    -					info->lwi_on_signal(info->lwi_cb_data);\
    -				ret = -EINTR;				  \
    -				break;					 \
    -			}						      \
    -			/* We have to do this here because some signals */     \
    -			/* are not blockable - ie from strace(1).       */     \
    -			/* In these cases we want to schedule_timeout() */     \
    -			/* again, because we don't want that to return  */     \
    -			/* -EINTR when the RPC actually succeeded.      */     \
    -			/* the recalc_sigpending() below will deliver the */     \
    -			/* signal properly.			     */     \
    -			cfs_clear_sigpending();				\
    -		}							      \
    -	}								      \
    -									       \
    -	cfs_restore_sigs(__blocked);					   \
    -									       \
    -	remove_wait_queue(&wq, &__wait);					   \
    -} while (0)
    -
    -#define l_wait_event(wq, condition, info)		       \
    -({							      \
    -	int		 __ret;			      \
    -	struct l_wait_info *__info = (info);		    \
    -								\
    -	__l_wait_event(wq, condition, __info,		   \
    -		       __ret, add_wait_queue);		   \
    -	__ret;						  \
    -})
    -
    -#define l_wait_event_exclusive(wq, condition, info)	     \
    -({							      \
    -	int		 __ret;			      \
    -	struct l_wait_info *__info = (info);		    \
    -								\
    -	__l_wait_event(wq, condition, __info,		   \
    -		       __ret, add_wait_queue_exclusive);	 \
    -	__ret;						  \
    -})
    -
    -#define l_wait_event_exclusive_head(wq, condition, info)	\
    -({							      \
    -	int		 __ret;			      \
    -	struct l_wait_info *__info = (info);		    \
    -								\
    -	__l_wait_event(wq, condition, __info,		   \
    -		       __ret, add_wait_queue_exclusive_head);    \
    -	__ret;						  \
    -})
    -
     /** @} lib */
     
     
    
    
    _______________________________________________
    lustre-devel mailing list
    lustre-devel at lists.lustre.org
    http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org
    

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH 08/19 - v2] staging: lustre: simplify waiting in ldlm_completion_ast()
  2018-02-12 21:22   ` [lustre-devel] " NeilBrown
@ 2018-02-13 20:17     ` NeilBrown
  -1 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-13 20:17 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre

[-- Attachment #1: Type: text/plain, Size: 5383 bytes --]


If a signal-callback (lwi_on_signal) is set without lwi_allow_intr, as
is the case in ldlm_completion_ast(), the behavior depends on the
timeout set.

If a timeout is set, then signals are ignored.  If the timeout is
reached, the timeout handler is called.  If the timeout handler
return 0, which ldlm_expired_completion_wait() always does, the
l_wait_event() switches to exactly the behavior if no timeout was set.

If no timeout is set, then "fatal" signals are not ignored.  If one
arrives the callback is run, but as the callback is empty in this
case, that is not relevant.

This can be simplified to:
 if a timeout is wanted
     wait_event_idle_timeout()
     if that timed out, call the timeout handler
 l_wait_event_abortable()

i.e. the code always waits indefinitely.  Sometimes it performs a
non-abortable wait first.  Sometimes it doesn't.  But it only
aborts before the condition is true if it is signaled.
This doesn't quite agree with the comments and debug messages.

Now that we call the timeout handler (ldlm_expired_completion_wait())
wait directly, we can pass the two args directly rather then
using a special-purpose struct.

Reviewed-by: Patrick Farrell <paf@cray.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---

Patrick discovered a bug in v1, which this v2 fixes.

Greg - do you need me to resend the whole series, or are you ok with
taking this replacement in the rest of the original series?

Thanks,
NeilBrown


 drivers/staging/lustre/lustre/ldlm/ldlm_request.c | 53 +++++++++--------------
 1 file changed, 20 insertions(+), 33 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index a244fa717134..c3c9186b74ce 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -72,15 +72,6 @@ MODULE_PARM_DESC(ldlm_enqueue_min, "lock enqueue timeout minimum");
 /* in client side, whether the cached locks will be canceled before replay */
 unsigned int ldlm_cancel_unused_locks_before_replay = 1;
 
-static void interrupted_completion_wait(void *data)
-{
-}
-
-struct lock_wait_data {
-	struct ldlm_lock *lwd_lock;
-	__u32	     lwd_conn_cnt;
-};
-
 struct ldlm_async_args {
 	struct lustre_handle lock_handle;
 };
@@ -112,10 +103,8 @@ static int ldlm_request_bufsize(int count, int type)
 	return sizeof(struct ldlm_request) + avail;
 }
 
-static int ldlm_expired_completion_wait(void *data)
+static void ldlm_expired_completion_wait(struct ldlm_lock *lock, __u32 conn_cnt)
 {
-	struct lock_wait_data *lwd = data;
-	struct ldlm_lock *lock = lwd->lwd_lock;
 	struct obd_import *imp;
 	struct obd_device *obd;
 
@@ -135,19 +124,17 @@ static int ldlm_expired_completion_wait(void *data)
 			if (last_dump == 0)
 				libcfs_debug_dumplog();
 		}
-		return 0;
+		return;
 	}
 
 	obd = lock->l_conn_export->exp_obd;
 	imp = obd->u.cli.cl_import;
-	ptlrpc_fail_import(imp, lwd->lwd_conn_cnt);
+	ptlrpc_fail_import(imp, conn_cnt);
 	LDLM_ERROR(lock,
 		   "lock timed out (enqueued at %lld, %llds ago), entering recovery for %s@%s",
 		   (s64)lock->l_last_activity,
 		   (s64)(ktime_get_real_seconds() - lock->l_last_activity),
 		   obd2cli_tgt(obd), imp->imp_connection->c_remote_uuid.uuid);
-
-	return 0;
 }
 
 /**
@@ -251,11 +238,10 @@ EXPORT_SYMBOL(ldlm_completion_ast_async);
 int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 {
 	/* XXX ALLOCATE - 160 bytes */
-	struct lock_wait_data lwd;
 	struct obd_device *obd;
 	struct obd_import *imp = NULL;
-	struct l_wait_info lwi;
 	__u32 timeout;
+	__u32 conn_cnt = 0;
 	int rc = 0;
 
 	if (flags == LDLM_FL_WAIT_NOREPROC) {
@@ -281,32 +267,33 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 
 	timeout = ldlm_cp_timeout(lock);
 
-	lwd.lwd_lock = lock;
 	lock->l_last_activity = ktime_get_real_seconds();
 
-	if (ldlm_is_no_timeout(lock)) {
-		LDLM_DEBUG(lock, "waiting indefinitely because of NO_TIMEOUT");
-		lwi = LWI_INTR(interrupted_completion_wait, &lwd);
-	} else {
-		lwi = LWI_TIMEOUT_INTR(timeout * HZ,
-				       ldlm_expired_completion_wait,
-				       interrupted_completion_wait, &lwd);
-	}
-
 	if (imp) {
 		spin_lock(&imp->imp_lock);
-		lwd.lwd_conn_cnt = imp->imp_conn_cnt;
+		conn_cnt = imp->imp_conn_cnt;
 		spin_unlock(&imp->imp_lock);
 	}
-
 	if (OBD_FAIL_CHECK_RESET(OBD_FAIL_LDLM_INTR_CP_AST,
 				 OBD_FAIL_LDLM_CP_BL_RACE | OBD_FAIL_ONCE)) {
 		ldlm_set_fail_loc(lock);
 		rc = -EINTR;
 	} else {
-		/* Go to sleep until the lock is granted or cancelled. */
-		rc = l_wait_event(lock->l_waitq,
-				  is_granted_or_cancelled(lock), &lwi);
+		/* Go to sleep until the lock is granted or canceled. */
+		if (!ldlm_is_no_timeout(lock)) {
+			/* Wait uninterruptible for a while first */
+			rc = wait_event_idle_timeout(lock->l_waitq,
+						     is_granted_or_cancelled(lock),
+						     timeout * HZ);
+			if (rc == 0)
+				ldlm_expired_completion_wait(lock, conn_cnt);
+		}
+		/* Now wait abortable */
+		if (rc == 0)
+			rc = l_wait_event_abortable(lock->l_waitq,
+						    is_granted_or_cancelled(lock));
+		else
+			rc = 0;
 	}
 
 	if (rc) {
-- 
2.14.0.rc0.dirty


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 08/19 - v2] staging: lustre: simplify waiting in ldlm_completion_ast()
@ 2018-02-13 20:17     ` NeilBrown
  0 siblings, 0 replies; 58+ messages in thread
From: NeilBrown @ 2018-02-13 20:17 UTC (permalink / raw)
  To: Oleg Drokin, Andreas Dilger, James Simmons, Greg Kroah-Hartman
  Cc: lkml, lustre


If a signal-callback (lwi_on_signal) is set without lwi_allow_intr, as
is the case in ldlm_completion_ast(), the behavior depends on the
timeout set.

If a timeout is set, then signals are ignored.  If the timeout is
reached, the timeout handler is called.  If the timeout handler
return 0, which ldlm_expired_completion_wait() always does, the
l_wait_event() switches to exactly the behavior if no timeout was set.

If no timeout is set, then "fatal" signals are not ignored.  If one
arrives the callback is run, but as the callback is empty in this
case, that is not relevant.

This can be simplified to:
 if a timeout is wanted
     wait_event_idle_timeout()
     if that timed out, call the timeout handler
 l_wait_event_abortable()

i.e. the code always waits indefinitely.  Sometimes it performs a
non-abortable wait first.  Sometimes it doesn't.  But it only
aborts before the condition is true if it is signaled.
This doesn't quite agree with the comments and debug messages.

Now that we call the timeout handler (ldlm_expired_completion_wait())
wait directly, we can pass the two args directly rather then
using a special-purpose struct.

Reviewed-by: Patrick Farrell <paf@cray.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---

Patrick discovered a bug in v1, which this v2 fixes.

Greg - do you need me to resend the whole series, or are you ok with
taking this replacement in the rest of the original series?

Thanks,
NeilBrown


 drivers/staging/lustre/lustre/ldlm/ldlm_request.c | 53 +++++++++--------------
 1 file changed, 20 insertions(+), 33 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index a244fa717134..c3c9186b74ce 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -72,15 +72,6 @@ MODULE_PARM_DESC(ldlm_enqueue_min, "lock enqueue timeout minimum");
 /* in client side, whether the cached locks will be canceled before replay */
 unsigned int ldlm_cancel_unused_locks_before_replay = 1;
 
-static void interrupted_completion_wait(void *data)
-{
-}
-
-struct lock_wait_data {
-	struct ldlm_lock *lwd_lock;
-	__u32	     lwd_conn_cnt;
-};
-
 struct ldlm_async_args {
 	struct lustre_handle lock_handle;
 };
@@ -112,10 +103,8 @@ static int ldlm_request_bufsize(int count, int type)
 	return sizeof(struct ldlm_request) + avail;
 }
 
-static int ldlm_expired_completion_wait(void *data)
+static void ldlm_expired_completion_wait(struct ldlm_lock *lock, __u32 conn_cnt)
 {
-	struct lock_wait_data *lwd = data;
-	struct ldlm_lock *lock = lwd->lwd_lock;
 	struct obd_import *imp;
 	struct obd_device *obd;
 
@@ -135,19 +124,17 @@ static int ldlm_expired_completion_wait(void *data)
 			if (last_dump == 0)
 				libcfs_debug_dumplog();
 		}
-		return 0;
+		return;
 	}
 
 	obd = lock->l_conn_export->exp_obd;
 	imp = obd->u.cli.cl_import;
-	ptlrpc_fail_import(imp, lwd->lwd_conn_cnt);
+	ptlrpc_fail_import(imp, conn_cnt);
 	LDLM_ERROR(lock,
 		   "lock timed out (enqueued at %lld, %llds ago), entering recovery for %s@%s",
 		   (s64)lock->l_last_activity,
 		   (s64)(ktime_get_real_seconds() - lock->l_last_activity),
 		   obd2cli_tgt(obd), imp->imp_connection->c_remote_uuid.uuid);
-
-	return 0;
 }
 
 /**
@@ -251,11 +238,10 @@ EXPORT_SYMBOL(ldlm_completion_ast_async);
 int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 {
 	/* XXX ALLOCATE - 160 bytes */
-	struct lock_wait_data lwd;
 	struct obd_device *obd;
 	struct obd_import *imp = NULL;
-	struct l_wait_info lwi;
 	__u32 timeout;
+	__u32 conn_cnt = 0;
 	int rc = 0;
 
 	if (flags == LDLM_FL_WAIT_NOREPROC) {
@@ -281,32 +267,33 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 
 	timeout = ldlm_cp_timeout(lock);
 
-	lwd.lwd_lock = lock;
 	lock->l_last_activity = ktime_get_real_seconds();
 
-	if (ldlm_is_no_timeout(lock)) {
-		LDLM_DEBUG(lock, "waiting indefinitely because of NO_TIMEOUT");
-		lwi = LWI_INTR(interrupted_completion_wait, &lwd);
-	} else {
-		lwi = LWI_TIMEOUT_INTR(timeout * HZ,
-				       ldlm_expired_completion_wait,
-				       interrupted_completion_wait, &lwd);
-	}
-
 	if (imp) {
 		spin_lock(&imp->imp_lock);
-		lwd.lwd_conn_cnt = imp->imp_conn_cnt;
+		conn_cnt = imp->imp_conn_cnt;
 		spin_unlock(&imp->imp_lock);
 	}
-
 	if (OBD_FAIL_CHECK_RESET(OBD_FAIL_LDLM_INTR_CP_AST,
 				 OBD_FAIL_LDLM_CP_BL_RACE | OBD_FAIL_ONCE)) {
 		ldlm_set_fail_loc(lock);
 		rc = -EINTR;
 	} else {
-		/* Go to sleep until the lock is granted or cancelled. */
-		rc = l_wait_event(lock->l_waitq,
-				  is_granted_or_cancelled(lock), &lwi);
+		/* Go to sleep until the lock is granted or canceled. */
+		if (!ldlm_is_no_timeout(lock)) {
+			/* Wait uninterruptible for a while first */
+			rc = wait_event_idle_timeout(lock->l_waitq,
+						     is_granted_or_cancelled(lock),
+						     timeout * HZ);
+			if (rc == 0)
+				ldlm_expired_completion_wait(lock, conn_cnt);
+		}
+		/* Now wait abortable */
+		if (rc == 0)
+			rc = l_wait_event_abortable(lock->l_waitq,
+						    is_granted_or_cancelled(lock));
+		else
+			rc = 0;
 	}
 
 	if (rc) {
-- 
2.14.0.rc0.dirty

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 832 bytes
Desc: not available
URL: <http://lists.lustre.org/pipermail/lustre-devel-lustre.org/attachments/20180214/a0dfaf9a/attachment-0001.sig>

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH 08/19 - v2] staging: lustre: simplify waiting in ldlm_completion_ast()
  2018-02-13 20:17     ` [lustre-devel] " NeilBrown
@ 2018-02-16 14:18       ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 58+ messages in thread
From: Greg Kroah-Hartman @ 2018-02-16 14:18 UTC (permalink / raw)
  To: NeilBrown; +Cc: Oleg Drokin, Andreas Dilger, James Simmons, lkml, lustre

On Wed, Feb 14, 2018 at 07:17:30AM +1100, NeilBrown wrote:
> 
> If a signal-callback (lwi_on_signal) is set without lwi_allow_intr, as
> is the case in ldlm_completion_ast(), the behavior depends on the
> timeout set.
> 
> If a timeout is set, then signals are ignored.  If the timeout is
> reached, the timeout handler is called.  If the timeout handler
> return 0, which ldlm_expired_completion_wait() always does, the
> l_wait_event() switches to exactly the behavior if no timeout was set.
> 
> If no timeout is set, then "fatal" signals are not ignored.  If one
> arrives the callback is run, but as the callback is empty in this
> case, that is not relevant.
> 
> This can be simplified to:
>  if a timeout is wanted
>      wait_event_idle_timeout()
>      if that timed out, call the timeout handler
>  l_wait_event_abortable()
> 
> i.e. the code always waits indefinitely.  Sometimes it performs a
> non-abortable wait first.  Sometimes it doesn't.  But it only
> aborts before the condition is true if it is signaled.
> This doesn't quite agree with the comments and debug messages.
> 
> Now that we call the timeout handler (ldlm_expired_completion_wait())
> wait directly, we can pass the two args directly rather then
> using a special-purpose struct.
> 
> Reviewed-by: Patrick Farrell <paf@cray.com>
> Reviewed-by: James Simmons <jsimmons@infradead.org>
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
> 
> Patrick discovered a bug in v1, which this v2 fixes.
> 
> Greg - do you need me to resend the whole series, or are you ok with
> taking this replacement in the rest of the original series?

I can take this replacement, thanks.

greg k-h

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 08/19 - v2] staging: lustre: simplify waiting in ldlm_completion_ast()
@ 2018-02-16 14:18       ` Greg Kroah-Hartman
  0 siblings, 0 replies; 58+ messages in thread
From: Greg Kroah-Hartman @ 2018-02-16 14:18 UTC (permalink / raw)
  To: NeilBrown; +Cc: Oleg Drokin, Andreas Dilger, James Simmons, lkml, lustre

On Wed, Feb 14, 2018 at 07:17:30AM +1100, NeilBrown wrote:
> 
> If a signal-callback (lwi_on_signal) is set without lwi_allow_intr, as
> is the case in ldlm_completion_ast(), the behavior depends on the
> timeout set.
> 
> If a timeout is set, then signals are ignored.  If the timeout is
> reached, the timeout handler is called.  If the timeout handler
> return 0, which ldlm_expired_completion_wait() always does, the
> l_wait_event() switches to exactly the behavior if no timeout was set.
> 
> If no timeout is set, then "fatal" signals are not ignored.  If one
> arrives the callback is run, but as the callback is empty in this
> case, that is not relevant.
> 
> This can be simplified to:
>  if a timeout is wanted
>      wait_event_idle_timeout()
>      if that timed out, call the timeout handler
>  l_wait_event_abortable()
> 
> i.e. the code always waits indefinitely.  Sometimes it performs a
> non-abortable wait first.  Sometimes it doesn't.  But it only
> aborts before the condition is true if it is signaled.
> This doesn't quite agree with the comments and debug messages.
> 
> Now that we call the timeout handler (ldlm_expired_completion_wait())
> wait directly, we can pass the two args directly rather then
> using a special-purpose struct.
> 
> Reviewed-by: Patrick Farrell <paf@cray.com>
> Reviewed-by: James Simmons <jsimmons@infradead.org>
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
> 
> Patrick discovered a bug in v1, which this v2 fixes.
> 
> Greg - do you need me to resend the whole series, or are you ok with
> taking this replacement in the rest of the original series?

I can take this replacement, thanks.

greg k-h

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 08/19] staging: lustre: simplify waiting in ldlm_completion_ast()
  2018-01-08  3:28 ` [lustre-devel] [PATCH 08/19] staging: lustre: simplify waiting in ldlm_completion_ast() NeilBrown
@ 2018-01-17 15:31   ` James Simmons
  0 siblings, 0 replies; 58+ messages in thread
From: James Simmons @ 2018-01-17 15:31 UTC (permalink / raw)
  To: NeilBrown; +Cc: Oleg Drokin, Andreas Dilger, Greg Kroah-Hartman, lkml, lustre


> If a signal-callback (lwi_on_signal) is set without lwi_allow_intr, as
> is the case in ldlm_completion_ast(), the behavior depends on the
> timeout set.
> 
> If a timeout is set, then signals are ignored.  If the timeout is
> reached, the timeout handler is called.  If the timeout handler
> return 0, which ldlm_expired_completion_wait() always does, the
> l_wait_event() switches to exactly the behavior if no timeout was set.
> 
> If no timeout is set, then "fatal" signals are not ignored.  If one
> arrives the callback is run, but as the callback is empty in this
> case, that is not relevant.
> 
> This can be simplified to:
>  if a timeout is wanted
>      wait_event_idle_timeout()
>      if that timed out, call the timeout handler
>  l_wait_event_abortable()
> 
> i.e. the code always waits indefinitely.  Sometimes it performs a
> non-abortable wait first.  Sometimes it doesn't.  But it only
> aborts before the condition is true if it is signaled.
> This doesn't quite agree with the comments and debug messages.


Reviewed-by: James Simmons <jsimmons@infradead.org>
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/ldlm/ldlm_request.c |   55 +++++++--------------
>  1 file changed, 18 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
> index a244fa717134..f1233d844bbd 100644
> --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
> +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
> @@ -72,15 +72,6 @@ MODULE_PARM_DESC(ldlm_enqueue_min, "lock enqueue timeout minimum");
>  /* in client side, whether the cached locks will be canceled before replay */
>  unsigned int ldlm_cancel_unused_locks_before_replay = 1;
>  
> -static void interrupted_completion_wait(void *data)
> -{
> -}
> -
> -struct lock_wait_data {
> -	struct ldlm_lock *lwd_lock;
> -	__u32	     lwd_conn_cnt;
> -};
> -
>  struct ldlm_async_args {
>  	struct lustre_handle lock_handle;
>  };
> @@ -112,10 +103,8 @@ static int ldlm_request_bufsize(int count, int type)
>  	return sizeof(struct ldlm_request) + avail;
>  }
>  
> -static int ldlm_expired_completion_wait(void *data)
> +static void ldlm_expired_completion_wait(struct ldlm_lock *lock, struct obd_import *imp2)
>  {
> -	struct lock_wait_data *lwd = data;
> -	struct ldlm_lock *lock = lwd->lwd_lock;
>  	struct obd_import *imp;
>  	struct obd_device *obd;
>  
> @@ -135,19 +124,17 @@ static int ldlm_expired_completion_wait(void *data)
>  			if (last_dump == 0)
>  				libcfs_debug_dumplog();
>  		}
> -		return 0;
> +		return;
>  	}
>  
>  	obd = lock->l_conn_export->exp_obd;
>  	imp = obd->u.cli.cl_import;
> -	ptlrpc_fail_import(imp, lwd->lwd_conn_cnt);
> +	ptlrpc_fail_import(imp, imp2 ? imp2->imp_conn_cnt : 0);
>  	LDLM_ERROR(lock,
>  		   "lock timed out (enqueued at %lld, %llds ago), entering recovery for %s@%s",
>  		   (s64)lock->l_last_activity,
>  		   (s64)(ktime_get_real_seconds() - lock->l_last_activity),
>  		   obd2cli_tgt(obd), imp->imp_connection->c_remote_uuid.uuid);
> -
> -	return 0;
>  }
>  
>  /**
> @@ -251,10 +238,8 @@ EXPORT_SYMBOL(ldlm_completion_ast_async);
>  int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
>  {
>  	/* XXX ALLOCATE - 160 bytes */
> -	struct lock_wait_data lwd;
>  	struct obd_device *obd;
>  	struct obd_import *imp = NULL;
> -	struct l_wait_info lwi;
>  	__u32 timeout;
>  	int rc = 0;
>  
> @@ -281,32 +266,28 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
>  
>  	timeout = ldlm_cp_timeout(lock);
>  
> -	lwd.lwd_lock = lock;
>  	lock->l_last_activity = ktime_get_real_seconds();
>  
> -	if (ldlm_is_no_timeout(lock)) {
> -		LDLM_DEBUG(lock, "waiting indefinitely because of NO_TIMEOUT");
> -		lwi = LWI_INTR(interrupted_completion_wait, &lwd);
> -	} else {
> -		lwi = LWI_TIMEOUT_INTR(timeout * HZ,
> -				       ldlm_expired_completion_wait,
> -				       interrupted_completion_wait, &lwd);
> -	}
> -
> -	if (imp) {
> -		spin_lock(&imp->imp_lock);
> -		lwd.lwd_conn_cnt = imp->imp_conn_cnt;
> -		spin_unlock(&imp->imp_lock);
> -	}
> -
>  	if (OBD_FAIL_CHECK_RESET(OBD_FAIL_LDLM_INTR_CP_AST,
>  				 OBD_FAIL_LDLM_CP_BL_RACE | OBD_FAIL_ONCE)) {
>  		ldlm_set_fail_loc(lock);
>  		rc = -EINTR;
>  	} else {
> -		/* Go to sleep until the lock is granted or cancelled. */
> -		rc = l_wait_event(lock->l_waitq,
> -				  is_granted_or_cancelled(lock), &lwi);
> +		/* Go to sleep until the lock is granted or canceled. */
> +		if (!ldlm_is_no_timeout(lock)) {
> +			/* Wait uninterruptible for a while first */
> +			rc = wait_event_idle_timeout(lock->l_waitq,
> +						     is_granted_or_cancelled(lock),
> +						     timeout * HZ);
> +			if (rc == 0)
> +				ldlm_expired_completion_wait(lock, imp);
> +		}
> +		/* Now wait abortable */
> +		if (rc == 0)
> +			rc = l_wait_event_abortable(lock->l_waitq,
> +						    is_granted_or_cancelled(lock));
> +		else
> +			rc = 0;
>  	}
>  
>  	if (rc) {
> 
> 
> 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [lustre-devel] [PATCH 08/19] staging: lustre: simplify waiting in ldlm_completion_ast()
  2018-01-08  3:28 [PATCH 5 v2: 00/19] staging: lustre: use standard wait_event macros NeilBrown
@ 2018-01-08  3:28 ` NeilBrown
  2018-01-17 15:31   ` James Simmons
  0 siblings, 1 reply; 58+ messages in thread
From: NeilBrown @ 2018-01-08  3:28 UTC (permalink / raw)
  To: Oleg Drokin, James Simmons, Andreas Dilger, Greg Kroah-Hartman
  Cc: lkml, lustre

If a signal-callback (lwi_on_signal) is set without lwi_allow_intr, as
is the case in ldlm_completion_ast(), the behavior depends on the
timeout set.

If a timeout is set, then signals are ignored.  If the timeout is
reached, the timeout handler is called.  If the timeout handler
return 0, which ldlm_expired_completion_wait() always does, the
l_wait_event() switches to exactly the behavior if no timeout was set.

If no timeout is set, then "fatal" signals are not ignored.  If one
arrives the callback is run, but as the callback is empty in this
case, that is not relevant.

This can be simplified to:
 if a timeout is wanted
     wait_event_idle_timeout()
     if that timed out, call the timeout handler
 l_wait_event_abortable()

i.e. the code always waits indefinitely.  Sometimes it performs a
non-abortable wait first.  Sometimes it doesn't.  But it only
aborts before the condition is true if it is signaled.
This doesn't quite agree with the comments and debug messages.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/ldlm/ldlm_request.c |   55 +++++++--------------
 1 file changed, 18 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
index a244fa717134..f1233d844bbd 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c
@@ -72,15 +72,6 @@ MODULE_PARM_DESC(ldlm_enqueue_min, "lock enqueue timeout minimum");
 /* in client side, whether the cached locks will be canceled before replay */
 unsigned int ldlm_cancel_unused_locks_before_replay = 1;
 
-static void interrupted_completion_wait(void *data)
-{
-}
-
-struct lock_wait_data {
-	struct ldlm_lock *lwd_lock;
-	__u32	     lwd_conn_cnt;
-};
-
 struct ldlm_async_args {
 	struct lustre_handle lock_handle;
 };
@@ -112,10 +103,8 @@ static int ldlm_request_bufsize(int count, int type)
 	return sizeof(struct ldlm_request) + avail;
 }
 
-static int ldlm_expired_completion_wait(void *data)
+static void ldlm_expired_completion_wait(struct ldlm_lock *lock, struct obd_import *imp2)
 {
-	struct lock_wait_data *lwd = data;
-	struct ldlm_lock *lock = lwd->lwd_lock;
 	struct obd_import *imp;
 	struct obd_device *obd;
 
@@ -135,19 +124,17 @@ static int ldlm_expired_completion_wait(void *data)
 			if (last_dump == 0)
 				libcfs_debug_dumplog();
 		}
-		return 0;
+		return;
 	}
 
 	obd = lock->l_conn_export->exp_obd;
 	imp = obd->u.cli.cl_import;
-	ptlrpc_fail_import(imp, lwd->lwd_conn_cnt);
+	ptlrpc_fail_import(imp, imp2 ? imp2->imp_conn_cnt : 0);
 	LDLM_ERROR(lock,
 		   "lock timed out (enqueued at %lld, %llds ago), entering recovery for %s@%s",
 		   (s64)lock->l_last_activity,
 		   (s64)(ktime_get_real_seconds() - lock->l_last_activity),
 		   obd2cli_tgt(obd), imp->imp_connection->c_remote_uuid.uuid);
-
-	return 0;
 }
 
 /**
@@ -251,10 +238,8 @@ EXPORT_SYMBOL(ldlm_completion_ast_async);
 int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 {
 	/* XXX ALLOCATE - 160 bytes */
-	struct lock_wait_data lwd;
 	struct obd_device *obd;
 	struct obd_import *imp = NULL;
-	struct l_wait_info lwi;
 	__u32 timeout;
 	int rc = 0;
 
@@ -281,32 +266,28 @@ int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
 
 	timeout = ldlm_cp_timeout(lock);
 
-	lwd.lwd_lock = lock;
 	lock->l_last_activity = ktime_get_real_seconds();
 
-	if (ldlm_is_no_timeout(lock)) {
-		LDLM_DEBUG(lock, "waiting indefinitely because of NO_TIMEOUT");
-		lwi = LWI_INTR(interrupted_completion_wait, &lwd);
-	} else {
-		lwi = LWI_TIMEOUT_INTR(timeout * HZ,
-				       ldlm_expired_completion_wait,
-				       interrupted_completion_wait, &lwd);
-	}
-
-	if (imp) {
-		spin_lock(&imp->imp_lock);
-		lwd.lwd_conn_cnt = imp->imp_conn_cnt;
-		spin_unlock(&imp->imp_lock);
-	}
-
 	if (OBD_FAIL_CHECK_RESET(OBD_FAIL_LDLM_INTR_CP_AST,
 				 OBD_FAIL_LDLM_CP_BL_RACE | OBD_FAIL_ONCE)) {
 		ldlm_set_fail_loc(lock);
 		rc = -EINTR;
 	} else {
-		/* Go to sleep until the lock is granted or cancelled. */
-		rc = l_wait_event(lock->l_waitq,
-				  is_granted_or_cancelled(lock), &lwi);
+		/* Go to sleep until the lock is granted or canceled. */
+		if (!ldlm_is_no_timeout(lock)) {
+			/* Wait uninterruptible for a while first */
+			rc = wait_event_idle_timeout(lock->l_waitq,
+						     is_granted_or_cancelled(lock),
+						     timeout * HZ);
+			if (rc == 0)
+				ldlm_expired_completion_wait(lock, imp);
+		}
+		/* Now wait abortable */
+		if (rc == 0)
+			rc = l_wait_event_abortable(lock->l_waitq,
+						    is_granted_or_cancelled(lock));
+		else
+			rc = 0;
 	}
 
 	if (rc) {

^ permalink raw reply related	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2018-02-16 14:18 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-12 21:22 [PATCH 00/19] RESEND staging: lustre: use standard wait_event macros NeilBrown
2018-02-12 21:22 ` [lustre-devel] " NeilBrown
2018-02-12 21:22 ` [PATCH 05/19] staging: lustre: use wait_event_idle_timeout() where appropriate NeilBrown
2018-02-12 21:22   ` [lustre-devel] " NeilBrown
2018-02-12 21:22 ` [PATCH 04/19] staging: lustre: discard cfs_time_seconds() NeilBrown
2018-02-12 21:22   ` [lustre-devel] " NeilBrown
2018-02-12 21:22 ` [PATCH 08/19] staging: lustre: simplify waiting in ldlm_completion_ast() NeilBrown
2018-02-12 21:22   ` [lustre-devel] " NeilBrown
2018-02-12 22:08   ` Patrick Farrell
2018-02-12 22:08     ` Patrick Farrell
2018-02-13  0:17     ` NeilBrown
2018-02-13  0:17       ` NeilBrown
2018-02-13  0:46       ` Patrick Farrell
2018-02-13  0:46         ` Patrick Farrell
2018-02-13 20:17   ` [PATCH 08/19 - v2] " NeilBrown
2018-02-13 20:17     ` [lustre-devel] " NeilBrown
2018-02-16 14:18     ` Greg Kroah-Hartman
2018-02-16 14:18       ` [lustre-devel] " Greg Kroah-Hartman
2018-02-12 21:22 ` [PATCH 06/19] staging: lustre: introduce and use l_wait_event_abortable() NeilBrown
2018-02-12 21:22   ` [lustre-devel] " NeilBrown
2018-02-12 21:36   ` Patrick Farrell
2018-02-12 21:36     ` Patrick Farrell
2018-02-12 23:58     ` NeilBrown
2018-02-12 23:58       ` NeilBrown
2018-02-12 21:22 ` [PATCH 03/19] staging: lustre: replace simple cases of l_wait_event() with wait_event() NeilBrown
2018-02-12 21:22   ` [lustre-devel] " NeilBrown
2018-02-12 21:22 ` [PATCH 02/19] staging: lustre: discard SVC_SIGNAL and related functions NeilBrown
2018-02-12 21:22   ` [lustre-devel] " NeilBrown
2018-02-12 21:22 ` [PATCH 07/19] staging: lustre: simplify l_wait_event when intr handler but no timeout NeilBrown
2018-02-12 21:22   ` [lustre-devel] " NeilBrown
2018-02-12 21:22 ` [PATCH 01/19] sched/wait: add wait_event_idle() functions NeilBrown
2018-02-12 21:22   ` [lustre-devel] " NeilBrown
2018-02-12 23:47 ` [PATCH 13/19] staging: lustre: use wait_event_idle_timeout in ptlrpcd() NeilBrown
2018-02-12 23:47   ` [lustre-devel] " NeilBrown
2018-02-12 23:47 ` [PATCH 10/19] staging: lustre: simplify waiting in ptlrpc_invalidate_import() NeilBrown
2018-02-12 23:47   ` [lustre-devel] " NeilBrown
2018-02-12 23:47 ` [PATCH 19/19] staging: lustre: remove l_wait_event() and related code NeilBrown
2018-02-12 23:47   ` [lustre-devel] " NeilBrown
2018-02-13 18:15   ` Patrick Farrell
2018-02-13 18:15     ` Patrick Farrell
2018-02-12 23:47 ` [PATCH 09/19] staging: lustre: open code polling loop instead of using l_wait_event() NeilBrown
2018-02-12 23:47   ` [lustre-devel] " NeilBrown
2018-02-12 23:47 ` [PATCH 14/19] staging: lustre: improve waiting in sptlrpc_req_refresh_ctx NeilBrown
2018-02-12 23:47   ` [lustre-devel] " NeilBrown
2018-02-12 23:47 ` [PATCH 16/19] staging: lustre: use explicit poll loop in ptlrpc_unregister_reply NeilBrown
2018-02-12 23:47   ` [lustre-devel] " NeilBrown
2018-02-12 23:47 ` [PATCH 17/19] staging: lustre: remove l_wait_event from ptlrpc_set_wait NeilBrown
2018-02-12 23:47   ` [lustre-devel] " NeilBrown
2018-02-12 23:47 ` [PATCH 18/19] staging: lustre: replace l_wait_event_exclusive_head() with wait_event_idle_exclusive NeilBrown
2018-02-12 23:47   ` [lustre-devel] " NeilBrown
2018-02-12 23:47 ` [PATCH 12/19] staging: lustre: make polling loop in ptlrpc_unregister_bulk more obvious NeilBrown
2018-02-12 23:47   ` [lustre-devel] " NeilBrown
2018-02-12 23:47 ` [PATCH 11/19] staging: lustre: remove back_to_sleep() NeilBrown
2018-02-12 23:47   ` [lustre-devel] " NeilBrown
2018-02-12 23:47 ` [PATCH 15/19] staging: lustre: use explicit poll loop in ptlrpc_service_unlink_rqbd NeilBrown
2018-02-12 23:47   ` [lustre-devel] " NeilBrown
  -- strict thread matches above, loose matches on Subject: below --
2018-01-08  3:28 [PATCH 5 v2: 00/19] staging: lustre: use standard wait_event macros NeilBrown
2018-01-08  3:28 ` [lustre-devel] [PATCH 08/19] staging: lustre: simplify waiting in ldlm_completion_ast() NeilBrown
2018-01-17 15:31   ` James Simmons

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.