All of lore.kernel.org
 help / color / mirror / Atom feed
* [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass
@ 2019-02-07  0:03 NeilBrown
  2019-02-07  0:03 ` [lustre-devel] [PATCH 02/21] lustre: obd_class: remove csi_barrier from struct cl_sync_io NeilBrown
                   ` (20 more replies)
  0 siblings, 21 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

I've been reading through obdclass and writing patches as I go.
I'm not done yet, but this patch set to big enough to send for
review.

NeilBrown


---

NeilBrown (21):
      lustre: obdclass: discard csi_end_io
      lustre: obd_class: remove csi_barrier from struct cl_sync_io
      lustre: obdclass: use list_sort() to sort a list.
      lustre: use list*entry macros in place of container_of()
      lustre: use list_first_entry() in lustre subdirectory.
      lustre: use list_first_entry() in lnet/lnet subdirectory.
      lustre: use list_first_entry() in lnet/klnds subdirectory.
      lustre: use list_first_entry() throughout
      lustre: use list_last_entry() throughout
      lustre: obdclass: use cl_object_for_each where appropriate
      lustre: cl_object: remove vestigial debugging.
      lustre: cl_page.c: remove PINVRNT()
      lustre: make cp_ref in cl_page a refcount_t
      lustre: make ccc_users in cl_client_cache a refcount_t
      lustre: obdclass: char obd_ioctl_getdata type.
      lustre: obdclass: normalize a switch statement.
      lustre: obdclass: result of try_module_get() should not be ignored.
      lustre: move debug.c from obdclass to obdecho
      lustre: obdclass: avoid races in class_register_type()
      lustre: obdclass: fix module load locking.
      lustre: make exp_refcount in obd_export a refcount_t


 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c    |   19 ++-
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c |   61 ++++++-----
 .../staging/lustre/lnet/klnds/socklnd/socklnd.c    |    9 +-
 .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c |   79 +++++++-------
 .../lustre/lnet/klnds/socklnd/socklnd_proto.c      |    4 -
 drivers/staging/lustre/lnet/libcfs/libcfs_string.c |   12 +-
 drivers/staging/lustre/lnet/lnet/api-ni.c          |  111 ++++++++++----------
 drivers/staging/lustre/lnet/lnet/config.c          |   22 ++--
 drivers/staging/lustre/lnet/lnet/lib-move.c        |   53 +++++-----
 drivers/staging/lustre/lnet/lnet/lib-msg.c         |   16 +--
 drivers/staging/lustre/lnet/lnet/lib-ptl.c         |    7 +
 drivers/staging/lustre/lnet/lnet/net_fault.c       |   24 ++--
 drivers/staging/lustre/lnet/lnet/nidstrings.c      |    9 +-
 drivers/staging/lustre/lnet/lnet/peer.c            |   24 ++--
 drivers/staging/lustre/lnet/lnet/router.c          |   13 +-
 drivers/staging/lustre/lnet/selftest/conrpc.c      |    5 -
 drivers/staging/lustre/lnet/selftest/console.c     |   39 +++----
 drivers/staging/lustre/lnet/selftest/framework.c   |   44 ++++----
 drivers/staging/lustre/lnet/selftest/rpc.c         |   27 ++---
 drivers/staging/lustre/lnet/selftest/timer.c       |    4 -
 drivers/staging/lustre/lustre/include/cl_object.h  |   19 +--
 .../staging/lustre/lustre/include/lustre_debug.h   |   52 ---------
 .../staging/lustre/lustre/include/lustre_export.h  |    2 
 drivers/staging/lustre/lustre/include/obd.h        |    1 
 drivers/staging/lustre/lustre/include/obd_class.h  |    3 -
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c     |   10 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |    4 -
 drivers/staging/lustre/lustre/llite/dir.c          |   17 +--
 .../staging/lustre/lustre/llite/llite_internal.h   |    2 
 drivers/staging/lustre/lustre/llite/llite_lib.c    |    8 +
 drivers/staging/lustre/lustre/llite/lproc_llite.c  |    2 
 drivers/staging/lustre/lustre/llite/statahead.c    |   23 ++--
 drivers/staging/lustre/lustre/llite/vvp_page.c     |    9 +-
 drivers/staging/lustre/lustre/lov/lov_io.c         |    9 +-
 drivers/staging/lustre/lustre/lov/lov_obd.c        |   15 +--
 drivers/staging/lustre/lustre/lov/lov_page.c       |    3 -
 drivers/staging/lustre/lustre/obdclass/Makefile    |    2 
 drivers/staging/lustre/lustre/obdclass/cl_io.c     |   91 ++++------------
 drivers/staging/lustre/lustre/obdclass/cl_lock.c   |    5 -
 drivers/staging/lustre/lustre/obdclass/cl_object.c |  110 ++++++++------------
 drivers/staging/lustre/lustre/obdclass/cl_page.c   |   77 ++++----------
 drivers/staging/lustre/lustre/obdclass/class_obd.c |   32 ++----
 drivers/staging/lustre/lustre/obdclass/debug.c     |   96 -----------------
 drivers/staging/lustre/lustre/obdclass/genops.c    |   90 ++++++++++------
 drivers/staging/lustre/lustre/obdclass/lu_object.c |    7 +
 .../staging/lustre/lustre/obdclass/lustre_peer.c   |    5 -
 drivers/staging/lustre/lustre/obdecho/Makefile     |    2 
 drivers/staging/lustre/lustre/obdecho/debug.c      |   96 +++++++++++++++++
 .../staging/lustre/lustre/obdecho/echo_client.c    |    3 -
 .../staging/lustre/lustre/obdecho/echo_internal.h  |    4 +
 drivers/staging/lustre/lustre/osc/osc_cache.c      |   17 ++-
 drivers/staging/lustre/lustre/osc/osc_lock.c       |    7 +
 drivers/staging/lustre/lustre/osc/osc_page.c       |   21 ++--
 drivers/staging/lustre/lustre/osc/osc_request.c    |   11 +-
 drivers/staging/lustre/lustre/ptlrpc/client.c      |   14 +--
 drivers/staging/lustre/lustre/ptlrpc/layout.c      |    1 
 drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c    |    6 +
 .../staging/lustre/lustre/ptlrpc/pack_generic.c    |    4 -
 drivers/staging/lustre/lustre/ptlrpc/sec_gc.c      |    6 +
 drivers/staging/lustre/lustre/ptlrpc/service.c     |   68 ++++++------
 60 files changed, 689 insertions(+), 847 deletions(-)
 delete mode 100644 drivers/staging/lustre/lustre/include/lustre_debug.h
 delete mode 100644 drivers/staging/lustre/lustre/obdclass/debug.c
 create mode 100644 drivers/staging/lustre/lustre/obdecho/debug.c

--
Signature

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

* [lustre-devel] [PATCH 01/21] lustre: obdclass: discard csi_end_io
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (3 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 06/21] lustre: use list_first_entry() in lnet/lnet subdirectory NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-07  0:20   ` Andreas Dilger
  2019-02-11  0:19   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 04/21] lustre: use list*entry macros in place of container_of() NeilBrown
                   ` (15 subsequent siblings)
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

The csi_end_io field in "struct cl_sync_io" is always
set to cl_sync_io_end(), which is a tiny function.
This indirection doesn't help clarity, so remove it.

Inline the function in the one place where ->csi_end_io()
is called, and discard the field.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/include/cl_object.h |    7 +-----
 drivers/staging/lustre/lustre/obdclass/cl_io.c    |   26 ++++++---------------
 drivers/staging/lustre/lustre/obdclass/cl_lock.c  |    2 +-
 drivers/staging/lustre/lustre/osc/osc_lock.c      |    2 +-
 4 files changed, 10 insertions(+), 27 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
index b8ae41de7192..71ba73cdbb5e 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -2395,18 +2395,13 @@ struct cl_sync_io {
 	atomic_t		csi_barrier;
 	/** completion to be signaled when transfer is complete. */
 	wait_queue_head_t	csi_waitq;
-	/** callback to invoke when this IO is finished */
-	void			(*csi_end_io)(const struct lu_env *,
-					      struct cl_sync_io *);
 };
 
-void cl_sync_io_init(struct cl_sync_io *anchor, int nr,
-		     void (*end)(const struct lu_env *, struct cl_sync_io *));
+void cl_sync_io_init(struct cl_sync_io *anchor, int nr);
 int  cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
 		     long timeout);
 void cl_sync_io_note(const struct lu_env *env, struct cl_sync_io *anchor,
 		     int ioret);
-void cl_sync_io_end(const struct lu_env *env, struct cl_sync_io *anchor);
 
 /** @} cl_sync_io */
 
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
index 09fd45d5394a..e9ad055f84b8 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -668,7 +668,7 @@ int cl_io_submit_sync(const struct lu_env *env, struct cl_io *io,
 		pg->cp_sync_io = anchor;
 	}
 
-	cl_sync_io_init(anchor, queue->c2_qin.pl_nr, &cl_sync_io_end);
+	cl_sync_io_init(anchor, queue->c2_qin.pl_nr);
 	rc = cl_io_submit_rw(env, io, iot, queue);
 	if (rc == 0) {
 		/*
@@ -1039,31 +1039,16 @@ void cl_req_attr_set(const struct lu_env *env, struct cl_object *obj,
 }
 EXPORT_SYMBOL(cl_req_attr_set);
 
-/* cl_sync_io_callback assumes the caller must call cl_sync_io_wait() to
- * wait for the IO to finish.
- */
-void cl_sync_io_end(const struct lu_env *env, struct cl_sync_io *anchor)
-{
-	wake_up_all(&anchor->csi_waitq);
-
-	/* it's safe to nuke or reuse anchor now */
-	atomic_set(&anchor->csi_barrier, 0);
-}
-EXPORT_SYMBOL(cl_sync_io_end);
-
 /**
  * Initialize synchronous io wait anchor
  */
-void cl_sync_io_init(struct cl_sync_io *anchor, int nr,
-		     void (*end)(const struct lu_env *, struct cl_sync_io *))
+void cl_sync_io_init(struct cl_sync_io *anchor, int nr)
 {
 	memset(anchor, 0, sizeof(*anchor));
 	init_waitqueue_head(&anchor->csi_waitq);
 	atomic_set(&anchor->csi_sync_nr, nr);
 	atomic_set(&anchor->csi_barrier, nr > 0);
 	anchor->csi_sync_rc = 0;
-	anchor->csi_end_io = end;
-	LASSERT(end);
 }
 EXPORT_SYMBOL(cl_sync_io_init);
 
@@ -1120,8 +1105,11 @@ void cl_sync_io_note(const struct lu_env *env, struct cl_sync_io *anchor,
 	 */
 	LASSERT(atomic_read(&anchor->csi_sync_nr) > 0);
 	if (atomic_dec_and_test(&anchor->csi_sync_nr)) {
-		LASSERT(anchor->csi_end_io);
-		anchor->csi_end_io(env, anchor);
+
+		wake_up_all(&anchor->csi_waitq);
+		/* it's safe to nuke or reuse anchor now */
+		atomic_set(&anchor->csi_barrier, 0);
+
 		/* Can't access anchor any more */
 	}
 }
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
index d7bcb8c203dd..8133d992cc73 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
@@ -189,7 +189,7 @@ int cl_lock_request(const struct lu_env *env, struct cl_io *io,
 
 	if ((enq_flags & CEF_ASYNC) && !(enq_flags & CEF_AGL)) {
 		anchor = &cl_env_info(env)->clt_anchor;
-		cl_sync_io_init(anchor, 1, cl_sync_io_end);
+		cl_sync_io_init(anchor, 1);
 	}
 
 	rc = cl_lock_enqueue(env, io, lock, anchor);
diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c
index 5a1717c7d132..da8c3978fab8 100644
--- a/drivers/staging/lustre/lustre/osc/osc_lock.c
+++ b/drivers/staging/lustre/lustre/osc/osc_lock.c
@@ -877,7 +877,7 @@ static int osc_lock_enqueue_wait(const struct lu_env *env,
 			continue;
 
 		/* wait for conflicting lock to be canceled */
-		cl_sync_io_init(waiter, 1, cl_sync_io_end);
+		cl_sync_io_init(waiter, 1);
 		oscl->ols_owner = waiter;
 
 		spin_lock(&tmp_oscl->ols_lock);

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

* [lustre-devel] [PATCH 02/21] lustre: obd_class: remove csi_barrier from struct cl_sync_io
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  0:09   ` Andreas Dilger
  2019-02-11  0:34   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 05/21] lustre: use list_first_entry() in lustre subdirectory NeilBrown
                   ` (19 subsequent siblings)
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

This flag is used to ensure that structure isn't freed before
the wakeup completes.  The same can be achieved using the
csi_waitq.lock and calling wake_up_all_locked().

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/include/cl_object.h |    2 --
 drivers/staging/lustre/lustre/obdclass/cl_io.c    |   16 +++++++---------
 2 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
index 71ba73cdbb5e..13d79810dd39 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -2391,8 +2391,6 @@ struct cl_sync_io {
 	atomic_t		csi_sync_nr;
 	/** error code. */
 	int			csi_sync_rc;
-	/** barrier of destroy this structure */
-	atomic_t		csi_barrier;
 	/** completion to be signaled when transfer is complete. */
 	wait_queue_head_t	csi_waitq;
 };
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
index e9ad055f84b8..beac7e8bc92a 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -1047,7 +1047,6 @@ void cl_sync_io_init(struct cl_sync_io *anchor, int nr)
 	memset(anchor, 0, sizeof(*anchor));
 	init_waitqueue_head(&anchor->csi_waitq);
 	atomic_set(&anchor->csi_sync_nr, nr);
-	atomic_set(&anchor->csi_barrier, nr > 0);
 	anchor->csi_sync_rc = 0;
 }
 EXPORT_SYMBOL(cl_sync_io_init);
@@ -1080,11 +1079,10 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
 	} else {
 		rc = anchor->csi_sync_rc;
 	}
+	/* We take the lock to ensure that cl_sync_io_note() has finished */
+	spin_lock(&anchor->csi_waitq.lock);
 	LASSERT(atomic_read(&anchor->csi_sync_nr) == 0);
-
-	/* wait until cl_sync_io_note() has done wakeup */
-	while (unlikely(atomic_read(&anchor->csi_barrier) != 0))
-		cpu_relax();
+	spin_unlock(&anchor->csi_waitq.lock);
 
 	return rc;
 }
@@ -1104,11 +1102,11 @@ void cl_sync_io_note(const struct lu_env *env, struct cl_sync_io *anchor,
 	 * IO.
 	 */
 	LASSERT(atomic_read(&anchor->csi_sync_nr) > 0);
-	if (atomic_dec_and_test(&anchor->csi_sync_nr)) {
+	if (atomic_dec_and_lock(&anchor->csi_sync_nr,
+				&anchor->csi_waitq.lock)) {
 
-		wake_up_all(&anchor->csi_waitq);
-		/* it's safe to nuke or reuse anchor now */
-		atomic_set(&anchor->csi_barrier, 0);
+		wake_up_all_locked(&anchor->csi_waitq);
+		spin_unlock(&anchor->csi_waitq.lock);
 
 		/* Can't access anchor any more */
 	}

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

* [lustre-devel] [PATCH 03/21] lustre: obdclass: use list_sort() to sort a list.
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
  2019-02-07  0:03 ` [lustre-devel] [PATCH 02/21] lustre: obd_class: remove csi_barrier from struct cl_sync_io NeilBrown
  2019-02-07  0:03 ` [lustre-devel] [PATCH 05/21] lustre: use list_first_entry() in lustre subdirectory NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  0:13   ` Andreas Dilger
  2019-02-11  0:39   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 06/21] lustre: use list_first_entry() in lnet/lnet subdirectory NeilBrown
                   ` (17 subsequent siblings)
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

Rather than a bespoke bubble-sort, use list_sort() to
sort this linked list.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/obdclass/cl_io.c |   51 +++++-------------------
 1 file changed, 10 insertions(+), 41 deletions(-)

diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
index beac7e8bc92a..7bf02350f19d 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -42,6 +42,7 @@
 #include <obd_support.h>
 #include <lustre_fid.h>
 #include <linux/list.h>
+#include <linux/list_sort.h>
 #include <linux/sched.h>
 #include <cl_object.h>
 #include "cl_internal.h"
@@ -213,9 +214,15 @@ int cl_io_rw_init(const struct lu_env *env, struct cl_io *io,
 }
 EXPORT_SYMBOL(cl_io_rw_init);
 
-static int cl_lock_descr_sort(const struct cl_lock_descr *d0,
-			      const struct cl_lock_descr *d1)
+static int cl_lock_descr_cmp(void *priv,
+			     struct list_head *a, struct list_head *b)
 {
+	const struct cl_io_lock_link *l0 = list_entry(a, struct cl_io_lock_link, cill_linkage);
+	const struct cl_io_lock_link *l1 = list_entry(b, struct cl_io_lock_link, cill_linkage);
+
+	const struct cl_lock_descr *d0 = &l0->cill_descr;
+	const struct cl_lock_descr *d1 = &l1->cill_descr;
+
 	return lu_fid_cmp(lu_object_fid(&d0->cld_obj->co_lu),
 			  lu_object_fid(&d1->cld_obj->co_lu));
 }
@@ -225,45 +232,7 @@ static int cl_lock_descr_sort(const struct cl_lock_descr *d0,
  */
 static void cl_io_locks_sort(struct cl_io *io)
 {
-	int done = 0;
-
-	/* hidden treasure: bubble sort for now. */
-	do {
-		struct cl_io_lock_link *curr;
-		struct cl_io_lock_link *prev;
-		struct cl_io_lock_link *temp;
-
-		done = 1;
-		prev = NULL;
-
-		list_for_each_entry_safe(curr, temp,
-					 &io->ci_lockset.cls_todo,
-					 cill_linkage) {
-			if (prev) {
-				switch (cl_lock_descr_sort(&prev->cill_descr,
-							   &curr->cill_descr)) {
-				case 0:
-					/*
-					 * IMPOSSIBLE: Identical locks are
-					 *	     already removed at
-					 *	     this point.
-					 */
-				default:
-					LBUG();
-				case 1:
-					list_move_tail(&curr->cill_linkage,
-						       &prev->cill_linkage);
-					done = 0;
-					continue; /* don't change prev: it's
-						   * still "previous"
-						   */
-				case -1: /* already in order */
-					break;
-				}
-			}
-			prev = curr;
-		}
-	} while (!done);
+	list_sort(NULL, &io->ci_lockset.cls_todo, cl_lock_descr_cmp);
 }
 
 static void cl_lock_descr_merge(struct cl_lock_descr *d0,

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

* [lustre-devel] [PATCH 04/21] lustre: use list*entry macros in place of container_of()
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (4 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 01/21] lustre: obdclass: discard csi_end_io NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  0:25   ` Andreas Dilger
  2019-02-11  1:32   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 13/21] lustre: make cp_ref in cl_page a refcount_t NeilBrown
                   ` (14 subsequent siblings)
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

There are a number of places that use container_of() but where
list_first_entry(), or list_last_entry() make the meaning more clear.
So change them over.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |    4 ++--
 drivers/staging/lustre/lustre/obdclass/cl_io.c     |    4 ++--
 drivers/staging/lustre/lustre/obdclass/cl_object.c |   13 ++++++++-----
 drivers/staging/lustre/lustre/obdclass/cl_page.c   |    4 ++--
 drivers/staging/lustre/lustre/obdclass/lu_object.c |    7 +++----
 5 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
index 85c5047f4ba2..74c7644d6ef8 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
@@ -987,8 +987,8 @@ struct ldlm_namespace *ldlm_namespace_first_locked(enum ldlm_side client)
 {
 	LASSERT(mutex_is_locked(ldlm_namespace_lock(client)));
 	LASSERT(!list_empty(ldlm_namespace_list(client)));
-	return container_of(ldlm_namespace_list(client)->next,
-		struct ldlm_namespace, ns_list_chain);
+	return list_first_entry(ldlm_namespace_list(client),
+				struct ldlm_namespace, ns_list_chain);
 }
 
 /** Create and initialize new resource. */
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
index 7bf02350f19d..34b4e63e7d1a 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -93,8 +93,8 @@ void cl_io_fini(const struct lu_env *env, struct cl_io *io)
 	LINVRNT(cl_io_invariant(io));
 
 	while (!list_empty(&io->ci_layers)) {
-		slice = container_of(io->ci_layers.prev, struct cl_io_slice,
-				     cis_linkage);
+		slice = list_last_entry(&io->ci_layers, struct cl_io_slice,
+					cis_linkage);
 		list_del_init(&slice->cis_linkage);
 		if (slice->cis_iop->op[io->ci_type].cio_fini)
 			slice->cis_iop->op[io->ci_type].cio_fini(env, slice);
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
index 05d784ae7a6c..f724b2d62df1 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
@@ -649,8 +649,8 @@ static struct lu_env *cl_env_obtain(void *debug)
 	if (cl_envs[cpu].cec_count > 0) {
 		int rc;
 
-		cle = container_of(cl_envs[cpu].cec_envs.next, struct cl_env,
-				   ce_linkage);
+		cle = list_first_entry(&cl_envs[cpu].cec_envs, struct cl_env,
+				       ce_linkage);
 		list_del_init(&cle->ce_linkage);
 		cl_envs[cpu].cec_count--;
 		read_unlock(&cl_envs[cpu].cec_guard);
@@ -748,9 +748,12 @@ unsigned int cl_env_cache_purge(unsigned int nr)
 
 	for_each_possible_cpu(i) {
 		write_lock(&cl_envs[i].cec_guard);
-		for (; !list_empty(&cl_envs[i].cec_envs) && nr > 0; --nr) {
-			cle = container_of(cl_envs[i].cec_envs.next,
-					   struct cl_env, ce_linkage);
+		for (; nr >0 &&
+			     (cle = list_first_entry_or_null(
+				     &cl_envs[i].cec_envs,
+				     struct cl_env,
+				     ce_linkage)) != NULL;
+		     --nr) {
 			list_del_init(&cle->ce_linkage);
 			LASSERT(cl_envs[i].cec_count > 0);
 			cl_envs[i].cec_count--;
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
index b1b4dc7ea22f..d025ea55818f 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
@@ -690,8 +690,8 @@ int cl_page_is_vmlocked(const struct lu_env *env, const struct cl_page *pg)
 	const struct cl_page_slice *slice;
 	int result;
 
-	slice = container_of(pg->cp_layers.next,
-			     const struct cl_page_slice, cpl_linkage);
+	slice = list_first_entry(&pg->cp_layers,
+				 const struct cl_page_slice, cpl_linkage);
 	PASSERT(env, pg, slice->cpl_ops->cpo_is_vmlocked);
 	/*
 	 * Call ->cpo_is_vmlocked() directly instead of going through
diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c
index 3bd48748f46c..639c298b6a90 100644
--- a/drivers/staging/lustre/lustre/obdclass/lu_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c
@@ -349,7 +349,7 @@ static void lu_object_free(const struct lu_env *env, struct lu_object *o)
 		 * lives as long as possible and ->loo_object_free() methods
 		 * can look at its contents.
 		 */
-		o = container_of(splice.prev, struct lu_object, lo_linkage);
+		o = list_last_entry(&splice, struct lu_object, lo_linkage);
 		list_del_init(&o->lo_linkage);
 		o->lo_ops->loo_object_free(env, o);
 	}
@@ -432,9 +432,8 @@ int lu_site_purge_objects(const struct lu_env *env, struct lu_site *s,
 		 * Free everything on the dispose list. This is safe against
 		 * races due to the reasons described in lu_object_put().
 		 */
-		while (!list_empty(&dispose)) {
-			h = container_of(dispose.next,
-					 struct lu_object_header, loh_lru);
+		while ((h = list_first_entry_or_null(
+				&dispose, struct lu_object_header, loh_lru)) != NULL) {
 			list_del_init(&h->loh_lru);
 			lu_object_free(env, lu_object_top(h));
 			lprocfs_counter_incr(s->ls_stats, LU_SS_LRU_PURGED);

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

* [lustre-devel] [PATCH 05/21] lustre: use list_first_entry() in lustre subdirectory.
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
  2019-02-07  0:03 ` [lustre-devel] [PATCH 02/21] lustre: obd_class: remove csi_barrier from struct cl_sync_io NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  0:31   ` Andreas Dilger
  2019-02-11  1:45   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 03/21] lustre: obdclass: use list_sort() to sort a list NeilBrown
                   ` (18 subsequent siblings)
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

Convert
  list_entry(foo->next .....)
to
  list_first_entry(foo, ....)

in 'lustre'

In several cases the call is combined with
a list_empty() test and list_first_entry_or_null() is used

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/include/cl_object.h  |    2 -
 drivers/staging/lustre/lustre/llite/statahead.c    |   23 ++++----
 drivers/staging/lustre/lustre/lov/lov_io.c         |    9 +--
 drivers/staging/lustre/lustre/obdclass/cl_page.c   |    9 +--
 drivers/staging/lustre/lustre/obdclass/genops.c    |   22 ++++---
 .../staging/lustre/lustre/obdclass/lustre_peer.c   |    5 +-
 drivers/staging/lustre/lustre/osc/osc_cache.c      |   17 +++---
 drivers/staging/lustre/lustre/osc/osc_lock.c       |    5 +-
 drivers/staging/lustre/lustre/osc/osc_page.c       |   17 +++---
 drivers/staging/lustre/lustre/osc/osc_request.c    |    8 +--
 drivers/staging/lustre/lustre/ptlrpc/client.c      |    8 +--
 drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c    |    6 +-
 .../staging/lustre/lustre/ptlrpc/pack_generic.c    |    4 +
 drivers/staging/lustre/lustre/ptlrpc/sec_gc.c      |    6 +-
 drivers/staging/lustre/lustre/ptlrpc/service.c     |   59 ++++++++++----------
 15 files changed, 101 insertions(+), 99 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
index 13d79810dd39..53fd8d469e55 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -2335,7 +2335,7 @@ static inline struct cl_page *cl_page_list_last(struct cl_page_list *plist)
 static inline struct cl_page *cl_page_list_first(struct cl_page_list *plist)
 {
 	LASSERT(plist->pl_nr > 0);
-	return list_entry(plist->pl_pages.next, struct cl_page, cp_batch);
+	return list_first_entry(&plist->pl_pages, struct cl_page, cp_batch);
 }
 
 /**
diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c
index 0c305ba2b178..de7586d11d14 100644
--- a/drivers/staging/lustre/lustre/llite/statahead.c
+++ b/drivers/staging/lustre/lustre/llite/statahead.c
@@ -643,8 +643,8 @@ static void sa_handle_callback(struct ll_statahead_info *sai)
 			spin_unlock(&lli->lli_sa_lock);
 			break;
 		}
-		entry = list_entry(sai->sai_interim_entries.next,
-				   struct sa_entry, se_list);
+		entry = list_first_entry(&sai->sai_interim_entries,
+					 struct sa_entry, se_list);
 		list_del_init(&entry->se_list);
 		spin_unlock(&lli->lli_sa_lock);
 
@@ -893,9 +893,10 @@ static int ll_agl_thread(void *arg)
 		/* The statahead thread maybe help to process AGL entries,
 		 * so check whether list empty again.
 		 */
-		if (!list_empty(&sai->sai_agls)) {
-			clli = list_entry(sai->sai_agls.next,
-					  struct ll_inode_info, lli_agl_list);
+		clli = list_first_entry_or_null(&sai->sai_agls,
+						struct ll_inode_info,
+						lli_agl_list);
+		if (clli) {
 			list_del_init(&clli->lli_agl_list);
 			spin_unlock(&plli->lli_agl_lock);
 			ll_agl_trigger(&clli->lli_vfs_inode, sai);
@@ -912,9 +913,9 @@ static int ll_agl_thread(void *arg)
 
 	spin_lock(&plli->lli_agl_lock);
 	sai->sai_agl_valid = 0;
-	while (!list_empty(&sai->sai_agls)) {
-		clli = list_entry(sai->sai_agls.next,
-				  struct ll_inode_info, lli_agl_list);
+	while ((clli = list_first_entry_or_null(&sai->sai_agls,
+						struct ll_inode_info,
+						lli_agl_list)) != NULL) {
 		list_del_init(&clli->lli_agl_list);
 		spin_unlock(&plli->lli_agl_lock);
 		clli->lli_agl_index = 0;
@@ -1055,9 +1056,9 @@ static int ll_statahead_thread(void *arg)
 				       !agl_list_empty(sai)) {
 					struct ll_inode_info *clli;
 
-					clli = list_entry(sai->sai_agls.next,
-							  struct ll_inode_info,
-							  lli_agl_list);
+					clli = list_first_entry(&sai->sai_agls,
+								struct ll_inode_info,
+								lli_agl_list);
 					list_del_init(&clli->lli_agl_list);
 					spin_unlock(&lli->lli_agl_lock);
 
diff --git a/drivers/staging/lustre/lustre/lov/lov_io.c b/drivers/staging/lustre/lustre/lov/lov_io.c
index de43f47d455e..77efb86d8683 100644
--- a/drivers/staging/lustre/lustre/lov/lov_io.c
+++ b/drivers/staging/lustre/lustre/lov/lov_io.c
@@ -270,14 +270,13 @@ static void lov_io_fini(const struct lu_env *env, const struct cl_io_slice *ios)
 {
 	struct lov_io *lio = cl2lov_io(env, ios);
 	struct lov_object *lov = cl2lov(ios->cis_obj);
+	struct lov_io_sub *sub;
 
 	LASSERT(list_empty(&lio->lis_active));
 
-	while (!list_empty(&lio->lis_subios)) {
-		struct lov_io_sub *sub = list_entry(lio->lis_subios.next,
-						    struct lov_io_sub,
-						    sub_list);
-
+	while ((sub = list_first_entry_or_null(&lio->lis_subios,
+					       struct lov_io_sub,
+					       sub_list)) != NULL) {
 		list_del_init(&sub->sub_list);
 		lio->lis_nr_subios--;
 
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
index d025ea55818f..057318deaa4e 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
@@ -96,16 +96,15 @@ cl_page_at_trusted(const struct cl_page *page,
 static void cl_page_free(const struct lu_env *env, struct cl_page *page)
 {
 	struct cl_object *obj = page->cp_obj;
+	struct cl_page_slice *slice;
 
 	PASSERT(env, page, list_empty(&page->cp_batch));
 	PASSERT(env, page, !page->cp_owner);
 	PASSERT(env, page, page->cp_state == CPS_FREEING);
 
-	while (!list_empty(&page->cp_layers)) {
-		struct cl_page_slice *slice;
-
-		slice = list_entry(page->cp_layers.next,
-				   struct cl_page_slice, cpl_linkage);
+	while ((slice = list_first_entry_or_null(&page->cp_layers,
+						 struct cl_page_slice,
+						 cpl_linkage)) != NULL) {
 		list_del_init(page->cp_layers.next);
 		if (unlikely(slice->cpl_ops->cpo_fini))
 			slice->cpl_ops->cpo_fini(env, slice);
diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
index cee144c0ac6c..382eaf519a79 100644
--- a/drivers/staging/lustre/lustre/obdclass/genops.c
+++ b/drivers/staging/lustre/lustre/obdclass/genops.c
@@ -939,6 +939,8 @@ void class_unlink_export(struct obd_export *exp)
 /* Import management functions */
 static void class_import_destroy(struct obd_import *imp)
 {
+	struct obd_import_conn *imp_conn;
+
 	CDEBUG(D_IOCTL, "destroying import %p for %s\n", imp,
 	       imp->imp_obd->obd_name);
 
@@ -946,11 +948,9 @@ static void class_import_destroy(struct obd_import *imp)
 
 	ptlrpc_put_connection_superhack(imp->imp_connection);
 
-	while (!list_empty(&imp->imp_conn_list)) {
-		struct obd_import_conn *imp_conn;
-
-		imp_conn = list_entry(imp->imp_conn_list.next,
-				      struct obd_import_conn, oic_item);
+	while ((imp_conn = list_first_entry_or_null(&imp->imp_conn_list,
+						    struct obd_import_conn,
+						    oic_item)) != NULL) {
 		list_del_init(&imp_conn->oic_item);
 		ptlrpc_put_connection_superhack(imp_conn->oic_conn);
 		kfree(imp_conn);
@@ -1356,8 +1356,9 @@ void obd_put_request_slot(struct client_obd *cli)
 	/* If there is free slot, wakeup the first waiter. */
 	if (!list_empty(&cli->cl_loi_read_list) &&
 	    likely(cli->cl_r_in_flight < cli->cl_max_rpcs_in_flight)) {
-		orsw = list_entry(cli->cl_loi_read_list.next,
-				  struct obd_request_slot_waiter, orsw_entry);
+		orsw = list_first_entry(&cli->cl_loi_read_list,
+					struct obd_request_slot_waiter,
+					orsw_entry);
 		list_del_init(&orsw->orsw_entry);
 		cli->cl_r_in_flight++;
 		wake_up(&orsw->orsw_waitq);
@@ -1409,11 +1410,12 @@ int obd_set_max_rpcs_in_flight(struct client_obd *cli, u32 max)
 
 	/* We increase the max_rpcs_in_flight, then wakeup some waiters. */
 	for (i = 0; i < diff; i++) {
-		if (list_empty(&cli->cl_loi_read_list))
+		orsw = list_first_entry_or_null(&cli->cl_loi_read_list,
+						struct obd_request_slot_waiter,
+						orsw_entry);
+		if (!orsw)
 			break;
 
-		orsw = list_entry(cli->cl_loi_read_list.next,
-				  struct obd_request_slot_waiter, orsw_entry);
 		list_del_init(&orsw->orsw_entry);
 		cli->cl_r_in_flight++;
 		wake_up(&orsw->orsw_waitq);
diff --git a/drivers/staging/lustre/lustre/obdclass/lustre_peer.c b/drivers/staging/lustre/lustre/obdclass/lustre_peer.c
index 0c3e0ca8c03c..69a3b322119d 100644
--- a/drivers/staging/lustre/lustre/obdclass/lustre_peer.c
+++ b/drivers/staging/lustre/lustre/obdclass/lustre_peer.c
@@ -156,9 +156,8 @@ int class_del_uuid(const char *uuid)
 		return -EINVAL;
 	}
 
-	while (!list_empty(&deathrow)) {
-		data = list_entry(deathrow.next, struct uuid_nid_data,
-				  un_list);
+	while ((data = list_first_entry_or_null(&deathrow, struct uuid_nid_data,
+						un_list)) != NULL) {
 		list_del(&data->un_list);
 
 		CDEBUG(D_INFO, "del uuid %s %s/%d\n",
diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c
index 673e139bff82..4359a9320f37 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cache.c
+++ b/drivers/staging/lustre/lustre/osc/osc_cache.c
@@ -2000,9 +2000,9 @@ static unsigned int get_write_extents(struct osc_object *obj,
 		EASSERT(ext->oe_nr_pages <= data.erd_max_pages, ext);
 	}
 
-	while (!list_empty(&obj->oo_urgent_exts)) {
-		ext = list_entry(obj->oo_urgent_exts.next,
-				 struct osc_extent, oe_link);
+	while ((ext = list_first_entry_or_null(&obj->oo_urgent_exts,
+					       struct osc_extent,
+					       oe_link)) != NULL) {
 		if (!try_to_add_extent_for_io(cli, ext, &data))
 			return data.erd_page_count;
 	}
@@ -2014,9 +2014,9 @@ static unsigned int get_write_extents(struct osc_object *obj,
 	 * is so we don't miss adding extra extents to an RPC containing high
 	 * priority or urgent extents.
 	 */
-	while (!list_empty(&obj->oo_full_exts)) {
-		ext = list_entry(obj->oo_full_exts.next,
-				 struct osc_extent, oe_link);
+	while ((ext = list_first_entry_or_null(&obj->oo_full_exts,
+					       struct osc_extent,
+					       oe_link)) != NULL) {
 		if (!try_to_add_extent_for_io(cli, ext, &data))
 			break;
 	}
@@ -2751,10 +2751,11 @@ int osc_cache_truncate_start(const struct lu_env *env, struct osc_object *obj,
 
 	osc_list_maint(cli, obj);
 
-	while (!list_empty(&list)) {
+	while ((ext = list_first_entry_or_null(&list,
+					       struct osc_extent,
+					       oe_link)) != NULL) {
 		int rc;
 
-		ext = list_entry(list.next, struct osc_extent, oe_link);
 		list_del_init(&ext->oe_link);
 
 		/* extent may be in OES_ACTIVE state because inode mutex
diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c
index da8c3978fab8..75b5dedd4fbb 100644
--- a/drivers/staging/lustre/lustre/osc/osc_lock.c
+++ b/drivers/staging/lustre/lustre/osc/osc_lock.c
@@ -834,8 +834,9 @@ static void osc_lock_wake_waiters(const struct lu_env *env,
 	while (!list_empty(&oscl->ols_waiting_list)) {
 		struct osc_lock *scan;
 
-		scan = list_entry(oscl->ols_waiting_list.next, struct osc_lock,
-				  ols_wait_entry);
+		scan = list_first_entry(&oscl->ols_waiting_list,
+					struct osc_lock,
+					ols_wait_entry);
 		list_del_init(&scan->ols_wait_entry);
 
 		cl_sync_io_note(env, scan->ols_owner, 0);
diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c
index 71f548570fec..135bfe5e1b37 100644
--- a/drivers/staging/lustre/lustre/osc/osc_page.c
+++ b/drivers/staging/lustre/lustre/osc/osc_page.c
@@ -572,8 +572,8 @@ long osc_lru_shrink(const struct lu_env *env, struct client_obd *cli,
 		if (--maxscan < 0)
 			break;
 
-		opg = list_entry(cli->cl_lru_list.next, struct osc_page,
-				 ops_lru);
+		opg = list_first_entry(&cli->cl_lru_list, struct osc_page,
+				       ops_lru);
 		page = opg->ops_cl.cpl_page;
 		if (lru_page_busy(cli, page)) {
 			list_move_tail(&opg->ops_lru, &cli->cl_lru_list);
@@ -708,9 +708,10 @@ static long osc_lru_reclaim(struct client_obd *cli, unsigned long npages)
 	list_move_tail(&cli->cl_lru_osc, &cache->ccc_lru);
 
 	max_scans = atomic_read(&cache->ccc_users) - 2;
-	while (--max_scans > 0 && !list_empty(&cache->ccc_lru)) {
-		cli = list_entry(cache->ccc_lru.next, struct client_obd,
-				 cl_lru_osc);
+	while (--max_scans > 0 &&
+	       (cli = list_first_entry_or_null(&cache->ccc_lru,
+					       struct client_obd,
+					       cl_lru_osc)) != NULL) {
 
 		CDEBUG(D_CACHE, "%s: cli %p LRU pages: %ld, busy: %ld.\n",
 		       cli_name(cli), cli,
@@ -1047,9 +1048,9 @@ unsigned long osc_cache_shrink_scan(struct shrinker *sk,
 		return SHRINK_STOP;
 
 	spin_lock(&osc_shrink_lock);
-	while (!list_empty(&osc_shrink_list)) {
-		cli = list_entry(osc_shrink_list.next, struct client_obd,
-				 cl_shrink_list);
+	while ((cli = list_first_entry_or_null(&osc_shrink_list,
+					       struct client_obd,
+					       cl_shrink_list)) != NULL) {
 
 		if (!stop_anchor)
 			stop_anchor = cli;
diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
index 86f9de611221..9e72fa8f68b3 100644
--- a/drivers/staging/lustre/lustre/osc/osc_request.c
+++ b/drivers/staging/lustre/lustre/osc/osc_request.c
@@ -1936,7 +1936,7 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
 	}
 
 	/* first page in the list */
-	oap = list_entry(rpc_list.next, typeof(*oap), oap_rpc_item);
+	oap = list_first_entry(&rpc_list, typeof(*oap), oap_rpc_item);
 
 	crattr = &osc_env_info(env)->oti_req_attr;
 	memset(crattr, 0, sizeof(*crattr));
@@ -2019,9 +2019,9 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
 		/* this should happen rarely and is pretty bad, it makes the
 		 * pending list not follow the dirty order
 		 */
-		while (!list_empty(ext_list)) {
-			ext = list_entry(ext_list->next, struct osc_extent,
-					 oe_link);
+		while ((ext = list_first_entry_or_null(ext_list,
+						       struct osc_extent,
+						       oe_link)) != NULL) {
 			list_del_init(&ext->oe_link);
 			osc_extent_finish(env, ext, 0, rc);
 		}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index 2c519ad6f7cc..a78d49621c42 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -625,8 +625,8 @@ ptlrpc_prep_req_from_pool(struct ptlrpc_request_pool *pool)
 		return NULL;
 	}
 
-	request = list_entry(pool->prp_req_list.next, struct ptlrpc_request,
-			     rq_list);
+	request = list_first_entry(&pool->prp_req_list, struct ptlrpc_request,
+				   rq_list);
 	list_del_init(&request->rq_list);
 	spin_unlock(&pool->prp_lock);
 
@@ -1274,8 +1274,8 @@ u64 ptlrpc_known_replied_xid(struct obd_import *imp)
 	if (list_empty(&imp->imp_unreplied_list))
 		return 0;
 
-	req = list_entry(imp->imp_unreplied_list.next, struct ptlrpc_request,
-			 rq_unreplied_list);
+	req = list_first_entry(&imp->imp_unreplied_list, struct ptlrpc_request,
+			       rq_unreplied_list);
 	LASSERTF(req->rq_xid >= 1, "XID:%llu\n", req->rq_xid);
 
 	if (imp->imp_known_replied_xid < req->rq_xid - 1)
diff --git a/drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c b/drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c
index 7fe8aeeff428..ab186d84aefe 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c
@@ -163,9 +163,9 @@ struct ptlrpc_nrs_request *nrs_fifo_req_get(struct ptlrpc_nrs_policy *policy,
 	struct nrs_fifo_head *head = policy->pol_private;
 	struct ptlrpc_nrs_request *nrq;
 
-	nrq = unlikely(list_empty(&head->fh_list)) ? NULL :
-	      list_entry(head->fh_list.next, struct ptlrpc_nrs_request,
-			 nr_u.fifo.fr_list);
+	nrq = list_first_entry_or_null(&head->fh_list,
+				       struct ptlrpc_nrs_request,
+				       nr_u.fifo.fr_list);
 
 	if (likely(!peek && nrq)) {
 		struct ptlrpc_request *req = container_of(nrq,
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
index 1fadba2be16b..c7cc86c3fbc3 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
@@ -272,8 +272,8 @@ lustre_get_emerg_rs(struct ptlrpc_service_part *svcpt)
 		spin_lock(&svcpt->scp_rep_lock);
 	}
 
-	rs = list_entry(svcpt->scp_rep_idle.next,
-			struct ptlrpc_reply_state, rs_list);
+	rs = list_first_entry(&svcpt->scp_rep_idle,
+			      struct ptlrpc_reply_state, rs_list);
 	list_del(&rs->rs_list);
 
 	spin_unlock(&svcpt->scp_rep_lock);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
index 2c8bad7b7877..c4dba675db52 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
@@ -101,9 +101,9 @@ static void sec_process_ctx_list(void)
 
 	spin_lock(&sec_gc_ctx_list_lock);
 
-	while (!list_empty(&sec_gc_ctx_list)) {
-		ctx = list_entry(sec_gc_ctx_list.next,
-				 struct ptlrpc_cli_ctx, cc_gc_chain);
+	while ((ctx = list_first_entry_or_null(&sec_gc_ctx_list,
+					       struct ptlrpc_cli_ctx,
+					       cc_gc_chain)) != NULL) {
 		list_del_init(&ctx->cc_gc_chain);
 		spin_unlock(&sec_gc_ctx_list_lock);
 
diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
index 5b97f2a1fea1..a69736dfe8b7 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -299,9 +299,9 @@ ptlrpc_server_post_idle_rqbds(struct ptlrpc_service_part *svcpt)
 			return posted;
 		}
 
-		rqbd = list_entry(svcpt->scp_rqbd_idle.next,
-				  struct ptlrpc_request_buffer_desc,
-				  rqbd_list);
+		rqbd = list_first_entry(&svcpt->scp_rqbd_idle,
+					struct ptlrpc_request_buffer_desc,
+					rqbd_list);
 		list_del(&rqbd->rqbd_list);
 
 		/* assume we will post successfully */
@@ -769,9 +769,9 @@ static void ptlrpc_server_drop_request(struct ptlrpc_request *req)
 		 * I expect only about 1 or 2 rqbds need to be recycled here
 		 */
 		while (svcpt->scp_hist_nrqbds > svc->srv_hist_nrqbds_cpt_max) {
-			rqbd = list_entry(svcpt->scp_hist_rqbds.next,
-					  struct ptlrpc_request_buffer_desc,
-					  rqbd_list);
+			rqbd = list_first_entry(&svcpt->scp_hist_rqbds,
+						struct ptlrpc_request_buffer_desc,
+						rqbd_list);
 
 			list_del(&rqbd->rqbd_list);
 			svcpt->scp_hist_nrqbds--;
@@ -1240,9 +1240,9 @@ static void ptlrpc_at_check_timed(struct ptlrpc_service_part *svcpt)
 	/* we took additional refcount so entries can't be deleted from list, no
 	 * locking is needed
 	 */
-	while (!list_empty(&work_list)) {
-		rq = list_entry(work_list.next, struct ptlrpc_request,
-				rq_timed_list);
+	while ((rq = list_first_entry_or_null(&work_list,
+					      struct ptlrpc_request,
+					      rq_timed_list)) != NULL) {
 		list_del_init(&rq->rq_timed_list);
 
 		if (ptlrpc_at_send_early_reply(rq) == 0)
@@ -1485,8 +1485,8 @@ ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt,
 		return 0;
 	}
 
-	req = list_entry(svcpt->scp_req_incoming.next,
-			 struct ptlrpc_request, rq_list);
+	req = list_first_entry(&svcpt->scp_req_incoming,
+			       struct ptlrpc_request, rq_list);
 	list_del_init(&req->rq_list);
 	svcpt->scp_nreqs_incoming--;
 	/* Consider this still a "queued" request as far as stats are
@@ -2345,9 +2345,9 @@ static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt)
 
 	wake_up_all(&svcpt->scp_waitq);
 
-	while (!list_empty(&svcpt->scp_threads)) {
-		thread = list_entry(svcpt->scp_threads.next,
-				    struct ptlrpc_thread, t_link);
+	while ((thread = list_first_entry_or_null(&svcpt->scp_threads,
+						  struct ptlrpc_thread,
+						  t_link)) != NULL) {
 		if (thread_is_stopped(thread)) {
 			list_del(&thread->t_link);
 			list_add(&thread->t_link, &zombie);
@@ -2365,9 +2365,9 @@ static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt)
 
 	spin_unlock(&svcpt->scp_lock);
 
-	while (!list_empty(&zombie)) {
-		thread = list_entry(zombie.next,
-				    struct ptlrpc_thread, t_link);
+	while ((thread = list_first_entry(&zombie,
+					  struct ptlrpc_thread,
+					  t_link)) != NULL) {
 		list_del(&thread->t_link);
 		kfree(thread);
 	}
@@ -2707,9 +2707,9 @@ ptlrpc_service_purge_all(struct ptlrpc_service *svc)
 			break;
 
 		spin_lock(&svcpt->scp_rep_lock);
-		while (!list_empty(&svcpt->scp_rep_active)) {
-			rs = list_entry(svcpt->scp_rep_active.next,
-					struct ptlrpc_reply_state, rs_list);
+		while ((rs = list_first_entry_or_null(&svcpt->scp_rep_active,
+						      struct ptlrpc_reply_state,
+						      rs_list)) != NULL) {
 			spin_lock(&rs->rs_lock);
 			ptlrpc_schedule_difficult_reply(rs);
 			spin_unlock(&rs->rs_lock);
@@ -2720,10 +2720,9 @@ ptlrpc_service_purge_all(struct ptlrpc_service *svc)
 		 * all unlinked) and no service threads, so I'm the only
 		 * thread noodling the request queue now
 		 */
-		while (!list_empty(&svcpt->scp_req_incoming)) {
-			req = list_entry(svcpt->scp_req_incoming.next,
-					 struct ptlrpc_request, rq_list);
-
+		while ((req = list_first_entry_or_null(&svcpt->scp_req_incoming,
+						       struct ptlrpc_request,
+						       rq_list)) != NULL) {
 			list_del(&req->rq_list);
 			svcpt->scp_nreqs_incoming--;
 			ptlrpc_server_finish_request(svcpt, req);
@@ -2747,17 +2746,17 @@ ptlrpc_service_purge_all(struct ptlrpc_service *svc)
 		 */
 
 		while (!list_empty(&svcpt->scp_rqbd_idle)) {
-			rqbd = list_entry(svcpt->scp_rqbd_idle.next,
-					  struct ptlrpc_request_buffer_desc,
-					  rqbd_list);
+			rqbd = list_first_entry(&svcpt->scp_rqbd_idle,
+						struct ptlrpc_request_buffer_desc,
+						rqbd_list);
 			ptlrpc_free_rqbd(rqbd);
 		}
 		ptlrpc_wait_replies(svcpt);
 
 		while (!list_empty(&svcpt->scp_rep_idle)) {
-			rs = list_entry(svcpt->scp_rep_idle.next,
-					struct ptlrpc_reply_state,
-					rs_list);
+			rs = list_first_entry(&svcpt->scp_rep_idle,
+					      struct ptlrpc_reply_state,
+					      rs_list);
 			list_del(&rs->rs_list);
 			kvfree(rs);
 		}

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

* [lustre-devel] [PATCH 06/21] lustre: use list_first_entry() in lnet/lnet subdirectory.
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (2 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 03/21] lustre: obdclass: use list_sort() to sort a list NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  0:44   ` Andreas Dilger
  2019-02-11  1:46   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 01/21] lustre: obdclass: discard csi_end_io NeilBrown
                   ` (16 subsequent siblings)
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

Convert
  list_entry(foo->next .....)
to
  list_first_entry(foo, ....)

in 'lnet/lnet'

In several cases the call is combined with
a list_empty() test and list_first_entry_or_null() is used

In one case, list_splice_init() is used.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lnet/lnet/api-ni.c     |  111 ++++++++++++-------------
 drivers/staging/lustre/lnet/lnet/config.c     |   22 ++---
 drivers/staging/lustre/lnet/lnet/lib-move.c   |   53 ++++++------
 drivers/staging/lustre/lnet/lnet/lib-msg.c    |   16 ++--
 drivers/staging/lustre/lnet/lnet/lib-ptl.c    |    7 +-
 drivers/staging/lustre/lnet/lnet/net_fault.c  |   24 +++--
 drivers/staging/lustre/lnet/lnet/nidstrings.c |    9 +-
 drivers/staging/lustre/lnet/lnet/peer.c       |   24 +++--
 drivers/staging/lustre/lnet/lnet/router.c     |   13 ++-
 9 files changed, 141 insertions(+), 138 deletions(-)

diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c
index 64b8bef91915..671591a092ac 100644
--- a/drivers/staging/lustre/lnet/lnet/api-ni.c
+++ b/drivers/staging/lustre/lnet/lnet/api-ni.c
@@ -812,8 +812,8 @@ lnet_net2ni_locked(u32 net_id, int cpt)
 
 	list_for_each_entry(net, &the_lnet.ln_nets, net_list) {
 		if (net->net_id == net_id) {
-			ni = list_entry(net->net_ni_list.next, struct lnet_ni,
-					ni_netlist);
+			ni = list_first_entry(&net->net_ni_list, struct lnet_ni,
+					      ni_netlist);
 			return ni;
 		}
 	}
@@ -1504,12 +1504,12 @@ lnet_clear_zombies_nis_locked(struct lnet_net *net)
 	 * list and shut them down in guaranteed thread context
 	 */
 	i = 2;
-	while (!list_empty(zombie_list)) {
+	while ((ni = list_first_entry_or_null(zombie_list,
+					      struct lnet_ni,
+					      ni_netlist)) != NULL) {
 		int *ref;
 		int j;
 
-		ni = list_entry(zombie_list->next,
-				struct lnet_ni, ni_netlist);
 		list_del_init(&ni->ni_netlist);
 		/* the ni should be in deleting state. If it's not it's
 		 * a bug */
@@ -1583,9 +1583,9 @@ lnet_shutdown_lndnet(struct lnet_net *net)
 
 	list_del_init(&net->net_list);
 
-	while (!list_empty(&net->net_ni_list)) {
-		ni = list_entry(net->net_ni_list.next,
-				struct lnet_ni, ni_netlist);
+	while ((ni = list_first_entry_or_null(&net->net_ni_list,
+					      struct lnet_ni,
+					      ni_netlist)) != NULL) {
 		lnet_net_unlock(LNET_LOCK_EX);
 		lnet_shutdown_lndni(ni);
 		lnet_net_lock(LNET_LOCK_EX);
@@ -1622,16 +1622,12 @@ lnet_shutdown_lndnets(void)
 	lnet_net_lock(LNET_LOCK_EX);
 	the_lnet.ln_state = LNET_STATE_STOPPING;
 
-	while (!list_empty(&the_lnet.ln_nets)) {
-		/*
-		 * move the nets to the zombie list to avoid them being
-		 * picked up for new work. LONET is also included in the
-		 * Nets that will be moved to the zombie list
-		 */
-		net = list_entry(the_lnet.ln_nets.next,
-				 struct lnet_net, net_list);
-		list_move(&net->net_list, &the_lnet.ln_net_zombie);
-	}
+	/*
+	 * move the nets to the zombie list to avoid them being
+	 * picked up for new work. LONET is also included in the
+	 * Nets that will be moved to the zombie list
+	 */
+	list_splice_init(&the_lnet.ln_nets, &the_lnet.ln_net_zombie);
 
 	/* Drop the cached loopback Net. */
 	if (the_lnet.ln_loni) {
@@ -1641,11 +1637,10 @@ lnet_shutdown_lndnets(void)
 	lnet_net_unlock(LNET_LOCK_EX);
 
 	/* iterate through the net zombie list and delete each net */
-	while (!list_empty(&the_lnet.ln_net_zombie)) {
-		net = list_entry(the_lnet.ln_net_zombie.next,
-				 struct lnet_net, net_list);
+	while ((net = list_first_entry_or_null(&the_lnet.ln_net_zombie,
+					       struct lnet_net,
+					       net_list)) != NULL)
 		lnet_shutdown_lndnet(net);
-	}
 
 	lnet_net_lock(LNET_LOCK_EX);
 	the_lnet.ln_state = LNET_STATE_SHUTDOWN;
@@ -1833,9 +1828,9 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun)
 		goto failed0;
 	}
 
-	while (!list_empty(&net->net_ni_added)) {
-		ni = list_entry(net->net_ni_added.next, struct lnet_ni,
-				ni_netlist);
+	while ((ni = list_first_entry_or_null(&net->net_ni_added,
+					      struct lnet_ni,
+					      ni_netlist)) != NULL) {
 		list_del_init(&ni->ni_netlist);
 
 		/* make sure that the the NI we're about to start
@@ -1902,12 +1897,10 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun)
 	 * shutdown the new NIs that are being started up
 	 * free the NET being started
 	 */
-	while (!list_empty(&local_ni_list)) {
-		ni = list_entry(local_ni_list.next, struct lnet_ni,
-				ni_netlist);
-
+	while ((ni = list_first_entry_or_null(&local_ni_list,
+					      struct lnet_ni,
+					      ni_netlist)) != NULL)
 		lnet_shutdown_lndni(ni);
-	}
 
 failed0:
 	lnet_net_free(net);
@@ -1931,8 +1924,9 @@ lnet_startup_lndnets(struct list_head *netlist)
 	the_lnet.ln_state = LNET_STATE_RUNNING;
 	lnet_net_unlock(LNET_LOCK_EX);
 
-	while (!list_empty(netlist)) {
-		net = list_entry(netlist->next, struct lnet_net, net_list);
+	while ((net = list_first_entry_or_null(netlist,
+					       struct lnet_net,
+					       net_list)) != NULL) {
 		list_del_init(&net->net_list);
 
 		rc = lnet_startup_lndnet(net, NULL);
@@ -2022,11 +2016,13 @@ int lnet_lib_init(void)
  */
 void lnet_lib_exit(void)
 {
+	struct lnet_lnd *lnd;
 	LASSERT(!the_lnet.ln_refcount);
 
-	while (!list_empty(&the_lnet.ln_lnds))
-		lnet_unregister_lnd(list_entry(the_lnet.ln_lnds.next,
-					       struct lnet_lnd, lnd_list));
+	while ((lnd = list_first_entry_or_null(&the_lnet.ln_lnds,
+					       struct lnet_lnd,
+					       lnd_list)) != NULL)
+		lnet_unregister_lnd(lnd);
 	lnet_destroy_locks();
 }
 
@@ -2172,10 +2168,9 @@ LNetNIInit(lnet_pid_t requested_pid)
 	lnet_unprepare();
 	LASSERT(rc < 0);
 	mutex_unlock(&the_lnet.ln_api_mutex);
-	while (!list_empty(&net_head)) {
-		struct lnet_net *net;
-
-		net = list_entry(net_head.next, struct lnet_net, net_list);
+	while ((net = list_first_entry_or_null(&net_head,
+					       struct lnet_net,
+					       net_list)) != NULL) {
 		list_del_init(&net->net_list);
 		lnet_net_free(net);
 	}
@@ -2411,10 +2406,11 @@ lnet_get_next_ni_locked(struct lnet_net *mynet, struct lnet_ni *prev)
 
 	if (!prev) {
 		if (!net)
-			net = list_entry(the_lnet.ln_nets.next, struct lnet_net,
-					 net_list);
-		ni = list_entry(net->net_ni_list.next, struct lnet_ni,
-				ni_netlist);
+			net = list_first_entry(&the_lnet.ln_nets,
+					       struct lnet_net,
+					       net_list);
+		ni = list_first_entry(&net->net_ni_list, struct lnet_ni,
+				      ni_netlist);
 
 		return ni;
 	}
@@ -2432,17 +2428,17 @@ lnet_get_next_ni_locked(struct lnet_net *mynet, struct lnet_ni *prev)
 			return NULL;
 
 		/* get the next net */
-		net = list_entry(prev->ni_net->net_list.next, struct lnet_net,
-				 net_list);
+		net = list_first_entry(&prev->ni_net->net_list, struct lnet_net,
+				       net_list);
 		/* get the ni on it */
-		ni = list_entry(net->net_ni_list.next, struct lnet_ni,
-				ni_netlist);
+		ni = list_first_entry(&net->net_ni_list, struct lnet_ni,
+				      ni_netlist);
 
 		return ni;
 	}
 
 	/* there are more nis left */
-	ni = list_entry(prev->ni_netlist.next, struct lnet_ni, ni_netlist);
+	ni = list_first_entry(&prev->ni_netlist, struct lnet_ni, ni_netlist);
 
 	return ni;
 }
@@ -2637,8 +2633,9 @@ static int lnet_handle_legacy_ip2nets(char *ip2nets,
 		return rc;
 
 	mutex_lock(&the_lnet.ln_api_mutex);
-	while (!list_empty(&net_head)) {
-		net = list_entry(net_head.next, struct lnet_net, net_list);
+	while ((net = list_first_entry_or_null(&net_head,
+					       struct lnet_net,
+					       net_list)) != NULL) {
 		list_del_init(&net->net_list);
 		rc = lnet_add_net_common(net, tun);
 		if (rc < 0)
@@ -2648,8 +2645,9 @@ static int lnet_handle_legacy_ip2nets(char *ip2nets,
 out:
 	mutex_unlock(&the_lnet.ln_api_mutex);
 
-	while (!list_empty(&net_head)) {
-		net = list_entry(net_head.next, struct lnet_net, net_list);
+	while ((net = list_first_entry_or_null(&net_head,
+					       struct lnet_net,
+					       net_list)) != NULL) {
 		list_del_init(&net->net_list);
 		lnet_net_free(net);
 	}
@@ -2819,7 +2817,7 @@ lnet_dyn_add_net(struct lnet_ioctl_config_data *conf)
 		goto out_unlock_clean;
 	}
 
-	net = list_entry(net_head.next, struct lnet_net, net_list);
+	net = list_first_entry(&net_head, struct lnet_net, net_list);
 	list_del_init(&net->net_list);
 
 	LASSERT(lnet_net_unique(net->net_id, &the_lnet.ln_nets, NULL));
@@ -2839,9 +2837,10 @@ lnet_dyn_add_net(struct lnet_ioctl_config_data *conf)
 
 out_unlock_clean:
 	mutex_unlock(&the_lnet.ln_api_mutex);
-	while (!list_empty(&net_head)) {
-		/* net_head list is empty in success case */
-		net = list_entry(net_head.next, struct lnet_net, net_list);
+	/* net_head list is empty in success case */
+	while ((net = list_first_entry_or_null(&net_head,
+					       struct lnet_net,
+					       net_list)) != NULL) {
 		list_del_init(&net->net_list);
 		lnet_net_free(net);
 	}
diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c
index ecf656bce73f..f34844465d01 100644
--- a/drivers/staging/lustre/lnet/lnet/config.c
+++ b/drivers/staging/lustre/lnet/lnet/config.c
@@ -817,8 +817,9 @@ lnet_parse_networks(struct list_head *netlist, char *networks,
 	lnet_syntax("networks", networks, (int)(str - tokens), strlen(str));
 failed:
 	/* free the net list and all the nis on each net */
-	while (!list_empty(netlist)) {
-		net = list_entry(netlist->next, struct lnet_net, net_list);
+	while ((net = list_first_entry_or_null(netlist,
+					       struct lnet_net,
+					       net_list)) != NULL) {
 
 		list_del_init(&net->net_list);
 		lnet_net_free(net);
@@ -875,9 +876,8 @@ lnet_free_text_bufs(struct list_head *tbs)
 {
 	struct lnet_text_buf *ltb;
 
-	while (!list_empty(tbs)) {
-		ltb = list_entry(tbs->next, struct lnet_text_buf, ltb_list);
-
+	while ((ltb = list_first_entry_or_null(tbs, struct lnet_text_buf,
+					       ltb_list)) != NULL) {
 		list_del(&ltb->ltb_list);
 		lnet_free_text_buf(ltb);
 	}
@@ -1239,8 +1239,8 @@ lnet_parse_route_tbs(struct list_head *tbs, int *im_a_router)
 {
 	struct lnet_text_buf *ltb;
 
-	while (!list_empty(tbs)) {
-		ltb = list_entry(tbs->next, struct lnet_text_buf, ltb_list);
+	while ((ltb = list_first_entry_or_null(tbs, struct lnet_text_buf,
+					       ltb_list)) != NULL) {
 
 		if (lnet_parse_route(ltb->ltb_text, im_a_router) < 0) {
 			lnet_free_text_bufs(tbs);
@@ -1383,7 +1383,7 @@ lnet_splitnets(char *source, struct list_head *nets)
 	LASSERT(!list_empty(nets));
 	LASSERT(nets->next == nets->prev);     /* single entry */
 
-	tb = list_entry(nets->next, struct lnet_text_buf, ltb_list);
+	tb = list_first_entry(nets, struct lnet_text_buf, ltb_list);
 
 	for (;;) {
 		sep = strchr(tb->ltb_text, ',');
@@ -1478,9 +1478,9 @@ lnet_match_networks(char **networksp, char *ip2nets, u32 *ipaddrs, int nip)
 	len = 0;
 	rc = 0;
 
-	while (!list_empty(&raw_entries)) {
-		tb = list_entry(raw_entries.next, struct lnet_text_buf,
-				ltb_list);
+	while ((tb = list_first_entry_or_null(&raw_entries,
+					      struct lnet_text_buf,
+					      ltb_list)) != NULL) {
 		strncpy(source, tb->ltb_text, sizeof(source));
 		source[sizeof(source) - 1] = '\0';
 
diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c
index 92c6a34b44e6..185ea51d2771 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-move.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-move.c
@@ -185,9 +185,9 @@ lnet_fail_nid(lnet_nid_t nid, unsigned int threshold)
 
 	lnet_net_unlock(0);
 
-	while (!list_empty(&cull)) {
-		tp = list_entry(cull.next, struct lnet_test_peer, tp_list);
-
+	while ((tp = list_first_entry_or_null(&cull,
+					      struct lnet_test_peer,
+					      tp_list)) != NULL) {
 		list_del(&tp->tp_list);
 		kfree(tp);
 	}
@@ -244,8 +244,9 @@ fail_peer(lnet_nid_t nid, int outgoing)
 
 	lnet_net_unlock(0);
 
-	while (!list_empty(&cull)) {
-		tp = list_entry(cull.next, struct lnet_test_peer, tp_list);
+	while ((tp = list_first_entry_or_null(&cull,
+					      struct lnet_test_peer,
+					      tp_list)) != NULL) {
 		list_del(&tp->tp_list);
 
 		kfree(tp);
@@ -889,7 +890,7 @@ lnet_post_routed_recv_locked(struct lnet_msg *msg, int do_recv)
 	}
 
 	LASSERT(!list_empty(&rbp->rbp_bufs));
-	rb = list_entry(rbp->rbp_bufs.next, struct lnet_rtrbuf, rb_list);
+	rb = list_first_entry(&rbp->rbp_bufs, struct lnet_rtrbuf, rb_list);
 	list_del(&rb->rb_list);
 
 	msg->msg_niov = rbp->rbp_npages;
@@ -926,8 +927,8 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg)
 		tq->tq_credits++;
 		atomic_inc(&ni->ni_tx_credits);
 		if (tq->tq_credits <= 0) {
-			msg2 = list_entry(tq->tq_delayed.next,
-					  struct lnet_msg, msg_list);
+			msg2 = list_first_entry(&tq->tq_delayed,
+						struct lnet_msg, msg_list);
 			list_del(&msg2->msg_list);
 
 			LASSERT(msg2->msg_txni == ni);
@@ -953,8 +954,8 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg)
 		if (txpeer->lpni_txcredits <= 0) {
 			int msg2_cpt;
 
-			msg2 = list_entry(txpeer->lpni_txq.next,
-					  struct lnet_msg, msg_list);
+			msg2 = list_first_entry(&txpeer->lpni_txq,
+						struct lnet_msg, msg_list);
 			list_del(&msg2->msg_list);
 			spin_unlock(&txpeer->lpni_lock);
 
@@ -1015,8 +1016,8 @@ lnet_schedule_blocked_locked(struct lnet_rtrbufpool *rbp)
 
 	if (list_empty(&rbp->rbp_msgs))
 		return;
-	msg = list_entry(rbp->rbp_msgs.next,
-			 struct lnet_msg, msg_list);
+	msg = list_first_entry(&rbp->rbp_msgs,
+			       struct lnet_msg, msg_list);
 	list_del(&msg->msg_list);
 
 	(void)lnet_post_routed_recv_locked(msg, 1);
@@ -1117,8 +1118,8 @@ lnet_return_rx_credits_locked(struct lnet_msg *msg)
 			spin_unlock(&rxpeer->lpni_lock);
 			lnet_drop_routed_msgs_locked(&drop, msg->msg_rx_cpt);
 		} else if (rxpeer->lpni_rtrcredits <= 0) {
-			msg2 = list_entry(rxpeer->lpni_rtrq.next,
-					  struct lnet_msg, msg_list);
+			msg2 = list_first_entry(&rxpeer->lpni_rtrq,
+						struct lnet_msg, msg_list);
 			list_del(&msg2->msg_list);
 			spin_unlock(&rxpeer->lpni_lock);
 			(void)lnet_post_routed_recv_locked(msg2, 1);
@@ -1553,8 +1554,8 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid,
 				       libcfs_net2str(best_lpni->lpni_net->net_id));
 				return -EHOSTUNREACH;
 			}
-			lpni = list_entry(peer_net->lpn_peer_nis.next,
-					  struct lnet_peer_ni,
+			lpni = list_first_entry(&peer_net->lpn_peer_nis,
+						struct lnet_peer_ni,
 					  lpni_peer_nis);
 		}
 		/* Set preferred NI if necessary. */
@@ -1595,9 +1596,9 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid,
 		if (!local_net && !routing && !local_found) {
 			struct lnet_peer_ni *net_gw;
 
-			lpni = list_entry(peer_net->lpn_peer_nis.next,
-					  struct lnet_peer_ni,
-					  lpni_peer_nis);
+			lpni = list_first_entry(&peer_net->lpn_peer_nis,
+						struct lnet_peer_ni,
+						lpni_peer_nis);
 
 			net_gw = lnet_find_route_locked(NULL,
 							lpni->lpni_nid,
@@ -2620,11 +2621,12 @@ EXPORT_SYMBOL(lnet_parse);
 void
 lnet_drop_delayed_msg_list(struct list_head *head, char *reason)
 {
-	while (!list_empty(head)) {
+	struct lnet_msg *msg;
+
+	while ((msg = list_first_entry_or_null(head, struct lnet_msg,
+					       msg_list)) != NULL) {
 		struct lnet_process_id id = { 0 };
-		struct lnet_msg *msg;
 
-		msg = list_entry(head->next, struct lnet_msg, msg_list);
 		list_del(&msg->msg_list);
 
 		id.nid = msg->msg_hdr.src_nid;
@@ -2662,11 +2664,12 @@ lnet_drop_delayed_msg_list(struct list_head *head, char *reason)
 void
 lnet_recv_delayed_msg_list(struct list_head *head)
 {
-	while (!list_empty(head)) {
-		struct lnet_msg *msg;
+	struct lnet_msg *msg;
+
+	while ((msg = list_first_entry_or_null(head, struct lnet_msg,
+					       msg_list)) != NULL) {
 		struct lnet_process_id id;
 
-		msg = list_entry(head->next, struct lnet_msg, msg_list);
 		list_del(&msg->msg_list);
 
 		/*
diff --git a/drivers/staging/lustre/lnet/lnet/lib-msg.c b/drivers/staging/lustre/lnet/lnet/lib-msg.c
index b9e9257a4c5a..02620fe2a0fa 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-msg.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-msg.c
@@ -528,10 +528,9 @@ lnet_finalize(struct lnet_msg *msg, int status)
 
 	container->msc_finalizers[my_slot] = current;
 
-	while (!list_empty(&container->msc_finalizing)) {
-		msg = list_entry(container->msc_finalizing.next,
-				 struct lnet_msg, msg_list);
-
+	while ((msg = list_first_entry_or_null(&container->msc_finalizing,
+					       struct lnet_msg,
+					       msg_list)) != NULL) {
 		list_del(&msg->msg_list);
 
 		/*
@@ -561,15 +560,14 @@ void
 lnet_msg_container_cleanup(struct lnet_msg_container *container)
 {
 	int count = 0;
+	struct lnet_msg *msg;
 
 	if (!container->msc_init)
 		return;
 
-	while (!list_empty(&container->msc_active)) {
-		struct lnet_msg *msg;
-
-		msg = list_entry(container->msc_active.next,
-				 struct lnet_msg, msg_activelist);
+	while ((msg = list_first_entry_or_null(&container->msc_active,
+					       struct lnet_msg,
+					       msg_activelist)) != NULL) {
 		LASSERT(msg->msg_onactivelist);
 		msg->msg_onactivelist = 0;
 		list_del(&msg->msg_activelist);
diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c
index ea232c76b64d..4a12d86e6d64 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c
@@ -767,9 +767,10 @@ lnet_ptl_cleanup(struct lnet_portal *ptl)
 		mhash = mtable->mt_mhash;
 		/* cleanup ME */
 		for (j = 0; j < LNET_MT_HASH_SIZE + 1; j++) {
-			while (!list_empty(&mhash[j])) {
-				me = list_entry(mhash[j].next,
-						struct lnet_me, me_list);
+			while ((me = list_first_entry_or_null(&mhash[j],
+							      struct lnet_me,
+							      me_list))
+			       != NULL) {
 				CERROR("Active ME %p on exit\n", me);
 				list_del(&me->me_list);
 				kfree(me);
diff --git a/drivers/staging/lustre/lnet/lnet/net_fault.c b/drivers/staging/lustre/lnet/lnet/net_fault.c
index 4234ce1ce539..130a7c90965d 100644
--- a/drivers/staging/lustre/lnet/lnet/net_fault.c
+++ b/drivers/staging/lustre/lnet/lnet/net_fault.c
@@ -581,8 +581,8 @@ delayed_msg_check(struct lnet_delay_rule *rule, bool all,
 		 * dequeued some timedout messages, update timer for the
 		 * next delayed message on rule
 		 */
-		msg = list_entry(rule->dl_msg_list.next,
-				 struct lnet_msg, msg_list);
+		msg = list_first_entry(&rule->dl_msg_list,
+				       struct lnet_msg, msg_list);
 		rule->dl_msg_send = msg->msg_delay_send;
 		mod_timer(&rule->dl_timer, rule->dl_msg_send);
 	}
@@ -594,12 +594,12 @@ delayed_msg_process(struct list_head *msg_list, bool drop)
 {
 	struct lnet_msg	*msg;
 
-	while (!list_empty(msg_list)) {
+	while ((msg = list_first_entry_or_null(msg_list, struct lnet_msg,
+					       msg_list)) != NULL) {
 		struct lnet_ni *ni;
 		int cpt;
 		int rc;
 
-		msg = list_entry(msg_list->next, struct lnet_msg, msg_list);
 		LASSERT(msg->msg_rxpeer);
 		LASSERT(msg->msg_rxni);
 
@@ -653,16 +653,16 @@ lnet_delay_rule_check(void)
 			break;
 
 		spin_lock_bh(&delay_dd.dd_lock);
-		if (list_empty(&delay_dd.dd_sched_rules)) {
-			spin_unlock_bh(&delay_dd.dd_lock);
-			break;
-		}
-
-		rule = list_entry(delay_dd.dd_sched_rules.next,
-				  struct lnet_delay_rule, dl_sched_link);
-		list_del_init(&rule->dl_sched_link);
+		rule = list_first_entry_or_null(&delay_dd.dd_sched_rules,
+						struct lnet_delay_rule,
+						dl_sched_link);
+		if (!rule)
+			list_del_init(&rule->dl_sched_link);
 		spin_unlock_bh(&delay_dd.dd_lock);
 
+		if (!rule)
+			break;
+
 		delayed_msg_check(rule, false, &msgs);
 		delay_rule_decref(rule); /* -1 for delay_dd.dd_sched_rules */
 	}
diff --git a/drivers/staging/lustre/lnet/lnet/nidstrings.c b/drivers/staging/lustre/lnet/lnet/nidstrings.c
index 8f3d87c5467c..2df9ce4995f3 100644
--- a/drivers/staging/lustre/lnet/lnet/nidstrings.c
+++ b/drivers/staging/lustre/lnet/lnet/nidstrings.c
@@ -282,10 +282,11 @@ parse_nidrange(struct cfs_lstr *src, struct list_head *nidlist)
 static void
 free_addrranges(struct list_head *list)
 {
-	while (!list_empty(list)) {
-		struct addrrange *ar;
+	struct addrrange *ar;
 
-		ar = list_entry(list->next, struct addrrange, ar_link);
+	while ((ar = list_first_entry_or_null(list,
+					      struct addrrange,
+					      ar_link)) != NULL) {
 
 		cfs_expr_list_free_list(&ar->ar_numaddr_ranges);
 		list_del(&ar->ar_link);
@@ -960,7 +961,7 @@ libcfs_num_match(u32 addr, struct list_head *numaddr)
 	struct cfs_expr_list *el;
 
 	LASSERT(!list_empty(numaddr));
-	el = list_entry(numaddr->next, struct cfs_expr_list, el_link);
+	el = list_first_entry(numaddr, struct cfs_expr_list, el_link);
 
 	return cfs_expr_list_match(addr, el);
 }
diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c
index dfe1f3d09bc6..ade7f23b3bf4 100644
--- a/drivers/staging/lustre/lnet/lnet/peer.c
+++ b/drivers/staging/lustre/lnet/lnet/peer.c
@@ -649,12 +649,12 @@ lnet_get_next_peer_ni_locked(struct lnet_peer *peer,
 			if (list_empty(&peer->lp_peer_nets))
 				return NULL;
 
-			net = list_entry(peer->lp_peer_nets.next,
-					 struct lnet_peer_net,
-					 lpn_peer_nets);
+			net = list_first_entry(&peer->lp_peer_nets,
+					       struct lnet_peer_net,
+					       lpn_peer_nets);
 		}
-		lpni = list_entry(net->lpn_peer_nis.next, struct lnet_peer_ni,
-				  lpni_peer_nis);
+		lpni = list_first_entry(&net->lpn_peer_nis, struct lnet_peer_ni,
+					lpni_peer_nis);
 
 		return lpni;
 	}
@@ -678,19 +678,19 @@ lnet_get_next_peer_ni_locked(struct lnet_peer *peer,
 			return NULL;
 
 		/* get the next net */
-		net = list_entry(prev->lpni_peer_net->lpn_peer_nets.next,
-				 struct lnet_peer_net,
-				 lpn_peer_nets);
+		net = list_first_entry(&prev->lpni_peer_net->lpn_peer_nets,
+				       struct lnet_peer_net,
+				       lpn_peer_nets);
 		/* get the ni on it */
-		lpni = list_entry(net->lpn_peer_nis.next, struct lnet_peer_ni,
-				  lpni_peer_nis);
+		lpni = list_first_entry(&net->lpn_peer_nis, struct lnet_peer_ni,
+					lpni_peer_nis);
 
 		return lpni;
 	}
 
 	/* there are more nis left */
-	lpni = list_entry(prev->lpni_peer_nis.next,
-			  struct lnet_peer_ni, lpni_peer_nis);
+	lpni = list_first_entry(&prev->lpni_peer_nis,
+				struct lnet_peer_ni, lpni_peer_nis);
 
 	return lpni;
 }
diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c
index 463b123e0e5c..bcde61d2a984 100644
--- a/drivers/staging/lustre/lnet/lnet/router.c
+++ b/drivers/staging/lustre/lnet/lnet/router.c
@@ -1220,9 +1220,9 @@ lnet_prune_rc_data(int wait_unlink)
 
 		lnet_net_unlock(LNET_LOCK_EX);
 
-		while (!list_empty(&head)) {
-			rcd = list_entry(head.next,
-					 struct lnet_rc_data, rcd_list);
+		while ((rcd = list_first_entry_or_null(&head,
+						       struct lnet_rc_data,
+						       rcd_list)) != NULL) {
 			list_del_init(&rcd->rcd_list);
 			lnet_destroy_rc_data(rcd);
 		}
@@ -1397,7 +1397,7 @@ lnet_rtrpool_free_bufs(struct lnet_rtrbufpool *rbp, int cpt)
 
 	/* Free buffers on the free list. */
 	while (!list_empty(&tmp)) {
-		rb = list_entry(tmp.next, struct lnet_rtrbuf, rb_list);
+		rb = list_first_entry(&tmp, struct lnet_rtrbuf, rb_list);
 		list_del(&rb->rb_list);
 		lnet_destroy_rtrbuf(rb, npages);
 	}
@@ -1481,8 +1481,9 @@ lnet_rtrpool_adjust_bufs(struct lnet_rtrbufpool *rbp, int nbufs, int cpt)
 	return 0;
 
 failed:
-	while (!list_empty(&rb_list)) {
-		rb = list_entry(rb_list.next, struct lnet_rtrbuf, rb_list);
+	while ((rb = list_first_entry_or_null(&rb_list,
+					      struct lnet_rtrbuf,
+					      rb_list)) != NULL) {
 		list_del(&rb->rb_list);
 		lnet_destroy_rtrbuf(rb, npages);
 	}

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

* [lustre-devel] [PATCH 07/21] lustre: use list_first_entry() in lnet/klnds subdirectory.
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (16 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 09/21] lustre: use list_last_entry() throughout NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  0:59   ` Andreas Dilger
  2019-02-11  1:47   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 16/21] lustre: obdclass: normalize a switch statement NeilBrown
                   ` (2 subsequent siblings)
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

Convert
  list_entry(foo->next .....)
to
  list_first_entry(foo, ....)

in 'lnet/klnds

In several cases the call is combined with a list_empty() test and
list_first_entry_or_null() is used

Signed-off-by: NeilBrown <neilb@suse.com>
---
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c    |   19 +++--
 .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c |   61 ++++++++-------
 .../staging/lustre/lnet/klnds/socklnd/socklnd.c    |    9 +-
 .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c |   79 ++++++++++----------
 .../lustre/lnet/klnds/socklnd/socklnd_proto.c      |    4 +
 5 files changed, 88 insertions(+), 84 deletions(-)

diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
index 74b21fe2c091..df6b1b134709 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
@@ -1386,8 +1386,8 @@ static void kiblnd_destroy_fmr_pool_list(struct list_head *head)
 {
 	struct kib_fmr_pool *fpo;
 
-	while (!list_empty(head)) {
-		fpo = list_entry(head->next, struct kib_fmr_pool, fpo_list);
+	while ((fpo = list_first_entry_or_null(head, struct kib_fmr_pool,
+					       fpo_list)) != NULL) {
 		list_del(&fpo->fpo_list);
 		kiblnd_destroy_fmr_pool(fpo);
 	}
@@ -1544,14 +1544,16 @@ static int kiblnd_create_fmr_pool(struct kib_fmr_poolset *fps,
 static void kiblnd_fail_fmr_poolset(struct kib_fmr_poolset *fps,
 				    struct list_head *zombies)
 {
+	struct kib_fmr_pool *fpo;
+
 	if (!fps->fps_net) /* initialized? */
 		return;
 
 	spin_lock(&fps->fps_lock);
 
-	while (!list_empty(&fps->fps_pool_list)) {
-		struct kib_fmr_pool *fpo = list_entry(fps->fps_pool_list.next,
-						 struct kib_fmr_pool, fpo_list);
+	while ((fpo = list_first_entry_or_null(&fps->fps_pool_list,
+					       struct kib_fmr_pool,
+					       fpo_list)) != NULL) {
 		fpo->fpo_failed = 1;
 		list_del(&fpo->fpo_list);
 		if (!fpo->fpo_map_count)
@@ -1853,8 +1855,9 @@ static void kiblnd_destroy_pool_list(struct list_head *head)
 {
 	struct kib_pool *pool;
 
-	while (!list_empty(head)) {
-		pool = list_entry(head->next, struct kib_pool, po_list);
+	while ((pool = list_first_entry_or_null(head,
+						struct kib_pool,
+						po_list)) != NULL) {
 		list_del(&pool->po_list);
 
 		LASSERT(pool->po_owner);
@@ -1869,7 +1872,7 @@ static void kiblnd_fail_poolset(struct kib_poolset *ps, struct list_head *zombie
 
 	spin_lock(&ps->ps_lock);
 	while (!list_empty(&ps->ps_pool_list)) {
-		struct kib_pool *po = list_entry(ps->ps_pool_list.next,
+		struct kib_pool *po = list_first_entry(&ps->ps_pool_list,
 					    struct kib_pool, po_list);
 		po->po_failed = 1;
 		list_del(&po->po_list);
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
index ad1726098ea3..b9585f607463 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
@@ -98,9 +98,9 @@ kiblnd_txlist_done(struct list_head *txlist, int status)
 {
 	struct kib_tx *tx;
 
-	while (!list_empty(txlist)) {
-		tx = list_entry(txlist->next, struct kib_tx, tx_list);
-
+	while ((tx = list_first_entry_or_null(txlist,
+					      struct kib_tx,
+					      tx_list)) != NULL) {
 		list_del(&tx->tx_list);
 		/* complete now */
 		tx->tx_waiting = 0;
@@ -958,9 +958,9 @@ kiblnd_check_sends_locked(struct kib_conn *conn)
 	LASSERT(conn->ibc_reserved_credits >= 0);
 
 	while (conn->ibc_reserved_credits > 0 &&
-	       !list_empty(&conn->ibc_tx_queue_rsrvd)) {
-		tx = list_entry(conn->ibc_tx_queue_rsrvd.next,
-				struct kib_tx, tx_list);
+	       (tx = list_first_entry_or_null(
+		       &conn->ibc_tx_queue_rsrvd,
+		       struct kib_tx, tx_list)) != NULL) {
 		list_del(&tx->tx_list);
 		list_add_tail(&tx->tx_list, &conn->ibc_tx_queue);
 		conn->ibc_reserved_credits--;
@@ -983,17 +983,17 @@ kiblnd_check_sends_locked(struct kib_conn *conn)
 
 		if (!list_empty(&conn->ibc_tx_queue_nocred)) {
 			credit = 0;
-			tx = list_entry(conn->ibc_tx_queue_nocred.next,
-					struct kib_tx, tx_list);
+			tx = list_first_entry(&conn->ibc_tx_queue_nocred,
+					      struct kib_tx, tx_list);
 		} else if (!list_empty(&conn->ibc_tx_noops)) {
 			LASSERT(!IBLND_OOB_CAPABLE(ver));
 			credit = 1;
-			tx = list_entry(conn->ibc_tx_noops.next,
-					struct kib_tx, tx_list);
+			tx = list_first_entry(&conn->ibc_tx_noops,
+					      struct kib_tx, tx_list);
 		} else if (!list_empty(&conn->ibc_tx_queue)) {
 			credit = 1;
-			tx = list_entry(conn->ibc_tx_queue.next,
-					struct kib_tx, tx_list);
+			tx = list_first_entry(&conn->ibc_tx_queue,
+					      struct kib_tx, tx_list);
 		} else {
 			break;
 		}
@@ -2013,9 +2013,9 @@ kiblnd_handle_early_rxs(struct kib_conn *conn)
 	LASSERT(conn->ibc_state >= IBLND_CONN_ESTABLISHED);
 
 	write_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
-	while (!list_empty(&conn->ibc_early_rxs)) {
-		rx = list_entry(conn->ibc_early_rxs.next,
-				struct kib_rx, rx_list);
+	while ((rx = list_first_entry_or_null(&conn->ibc_early_rxs,
+					      struct kib_rx,
+					      rx_list)) != NULL) {
 		list_del(&rx->rx_list);
 		write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
 
@@ -3311,8 +3311,9 @@ kiblnd_check_conns(int idx)
 	 * NOOP, but there were no non-blocking tx descs
 	 * free to do it last time...
 	 */
-	while (!list_empty(&checksends)) {
-		conn = list_entry(checksends.next, struct kib_conn, ibc_connd_list);
+	while ((conn = list_first_entry_or_null(&checksends,
+						struct kib_conn,
+						ibc_connd_list)) != NULL) {
 		list_del(&conn->ibc_connd_list);
 
 		spin_lock(&conn->ibc_lock);
@@ -3370,11 +3371,12 @@ kiblnd_connd(void *arg)
 
 		dropped_lock = 0;
 
-		if (!list_empty(&kiblnd_data.kib_connd_zombies)) {
+		conn = list_first_entry_or_null(
+			&kiblnd_data.kib_connd_zombies,
+			struct kib_conn, ibc_list);
+		if (conn) {
 			struct kib_peer_ni *peer_ni = NULL;
 
-			conn = list_entry(kiblnd_data.kib_connd_zombies.next,
-					  struct kib_conn, ibc_list);
 			list_del(&conn->ibc_list);
 			if (conn->ibc_reconnect) {
 				peer_ni = conn->ibc_peer;
@@ -3401,9 +3403,9 @@ kiblnd_connd(void *arg)
 					      &kiblnd_data.kib_reconn_wait);
 		}
 
-		if (!list_empty(&kiblnd_data.kib_connd_conns)) {
-			conn = list_entry(kiblnd_data.kib_connd_conns.next,
-					  struct kib_conn, ibc_list);
+		conn = list_first_entry_or_null(&kiblnd_data.kib_connd_conns,
+						struct kib_conn, ibc_list);
+		if (conn) {
 			list_del(&conn->ibc_list);
 
 			spin_unlock_irqrestore(lock, flags);
@@ -3423,11 +3425,11 @@ kiblnd_connd(void *arg)
 						 &kiblnd_data.kib_reconn_list);
 			}
 
-			if (list_empty(&kiblnd_data.kib_reconn_list))
+			conn = list_first_entry_or_null(&kiblnd_data.kib_reconn_list,
+							struct kib_conn, ibc_list);
+			if (!conn)
 				break;
 
-			conn = list_entry(kiblnd_data.kib_reconn_list.next,
-					  struct kib_conn, ibc_list);
 			list_del(&conn->ibc_list);
 
 			spin_unlock_irqrestore(lock, flags);
@@ -3636,9 +3638,10 @@ kiblnd_scheduler(void *arg)
 
 		did_something = 0;
 
-		if (!list_empty(&sched->ibs_conns)) {
-			conn = list_entry(sched->ibs_conns.next, struct kib_conn,
-					  ibc_sched_list);
+		conn = list_first_entry_or_null(&sched->ibs_conns,
+						struct kib_conn,
+						ibc_sched_list);
+		if (conn) {
 			/* take over kib_sched_conns' ref on conn... */
 			LASSERT(conn->ibc_scheduled);
 			list_del(&conn->ibc_sched_list);
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
index 785f76cf9067..08feaf7ce33a 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
@@ -1566,9 +1566,8 @@ ksocknal_finalize_zcreq(struct ksock_conn *conn)
 
 	spin_unlock(&peer_ni->ksnp_lock);
 
-	while (!list_empty(&zlist)) {
-		tx = list_entry(zlist.next, struct ksock_tx, tx_zc_list);
-
+	while ((tx = list_first_entry_or_null(&zlist, struct ksock_tx,
+					      tx_zc_list)) != NULL) {
 		list_del(&tx->tx_zc_list);
 		ksocknal_tx_decref(tx);
 	}
@@ -2267,8 +2266,8 @@ ksocknal_free_buffers(void)
 		list_del_init(&ksocknal_data.ksnd_idle_noop_txs);
 		spin_unlock(&ksocknal_data.ksnd_tx_lock);
 
-		while (!list_empty(&zlist)) {
-			tx = list_entry(zlist.next, struct ksock_tx, tx_list);
+		while ((tx = list_first_entry_or_null(&zlist, struct ksock_tx,
+						      tx_list)) != NULL) {
 			list_del(&tx->tx_list);
 			kfree(tx);
 		}
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
index 8e20f430a3f3..208b8d360d5c 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
@@ -36,9 +36,9 @@ ksocknal_alloc_tx(int type, int size)
 		/* searching for a noop tx in free list */
 		spin_lock(&ksocknal_data.ksnd_tx_lock);
 
-		if (!list_empty(&ksocknal_data.ksnd_idle_noop_txs)) {
-			tx = list_entry(ksocknal_data.ksnd_idle_noop_txs.next,
-					struct ksock_tx, tx_list);
+		tx = list_first_entry_or_null(&ksocknal_data.ksnd_idle_noop_txs,
+					      struct ksock_tx, tx_list);
+		if (tx) {
 			LASSERT(tx->tx_desc_size == size);
 			list_del(&tx->tx_list);
 		}
@@ -347,8 +347,8 @@ ksocknal_txlist_done(struct lnet_ni *ni, struct list_head *txlist, int error)
 {
 	struct ksock_tx *tx;
 
-	while (!list_empty(txlist)) {
-		tx = list_entry(txlist->next, struct ksock_tx, tx_list);
+	while ((tx = list_first_entry_or_null(txlist, struct ksock_tx,
+					      tx_list)) != NULL) {
 
 		if (error && tx->tx_lnetmsg) {
 			CNETERR("Deleting packet type %d len %d %s->%s\n",
@@ -1322,9 +1322,10 @@ int ksocknal_scheduler(void *arg)
 
 		/* Ensure I progress everything semi-fairly */
 
-		if (!list_empty(&sched->kss_rx_conns)) {
-			conn = list_entry(sched->kss_rx_conns.next,
-					  struct ksock_conn, ksnc_rx_list);
+		conn = list_first_entry_or_null(&sched->kss_rx_conns,
+						struct ksock_conn,
+						ksnc_rx_list);
+		if (conn) {
 			list_del(&conn->ksnc_rx_list);
 
 			LASSERT(conn->ksnc_rx_scheduled);
@@ -1378,16 +1379,17 @@ int ksocknal_scheduler(void *arg)
 				list_del_init(&sched->kss_zombie_noop_txs);
 			}
 
-			conn = list_entry(sched->kss_tx_conns.next,
-					  struct ksock_conn, ksnc_tx_list);
+			conn = list_first_entry(&sched->kss_tx_conns,
+						struct ksock_conn,
+						ksnc_tx_list);
 			list_del(&conn->ksnc_tx_list);
 
 			LASSERT(conn->ksnc_tx_scheduled);
 			LASSERT(conn->ksnc_tx_ready);
 			LASSERT(!list_empty(&conn->ksnc_tx_queue));
 
-			tx = list_entry(conn->ksnc_tx_queue.next,
-					struct ksock_tx, tx_list);
+			tx = list_first_entry(&conn->ksnc_tx_queue,
+					      struct ksock_tx, tx_list);
 
 			if (conn->ksnc_tx_carrier == tx)
 				ksocknal_next_tx_carrier(conn);
@@ -1900,8 +1902,8 @@ ksocknal_connect(struct ksock_route *route)
 		 * connection for V1.x and V2.x
 		 */
 		if (!list_empty(&peer_ni->ksnp_conns)) {
-			conn = list_entry(peer_ni->ksnp_conns.next,
-					  struct ksock_conn, ksnc_list);
+			conn = list_first_entry(&peer_ni->ksnp_conns,
+						struct ksock_conn, ksnc_list);
 			LASSERT(conn->ksnc_proto == &ksocknal_protocol_v3x);
 		}
 
@@ -2082,10 +2084,10 @@ ksocknal_connd(void *arg)
 			dropped_lock = 1;
 		}
 
-		if (!list_empty(&ksocknal_data.ksnd_connd_connreqs)) {
+		cr = list_first_entry_or_null(&ksocknal_data.ksnd_connd_connreqs,
+					      struct ksock_connreq, ksncr_list);
+		if (cr) {
 			/* Connection accepted by the listener */
-			cr = list_entry(ksocknal_data.ksnd_connd_connreqs.next,
-					struct ksock_connreq, ksncr_list);
 
 			list_del(&cr->ksncr_list);
 			spin_unlock_bh(connd_lock);
@@ -2246,9 +2248,9 @@ ksocknal_flush_stale_txs(struct ksock_peer *peer_ni)
 
 	write_lock_bh(&ksocknal_data.ksnd_global_lock);
 
-	while (!list_empty(&peer_ni->ksnp_tx_queue)) {
-		tx = list_entry(peer_ni->ksnp_tx_queue.next, struct ksock_tx,
-				tx_list);
+	while ((tx = list_first_entry_or_null(&peer_ni->ksnp_tx_queue,
+					      struct ksock_tx,
+					      tx_list)) != NULL) {
 
 		if (ktime_get_seconds() < tx->tx_deadline)
 			break;
@@ -2372,19 +2374,16 @@ ksocknal_check_peer_timeouts(int idx)
 		 * we can't process stale txs right here because we're
 		 * holding only shared lock
 		 */
-		if (!list_empty(&peer_ni->ksnp_tx_queue)) {
-			tx = list_entry(peer_ni->ksnp_tx_queue.next,
-					struct ksock_tx, tx_list);
-
-			if (ktime_get_seconds() >= tx->tx_deadline) {
-				ksocknal_peer_addref(peer_ni);
-				read_unlock(&ksocknal_data.ksnd_global_lock);
+		tx = list_first_entry_or_null(&peer_ni->ksnp_tx_queue,
+					      struct ksock_tx, tx_list);
+		if (tx && ktime_get_seconds() >= tx->tx_deadline) {
+			ksocknal_peer_addref(peer_ni);
+			read_unlock(&ksocknal_data.ksnd_global_lock);
 
-				ksocknal_flush_stale_txs(peer_ni);
+			ksocknal_flush_stale_txs(peer_ni);
 
-				ksocknal_peer_decref(peer_ni);
-				goto again;
-			}
+			ksocknal_peer_decref(peer_ni);
+			goto again;
 		}
 
 		if (list_empty(&peer_ni->ksnp_zc_req_list))
@@ -2449,9 +2448,9 @@ ksocknal_reaper(void *arg)
 	spin_lock_bh(&ksocknal_data.ksnd_reaper_lock);
 
 	while (!ksocknal_data.ksnd_shuttingdown) {
-		if (!list_empty(&ksocknal_data.ksnd_deathrow_conns)) {
-			conn = list_entry(ksocknal_data.ksnd_deathrow_conns.next,
-					  struct ksock_conn, ksnc_list);
+		conn = list_first_entry_or_null(&ksocknal_data.ksnd_deathrow_conns,
+						struct ksock_conn, ksnc_list);
+		if (conn) {
 			list_del(&conn->ksnc_list);
 
 			spin_unlock_bh(&ksocknal_data.ksnd_reaper_lock);
@@ -2463,9 +2462,9 @@ ksocknal_reaper(void *arg)
 			continue;
 		}
 
-		if (!list_empty(&ksocknal_data.ksnd_zombie_conns)) {
-			conn = list_entry(ksocknal_data.ksnd_zombie_conns.next,
-					  struct ksock_conn, ksnc_list);
+		conn = list_first_entry_or_null(&ksocknal_data.ksnd_zombie_conns,
+						struct ksock_conn, ksnc_list);
+		if (conn) {
 			list_del(&conn->ksnc_list);
 
 			spin_unlock_bh(&ksocknal_data.ksnd_reaper_lock);
@@ -2486,9 +2485,9 @@ ksocknal_reaper(void *arg)
 
 		/* reschedule all the connections that stalled with ENOMEM... */
 		nenomem_conns = 0;
-		while (!list_empty(&enomem_conns)) {
-			conn = list_entry(enomem_conns.next, struct ksock_conn,
-					  ksnc_tx_list);
+		while ((conn = list_first_entry_or_null(&enomem_conns,
+							struct ksock_conn,
+							ksnc_tx_list)) != NULL) {
 			list_del(&conn->ksnc_tx_list);
 
 			sched = conn->ksnc_scheduler;
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
index c694feceaaf2..e8b95affee96 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
@@ -447,8 +447,8 @@ ksocknal_handle_zcack(struct ksock_conn *conn, u64 cookie1, u64 cookie2)
 
 	spin_unlock(&peer_ni->ksnp_lock);
 
-	while (!list_empty(&zlist)) {
-		tx = list_entry(zlist.next, struct ksock_tx, tx_zc_list);
+	while ((tx = list_first_entry_or_null(&zlist, struct ksock_tx,
+					      tx_zc_list)) != NULL) {
 		list_del(&tx->tx_zc_list);
 		ksocknal_tx_decref(tx);
 	}

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

* [lustre-devel] [PATCH 08/21] lustre: use list_first_entry() throughout
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (7 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 14/21] lustre: make ccc_users in cl_client_cache " NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  1:06   ` Andreas Dilger
  2019-02-11  1:48   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 20/21] lustre: obdclass: fix module load locking NeilBrown
                   ` (11 subsequent siblings)
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

Convert
  list_entry(foo->next .....)
to
  list_first_entry(foo, ....)

in remainder of lustre.

In several cases the call is combined with a list_empty() test and
list_first_entry_or_null() is used

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lnet/libcfs/libcfs_string.c |   12 +++--
 drivers/staging/lustre/lnet/selftest/conrpc.c      |    5 +-
 drivers/staging/lustre/lnet/selftest/console.c     |   39 ++++++++----------
 drivers/staging/lustre/lnet/selftest/framework.c   |   44 ++++++++++----------
 drivers/staging/lustre/lnet/selftest/rpc.c         |   27 ++++++------
 drivers/staging/lustre/lnet/selftest/timer.c       |    4 +-
 6 files changed, 62 insertions(+), 69 deletions(-)

diff --git a/drivers/staging/lustre/lnet/libcfs/libcfs_string.c b/drivers/staging/lustre/lnet/libcfs/libcfs_string.c
index 5fb85247525d..ae17b4d44cac 100644
--- a/drivers/staging/lustre/lnet/libcfs/libcfs_string.c
+++ b/drivers/staging/lustre/lnet/libcfs/libcfs_string.c
@@ -468,11 +468,11 @@ EXPORT_SYMBOL(cfs_expr_list_values);
 void
 cfs_expr_list_free(struct cfs_expr_list *expr_list)
 {
-	while (!list_empty(&expr_list->el_exprs)) {
-		struct cfs_range_expr *expr;
+	struct cfs_range_expr *expr;
 
-		expr = list_entry(expr_list->el_exprs.next,
-				  struct cfs_range_expr, re_link);
+	while ((expr = list_first_entry_or_null(&expr_list->el_exprs,
+						struct cfs_range_expr,
+						re_link)) != NULL) {
 		list_del(&expr->re_link);
 		kfree(expr);
 	}
@@ -553,8 +553,8 @@ cfs_expr_list_free_list(struct list_head *list)
 {
 	struct cfs_expr_list *el;
 
-	while (!list_empty(list)) {
-		el = list_entry(list->next, struct cfs_expr_list, el_link);
+	while ((el = list_first_entry_or_null(list, struct cfs_expr_list,
+					      el_link)) != NULL) {
 		list_del(&el->el_link);
 		cfs_expr_list_free(el);
 	}
diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c
index d9bcfa8c92ae..af0d2aa3b6e8 100644
--- a/drivers/staging/lustre/lnet/selftest/conrpc.c
+++ b/drivers/staging/lustre/lnet/selftest/conrpc.c
@@ -1362,9 +1362,8 @@ lstcon_rpc_cleanup_wait(void)
 
 	spin_unlock(&console_session.ses_rpc_lock);
 
-	while (!list_empty(&zlist)) {
-		crpc = list_entry(zlist.next, struct lstcon_rpc, crp_link);
-
+	while ((crpc = list_first_entry_or_null(&zlist, struct lstcon_rpc,
+					       crp_link)) != NULL) {
 		list_del(&crpc->crp_link);
 		kfree(crpc);
 	}
diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c
index 045d79f44321..abc342c6a842 100644
--- a/drivers/staging/lustre/lnet/selftest/console.c
+++ b/drivers/staging/lustre/lnet/selftest/console.c
@@ -330,11 +330,10 @@ lstcon_group_move(struct lstcon_group *old, struct lstcon_group *new)
 {
 	struct lstcon_ndlink *ndl;
 
-	while (!list_empty(&old->grp_ndl_list)) {
-		ndl = list_entry(old->grp_ndl_list.next,
-				 struct lstcon_ndlink, ndl_link);
+	while ((ndl = list_first_entry_or_null(&old->grp_ndl_list,
+					       struct lstcon_ndlink,
+					       ndl_link)) != NULL)
 		lstcon_group_ndlink_move(old, new, ndl);
-	}
 }
 
 static int
@@ -1095,9 +1094,9 @@ lstcon_batch_destroy(struct lstcon_batch *bat)
 
 	list_del(&bat->bat_link);
 
-	while (!list_empty(&bat->bat_test_list)) {
-		test = list_entry(bat->bat_test_list.next,
-				  struct lstcon_test, tes_link);
+	while ((test = list_first_entry_or_null(&bat->bat_test_list,
+						struct lstcon_test,
+						tes_link)) != NULL) {
 		LASSERT(list_empty(&test->tes_trans_list));
 
 		list_del(&test->tes_link);
@@ -1110,17 +1109,17 @@ lstcon_batch_destroy(struct lstcon_batch *bat)
 
 	LASSERT(list_empty(&bat->bat_trans_list));
 
-	while (!list_empty(&bat->bat_cli_list)) {
-		ndl = list_entry(bat->bat_cli_list.next,
-				 struct lstcon_ndlink, ndl_link);
+	while ((ndl = list_first_entry_or_null(&bat->bat_cli_list,
+					       struct lstcon_ndlink,
+					       ndl_link)) != NULL) {
 		list_del_init(&ndl->ndl_link);
 
 		lstcon_ndlink_release(ndl);
 	}
 
-	while (!list_empty(&bat->bat_srv_list)) {
-		ndl = list_entry(bat->bat_srv_list.next,
-				 struct lstcon_ndlink, ndl_link);
+	while ((ndl = list_first_entry_or_null(&bat->bat_srv_list,
+					       struct lstcon_ndlink,
+					       ndl_link)) != NULL) {
 		list_del_init(&ndl->ndl_link);
 
 		lstcon_ndlink_release(ndl);
@@ -1844,17 +1843,15 @@ lstcon_session_end(void)
 	console_session.ses_feats_updated = 0;
 
 	/* destroy all batches */
-	while (!list_empty(&console_session.ses_bat_list)) {
-		bat = list_entry(console_session.ses_bat_list.next,
-				 struct lstcon_batch, bat_link);
-
+	while ((bat = list_first_entry_or_null(&console_session.ses_bat_list,
+					       struct lstcon_batch,
+					       bat_link)) != NULL)
 		lstcon_batch_destroy(bat);
-	}
 
 	/* destroy all groups */
-	while (!list_empty(&console_session.ses_grp_list)) {
-		grp = list_entry(console_session.ses_grp_list.next,
-				 struct lstcon_group, grp_link);
+	while ((grp = list_first_entry_or_null(&console_session.ses_grp_list,
+					       struct lstcon_group,
+					       grp_link)) != NULL) {
 		LASSERT(grp->grp_ref == 1);
 
 		lstcon_group_decref(grp);
diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c
index a82efc394659..958f627580e7 100644
--- a/drivers/staging/lustre/lnet/selftest/framework.c
+++ b/drivers/staging/lustre/lnet/selftest/framework.c
@@ -628,16 +628,16 @@ sfw_destroy_test_instance(struct sfw_test_instance *tsi)
 	LASSERT(list_empty(&tsi->tsi_active_rpcs));
 	LASSERT(!sfw_test_active(tsi));
 
-	while (!list_empty(&tsi->tsi_units)) {
-		tsu = list_entry(tsi->tsi_units.next,
-				 struct sfw_test_unit, tsu_list);
+	while ((tsu = list_first_entry_or_null(&tsi->tsi_units,
+					       struct sfw_test_unit,
+					       tsu_list)) != NULL) {
 		list_del(&tsu->tsu_list);
 		kfree(tsu);
 	}
 
-	while (!list_empty(&tsi->tsi_free_rpcs)) {
-		rpc = list_entry(tsi->tsi_free_rpcs.next,
-				 struct srpc_client_rpc, crpc_list);
+	while ((rpc = list_first_entry_or_null(&tsi->tsi_free_rpcs,
+					       struct srpc_client_rpc,
+					       crpc_list)) != NULL) {
 		list_del(&rpc->crpc_list);
 		kfree(rpc);
 	}
@@ -655,9 +655,9 @@ sfw_destroy_batch(struct sfw_batch *tsb)
 	LASSERT(!sfw_batch_active(tsb));
 	LASSERT(list_empty(&tsb->bat_list));
 
-	while (!list_empty(&tsb->bat_tests)) {
-		tsi = list_entry(tsb->bat_tests.next,
-				 struct sfw_test_instance, tsi_list);
+	while ((tsi = list_first_entry_or_null(&tsb->bat_tests,
+					       struct sfw_test_instance,
+					       tsi_list)) != NULL) {
 		list_del_init(&tsi->tsi_list);
 		sfw_destroy_test_instance(tsi);
 	}
@@ -673,9 +673,9 @@ sfw_destroy_session(struct sfw_session *sn)
 	LASSERT(list_empty(&sn->sn_list));
 	LASSERT(sn != sfw_data.fw_session);
 
-	while (!list_empty(&sn->sn_batches)) {
-		batch = list_entry(sn->sn_batches.next,
-				   struct sfw_batch, bat_list);
+	while ((batch = list_first_entry_or_null(&sn->sn_batches,
+						 struct sfw_batch,
+						 bat_list)) != NULL) {
 		list_del_init(&batch->bat_list);
 		sfw_destroy_batch(batch);
 	}
@@ -1389,8 +1389,8 @@ sfw_create_rpc(struct lnet_process_id peer, int service,
 	LASSERT(service <= SRPC_FRAMEWORK_SERVICE_MAX_ID);
 
 	if (!nbulkiov && !list_empty(&sfw_data.fw_zombie_rpcs)) {
-		rpc = list_entry(sfw_data.fw_zombie_rpcs.next,
-				 struct srpc_client_rpc, crpc_list);
+		rpc = list_first_entry(&sfw_data.fw_zombie_rpcs,
+				       struct srpc_client_rpc, crpc_list);
 		list_del(&rpc->crpc_list);
 
 		srpc_init_client_rpc(rpc, peer, service, 0, 0,
@@ -1722,6 +1722,7 @@ sfw_shutdown(void)
 {
 	struct srpc_service *sv;
 	struct sfw_test_case	*tsc;
+	struct srpc_client_rpc *rpc;
 	int i;
 
 	spin_lock(&sfw_data.fw_lock);
@@ -1757,11 +1758,9 @@ sfw_shutdown(void)
 		srpc_remove_service(sv);
 	}
 
-	while (!list_empty(&sfw_data.fw_zombie_rpcs)) {
-		struct srpc_client_rpc *rpc;
-
-		rpc = list_entry(sfw_data.fw_zombie_rpcs.next,
-				 struct srpc_client_rpc, crpc_list);
+	while ((rpc = list_first_entry_or_null(&sfw_data.fw_zombie_rpcs,
+					       struct srpc_client_rpc,
+					       crpc_list)) != NULL) {
 		list_del(&rpc->crpc_list);
 
 		kfree(rpc);
@@ -1775,10 +1774,9 @@ sfw_shutdown(void)
 		srpc_wait_service_shutdown(sv);
 	}
 
-	while (!list_empty(&sfw_data.fw_tests)) {
-		tsc = list_entry(sfw_data.fw_tests.next,
-				 struct sfw_test_case, tsc_list);
-
+	while ((tsc = list_first_entry_or_null(&sfw_data.fw_tests,
+					       struct sfw_test_case,
+					       tsc_list)) != NULL) {
 		srpc_wait_service_shutdown(tsc->tsc_srv_service);
 
 		list_del(&tsc->tsc_list);
diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c
index 2a3010774dbe..abb6f8fb011e 100644
--- a/drivers/staging/lustre/lnet/selftest/rpc.c
+++ b/drivers/staging/lustre/lnet/selftest/rpc.c
@@ -210,9 +210,9 @@ srpc_service_fini(struct srpc_service *svc)
 			else
 				break;
 
-			while (!list_empty(q)) {
-				buf = list_entry(q->next, struct srpc_buffer,
-						 buf_list);
+			while ((buf = list_first_entry_or_null(
+					q, struct srpc_buffer,
+					buf_list)) != NULL) {
 				list_del(&buf->buf_list);
 				kfree(buf);
 			}
@@ -220,10 +220,9 @@ srpc_service_fini(struct srpc_service *svc)
 
 		LASSERT(list_empty(&scd->scd_rpc_active));
 
-		while (!list_empty(&scd->scd_rpc_free)) {
-			rpc = list_entry(scd->scd_rpc_free.next,
-					 struct srpc_server_rpc,
-					 srpc_list);
+		while ((rpc = list_first_entry_or_null(&scd->scd_rpc_free,
+						       struct srpc_server_rpc,
+						       srpc_list)) != NULL) {
 			list_del(&rpc->srpc_list);
 			kfree(rpc);
 		}
@@ -674,8 +673,8 @@ srpc_finish_service(struct srpc_service *sv)
 			continue;
 		}
 
-		rpc = list_entry(scd->scd_rpc_active.next,
-				 struct srpc_server_rpc, srpc_list);
+		rpc = list_first_entry(&scd->scd_rpc_active,
+				       struct srpc_server_rpc, srpc_list);
 		CNETERR("Active RPC %p on shutdown: sv %s, peer %s, wi %s, ev fired %d type %d status %d lnet %d\n",
 			rpc, sv->sv_name, libcfs_id2str(rpc->srpc_peer),
 			swi_state2str(rpc->srpc_wi.swi_state),
@@ -943,8 +942,8 @@ srpc_server_rpc_done(struct srpc_server_rpc *rpc, int status)
 	LASSERT(rpc->srpc_ev.ev_fired);
 
 	if (!sv->sv_shuttingdown && !list_empty(&scd->scd_buf_blocked)) {
-		buffer = list_entry(scd->scd_buf_blocked.next,
-				    struct srpc_buffer, buf_list);
+		buffer = list_first_entry(&scd->scd_buf_blocked,
+					  struct srpc_buffer, buf_list);
 		list_del(&buffer->buf_list);
 
 		srpc_init_server_rpc(rpc, scd, buffer);
@@ -1535,9 +1534,9 @@ srpc_lnet_ev_handler(struct lnet_event *ev)
 		}
 
 		if (!list_empty(&scd->scd_rpc_free)) {
-			srpc = list_entry(scd->scd_rpc_free.next,
-					  struct srpc_server_rpc,
-					  srpc_list);
+			srpc = list_first_entry(&scd->scd_rpc_free,
+						struct srpc_server_rpc,
+						srpc_list);
 			list_del(&srpc->srpc_list);
 
 			srpc_init_server_rpc(srpc, scd, buffer);
diff --git a/drivers/staging/lustre/lnet/selftest/timer.c b/drivers/staging/lustre/lnet/selftest/timer.c
index c83473ebb368..bb61e3aa11e9 100644
--- a/drivers/staging/lustre/lnet/selftest/timer.c
+++ b/drivers/staging/lustre/lnet/selftest/timer.c
@@ -125,8 +125,8 @@ stt_expire_list(struct list_head *slot, time64_t now)
 	int expired = 0;
 	struct stt_timer *timer;
 
-	while (!list_empty(slot)) {
-		timer = list_entry(slot->next, struct stt_timer, stt_list);
+	while ((timer = list_first_entry_or_null(slot, struct stt_timer,
+						 stt_list)) != NULL) {
 
 		if (timer->stt_expires > now)
 			break;

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

* [lustre-devel] [PATCH 09/21] lustre: use list_last_entry() throughout
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (15 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 18/21] lustre: move debug.c from obdclass to obdecho NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  1:07   ` Andreas Dilger
  2019-02-11  1:48   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 07/21] lustre: use list_first_entry() in lnet/klnds subdirectory NeilBrown
                   ` (3 subsequent siblings)
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

Convert
  list_entry(foo->prev .....)
to
  list_last_entry(foo, ....)

throughout lustre.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/include/cl_object.h |    2 +-
 drivers/staging/lustre/lustre/ptlrpc/client.c     |    6 +++---
 drivers/staging/lustre/lustre/ptlrpc/service.c    |    5 +++--
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
index 53fd8d469e55..bf7678aed6bf 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -2329,7 +2329,7 @@ do {									\
 static inline struct cl_page *cl_page_list_last(struct cl_page_list *plist)
 {
 	LASSERT(plist->pl_nr > 0);
-	return list_entry(plist->pl_pages.prev, struct cl_page, cp_batch);
+	return list_last_entry(&plist->pl_pages, struct cl_page, cp_batch);
 }
 
 static inline struct cl_page *cl_page_list_first(struct cl_page_list *plist)
diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index a78d49621c42..b2b11047ea19 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -1464,9 +1464,9 @@ static int after_reply(struct ptlrpc_request *req)
 		if (!list_empty(&imp->imp_replay_list)) {
 			struct ptlrpc_request *last;
 
-			last = list_entry(imp->imp_replay_list.prev,
-					  struct ptlrpc_request,
-					  rq_replay_list);
+			last = list_last_entry(&imp->imp_replay_list,
+					       struct ptlrpc_request,
+					       rq_replay_list);
 			/*
 			 * Requests with rq_replay stay on the list even if no
 			 * commit is expected.
diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
index a69736dfe8b7..35a59e5a5e9d 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -2255,8 +2255,9 @@ static int ptlrpc_hr_main(void *arg)
 		while (!list_empty(&replies)) {
 			struct ptlrpc_reply_state *rs;
 
-			rs = list_entry(replies.prev, struct ptlrpc_reply_state,
-					rs_list);
+			rs = list_last_entry(&replies,
+					     struct ptlrpc_reply_state,
+					     rs_list);
 			list_del_init(&rs->rs_list);
 			ptlrpc_handle_rs(rs);
 		}

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

* [lustre-devel] [PATCH 10/21] lustre: obdclass: use cl_object_for_each where appropriate
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (13 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 21/21] lustre: make exp_refcount in obd_export a refcount_t NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  1:10   ` Andreas Dilger
  2019-02-11  1:57   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 18/21] lustre: move debug.c from obdclass to obdecho NeilBrown
                   ` (5 subsequent siblings)
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

There are various places which have a list_for_each_entry()
where cl_object_for_each (or .._reverse) is more appropriate.

Several of these re-use the 'obj' function parameter as a loop
iterator, which is a little confusing.

Change these to use cl_object_for_each{_reverse}, and where needed,
introduce a new iterator variable 'o'.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/lov/lov_page.c       |    3 -
 drivers/staging/lustre/lustre/obdclass/cl_lock.c   |    3 -
 drivers/staging/lustre/lustre/obdclass/cl_object.c |   82 +++++++++-----------
 drivers/staging/lustre/lustre/obdclass/cl_page.c   |   11 +--
 4 files changed, 44 insertions(+), 55 deletions(-)

diff --git a/drivers/staging/lustre/lustre/lov/lov_page.c b/drivers/staging/lustre/lustre/lov/lov_page.c
index 08485a95ec01..e64b350601d2 100644
--- a/drivers/staging/lustre/lustre/lov/lov_page.c
+++ b/drivers/staging/lustre/lustre/lov/lov_page.c
@@ -103,8 +103,7 @@ int lov_page_init_composite(const struct lu_env *env, struct cl_object *obj,
 		return PTR_ERR(sub);
 
 	subobj = lovsub2cl(r0->lo_sub[stripe]);
-	list_for_each_entry(o, &subobj->co_lu.lo_header->loh_layers,
-			    co_lu.lo_linkage) {
+	cl_object_for_each(o, subobj) {
 		if (o->co_ops->coo_page_init) {
 			rc = o->co_ops->coo_page_init(sub->sub_env, o, page,
 						      cl_index(subobj, suboff));
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
index 8133d992cc73..fc5976d8b37b 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
@@ -103,8 +103,7 @@ int cl_lock_init(const struct lu_env *env, struct cl_lock *lock,
 	LASSERT(obj);
 
 	INIT_LIST_HEAD(&lock->cll_layers);
-	list_for_each_entry(scan, &obj->co_lu.lo_header->loh_layers,
-			    co_lu.lo_linkage) {
+	cl_object_for_each(scan, obj) {
 		result = scan->co_ops->coo_lock_init(env, scan, lock, io);
 		if (result != 0) {
 			cl_lock_fini(env, lock);
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
index f724b2d62df1..d71a680660da 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
@@ -190,16 +190,15 @@ EXPORT_SYMBOL(cl_object_attr_unlock);
 int cl_object_attr_get(const struct lu_env *env, struct cl_object *obj,
 		       struct cl_attr *attr)
 {
-	struct lu_object_header *top;
+	struct cl_object *o;
 	int result;
 
 	assert_spin_locked(cl_object_attr_guard(obj));
 
-	top = obj->co_lu.lo_header;
 	result = 0;
-	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
-		if (obj->co_ops->coo_attr_get) {
-			result = obj->co_ops->coo_attr_get(env, obj, attr);
+	cl_object_for_each(o, obj) {
+		if (o->co_ops->coo_attr_get) {
+			result = o->co_ops->coo_attr_get(env, o, attr);
 			if (result != 0) {
 				if (result > 0)
 					result = 0;
@@ -221,17 +220,16 @@ EXPORT_SYMBOL(cl_object_attr_get);
 int cl_object_attr_update(const struct lu_env *env, struct cl_object *obj,
 			  const struct cl_attr *attr, unsigned int v)
 {
-	struct lu_object_header *top;
+	struct cl_object *o;
 	int result;
 
 	assert_spin_locked(cl_object_attr_guard(obj));
 
-	top = obj->co_lu.lo_header;
 	result = 0;
-	list_for_each_entry_reverse(obj, &top->loh_layers, co_lu.lo_linkage) {
-		if (obj->co_ops->coo_attr_update) {
-			result = obj->co_ops->coo_attr_update(env, obj, attr,
-							      v);
+	cl_object_for_each_reverse(o, obj) {
+		if (o->co_ops->coo_attr_update) {
+			result = o->co_ops->coo_attr_update(env, o, attr,
+							    v);
 			if (result != 0) {
 				if (result > 0)
 					result = 0;
@@ -254,19 +252,18 @@ EXPORT_SYMBOL(cl_object_attr_update);
 int cl_object_glimpse(const struct lu_env *env, struct cl_object *obj,
 		      struct ost_lvb *lvb)
 {
-	struct lu_object_header *top;
+	struct cl_object *o;
 	int result;
 
-	top = obj->co_lu.lo_header;
 	result = 0;
-	list_for_each_entry_reverse(obj, &top->loh_layers, co_lu.lo_linkage) {
-		if (obj->co_ops->coo_glimpse) {
-			result = obj->co_ops->coo_glimpse(env, obj, lvb);
+	cl_object_for_each_reverse(o, obj) {
+		if (o->co_ops->coo_glimpse) {
+			result = o->co_ops->coo_glimpse(env, o, lvb);
 			if (result != 0)
 				break;
 		}
 	}
-	LU_OBJECT_HEADER(D_DLMTRACE, env, lu_object_top(top),
+	LU_OBJECT_HEADER(D_DLMTRACE, env, lu_object_top(obj->co_lu.lo_header),
 			 "size: %llu mtime: %llu atime: %llu ctime: %llu blocks: %llu\n",
 			 lvb->lvb_size, lvb->lvb_mtime, lvb->lvb_atime,
 			 lvb->lvb_ctime, lvb->lvb_blocks);
@@ -280,14 +277,13 @@ EXPORT_SYMBOL(cl_object_glimpse);
 int cl_conf_set(const struct lu_env *env, struct cl_object *obj,
 		const struct cl_object_conf *conf)
 {
-	struct lu_object_header *top;
+	struct cl_object *o;
 	int result;
 
-	top = obj->co_lu.lo_header;
 	result = 0;
-	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
-		if (obj->co_ops->coo_conf_set) {
-			result = obj->co_ops->coo_conf_set(env, obj, conf);
+	cl_object_for_each(o, obj) {
+		if (o->co_ops->coo_conf_set) {
+			result = o->co_ops->coo_conf_set(env, o, conf);
 			if (result != 0)
 				break;
 		}
@@ -301,13 +297,11 @@ EXPORT_SYMBOL(cl_conf_set);
  */
 int cl_object_prune(const struct lu_env *env, struct cl_object *obj)
 {
-	struct lu_object_header *top;
 	struct cl_object *o;
 	int result;
 
-	top = obj->co_lu.lo_header;
 	result = 0;
-	list_for_each_entry(o, &top->loh_layers, co_lu.lo_linkage) {
+	cl_object_for_each(o, obj) {
 		if (o->co_ops->coo_prune) {
 			result = o->co_ops->coo_prune(env, o);
 			if (result != 0)
@@ -325,14 +319,13 @@ EXPORT_SYMBOL(cl_object_prune);
 int cl_object_getstripe(const struct lu_env *env, struct cl_object *obj,
 			struct lov_user_md __user *uarg, size_t size)
 {
-	struct lu_object_header *top;
+	struct cl_object *o;
 	int result = 0;
 
-	top = obj->co_lu.lo_header;
-	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
-		if (obj->co_ops->coo_getstripe) {
-			result = obj->co_ops->coo_getstripe(env, obj, uarg,
-							    size);
+	cl_object_for_each(o, obj) {
+		if (o->co_ops->coo_getstripe) {
+			result = o->co_ops->coo_getstripe(env, o, uarg,
+							  size);
 			if (result)
 				break;
 		}
@@ -357,14 +350,13 @@ int cl_object_fiemap(const struct lu_env *env, struct cl_object *obj,
 		     struct ll_fiemap_info_key *key,
 		     struct fiemap *fiemap, size_t *buflen)
 {
-	struct lu_object_header *top;
+	struct cl_object *o;
 	int result = 0;
 
-	top = obj->co_lu.lo_header;
-	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
-		if (obj->co_ops->coo_fiemap) {
-			result = obj->co_ops->coo_fiemap(env, obj, key, fiemap,
-							 buflen);
+	cl_object_for_each(o, obj) {
+		if (o->co_ops->coo_fiemap) {
+			result = o->co_ops->coo_fiemap(env, o, key, fiemap,
+						       buflen);
 			if (result)
 				break;
 		}
@@ -376,11 +368,11 @@ EXPORT_SYMBOL(cl_object_fiemap);
 int cl_object_layout_get(const struct lu_env *env, struct cl_object *obj,
 			 struct cl_layout *cl)
 {
-	struct lu_object_header *top = obj->co_lu.lo_header;
+	struct cl_object *o;
 
-	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
-		if (obj->co_ops->coo_layout_get)
-			return obj->co_ops->coo_layout_get(env, obj, cl);
+	cl_object_for_each(o, obj) {
+		if (o->co_ops->coo_layout_get)
+			return o->co_ops->coo_layout_get(env, o, cl);
 	}
 
 	return -EOPNOTSUPP;
@@ -389,12 +381,12 @@ EXPORT_SYMBOL(cl_object_layout_get);
 
 loff_t cl_object_maxbytes(struct cl_object *obj)
 {
-	struct lu_object_header *top = obj->co_lu.lo_header;
+	struct cl_object *o;
 	loff_t maxbytes = LLONG_MAX;
 
-	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
-		if (obj->co_ops->coo_maxbytes)
-			maxbytes = min_t(loff_t, obj->co_ops->coo_maxbytes(obj),
+	cl_object_for_each(o, obj) {
+		if (o->co_ops->coo_maxbytes)
+			maxbytes = min_t(loff_t, o->co_ops->coo_maxbytes(o),
 					 maxbytes);
 	}
 
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
index 057318deaa4e..7d00a9233a3b 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
@@ -132,7 +132,7 @@ struct cl_page *cl_page_alloc(const struct lu_env *env,
 			      enum cl_page_type type)
 {
 	struct cl_page *page;
-	struct lu_object_header *head;
+	struct cl_object *o2;
 
 	page = kzalloc(cl_object_header(o)->coh_page_bufsize, GFP_NOFS);
 	if (page) {
@@ -149,11 +149,10 @@ struct cl_page *cl_page_alloc(const struct lu_env *env,
 		INIT_LIST_HEAD(&page->cp_layers);
 		INIT_LIST_HEAD(&page->cp_batch);
 		lu_ref_init(&page->cp_reference);
-		head = o->co_lu.lo_header;
-		list_for_each_entry(o, &head->loh_layers, co_lu.lo_linkage) {
-			if (o->co_ops->coo_page_init) {
-				result = o->co_ops->coo_page_init(env, o, page,
-								  ind);
+		cl_object_for_each(o2, o) {
+			if (o2->co_ops->coo_page_init) {
+				result = o2->co_ops->coo_page_init(env, o2, page,
+								   ind);
 				if (result != 0) {
 					__cl_page_delete(env, page);
 					cl_page_free(env, page);

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

* [lustre-devel] [PATCH 11/21] lustre: cl_object: remove vestigial debugging.
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (11 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 19/21] lustre: obdclass: avoid races in class_register_type() NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  1:31   ` Andreas Dilger
  2019-02-11  2:04   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 21/21] lustre: make exp_refcount in obd_export a refcount_t NeilBrown
                   ` (7 subsequent siblings)
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

cl_env_inc() and cl_env_dec() don't do anything,
so discard them.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/obdclass/cl_object.c |   15 ---------------
 1 file changed, 15 deletions(-)

diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
index d71a680660da..1e704078664e 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
@@ -565,14 +565,6 @@ struct cl_env {
 	void		       *ce_debug;
 };
 
-static void cl_env_inc(enum cache_stats_item item)
-{
-}
-
-static void cl_env_dec(enum cache_stats_item item)
-{
-}
-
 static void cl_env_init0(struct cl_env *cle, void *debug)
 {
 	LASSERT(cle->ce_ref == 0);
@@ -581,7 +573,6 @@ static void cl_env_init0(struct cl_env *cle, void *debug)
 
 	cle->ce_ref = 1;
 	cle->ce_debug = debug;
-	cl_env_inc(CS_busy);
 }
 
 static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
@@ -611,9 +602,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
 		if (rc != 0) {
 			kmem_cache_free(cl_env_kmem, cle);
 			env = ERR_PTR(rc);
-		} else {
-			cl_env_inc(CS_create);
-			cl_env_inc(CS_total);
 		}
 	} else {
 		env = ERR_PTR(-ENOMEM);
@@ -623,7 +611,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
 
 static void cl_env_fini(struct cl_env *cle)
 {
-	cl_env_dec(CS_total);
 	lu_context_fini(&cle->ce_lu.le_ctx);
 	lu_context_fini(&cle->ce_ses);
 	kmem_cache_free(cl_env_kmem, cle);
@@ -782,7 +769,6 @@ void cl_env_put(struct lu_env *env, u16 *refcheck)
 	if (--cle->ce_ref == 0) {
 		int cpu = get_cpu();
 
-		cl_env_dec(CS_busy);
 		cle->ce_debug = NULL;
 		cl_env_exit(cle);
 		/*
@@ -903,7 +889,6 @@ void cl_env_percpu_put(struct lu_env *env)
 	cle->ce_ref--;
 	LASSERT(cle->ce_ref == 0);
 
-	cl_env_dec(CS_busy);
 	cle->ce_debug = NULL;
 
 	put_cpu();

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

* [lustre-devel] [PATCH 12/21] lustre: cl_page.c: remove PINVRNT()
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (18 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 16/21] lustre: obdclass: normalize a switch statement NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  5:43   ` Andreas Dilger
  2019-02-11  4:01   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 15/21] lustre: obdclass: char obd_ioctl_getdata type NeilBrown
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

This macro does nothing (it once was like 'assert'),
so remove it.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/obdclass/cl_page.c |   33 ----------------------
 1 file changed, 33 deletions(-)

diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
index 7d00a9233a3b..31ded52e0499 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
@@ -55,9 +55,6 @@ static void __cl_page_delete(const struct lu_env *env, struct cl_page *pg);
 		}							   \
 	} while (0)
 
-# define PINVRNT(env, page, exp) \
-	((void)sizeof(env), (void)sizeof(page), (void)sizeof !!(exp))
-
 /**
  * Internal version of cl_page_get().
  *
@@ -382,8 +379,6 @@ void __cl_page_disown(const struct lu_env *env,
 	enum cl_page_state state;
 
 	state = pg->cp_state;
-	PINVRNT(env, pg, state == CPS_OWNED || state == CPS_FREEING);
-	PINVRNT(env, pg, cl_page_invariant(pg) || state == CPS_FREEING);
 	cl_page_owner_clear(pg);
 
 	if (state == CPS_OWNED)
@@ -437,8 +432,6 @@ static int __cl_page_own(const struct lu_env *env, struct cl_io *io,
 	const struct cl_page_slice *slice;
 	int result = 0;
 
-	PINVRNT(env, pg, !cl_page_is_owned(pg, io));
-
 	io = cl_io_top(io);
 
 	if (pg->cp_state == CPS_FREEING) {
@@ -468,7 +461,6 @@ static int __cl_page_own(const struct lu_env *env, struct cl_io *io,
 		}
 	}
 out:
-	PINVRNT(env, pg, ergo(result == 0, cl_page_invariant(pg)));
 	return result;
 }
 
@@ -510,8 +502,6 @@ void cl_page_assume(const struct lu_env *env,
 {
 	const struct cl_page_slice *slice;
 
-	PINVRNT(env, pg, cl_object_same(pg->cp_obj, io->ci_obj));
-
 	io = cl_io_top(io);
 
 	list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) {
@@ -542,9 +532,6 @@ void cl_page_unassume(const struct lu_env *env,
 {
 	const struct cl_page_slice *slice;
 
-	PINVRNT(env, pg, cl_page_is_owned(pg, io));
-	PINVRNT(env, pg, cl_page_invariant(pg));
-
 	io = cl_io_top(io);
 	cl_page_owner_clear(pg);
 	cl_page_state_set(env, pg, CPS_CACHED);
@@ -570,9 +557,6 @@ EXPORT_SYMBOL(cl_page_unassume);
 void cl_page_disown(const struct lu_env *env,
 		    struct cl_io *io, struct cl_page *pg)
 {
-	PINVRNT(env, pg, cl_page_is_owned(pg, io) ||
-		pg->cp_state == CPS_FREEING);
-
 	io = cl_io_top(io);
 	__cl_page_disown(env, io, pg);
 }
@@ -593,9 +577,6 @@ void cl_page_discard(const struct lu_env *env,
 {
 	const struct cl_page_slice *slice;
 
-	PINVRNT(env, pg, cl_page_is_owned(pg, io));
-	PINVRNT(env, pg, cl_page_invariant(pg));
-
 	list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) {
 		if (slice->cpl_ops->cpo_discard)
 			(*slice->cpl_ops->cpo_discard)(env, slice, io);
@@ -652,7 +633,6 @@ static void __cl_page_delete(const struct lu_env *env, struct cl_page *pg)
  */
 void cl_page_delete(const struct lu_env *env, struct cl_page *pg)
 {
-	PINVRNT(env, pg, cl_page_invariant(pg));
 	__cl_page_delete(env, pg);
 }
 EXPORT_SYMBOL(cl_page_delete);
@@ -670,8 +650,6 @@ void cl_page_export(const struct lu_env *env, struct cl_page *pg, int uptodate)
 {
 	const struct cl_page_slice *slice;
 
-	PINVRNT(env, pg, cl_page_invariant(pg));
-
 	list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) {
 		if (slice->cpl_ops->cpo_export)
 			(*slice->cpl_ops->cpo_export)(env, slice, uptodate);
@@ -730,10 +708,6 @@ int cl_page_prep(const struct lu_env *env, struct cl_io *io,
 	const struct cl_page_slice *slice;
 	int result = 0;
 
-	PINVRNT(env, pg, cl_page_is_owned(pg, io));
-	PINVRNT(env, pg, cl_page_invariant(pg));
-	PINVRNT(env, pg, crt < CRT_NR);
-
 	/*
 	 * XXX this has to be called bottom-to-top, so that llite can set up
 	 * PG_writeback without risking other layers deciding to skip this
@@ -819,8 +793,6 @@ int cl_page_make_ready(const struct lu_env *env, struct cl_page *pg,
 	const struct cl_page_slice *sli;
 	int result = 0;
 
-	PINVRNT(env, pg, crt < CRT_NR);
-
 	if (crt >= CRT_NR)
 		return -EINVAL;
 
@@ -856,9 +828,6 @@ int cl_page_flush(const struct lu_env *env, struct cl_io *io,
 	const struct cl_page_slice *slice;
 	int result = 0;
 
-	PINVRNT(env, pg, cl_page_is_owned(pg, io));
-	PINVRNT(env, pg, cl_page_invariant(pg));
-
 	 list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) {
 		if (slice->cpl_ops->cpo_flush)
 			result = (*slice->cpl_ops->cpo_flush)(env, slice, io);
@@ -883,8 +852,6 @@ void cl_page_clip(const struct lu_env *env, struct cl_page *pg,
 {
 	const struct cl_page_slice *slice;
 
-	PINVRNT(env, pg, cl_page_invariant(pg));
-
 	CL_PAGE_HEADER(D_TRACE, env, pg, "%d %d\n", from, to);
 
 	list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) {

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

* [lustre-devel] [PATCH 13/21] lustre: make cp_ref in cl_page a refcount_t
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (5 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 04/21] lustre: use list*entry macros in place of container_of() NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  5:45   ` Andreas Dilger
  2019-02-11  4:00   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 14/21] lustre: make ccc_users in cl_client_cache " NeilBrown
                   ` (13 subsequent siblings)
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

As this is used as a refcount, it should be declared
as one.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/include/cl_object.h |    4 ++--
 drivers/staging/lustre/lustre/llite/vvp_page.c    |    9 +++++----
 drivers/staging/lustre/lustre/obdclass/cl_page.c  |   14 +++++++-------
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
index bf7678aed6bf..c2273c3100e8 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -717,7 +717,7 @@ enum cl_page_type {
  */
 struct cl_page {
 	/** Reference counter. */
-	atomic_t			 cp_ref;
+	refcount_t			 cp_ref;
 	/** An object this page is a part of. Immutable after creation. */
 	struct cl_object		*cp_obj;
 	/** vmpage */
@@ -1021,7 +1021,7 @@ static inline struct page *cl_page_vmpage(struct cl_page *page)
  */
 static inline bool __page_in_use(const struct cl_page *page, int refc)
 {
-	return (atomic_read(&page->cp_ref) > refc + 1);
+	return (refcount_read(&page->cp_ref) > refc + 1);
 }
 
 /**
diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c
index 77bf923f2578..ec0d93313f55 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_page.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_page.c
@@ -157,15 +157,16 @@ static void vvp_page_delete(const struct lu_env *env,
 	struct inode *inode = vmpage->mapping->host;
 	struct cl_object *obj = slice->cpl_obj;
 	struct cl_page *page = slice->cpl_page;
-	int refc;
 
 	LASSERT(PageLocked(vmpage));
 	LASSERT((struct cl_page *)vmpage->private == page);
 	LASSERT(inode == vvp_object_inode(obj));
 
 	/* Drop the reference count held in vvp_page_init */
-	refc = atomic_dec_return(&page->cp_ref);
-	LASSERTF(refc >= 1, "page = %p, refc = %d\n", page, refc);
+	if (refcount_dec_and_test(&page->cp_ref)) {
+		/* It mustn't reach zero here! */
+		LASSERTF(0, "page = %p, refc reached zero\n", page);
+	}
 
 	ClearPagePrivate(vmpage);
 	vmpage->private = 0;
@@ -507,7 +508,7 @@ int vvp_page_init(const struct lu_env *env, struct cl_object *obj,
 
 	if (page->cp_type == CPT_CACHEABLE) {
 		/* in cache, decref in vvp_page_delete */
-		atomic_inc(&page->cp_ref);
+		refcount_inc(&page->cp_ref);
 		SetPagePrivate(vmpage);
 		vmpage->private = (unsigned long)page;
 		cl_page_slice_add(page, &vpg->vpg_cl, obj, index,
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
index 31ded52e0499..f0ece7e9a4ac 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
@@ -67,8 +67,8 @@ static void __cl_page_delete(const struct lu_env *env, struct cl_page *pg);
  */
 static void cl_page_get_trust(struct cl_page *page)
 {
-	LASSERT(atomic_read(&page->cp_ref) > 0);
-	atomic_inc(&page->cp_ref);
+	LASSERT(refcount_read(&page->cp_ref) > 0);
+	refcount_inc(&page->cp_ref);
 }
 
 /**
@@ -135,7 +135,7 @@ struct cl_page *cl_page_alloc(const struct lu_env *env,
 	if (page) {
 		int result = 0;
 
-		atomic_set(&page->cp_ref, 1);
+		refcount_set(&page->cp_ref, 1);
 		page->cp_obj = o;
 		cl_object_get(o);
 		lu_object_ref_add_at(&o->co_lu, &page->cp_obj_ref, "cl_page",
@@ -310,12 +310,12 @@ EXPORT_SYMBOL(cl_page_get);
 void cl_page_put(const struct lu_env *env, struct cl_page *page)
 {
 	CL_PAGE_HEADER(D_TRACE, env, page, "%d\n",
-		       atomic_read(&page->cp_ref));
+		       refcount_read(&page->cp_ref));
 
-	if (atomic_dec_and_test(&page->cp_ref)) {
+	if (refcount_dec_and_test(&page->cp_ref)) {
 		LASSERT(page->cp_state == CPS_FREEING);
 
-		LASSERT(atomic_read(&page->cp_ref) == 0);
+		LASSERT(refcount_read(&page->cp_ref) == 0);
 		PASSERT(env, page, !page->cp_owner);
 		PASSERT(env, page, list_empty(&page->cp_batch));
 		/*
@@ -869,7 +869,7 @@ void cl_page_header_print(const struct lu_env *env, void *cookie,
 {
 	(*printer)(env, cookie,
 		   "page@%p[%d %p %d %d %p]\n",
-		   pg, atomic_read(&pg->cp_ref), pg->cp_obj,
+		   pg, refcount_read(&pg->cp_ref), pg->cp_obj,
 		   pg->cp_state, pg->cp_type,
 		   pg->cp_owner);
 }

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

* [lustre-devel] [PATCH 14/21] lustre: make ccc_users in cl_client_cache a refcount_t
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (6 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 13/21] lustre: make cp_ref in cl_page a refcount_t NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  5:46   ` Andreas Dilger
  2019-02-11  4:01   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 08/21] lustre: use list_first_entry() throughout NeilBrown
                   ` (12 subsequent siblings)
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

As this is used as a refcount, it should be declared
as one.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/include/cl_object.h |    2 +-
 drivers/staging/lustre/lustre/llite/lproc_llite.c |    2 +-
 drivers/staging/lustre/lustre/obdclass/cl_page.c  |    6 +++---
 drivers/staging/lustre/lustre/osc/osc_page.c      |    4 ++--
 drivers/staging/lustre/lustre/osc/osc_request.c   |    2 +-
 5 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
index c2273c3100e8..05be85306663 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -2181,7 +2181,7 @@ struct cl_client_cache {
 	 * # of client cache refcount
 	 * # of users (OSCs) + 2 (held by llite and lov)
 	 */
-	atomic_t		ccc_users;
+	refcount_t		ccc_users;
 	/**
 	 * # of threads are doing shrinking
 	 */
diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c
index 001bed90f4da..8215296dc15d 100644
--- a/drivers/staging/lustre/lustre/llite/lproc_llite.c
+++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c
@@ -467,7 +467,7 @@ static int ll_max_cached_mb_seq_show(struct seq_file *m, void *v)
 		   "used_mb: %ld\n"
 		   "unused_mb: %ld\n"
 		   "reclaim_count: %u\n",
-		   atomic_read(&cache->ccc_users),
+		   refcount_read(&cache->ccc_users),
 		   max_cached_mb,
 		   max_cached_mb - unused_mb,
 		   unused_mb,
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
index f0ece7e9a4ac..7dcd3aff229f 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
@@ -960,7 +960,7 @@ struct cl_client_cache *cl_cache_init(unsigned long lru_page_max)
 		return NULL;
 
 	/* Initialize cache data */
-	atomic_set(&cache->ccc_users, 1);
+	refcount_set(&cache->ccc_users, 1);
 	cache->ccc_lru_max = lru_page_max;
 	atomic_long_set(&cache->ccc_lru_left, lru_page_max);
 	spin_lock_init(&cache->ccc_lru_lock);
@@ -978,7 +978,7 @@ EXPORT_SYMBOL(cl_cache_init);
  */
 void cl_cache_incref(struct cl_client_cache *cache)
 {
-	atomic_inc(&cache->ccc_users);
+	refcount_inc(&cache->ccc_users);
 }
 EXPORT_SYMBOL(cl_cache_incref);
 
@@ -989,7 +989,7 @@ EXPORT_SYMBOL(cl_cache_incref);
  */
 void cl_cache_decref(struct cl_client_cache *cache)
 {
-	if (atomic_dec_and_test(&cache->ccc_users))
+	if (refcount_dec_and_test(&cache->ccc_users))
 		kfree(cache);
 }
 EXPORT_SYMBOL(cl_cache_decref);
diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c
index 135bfe5e1b37..ce911b82512d 100644
--- a/drivers/staging/lustre/lustre/osc/osc_page.c
+++ b/drivers/staging/lustre/lustre/osc/osc_page.c
@@ -346,7 +346,7 @@ static int osc_cache_too_much(struct client_obd *cli)
 	long pages = atomic_long_read(&cli->cl_lru_in_list);
 	unsigned long budget;
 
-	budget = cache->ccc_lru_max / (atomic_read(&cache->ccc_users) - 2);
+	budget = cache->ccc_lru_max / (refcount_read(&cache->ccc_users) - 2);
 
 	/* if it's going to run out LRU slots, we should free some, but not
 	 * too much to maintain fairness among OSCs.
@@ -707,7 +707,7 @@ static long osc_lru_reclaim(struct client_obd *cli, unsigned long npages)
 	cache->ccc_lru_shrinkers++;
 	list_move_tail(&cli->cl_lru_osc, &cache->ccc_lru);
 
-	max_scans = atomic_read(&cache->ccc_users) - 2;
+	max_scans = refcount_read(&cache->ccc_users) - 2;
 	while (--max_scans > 0 &&
 	       (cli = list_first_entry_or_null(&cache->ccc_lru,
 					       struct client_obd,
diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
index 9e72fa8f68b3..0dfc506f6d01 100644
--- a/drivers/staging/lustre/lustre/osc/osc_request.c
+++ b/drivers/staging/lustre/lustre/osc/osc_request.c
@@ -2959,7 +2959,7 @@ static int osc_cleanup(struct obd_device *obd)
 
 	/* lru cleanup */
 	if (cli->cl_cache) {
-		LASSERT(atomic_read(&cli->cl_cache->ccc_users) > 0);
+		LASSERT(refcount_read(&cli->cl_cache->ccc_users) > 0);
 		spin_lock(&cli->cl_cache->ccc_lru_lock);
 		list_del_init(&cli->cl_lru_osc);
 		spin_unlock(&cli->cl_cache->ccc_lru_lock);

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

* [lustre-devel] [PATCH 15/21] lustre: obdclass: char obd_ioctl_getdata type.
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (19 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 12/21] lustre: cl_page.c: remove PINVRNT() NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  5:56   ` Andreas Dilger
  2019-02-11  4:03   ` James Simmons
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

Instead of having obd_ioctl_getdata() return the allocated
data as a "char *", return it as it really is,
 struct obd_ioctl_data *

This avoids the need for extra variables and casts.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/include/obd_class.h  |    3 ++-
 drivers/staging/lustre/lustre/llite/dir.c          |   17 +++++------------
 drivers/staging/lustre/lustre/llite/llite_lib.c    |    8 +++-----
 drivers/staging/lustre/lustre/lov/lov_obd.c        |   15 ++++++---------
 drivers/staging/lustre/lustre/obdclass/class_obd.c |   18 ++++++++----------
 5 files changed, 24 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h
index 30b3e2c69f83..32d4ab6e78a0 100644
--- a/drivers/staging/lustre/lustre/include/obd_class.h
+++ b/drivers/staging/lustre/lustre/include/obd_class.h
@@ -1697,6 +1697,7 @@ struct root_squash_info {
 };
 
 /* linux-module.c */
-int obd_ioctl_getdata(char **buf, int *len, void __user *arg);
+struct obd_ioctl_data;
+int obd_ioctl_getdata(struct obd_ioctl_data **data, int *len, void __user *arg);
 
 #endif /* __LINUX_OBD_CLASS_H */
diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c
index fd1af4a5cdad..0c49244eaee8 100644
--- a/drivers/staging/lustre/lustre/llite/dir.c
+++ b/drivers/staging/lustre/lustre/llite/dir.c
@@ -1130,13 +1130,11 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	}
 	case IOC_MDC_LOOKUP: {
 		int namelen, len = 0;
-		char *buf = NULL;
 		char *filename;
 
-		rc = obd_ioctl_getdata(&buf, &len, (void __user *)arg);
+		rc = obd_ioctl_getdata(&data, &len, (void __user *)arg);
 		if (rc)
 			return rc;
-		data = (void *)buf;
 
 		filename = data->ioc_inlbuf1;
 		namelen = strlen(filename);
@@ -1155,12 +1153,11 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 			goto out_free;
 		}
 out_free:
-		kvfree(buf);
+		kvfree(data);
 		return rc;
 	}
 	case LL_IOC_LMV_SETSTRIPE: {
 		struct lmv_user_md  *lum;
-		char *buf = NULL;
 		char *filename;
 		int namelen = 0;
 		int lumlen = 0;
@@ -1168,11 +1165,10 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		int len;
 		int rc;
 
-		rc = obd_ioctl_getdata(&buf, &len, (void __user *)arg);
+		rc = obd_ioctl_getdata(&data, &len, (void __user *)arg);
 		if (rc)
 			return rc;
 
-		data = (void *)buf;
 		if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2 ||
 		    data->ioc_inllen1 == 0 || data->ioc_inllen2 == 0) {
 			rc = -EINVAL;
@@ -1205,7 +1201,7 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 #endif
 		rc = ll_dir_setdirstripe(dentry, lum, filename, mode);
 lmv_out_free:
-		kvfree(buf);
+		kvfree(data);
 		return rc;
 	}
 	case LL_IOC_LMV_SET_DEFAULT_STRIPE: {
@@ -1651,18 +1647,16 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		return rc;
 	}
 	case LL_IOC_MIGRATE: {
-		char *buf = NULL;
 		const char *filename;
 		int namelen = 0;
 		int len;
 		int rc;
 		int mdtidx;
 
-		rc = obd_ioctl_getdata(&buf, &len, (void __user *)arg);
+		rc = obd_ioctl_getdata(&data, &len, (void __user *)arg);
 		if (rc < 0)
 			return rc;
 
-		data = (struct obd_ioctl_data *)buf;
 		if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2 ||
 		    !data->ioc_inllen1 || !data->ioc_inllen2) {
 			rc = -EINVAL;
@@ -1684,7 +1678,6 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 
 		rc = ll_migrate(inode, file, mdtidx, filename, namelen - 1);
 migrate_free:
-		kvfree(buf);
 
 		return rc;
 	}
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
index 8e09fdd7a96e..e2417cd5aaed 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -2295,7 +2295,6 @@ int ll_obd_statfs(struct inode *inode, void __user *arg)
 {
 	struct ll_sb_info *sbi = NULL;
 	struct obd_export *exp;
-	char *buf = NULL;
 	struct obd_ioctl_data *data = NULL;
 	u32 type;
 	int len = 0, rc;
@@ -2311,11 +2310,10 @@ int ll_obd_statfs(struct inode *inode, void __user *arg)
 		goto out_statfs;
 	}
 
-	rc = obd_ioctl_getdata(&buf, &len, arg);
+	rc = obd_ioctl_getdata(&data, &len, arg);
 	if (rc)
 		goto out_statfs;
 
-	data = (void *)buf;
 	if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2 ||
 	    !data->ioc_pbuf1 || !data->ioc_pbuf2) {
 		rc = -EINVAL;
@@ -2340,11 +2338,11 @@ int ll_obd_statfs(struct inode *inode, void __user *arg)
 		goto out_statfs;
 	}
 
-	rc = obd_iocontrol(IOC_OBD_STATFS, exp, len, buf, NULL);
+	rc = obd_iocontrol(IOC_OBD_STATFS, exp, len, data, NULL);
 	if (rc)
 		goto out_statfs;
 out_statfs:
-	kvfree(buf);
+	kvfree(data);
 	return rc;
 }
 
diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c
index 04d0a9ed1d05..fd769c39b482 100644
--- a/drivers/staging/lustre/lustre/lov/lov_obd.c
+++ b/drivers/staging/lustre/lustre/lov/lov_obd.c
@@ -1039,27 +1039,24 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
 	case OBD_IOC_LOV_GET_CONFIG: {
 		struct obd_ioctl_data *data;
 		struct lov_desc *desc;
-		char *buf = NULL;
 		u32 *genp;
 
 		len = 0;
-		if (obd_ioctl_getdata(&buf, &len, uarg))
+		if (obd_ioctl_getdata(&data, &len, uarg))
 			return -EINVAL;
 
-		data = (struct obd_ioctl_data *)buf;
-
 		if (sizeof(*desc) > data->ioc_inllen1) {
-			kvfree(buf);
+			kvfree(data);
 			return -EINVAL;
 		}
 
 		if (sizeof(uuidp->uuid) * count > data->ioc_inllen2) {
-			kvfree(buf);
+			kvfree(data);
 			return -EINVAL;
 		}
 
 		if (sizeof(u32) * count > data->ioc_inllen3) {
-			kvfree(buf);
+			kvfree(data);
 			return -EINVAL;
 		}
 
@@ -1076,9 +1073,9 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
 			*genp = lov->lov_tgts[i]->ltd_gen;
 		}
 
-		if (copy_to_user(uarg, buf, len))
+		if (copy_to_user(uarg, data, len))
 			rc = -EFAULT;
-		kvfree(buf);
+		kvfree(data);
 		break;
 	}
 	case OBD_IOC_QUOTACTL: {
diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c
index b859ab19b9f6..2ef4fd41cdd0 100644
--- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
+++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
@@ -230,7 +230,7 @@ static int obd_ioctl_is_invalid(struct obd_ioctl_data *data)
 }
 
 /* buffer MUST be at least the size of obd_ioctl_hdr */
-int obd_ioctl_getdata(char **buf, int *len, void __user *arg)
+int obd_ioctl_getdata(struct obd_ioctl_data **datap, int *len, void __user *arg)
 {
 	struct obd_ioctl_data *data;
 	struct obd_ioctl_hdr hdr;
@@ -262,16 +262,16 @@ int obd_ioctl_getdata(char **buf, int *len, void __user *arg)
 	 * obdfilter-survey is an example, which relies on ioctl. So we'd
 	 * better avoid vmalloc on ioctl path. LU-66
 	 */
-	*buf = kvzalloc(hdr.ioc_len, GFP_KERNEL);
-	if (!*buf) {
+	data = kvzalloc(hdr.ioc_len, GFP_KERNEL);
+	if (!data) {
 		CERROR("Cannot allocate control buffer of len %d\n",
 		       hdr.ioc_len);
 		return -EINVAL;
 	}
 	*len = hdr.ioc_len;
-	data = (struct obd_ioctl_data *)*buf;
+	*datap = data;
 
-	if (copy_from_user(*buf, arg, hdr.ioc_len)) {
+	if (copy_from_user(data, arg, hdr.ioc_len)) {
 		err = -EFAULT;
 		goto free_buf;
 	}
@@ -308,14 +308,13 @@ int obd_ioctl_getdata(char **buf, int *len, void __user *arg)
 	return 0;
 
 free_buf:
-	kvfree(*buf);
+	kvfree(data);
 	return err;
 }
 EXPORT_SYMBOL(obd_ioctl_getdata);
 
 int class_handle_ioctl(unsigned int cmd, unsigned long arg)
 {
-	char *buf = NULL;
 	struct obd_ioctl_data *data;
 	struct libcfs_debug_ioctl_data *debug_data;
 	struct obd_device *obd = NULL;
@@ -330,11 +329,10 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
 	}
 
 	CDEBUG(D_IOCTL, "cmd = %x\n", cmd);
-	if (obd_ioctl_getdata(&buf, &len, (void __user *)arg)) {
+	if (obd_ioctl_getdata(&data, &len, (void __user *)arg)) {
 		CERROR("OBD ioctl: data error\n");
 		return -EINVAL;
 	}
-	data = (struct obd_ioctl_data *)buf;
 
 	switch (cmd) {
 	case OBD_IOC_PROCESS_CFG: {
@@ -545,7 +543,7 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
 	}
 
  out:
-	kvfree(buf);
+	kvfree(data);
 	return err;
 } /* class_handle_ioctl */
 

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

* [lustre-devel] [PATCH 16/21] lustre: obdclass: normalize a switch statement.
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (17 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 07/21] lustre: use list_first_entry() in lnet/klnds subdirectory NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  5:57   ` Andreas Dilger
  2019-02-11  4:03   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 12/21] lustre: cl_page.c: remove PINVRNT() NeilBrown
  2019-02-07  0:03 ` [lustre-devel] [PATCH 15/21] lustre: obdclass: char obd_ioctl_getdata type NeilBrown
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

Remove the unnecessary {}, and use "break" rather than
"goto out;" for normal exit from the cases.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/obdclass/class_obd.c |   10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c
index 2ef4fd41cdd0..48d1dabafa65 100644
--- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
+++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
@@ -518,7 +518,7 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
 	}
 
 	switch (cmd) {
-	case OBD_IOC_NO_TRANSNO: {
+	case OBD_IOC_NO_TRANSNO:
 		if (!obd->obd_attached) {
 			CERROR("Device %d not attached\n", obd->obd_minor);
 			err = -ENODEV;
@@ -528,18 +528,16 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
 		       obd->obd_name);
 		obd->obd_no_transno = 1;
 		err = 0;
-		goto out;
-	}
+		break;
 
-	default: {
+	default:
 		err = obd_iocontrol(cmd, obd->obd_self_export, len, data, NULL);
 		if (err)
 			goto out;
 
 		if (copy_to_user((void __user *)arg, data, len))
 			err = -EFAULT;
-		goto out;
-	}
+		break;
 	}
 
  out:

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

* [lustre-devel] [PATCH 17/21] lustre: obdclass: result of try_module_get() should not be ignored.
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (9 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 20/21] lustre: obdclass: fix module load locking NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  5:58   ` Andreas Dilger
  2019-02-11  4:22   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 19/21] lustre: obdclass: avoid races in class_register_type() NeilBrown
                   ` (9 subsequent siblings)
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

If try_module_get() fails, the open must fail.

In practice this should be impossible, but it is
best to make the code look right.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/obdclass/class_obd.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c
index 48d1dabafa65..982d47b6f50e 100644
--- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
+++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
@@ -548,8 +548,7 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
 /*  opening /dev/obd */
 static int obd_class_open(struct inode *inode, struct file *file)
 {
-	try_module_get(THIS_MODULE);
-	return 0;
+	return try_module_get(THIS_MODULE) ? 0 : -ENODEV;
 }
 
 /*  closing /dev/obd */

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

* [lustre-devel] [PATCH 18/21] lustre: move debug.c from obdclass to obdecho
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (14 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 10/21] lustre: obdclass: use cl_object_for_each where appropriate NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  6:02   ` Andreas Dilger
  2019-02-11  4:17   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 09/21] lustre: use list_last_entry() throughout NeilBrown
                   ` (4 subsequent siblings)
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

The functions defined in debug.c are only used in
obdecho, so move it there, and make the functions local
to that unit.
This allows lustre_debug.h to be removed.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 .../staging/lustre/lustre/include/lustre_debug.h   |   52 -----------
 .../staging/lustre/lustre/llite/llite_internal.h   |    2 
 drivers/staging/lustre/lustre/obdclass/Makefile    |    2 
 drivers/staging/lustre/lustre/obdclass/class_obd.c |    1 
 drivers/staging/lustre/lustre/obdclass/debug.c     |   96 --------------------
 drivers/staging/lustre/lustre/obdecho/Makefile     |    2 
 drivers/staging/lustre/lustre/obdecho/debug.c      |   96 ++++++++++++++++++++
 .../staging/lustre/lustre/obdecho/echo_client.c    |    1 
 .../staging/lustre/lustre/obdecho/echo_internal.h  |    4 +
 drivers/staging/lustre/lustre/osc/osc_request.c    |    1 
 drivers/staging/lustre/lustre/ptlrpc/layout.c      |    1 
 11 files changed, 103 insertions(+), 155 deletions(-)
 delete mode 100644 drivers/staging/lustre/lustre/include/lustre_debug.h
 delete mode 100644 drivers/staging/lustre/lustre/obdclass/debug.c
 create mode 100644 drivers/staging/lustre/lustre/obdecho/debug.c

diff --git a/drivers/staging/lustre/lustre/include/lustre_debug.h b/drivers/staging/lustre/lustre/include/lustre_debug.h
deleted file mode 100644
index b9414fc73f00..000000000000
--- a/drivers/staging/lustre/lustre/include/lustre_debug.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2011, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-
-#ifndef _LUSTRE_DEBUG_H
-#define _LUSTRE_DEBUG_H
-
-/** \defgroup debug debug
- *
- * @{
- */
-
-#include <lustre_net.h>
-#include <obd.h>
-
-/* lib/debug.c */
-int dump_req(struct ptlrpc_request *req);
-int block_debug_setup(void *addr, int len, u64 off, u64 id);
-int block_debug_check(char *who, void *addr, int len, u64 off, u64 id);
-
-/** @} debug */
-
-#endif
diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h
index bf7e46fe9ec6..c8860904bdd4 100644
--- a/drivers/staging/lustre/lustre/llite/llite_internal.h
+++ b/drivers/staging/lustre/lustre/llite/llite_internal.h
@@ -33,7 +33,7 @@
 
 #ifndef LLITE_INTERNAL_H
 #define LLITE_INTERNAL_H
-#include <lustre_debug.h>
+#include <obd.h>
 #include <uapi/linux/lustre/lustre_ver.h>
 #include <lustre_disk.h>	/* for s2sbi */
 #include <lustre_linkea.h>
diff --git a/drivers/staging/lustre/lustre/obdclass/Makefile b/drivers/staging/lustre/lustre/obdclass/Makefile
index b1fac48b3adc..1669c24a0b03 100644
--- a/drivers/staging/lustre/lustre/obdclass/Makefile
+++ b/drivers/staging/lustre/lustre/obdclass/Makefile
@@ -4,7 +4,7 @@ ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
 
 obj-$(CONFIG_LUSTRE_FS) += obdclass.o
 
-obdclass-y := llog.o llog_cat.o llog_obd.o llog_swab.o class_obd.o debug.o \
+obdclass-y := llog.o llog_cat.o llog_obd.o llog_swab.o class_obd.o \
 	      genops.o obd_sysfs.o lprocfs_status.o lprocfs_counters.o \
 	      lustre_handles.o lustre_peer.o statfs_pack.o linkea.o \
 	      obdo.o obd_config.o obd_mount.o lu_object.o lu_ref.o \
diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c
index 982d47b6f50e..4a717a29e385 100644
--- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
+++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
@@ -41,7 +41,6 @@
 #include <obd_support.h>
 #include <obd_class.h>
 #include <uapi/linux/lnet/lnetctl.h>
-#include <lustre_debug.h>
 #include <lustre_kernelcomm.h>
 #include <lprocfs_status.h>
 #include <linux/list.h>
diff --git a/drivers/staging/lustre/lustre/obdclass/debug.c b/drivers/staging/lustre/lustre/obdclass/debug.c
deleted file mode 100644
index 2e526c7389d8..000000000000
--- a/drivers/staging/lustre/lustre/obdclass/debug.c
+++ /dev/null
@@ -1,96 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2011, 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- *
- * lustre/obdclass/debug.c
- *
- * Helper routines for dumping data structs for debugging.
- */
-
-#define DEBUG_SUBSYSTEM D_OTHER
-
-#include <asm/unaligned.h>
-
-#include <obd_support.h>
-#include <lustre_debug.h>
-#include <lustre_net.h>
-
-#define LPDS sizeof(u64)
-int block_debug_setup(void *addr, int len, u64 off, u64 id)
-{
-	LASSERT(addr);
-
-	put_unaligned_le64(off, addr);
-	put_unaligned_le64(id, addr + LPDS);
-	addr += len - LPDS - LPDS;
-	put_unaligned_le64(off, addr);
-	put_unaligned_le64(id, addr + LPDS);
-
-	return 0;
-}
-EXPORT_SYMBOL(block_debug_setup);
-
-int block_debug_check(char *who, void *addr, int end, u64 off, u64 id)
-{
-	u64 ne_off;
-	int err = 0;
-
-	LASSERT(addr);
-
-	ne_off = le64_to_cpu(off);
-	id = le64_to_cpu(id);
-	if (memcmp(addr, (char *)&ne_off, LPDS)) {
-		CDEBUG(D_ERROR, "%s: id %#llx offset %llu off: %#llx != %#llx\n",
-		       who, id, off, *(u64 *)addr, ne_off);
-		err = -EINVAL;
-	}
-	if (memcmp(addr + LPDS, (char *)&id, LPDS)) {
-		CDEBUG(D_ERROR, "%s: id %#llx offset %llu id: %#llx != %#llx\n",
-		       who, id, off, *(u64 *)(addr + LPDS), id);
-		err = -EINVAL;
-	}
-
-	addr += end - LPDS - LPDS;
-	if (memcmp(addr, (char *)&ne_off, LPDS)) {
-		CDEBUG(D_ERROR, "%s: id %#llx offset %llu end off: %#llx != %#llx\n",
-		       who, id, off, *(u64 *)addr, ne_off);
-		err = -EINVAL;
-	}
-	if (memcmp(addr + LPDS, (char *)&id, LPDS)) {
-		CDEBUG(D_ERROR, "%s: id %#llx offset %llu end id: %#llx != %#llx\n",
-		       who, id, off, *(u64 *)(addr + LPDS), id);
-		err = -EINVAL;
-	}
-
-	return err;
-}
-EXPORT_SYMBOL(block_debug_check);
-#undef LPDS
diff --git a/drivers/staging/lustre/lustre/obdecho/Makefile b/drivers/staging/lustre/lustre/obdecho/Makefile
index ff85ef1db70a..0a02efae036d 100644
--- a/drivers/staging/lustre/lustre/obdecho/Makefile
+++ b/drivers/staging/lustre/lustre/obdecho/Makefile
@@ -2,4 +2,4 @@ ccflags-y += -I$(srctree)/drivers/staging/lustre/include
 ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
 
 obj-$(CONFIG_LUSTRE_FS) += obdecho.o
-obdecho-y := echo_client.o
+obdecho-y := echo_client.o debug.o
diff --git a/drivers/staging/lustre/lustre/obdecho/debug.c b/drivers/staging/lustre/lustre/obdecho/debug.c
new file mode 100644
index 000000000000..149aca54c776
--- /dev/null
+++ b/drivers/staging/lustre/lustre/obdecho/debug.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/obdclass/debug.c
+ *
+ * Helper routines for dumping data structs for debugging.
+ */
+
+#define DEBUG_SUBSYSTEM D_OTHER
+
+#include <asm/unaligned.h>
+
+#include <obd_support.h>
+#include "echo_internal.h"
+#include <lustre_net.h>
+
+#define LPDS sizeof(u64)
+int block_debug_setup(void *addr, int len, u64 off, u64 id)
+{
+	LASSERT(addr);
+
+	put_unaligned_le64(off, addr);
+	put_unaligned_le64(id, addr + LPDS);
+	addr += len - LPDS - LPDS;
+	put_unaligned_le64(off, addr);
+	put_unaligned_le64(id, addr + LPDS);
+
+	return 0;
+}
+EXPORT_SYMBOL(block_debug_setup);
+
+int block_debug_check(char *who, void *addr, int end, u64 off, u64 id)
+{
+	u64 ne_off;
+	int err = 0;
+
+	LASSERT(addr);
+
+	ne_off = le64_to_cpu(off);
+	id = le64_to_cpu(id);
+	if (memcmp(addr, (char *)&ne_off, LPDS)) {
+		CDEBUG(D_ERROR, "%s: id %#llx offset %llu off: %#llx != %#llx\n",
+		       who, id, off, *(u64 *)addr, ne_off);
+		err = -EINVAL;
+	}
+	if (memcmp(addr + LPDS, (char *)&id, LPDS)) {
+		CDEBUG(D_ERROR, "%s: id %#llx offset %llu id: %#llx != %#llx\n",
+		       who, id, off, *(u64 *)(addr + LPDS), id);
+		err = -EINVAL;
+	}
+
+	addr += end - LPDS - LPDS;
+	if (memcmp(addr, (char *)&ne_off, LPDS)) {
+		CDEBUG(D_ERROR, "%s: id %#llx offset %llu end off: %#llx != %#llx\n",
+		       who, id, off, *(u64 *)addr, ne_off);
+		err = -EINVAL;
+	}
+	if (memcmp(addr + LPDS, (char *)&id, LPDS)) {
+		CDEBUG(D_ERROR, "%s: id %#llx offset %llu end id: %#llx != %#llx\n",
+		       who, id, off, *(u64 *)(addr + LPDS), id);
+		err = -EINVAL;
+	}
+
+	return err;
+}
+EXPORT_SYMBOL(block_debug_check);
+#undef LPDS
diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c
index 1ebd98513239..1b7d98c649b6 100644
--- a/drivers/staging/lustre/lustre/obdecho/echo_client.c
+++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c
@@ -37,7 +37,6 @@
 #include <obd.h>
 #include <obd_support.h>
 #include <obd_class.h>
-#include <lustre_debug.h>
 #include <lprocfs_status.h>
 #include <cl_object.h>
 #include <lustre_fid.h>
diff --git a/drivers/staging/lustre/lustre/obdecho/echo_internal.h b/drivers/staging/lustre/lustre/obdecho/echo_internal.h
index 8094a94f605c..f9bb0b91d399 100644
--- a/drivers/staging/lustre/lustre/obdecho/echo_internal.h
+++ b/drivers/staging/lustre/lustre/obdecho/echo_internal.h
@@ -39,4 +39,8 @@
 /* block size to use for data verification */
 #define OBD_ECHO_BLOCK_SIZE	(4 << 10)
 
+/* debug.c */
+int block_debug_setup(void *addr, int len, u64 off, u64 id);
+int block_debug_check(char *who, void *addr, int len, u64 off, u64 id);
+
 #endif
diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
index 0dfc506f6d01..3fedfaf249c4 100644
--- a/drivers/staging/lustre/lustre/osc/osc_request.c
+++ b/drivers/staging/lustre/lustre/osc/osc_request.c
@@ -45,7 +45,6 @@
 #include <lustre_ha.h>
 #include <lprocfs_status.h>
 #include <uapi/linux/lustre/lustre_ioctl.h>
-#include <lustre_debug.h>
 #include <lustre_obdo.h>
 #include <uapi/linux/lustre/lustre_param.h>
 #include <lustre_fid.h>
diff --git a/drivers/staging/lustre/lustre/ptlrpc/layout.c b/drivers/staging/lustre/lustre/ptlrpc/layout.c
index f1f7d70b9790..d9f2b3d9e526 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/layout.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/layout.c
@@ -50,7 +50,6 @@
 #include <uapi/linux/lustre/lustre_idl.h>
 
 #include <llog_swab.h>
-#include <lustre_debug.h>
 #include <lustre_swab.h>
 #include <uapi/linux/lustre/lustre_ver.h>
 #include <obd.h>

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

* [lustre-devel] [PATCH 19/21] lustre: obdclass: avoid races in class_register_type()
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (10 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 17/21] lustre: obdclass: result of try_module_get() should not be ignored NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  6:41   ` Andreas Dilger
  2019-02-12  5:03   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 11/21] lustre: cl_object: remove vestigial debugging NeilBrown
                   ` (8 subsequent siblings)
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

If there are two parallel attempts to register the
same class name, it could get registered twice.
So re-check after allocation to make sure the name is
still unique.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/obdclass/genops.c |   29 +++++++++++++++--------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
index 382eaf519a79..a174f538dd0d 100644
--- a/drivers/staging/lustre/lustre/obdclass/genops.c
+++ b/drivers/staging/lustre/lustre/obdclass/genops.c
@@ -86,17 +86,23 @@ static void obd_device_free(struct obd_device *obd)
 	kmem_cache_free(obd_device_cachep, obd);
 }
 
-static struct obd_type *class_search_type(const char *name)
+static struct obd_type *__class_search_type(const char *name)
 {
 	struct obd_type *type;
 
-	spin_lock(&obd_types_lock);
 	list_for_each_entry(type, &obd_types, typ_chain) {
-		if (strcmp(type->typ_name, name) == 0) {
-			spin_unlock(&obd_types_lock);
+		if (strcmp(type->typ_name, name) == 0)
 			return type;
-		}
 	}
+	return NULL;
+}
+
+static struct obd_type *class_search_type(const char *name)
+{
+	struct obd_type *type;
+
+	spin_lock(&obd_types_lock);
+	type = __class_search_type(name);
 	spin_unlock(&obd_types_lock);
 	return NULL;
 }
@@ -214,19 +220,22 @@ int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops,
 	if (ldt) {
 		type->typ_lu = ldt;
 		rc = lu_device_type_init(ldt);
-		if (rc != 0) {
-			kobject_put(type->typ_kobj);
+		if (rc != 0)
 			goto failed;
-		}
 	}
 
+	INIT_LIST_HEAD(&type->typ_chain);
 	spin_lock(&obd_types_lock);
-	list_add(&type->typ_chain, &obd_types);
+	if (__class_search_type(name) == NULL)
+		list_add(&type->typ_chain, &obd_types);
 	spin_unlock(&obd_types_lock);
 
-	return 0;
+	if (!list_empty(&type->typ_chain))
+		return 0;
 
 failed:
+	if (!IS_ERR_OR_NULL(type->typ_kobj))
+		kobject_put(type->typ_kobj);
 	kfree(type->typ_name);
 	kfree(type->typ_md_ops);
 	kfree(type->typ_dt_ops);

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

* [lustre-devel] [PATCH 20/21] lustre: obdclass: fix module load locking.
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (8 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 08/21] lustre: use list_first_entry() throughout NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-13  1:53   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 17/21] lustre: obdclass: result of try_module_get() should not be ignored NeilBrown
                   ` (10 subsequent siblings)
  20 siblings, 1 reply; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

Safe module loading requires that we try_module_get() in a context
where the module cannot be unloaded, typically prodected by
a spinlock that module-unload has to take.
This doesn't currently happen in class_get_type().

There is a per-type spinlock, but it is almost entirely unused, and
cannot be used to protect the module from being unloaded.

So discard ->obd_type_lock, and ensure that __class_search_type() and
try_module_get() are both called while obd_types_lock is held - this
prevent class_unregister_type() from completing (so the 'type' won't get
freed.  That is always called from a module-unload function - if it
has got that far, try_module_get() will fail.

So also check the return status of try_module_get().

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/include/obd.h     |    1 -
 drivers/staging/lustre/lustre/obdclass/genops.c |   24 ++++++++++++++---------
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h
index 171d2c214be6..463ab680b524 100644
--- a/drivers/staging/lustre/lustre/include/obd.h
+++ b/drivers/staging/lustre/lustre/include/obd.h
@@ -106,7 +106,6 @@ struct obd_type {
 	char			*typ_name;
 	int			 typ_refcnt;
 	struct lu_device_type	*typ_lu;
-	spinlock_t		 obd_type_lock;
 	struct kobject		*typ_kobj;
 };
 
diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
index a174f538dd0d..dad21d9fa328 100644
--- a/drivers/staging/lustre/lustre/obdclass/genops.c
+++ b/drivers/staging/lustre/lustre/obdclass/genops.c
@@ -109,35 +109,42 @@ static struct obd_type *class_search_type(const char *name)
 
 static struct obd_type *class_get_type(const char *name)
 {
-	struct obd_type *type = class_search_type(name);
+	struct obd_type *type;
+
+	spin_lock(&obd_types_lock);
+	type = __class_search_type(name);
 
 	if (!type) {
 		const char *modname = name;
 
+		spin_unlock(&obd_types_lock);
 		if (!request_module("%s", modname)) {
 			CDEBUG(D_INFO, "Loaded module '%s'\n", modname);
-			type = class_search_type(name);
 		} else {
 			LCONSOLE_ERROR_MSG(0x158, "Can't load module '%s'\n",
 					   modname);
 		}
+		spin_lock(&obd_types_lock);
+		type = __class_search_type(name);
 	}
 	if (type) {
-		spin_lock(&type->obd_type_lock);
-		type->typ_refcnt++;
-		try_module_get(type->typ_dt_ops->owner);
-		spin_unlock(&type->obd_type_lock);
+		if (try_module_get(type->typ_dt_ops->owner))
+			type->typ_refcnt++;
+		else
+			type = NULL;
 	}
+	spin_unlock(&obd_types_lock);
 	return type;
 }
 
 void class_put_type(struct obd_type *type)
 {
 	LASSERT(type);
-	spin_lock(&type->obd_type_lock);
+	spin_lock(&obd_types_lock);
+	LASSERT(type->typ_refcnt > 0);
 	type->typ_refcnt--;
 	module_put(type->typ_dt_ops->owner);
-	spin_unlock(&type->obd_type_lock);
+	spin_unlock(&obd_types_lock);
 }
 
 static void class_sysfs_release(struct kobject *kobj)
@@ -206,7 +213,6 @@ int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops,
 	if (md_ops)
 		*type->typ_md_ops = *md_ops;
 	strcpy(type->typ_name, name);
-	spin_lock_init(&type->obd_type_lock);
 
 	type->typ_debugfs_entry = debugfs_create_dir(type->typ_name,
 						     debugfs_lustre_root);

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

* [lustre-devel] [PATCH 21/21] lustre: make exp_refcount in obd_export a refcount_t
  2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
                   ` (12 preceding siblings ...)
  2019-02-07  0:03 ` [lustre-devel] [PATCH 11/21] lustre: cl_object: remove vestigial debugging NeilBrown
@ 2019-02-07  0:03 ` NeilBrown
  2019-02-08  7:07   ` Andreas Dilger
  2019-02-11  4:18   ` James Simmons
  2019-02-07  0:03 ` [lustre-devel] [PATCH 10/21] lustre: obdclass: use cl_object_for_each where appropriate NeilBrown
                   ` (6 subsequent siblings)
  20 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-07  0:03 UTC (permalink / raw)
  To: lustre-devel

As this is used as a refcount, it should be declared
as one.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 .../staging/lustre/lustre/include/lustre_export.h  |    2 +-
 drivers/staging/lustre/lustre/ldlm/ldlm_lock.c     |   10 +++++-----
 drivers/staging/lustre/lustre/obdclass/genops.c    |   15 ++++++++-------
 .../staging/lustre/lustre/obdecho/echo_client.c    |    2 +-
 drivers/staging/lustre/lustre/ptlrpc/service.c     |    4 ++--
 5 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/lustre_export.h b/drivers/staging/lustre/lustre/include/lustre_export.h
index 63fa656eb7ba..fb34e0b7de35 100644
--- a/drivers/staging/lustre/lustre/include/lustre_export.h
+++ b/drivers/staging/lustre/lustre/include/lustre_export.h
@@ -67,7 +67,7 @@ struct obd_export {
 	 * what export they are talking to.
 	 */
 	struct portals_handle		exp_handle;
-	atomic_t			exp_refcount;
+	refcount_t			exp_refcount;
 	/**
 	 * Set of counters below is to track where export references are
 	 * kept. The exp_rpc_count is used for reconnect handling also,
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
index cea0e22d064b..f2433dc0e558 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
@@ -1998,7 +1998,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
 				   ldlm_lockname[lock->l_req_mode],
 				   lock->l_flags, nid,
 				   lock->l_remote_handle.cookie,
-				   exp ? atomic_read(&exp->exp_refcount) : -99,
+				   exp ? refcount_read(&exp->exp_refcount) : -99,
 				   lock->l_pid, lock->l_callback_timeout,
 				   lock->l_lvb_type);
 		va_end(args);
@@ -2024,7 +2024,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
 				   lock->l_req_extent.end,
 				   lock->l_flags, nid,
 				   lock->l_remote_handle.cookie,
-				   exp ? atomic_read(&exp->exp_refcount) : -99,
+				   exp ? refcount_read(&exp->exp_refcount) : -99,
 				   lock->l_pid, lock->l_callback_timeout,
 				   lock->l_lvb_type);
 		break;
@@ -2046,7 +2046,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
 				   lock->l_policy_data.l_flock.end,
 				   lock->l_flags, nid,
 				   lock->l_remote_handle.cookie,
-				   exp ? atomic_read(&exp->exp_refcount) : -99,
+				   exp ? refcount_read(&exp->exp_refcount) : -99,
 				   lock->l_pid, lock->l_callback_timeout);
 		break;
 
@@ -2065,7 +2065,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
 				   ldlm_typename[resource->lr_type],
 				   lock->l_flags, nid,
 				   lock->l_remote_handle.cookie,
-				   exp ? atomic_read(&exp->exp_refcount) : -99,
+				   exp ? refcount_read(&exp->exp_refcount) : -99,
 				   lock->l_pid, lock->l_callback_timeout,
 				   lock->l_lvb_type);
 		break;
@@ -2084,7 +2084,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
 				   ldlm_typename[resource->lr_type],
 				   lock->l_flags, nid,
 				   lock->l_remote_handle.cookie,
-				   exp ? atomic_read(&exp->exp_refcount) : -99,
+				   exp ? refcount_read(&exp->exp_refcount) : -99,
 				   lock->l_pid, lock->l_callback_timeout,
 				   lock->l_lvb_type);
 		break;
diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
index dad21d9fa328..39919f1c5b71 100644
--- a/drivers/staging/lustre/lustre/obdclass/genops.c
+++ b/drivers/staging/lustre/lustre/obdclass/genops.c
@@ -757,7 +757,7 @@ static void class_export_destroy(struct obd_export *exp)
 {
 	struct obd_device *obd = exp->exp_obd;
 
-	LASSERT_ATOMIC_ZERO(&exp->exp_refcount);
+	LASSERT(refcount_read(&exp->exp_refcount) == 0);
 	LASSERT(obd);
 
 	CDEBUG(D_IOCTL, "destroying export %p/%s for %s\n", exp,
@@ -793,20 +793,21 @@ static struct portals_handle_ops export_handle_ops = {
 
 struct obd_export *class_export_get(struct obd_export *exp)
 {
-	atomic_inc(&exp->exp_refcount);
+	refcount_inc(&exp->exp_refcount);
 	CDEBUG(D_INFO, "GETting export %p : new refcount %d\n", exp,
-	       atomic_read(&exp->exp_refcount));
+	       refcount_read(&exp->exp_refcount));
 	return exp;
 }
 EXPORT_SYMBOL(class_export_get);
 
 void class_export_put(struct obd_export *exp)
 {
-	LASSERT_ATOMIC_GT_LT(&exp->exp_refcount, 0, LI_POISON);
+	LASSERT(refcount_read(&exp->exp_refcount) >  0);
+	LASSERT(refcount_read(&exp->exp_refcount) < LI_POISON);
 	CDEBUG(D_INFO, "PUTting export %p : new refcount %d\n", exp,
-	       atomic_read(&exp->exp_refcount) - 1);
+	       refcount_read(&exp->exp_refcount) - 1);
 
-	if (atomic_dec_and_test(&exp->exp_refcount)) {
+	if (refcount_dec_and_test(&exp->exp_refcount)) {
 		struct obd_device *obd = exp->exp_obd;
 
 		CDEBUG(D_IOCTL, "final put %p/%s\n",
@@ -856,7 +857,7 @@ static struct obd_export *__class_new_export(struct obd_device *obd,
 
 	export->exp_conn_cnt = 0;
 	/* 2 = class_handle_hash + last */
-	atomic_set(&export->exp_refcount, 2);
+	refcount_set(&export->exp_refcount, 2);
 	atomic_set(&export->exp_rpc_count, 0);
 	atomic_set(&export->exp_cb_count, 0);
 	atomic_set(&export->exp_locks_count, 0);
diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c
index 1b7d98c649b6..317123fd27cb 100644
--- a/drivers/staging/lustre/lustre/obdecho/echo_client.c
+++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c
@@ -1638,7 +1638,7 @@ static int echo_client_cleanup(struct obd_device *obddev)
 		return -EBUSY;
 	}
 
-	LASSERT(atomic_read(&ec->ec_exp->exp_refcount) > 0);
+	LASSERT(refcount_read(&ec->ec_exp->exp_refcount) > 0);
 	rc = obd_disconnect(ec->ec_exp);
 	if (rc != 0)
 		CERROR("fail to disconnect device: %d\n", rc);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
index 35a59e5a5e9d..b7d44fc21d73 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/service.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
@@ -1697,7 +1697,7 @@ ptlrpc_server_handle_request(struct ptlrpc_service_part *svcpt,
 	       (request->rq_export ?
 		(char *)request->rq_export->exp_client_uuid.uuid : "0"),
 	       (request->rq_export ?
-		atomic_read(&request->rq_export->exp_refcount) : -99),
+		refcount_read(&request->rq_export->exp_refcount) : -99),
 	       lustre_msg_get_status(request->rq_reqmsg), request->rq_xid,
 	       libcfs_id2str(request->rq_peer),
 	       lustre_msg_get_opc(request->rq_reqmsg));
@@ -1741,7 +1741,7 @@ ptlrpc_server_handle_request(struct ptlrpc_service_part *svcpt,
 	       (request->rq_export ?
 		(char *)request->rq_export->exp_client_uuid.uuid : "0"),
 	       (request->rq_export ?
-		atomic_read(&request->rq_export->exp_refcount) : -99),
+		refcount_read(&request->rq_export->exp_refcount) : -99),
 	       lustre_msg_get_status(request->rq_reqmsg),
 	       request->rq_xid,
 	       libcfs_id2str(request->rq_peer),

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

* [lustre-devel] [PATCH 01/21] lustre: obdclass: discard csi_end_io
  2019-02-07  0:03 ` [lustre-devel] [PATCH 01/21] lustre: obdclass: discard csi_end_io NeilBrown
@ 2019-02-07  0:20   ` Andreas Dilger
  2019-02-11  0:19   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: Andreas Dilger @ 2019-02-07  0:20 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> The csi_end_io field in "struct cl_sync_io" is always
> set to cl_sync_io_end(), which is a tiny function.
> This indirection doesn't help clarity, so remove it.
> 
> Inline the function in the one place where ->csi_end_io()
> is called, and discard the field.
> 
> Signed-off-by: NeilBrown <neilb@suse.com>

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

> ---
> drivers/staging/lustre/lustre/include/cl_object.h |    7 +-----
> drivers/staging/lustre/lustre/obdclass/cl_io.c    |   26 ++++++---------------
> drivers/staging/lustre/lustre/obdclass/cl_lock.c  |    2 +-
> drivers/staging/lustre/lustre/osc/osc_lock.c      |    2 +-
> 4 files changed, 10 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
> index b8ae41de7192..71ba73cdbb5e 100644
> --- a/drivers/staging/lustre/lustre/include/cl_object.h
> +++ b/drivers/staging/lustre/lustre/include/cl_object.h
> @@ -2395,18 +2395,13 @@ struct cl_sync_io {
> 	atomic_t		csi_barrier;
> 	/** completion to be signaled when transfer is complete. */
> 	wait_queue_head_t	csi_waitq;
> -	/** callback to invoke when this IO is finished */
> -	void			(*csi_end_io)(const struct lu_env *,
> -					      struct cl_sync_io *);
> };
> 
> -void cl_sync_io_init(struct cl_sync_io *anchor, int nr,
> -		     void (*end)(const struct lu_env *, struct cl_sync_io *));
> +void cl_sync_io_init(struct cl_sync_io *anchor, int nr);
> int  cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
> 		     long timeout);
> void cl_sync_io_note(const struct lu_env *env, struct cl_sync_io *anchor,
> 		     int ioret);
> -void cl_sync_io_end(const struct lu_env *env, struct cl_sync_io *anchor);
> 
> /** @} cl_sync_io */
> 
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
> index 09fd45d5394a..e9ad055f84b8 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
> @@ -668,7 +668,7 @@ int cl_io_submit_sync(const struct lu_env *env, struct cl_io *io,
> 		pg->cp_sync_io = anchor;
> 	}
> 
> -	cl_sync_io_init(anchor, queue->c2_qin.pl_nr, &cl_sync_io_end);
> +	cl_sync_io_init(anchor, queue->c2_qin.pl_nr);
> 	rc = cl_io_submit_rw(env, io, iot, queue);
> 	if (rc == 0) {
> 		/*
> @@ -1039,31 +1039,16 @@ void cl_req_attr_set(const struct lu_env *env, struct cl_object *obj,
> }
> EXPORT_SYMBOL(cl_req_attr_set);
> 
> -/* cl_sync_io_callback assumes the caller must call cl_sync_io_wait() to
> - * wait for the IO to finish.
> - */
> -void cl_sync_io_end(const struct lu_env *env, struct cl_sync_io *anchor)
> -{
> -	wake_up_all(&anchor->csi_waitq);
> -
> -	/* it's safe to nuke or reuse anchor now */
> -	atomic_set(&anchor->csi_barrier, 0);
> -}
> -EXPORT_SYMBOL(cl_sync_io_end);
> -
> /**
>  * Initialize synchronous io wait anchor
>  */
> -void cl_sync_io_init(struct cl_sync_io *anchor, int nr,
> -		     void (*end)(const struct lu_env *, struct cl_sync_io *))
> +void cl_sync_io_init(struct cl_sync_io *anchor, int nr)
> {
> 	memset(anchor, 0, sizeof(*anchor));
> 	init_waitqueue_head(&anchor->csi_waitq);
> 	atomic_set(&anchor->csi_sync_nr, nr);
> 	atomic_set(&anchor->csi_barrier, nr > 0);
> 	anchor->csi_sync_rc = 0;
> -	anchor->csi_end_io = end;
> -	LASSERT(end);
> }
> EXPORT_SYMBOL(cl_sync_io_init);
> 
> @@ -1120,8 +1105,11 @@ void cl_sync_io_note(const struct lu_env *env, struct cl_sync_io *anchor,
> 	 */
> 	LASSERT(atomic_read(&anchor->csi_sync_nr) > 0);
> 	if (atomic_dec_and_test(&anchor->csi_sync_nr)) {
> -		LASSERT(anchor->csi_end_io);
> -		anchor->csi_end_io(env, anchor);
> +
> +		wake_up_all(&anchor->csi_waitq);
> +		/* it's safe to nuke or reuse anchor now */
> +		atomic_set(&anchor->csi_barrier, 0);
> +
> 		/* Can't access anchor any more */
> 	}
> }
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
> index d7bcb8c203dd..8133d992cc73 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
> @@ -189,7 +189,7 @@ int cl_lock_request(const struct lu_env *env, struct cl_io *io,
> 
> 	if ((enq_flags & CEF_ASYNC) && !(enq_flags & CEF_AGL)) {
> 		anchor = &cl_env_info(env)->clt_anchor;
> -		cl_sync_io_init(anchor, 1, cl_sync_io_end);
> +		cl_sync_io_init(anchor, 1);
> 	}
> 
> 	rc = cl_lock_enqueue(env, io, lock, anchor);
> diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c
> index 5a1717c7d132..da8c3978fab8 100644
> --- a/drivers/staging/lustre/lustre/osc/osc_lock.c
> +++ b/drivers/staging/lustre/lustre/osc/osc_lock.c
> @@ -877,7 +877,7 @@ static int osc_lock_enqueue_wait(const struct lu_env *env,
> 			continue;
> 
> 		/* wait for conflicting lock to be canceled */
> -		cl_sync_io_init(waiter, 1, cl_sync_io_end);
> +		cl_sync_io_init(waiter, 1);
> 		oscl->ols_owner = waiter;
> 
> 		spin_lock(&tmp_oscl->ols_lock);
> 
> 

Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 02/21] lustre: obd_class: remove csi_barrier from struct cl_sync_io
  2019-02-07  0:03 ` [lustre-devel] [PATCH 02/21] lustre: obd_class: remove csi_barrier from struct cl_sync_io NeilBrown
@ 2019-02-08  0:09   ` Andreas Dilger
  2019-02-11  0:24     ` NeilBrown
  2019-02-11  0:34   ` James Simmons
  1 sibling, 1 reply; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  0:09 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> This flag is used to ensure that structure isn't freed before
> the wakeup completes.  The same can be achieved using the
> csi_waitq.lock and calling wake_up_all_locked().
> 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
> drivers/staging/lustre/lustre/include/cl_object.h |    2 --
> drivers/staging/lustre/lustre/obdclass/cl_io.c    |   16 +++++++---------
> 2 files changed, 7 insertions(+), 11 deletions(-)
> 
> @@ -1080,11 +1079,10 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
> 	} else {
> 		rc = anchor->csi_sync_rc;
> 	}
> +	/* We take the lock to ensure that cl_sync_io_note() has finished */
> +	spin_lock(&anchor->csi_waitq.lock);
> 	LASSERT(atomic_read(&anchor->csi_sync_nr) == 0);
> -
> -	/* wait until cl_sync_io_note() has done wakeup */
> -	while (unlikely(atomic_read(&anchor->csi_barrier) != 0))
> -		cpu_relax();
> +	spin_unlock(&anchor->csi_waitq.lock);
> 
> 	return rc;
> }
> @@ -1104,11 +1102,11 @@ void cl_sync_io_note(const struct lu_env *env, struct cl_sync_io *anchor,
> 	 * IO.
> 	 */
> 	LASSERT(atomic_read(&anchor->csi_sync_nr) > 0);
> -	if (atomic_dec_and_test(&anchor->csi_sync_nr)) {
> +	if (atomic_dec_and_lock(&anchor->csi_sync_nr,
> +				&anchor->csi_waitq.lock)) {
> 
> -		wake_up_all(&anchor->csi_waitq);
> -		/* it's safe to nuke or reuse anchor now */
> -		atomic_set(&anchor->csi_barrier, 0);
> +		wake_up_all_locked(&anchor->csi_waitq);
> +		spin_unlock(&anchor->csi_waitq.lock);

Maybe a matching comment here that the lock is to synchronize with cl_sync_io_wait() cleanup?
Either way,

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 03/21] lustre: obdclass: use list_sort() to sort a list.
  2019-02-07  0:03 ` [lustre-devel] [PATCH 03/21] lustre: obdclass: use list_sort() to sort a list NeilBrown
@ 2019-02-08  0:13   ` Andreas Dilger
  2019-02-11  0:39   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  0:13 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> Rather than a bespoke bubble-sort, use list_sort() to
> sort this linked list.
> 
> Signed-off-by: NeilBrown <neilb@suse.com>

Probably a performance win as well, since it looks like list_sort() uses merge sort
instead of bubble sort.

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

> ---
> drivers/staging/lustre/lustre/obdclass/cl_io.c |   51 +++++-------------------
> 1 file changed, 10 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
> index beac7e8bc92a..7bf02350f19d 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
> @@ -42,6 +42,7 @@
> #include <obd_support.h>
> #include <lustre_fid.h>
> #include <linux/list.h>
> +#include <linux/list_sort.h>
> #include <linux/sched.h>
> #include <cl_object.h>
> #include "cl_internal.h"
> @@ -213,9 +214,15 @@ int cl_io_rw_init(const struct lu_env *env, struct cl_io *io,
> }
> EXPORT_SYMBOL(cl_io_rw_init);
> 
> -static int cl_lock_descr_sort(const struct cl_lock_descr *d0,
> -			      const struct cl_lock_descr *d1)
> +static int cl_lock_descr_cmp(void *priv,
> +			     struct list_head *a, struct list_head *b)
> {
> +	const struct cl_io_lock_link *l0 = list_entry(a, struct cl_io_lock_link, cill_linkage);
> +	const struct cl_io_lock_link *l1 = list_entry(b, struct cl_io_lock_link, cill_linkage);
> +
> +	const struct cl_lock_descr *d0 = &l0->cill_descr;
> +	const struct cl_lock_descr *d1 = &l1->cill_descr;
> +
> 	return lu_fid_cmp(lu_object_fid(&d0->cld_obj->co_lu),
> 			  lu_object_fid(&d1->cld_obj->co_lu));
> }
> @@ -225,45 +232,7 @@ static int cl_lock_descr_sort(const struct cl_lock_descr *d0,
>  */
> static void cl_io_locks_sort(struct cl_io *io)
> {
> -	int done = 0;
> -
> -	/* hidden treasure: bubble sort for now. */
> -	do {
> -		struct cl_io_lock_link *curr;
> -		struct cl_io_lock_link *prev;
> -		struct cl_io_lock_link *temp;
> -
> -		done = 1;
> -		prev = NULL;
> -
> -		list_for_each_entry_safe(curr, temp,
> -					 &io->ci_lockset.cls_todo,
> -					 cill_linkage) {
> -			if (prev) {
> -				switch (cl_lock_descr_sort(&prev->cill_descr,
> -							   &curr->cill_descr)) {
> -				case 0:
> -					/*
> -					 * IMPOSSIBLE: Identical locks are
> -					 *	     already removed at
> -					 *	     this point.
> -					 */
> -				default:
> -					LBUG();
> -				case 1:
> -					list_move_tail(&curr->cill_linkage,
> -						       &prev->cill_linkage);
> -					done = 0;
> -					continue; /* don't change prev: it's
> -						   * still "previous"
> -						   */
> -				case -1: /* already in order */
> -					break;
> -				}
> -			}
> -			prev = curr;
> -		}
> -	} while (!done);
> +	list_sort(NULL, &io->ci_lockset.cls_todo, cl_lock_descr_cmp);
> }
> 
> static void cl_lock_descr_merge(struct cl_lock_descr *d0,
> 
> 

Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 04/21] lustre: use list*entry macros in place of container_of()
  2019-02-07  0:03 ` [lustre-devel] [PATCH 04/21] lustre: use list*entry macros in place of container_of() NeilBrown
@ 2019-02-08  0:25   ` Andreas Dilger
  2019-02-11  1:32   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  0:25 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> There are a number of places that use container_of() but where
> list_first_entry(), or list_last_entry() make the meaning more clear.
> So change them over.
> 
> Signed-off-by: NeilBrown <neilb@suse.com>

Interesting, all these new helpers that I wasn't aware of.  IMHO, the common
list_* implementation in the kernel is really a major win for code efficiency
and bug avoidance if used properly.

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

> ---
> drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |    4 ++--
> drivers/staging/lustre/lustre/obdclass/cl_io.c     |    4 ++--
> drivers/staging/lustre/lustre/obdclass/cl_object.c |   13 ++++++++-----
> drivers/staging/lustre/lustre/obdclass/cl_page.c   |    4 ++--
> drivers/staging/lustre/lustre/obdclass/lu_object.c |    7 +++----
> 5 files changed, 17 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
> index 85c5047f4ba2..74c7644d6ef8 100644
> --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
> +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
> @@ -987,8 +987,8 @@ struct ldlm_namespace *ldlm_namespace_first_locked(enum ldlm_side client)
> {
> 	LASSERT(mutex_is_locked(ldlm_namespace_lock(client)));
> 	LASSERT(!list_empty(ldlm_namespace_list(client)));
> -	return container_of(ldlm_namespace_list(client)->next,
> -		struct ldlm_namespace, ns_list_chain);
> +	return list_first_entry(ldlm_namespace_list(client),
> +				struct ldlm_namespace, ns_list_chain);
> }
> 
> /** Create and initialize new resource. */
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
> index 7bf02350f19d..34b4e63e7d1a 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
> @@ -93,8 +93,8 @@ void cl_io_fini(const struct lu_env *env, struct cl_io *io)
> 	LINVRNT(cl_io_invariant(io));
> 
> 	while (!list_empty(&io->ci_layers)) {
> -		slice = container_of(io->ci_layers.prev, struct cl_io_slice,
> -				     cis_linkage);
> +		slice = list_last_entry(&io->ci_layers, struct cl_io_slice,
> +					cis_linkage);
> 		list_del_init(&slice->cis_linkage);
> 		if (slice->cis_iop->op[io->ci_type].cio_fini)
> 			slice->cis_iop->op[io->ci_type].cio_fini(env, slice);
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> index 05d784ae7a6c..f724b2d62df1 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> @@ -649,8 +649,8 @@ static struct lu_env *cl_env_obtain(void *debug)
> 	if (cl_envs[cpu].cec_count > 0) {
> 		int rc;
> 
> -		cle = container_of(cl_envs[cpu].cec_envs.next, struct cl_env,
> -				   ce_linkage);
> +		cle = list_first_entry(&cl_envs[cpu].cec_envs, struct cl_env,
> +				       ce_linkage);
> 		list_del_init(&cle->ce_linkage);
> 		cl_envs[cpu].cec_count--;
> 		read_unlock(&cl_envs[cpu].cec_guard);
> @@ -748,9 +748,12 @@ unsigned int cl_env_cache_purge(unsigned int nr)
> 
> 	for_each_possible_cpu(i) {
> 		write_lock(&cl_envs[i].cec_guard);
> -		for (; !list_empty(&cl_envs[i].cec_envs) && nr > 0; --nr) {
> -			cle = container_of(cl_envs[i].cec_envs.next,
> -					   struct cl_env, ce_linkage);
> +		for (; nr >0 &&
> +			     (cle = list_first_entry_or_null(
> +				     &cl_envs[i].cec_envs,
> +				     struct cl_env,
> +				     ce_linkage)) != NULL;
> +		     --nr) {
> 			list_del_init(&cle->ce_linkage);
> 			LASSERT(cl_envs[i].cec_count > 0);
> 			cl_envs[i].cec_count--;
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
> index b1b4dc7ea22f..d025ea55818f 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
> @@ -690,8 +690,8 @@ int cl_page_is_vmlocked(const struct lu_env *env, const struct cl_page *pg)
> 	const struct cl_page_slice *slice;
> 	int result;
> 
> -	slice = container_of(pg->cp_layers.next,
> -			     const struct cl_page_slice, cpl_linkage);
> +	slice = list_first_entry(&pg->cp_layers,
> +				 const struct cl_page_slice, cpl_linkage);
> 	PASSERT(env, pg, slice->cpl_ops->cpo_is_vmlocked);
> 	/*
> 	 * Call ->cpo_is_vmlocked() directly instead of going through
> diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c
> index 3bd48748f46c..639c298b6a90 100644
> --- a/drivers/staging/lustre/lustre/obdclass/lu_object.c
> +++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c
> @@ -349,7 +349,7 @@ static void lu_object_free(const struct lu_env *env, struct lu_object *o)
> 		 * lives as long as possible and ->loo_object_free() methods
> 		 * can look at its contents.
> 		 */
> -		o = container_of(splice.prev, struct lu_object, lo_linkage);
> +		o = list_last_entry(&splice, struct lu_object, lo_linkage);
> 		list_del_init(&o->lo_linkage);
> 		o->lo_ops->loo_object_free(env, o);
> 	}
> @@ -432,9 +432,8 @@ int lu_site_purge_objects(const struct lu_env *env, struct lu_site *s,
> 		 * Free everything on the dispose list. This is safe against
> 		 * races due to the reasons described in lu_object_put().
> 		 */
> -		while (!list_empty(&dispose)) {
> -			h = container_of(dispose.next,
> -					 struct lu_object_header, loh_lru);
> +		while ((h = list_first_entry_or_null(
> +				&dispose, struct lu_object_header, loh_lru)) != NULL) {
> 			list_del_init(&h->loh_lru);
> 			lu_object_free(env, lu_object_top(h));
> 			lprocfs_counter_incr(s->ls_stats, LU_SS_LRU_PURGED);
> 
> 

Cheers, Andreas
---
Andreas Dilger
CTO Whamcloud

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

* [lustre-devel] [PATCH 05/21] lustre: use list_first_entry() in lustre subdirectory.
  2019-02-07  0:03 ` [lustre-devel] [PATCH 05/21] lustre: use list_first_entry() in lustre subdirectory NeilBrown
@ 2019-02-08  0:31   ` Andreas Dilger
  2019-02-11  0:13     ` NeilBrown
  2019-02-11  1:45   ` James Simmons
  1 sibling, 1 reply; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  0:31 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> Convert
>  list_entry(foo->next .....)
> to
>  list_first_entry(foo, ....)
> 
> in 'lustre'
> 
> In several cases the call is combined with
> a list_empty() test and list_first_entry_or_null() is used
> 
> Signed-off-by: NeilBrown <neilb@suse.com>

One question below:

> @@ -912,9 +913,9 @@ static int ll_agl_thread(void *arg)
> 
> 	spin_lock(&plli->lli_agl_lock);
> 	sai->sai_agl_valid = 0;
> -	while (!list_empty(&sai->sai_agls)) {
> -		clli = list_entry(sai->sai_agls.next,
> -				  struct ll_inode_info, lli_agl_list);
> +	while ((clli = list_first_entry_or_null(&sai->sai_agls,
> +						struct ll_inode_info,
> +						lli_agl_list)) != NULL) {

Lustre coding style used to require explicit comparisons against NULL or 0
to avoid subtle bugs when developers treat pointers like booleans, so I'm
not against this, but the kernel style is to not do this, like:

	while ((clli = list_first_entry_or_null(&sai->sai_agls,
						struct ll_inode_info,
						lli_agl_list))) {

Will there be grief when this is pushed upstream?  In that case, it might
be better to just use the implicit "!= NULL" and avoid the complaints.

Either way, the technical aspects of the patch are OK, so:

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>


Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 06/21] lustre: use list_first_entry() in lnet/lnet subdirectory.
  2019-02-07  0:03 ` [lustre-devel] [PATCH 06/21] lustre: use list_first_entry() in lnet/lnet subdirectory NeilBrown
@ 2019-02-08  0:44   ` Andreas Dilger
  2019-02-11  1:46   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  0:44 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> Convert
>  list_entry(foo->next .....)
> to
>  list_first_entry(foo, ....)
> 
> in 'lnet/lnet'
> 
> In several cases the call is combined with
> a list_empty() test and list_first_entry_or_null() is used
> 
> In one case, list_splice_init() is used.
> 
> Signed-off-by: NeilBrown <neilb@suse.com>

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 07/21] lustre: use list_first_entry() in lnet/klnds subdirectory.
  2019-02-07  0:03 ` [lustre-devel] [PATCH 07/21] lustre: use list_first_entry() in lnet/klnds subdirectory NeilBrown
@ 2019-02-08  0:59   ` Andreas Dilger
  2019-02-11  0:34     ` NeilBrown
  2019-02-11  1:47   ` James Simmons
  1 sibling, 1 reply; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  0:59 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> Convert
>  list_entry(foo->next .....)
> to
>  list_first_entry(foo, ....)
> 
> in 'lnet/klnds
> 
> In several cases the call is combined with a list_empty() test and
> list_first_entry_or_null() is used
> 
> Signed-off-by: NeilBrown <neilb@suse.com>
> 
> @@ -1853,8 +1855,9 @@ static void kiblnd_destroy_pool_list(struct list_head *head)
> {
> 	struct kib_pool *pool;
> 
> -	while (!list_empty(head)) {
> -		pool = list_entry(head->next, struct kib_pool, po_list);
> +	while ((pool = list_first_entry_or_null(head,
> +						struct kib_pool,
> +						po_list)) != NULL) {
> 		list_del(&pool->po_list);
> 
> 		LASSERT(pool->po_owner);
> @@ -1869,7 +1872,7 @@ static void kiblnd_fail_poolset(struct kib_poolset *ps, struct list_head *zombie
> 
> 	spin_lock(&ps->ps_lock);
> 	while (!list_empty(&ps->ps_pool_list)) {
> -		struct kib_pool *po = list_entry(ps->ps_pool_list.next,
> +		struct kib_pool *po = list_first_entry(&ps->ps_pool_list,
> 					    struct kib_pool, po_list);
> 		po->po_failed = 1;
> 		list_del(&po->po_list);

Why not use the same style as elsewhere in the code:

	while ((po = list_first_entry_or_null(&ps->ps_pool_list,
					      struct kib_pool,
					      po_list)) != NULL) {

?

Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 08/21] lustre: use list_first_entry() throughout
  2019-02-07  0:03 ` [lustre-devel] [PATCH 08/21] lustre: use list_first_entry() throughout NeilBrown
@ 2019-02-08  1:06   ` Andreas Dilger
  2019-02-11  1:48   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  1:06 UTC (permalink / raw)
  To: lustre-devel



> On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> Convert
>  list_entry(foo->next .....)
> to
>  list_first_entry(foo, ....)
> 
> in remainder of lustre.
> 
> In several cases the call is combined with a list_empty() test and
> list_first_entry_or_null() is used
> 
> Signed-off-by: NeilBrown <neilb@suse.com>

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 09/21] lustre: use list_last_entry() throughout
  2019-02-07  0:03 ` [lustre-devel] [PATCH 09/21] lustre: use list_last_entry() throughout NeilBrown
@ 2019-02-08  1:07   ` Andreas Dilger
  2019-02-11  1:48   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  1:07 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> Convert
>  list_entry(foo->prev .....)
> to
>  list_last_entry(foo, ....)
> 
> throughout lustre.
> 
> Signed-off-by: NeilBrown <neilb@suse.com>

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 10/21] lustre: obdclass: use cl_object_for_each where appropriate
  2019-02-07  0:03 ` [lustre-devel] [PATCH 10/21] lustre: obdclass: use cl_object_for_each where appropriate NeilBrown
@ 2019-02-08  1:10   ` Andreas Dilger
  2019-02-11  0:42     ` NeilBrown
  2019-02-11  1:57   ` James Simmons
  1 sibling, 1 reply; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  1:10 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> There are various places which have a list_for_each_entry()
> where cl_object_for_each (or .._reverse) is more appropriate.
> 
> Several of these re-use the 'obj' function parameter as a loop
> iterator, which is a little confusing.
> 
> Change these to use cl_object_for_each{_reverse}, and where needed,
> introduce a new iterator variable 'o'.
> 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
> drivers/staging/lustre/lustre/lov/lov_page.c       |    3 -
> drivers/staging/lustre/lustre/obdclass/cl_lock.c   |    3 -
> drivers/staging/lustre/lustre/obdclass/cl_object.c |   82 +++++++++-----------
> drivers/staging/lustre/lustre/obdclass/cl_page.c   |   11 +--
> 4 files changed, 44 insertions(+), 55 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> index f724b2d62df1..d71a680660da 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> @@ -190,16 +190,15 @@ EXPORT_SYMBOL(cl_object_attr_unlock);
> int cl_object_attr_get(const struct lu_env *env, struct cl_object *obj,
> 		       struct cl_attr *attr)
> {
> -	struct lu_object_header *top;
> +	struct cl_object *o;
> 	int result;
> 
> 	assert_spin_locked(cl_object_attr_guard(obj));
> 
> -	top = obj->co_lu.lo_header;
> 	result = 0;

May as well move the "result = 0" initialization to the declaration for
all of these?  Another 5 fewer lines of code under your belt.

Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 11/21] lustre: cl_object: remove vestigial debugging.
  2019-02-07  0:03 ` [lustre-devel] [PATCH 11/21] lustre: cl_object: remove vestigial debugging NeilBrown
@ 2019-02-08  1:31   ` Andreas Dilger
  2019-02-11  0:48     ` NeilBrown
  2019-02-11  2:04   ` James Simmons
  1 sibling, 1 reply; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  1:31 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> cl_env_inc() and cl_env_dec() don't do anything,
> so discard them.
> 
> Signed-off-by: NeilBrown <neilb@suse.com>

It looks like these were being used for debugging page allocations,
wrapped under CONFIG_DEBUG_PAGESTATE_TRACKING, but that was dropped
from the upstream kernel.  It looks like you could also delete
cs_page_inc() and cs_page_dec() along with enum cache_stat_item,
since they are also wrapped under the same CONFIG value.

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

> ---
> drivers/staging/lustre/lustre/obdclass/cl_object.c |   15 ---------------
> 1 file changed, 15 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> index d71a680660da..1e704078664e 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> @@ -565,14 +565,6 @@ struct cl_env {
> 	void		       *ce_debug;
> };
> 
> -static void cl_env_inc(enum cache_stats_item item)
> -{
> -}
> -
> -static void cl_env_dec(enum cache_stats_item item)
> -{
> -}
> -
> static void cl_env_init0(struct cl_env *cle, void *debug)
> {
> 	LASSERT(cle->ce_ref == 0);
> @@ -581,7 +573,6 @@ static void cl_env_init0(struct cl_env *cle, void *debug)
> 
> 	cle->ce_ref = 1;
> 	cle->ce_debug = debug;
> -	cl_env_inc(CS_busy);
> }
> 
> static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
> @@ -611,9 +602,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
> 		if (rc != 0) {
> 			kmem_cache_free(cl_env_kmem, cle);
> 			env = ERR_PTR(rc);
> -		} else {
> -			cl_env_inc(CS_create);
> -			cl_env_inc(CS_total);
> 		}
> 	} else {
> 		env = ERR_PTR(-ENOMEM);
> @@ -623,7 +611,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
> 
> static void cl_env_fini(struct cl_env *cle)
> {
> -	cl_env_dec(CS_total);
> 	lu_context_fini(&cle->ce_lu.le_ctx);
> 	lu_context_fini(&cle->ce_ses);
> 	kmem_cache_free(cl_env_kmem, cle);
> @@ -782,7 +769,6 @@ void cl_env_put(struct lu_env *env, u16 *refcheck)
> 	if (--cle->ce_ref == 0) {
> 		int cpu = get_cpu();
> 
> -		cl_env_dec(CS_busy);
> 		cle->ce_debug = NULL;
> 		cl_env_exit(cle);
> 		/*
> @@ -903,7 +889,6 @@ void cl_env_percpu_put(struct lu_env *env)
> 	cle->ce_ref--;
> 	LASSERT(cle->ce_ref == 0);
> 
> -	cl_env_dec(CS_busy);
> 	cle->ce_debug = NULL;
> 
> 	put_cpu();
> 
> 

Cheers, Andreas
---
Andreas Dilger
CTO Whamcloud

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

* [lustre-devel] [PATCH 12/21] lustre: cl_page.c: remove PINVRNT()
  2019-02-07  0:03 ` [lustre-devel] [PATCH 12/21] lustre: cl_page.c: remove PINVRNT() NeilBrown
@ 2019-02-08  5:43   ` Andreas Dilger
  2019-02-11  4:01   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  5:43 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> This macro does nothing (it once was like 'assert'),
> so remove it.
> 
> Signed-off-by: NeilBrown <neilb@suse.com>

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 13/21] lustre: make cp_ref in cl_page a refcount_t
  2019-02-07  0:03 ` [lustre-devel] [PATCH 13/21] lustre: make cp_ref in cl_page a refcount_t NeilBrown
@ 2019-02-08  5:45   ` Andreas Dilger
  2019-02-11  4:00   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  5:45 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> As this is used as a refcount, it should be declared
> as one.
> 
> Signed-off-by: NeilBrown <neilb@suse.com>

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 14/21] lustre: make ccc_users in cl_client_cache a refcount_t
  2019-02-07  0:03 ` [lustre-devel] [PATCH 14/21] lustre: make ccc_users in cl_client_cache " NeilBrown
@ 2019-02-08  5:46   ` Andreas Dilger
  2019-02-11  4:01   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  5:46 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> As this is used as a refcount, it should be declared
> as one.
> 
> Signed-off-by: NeilBrown <neilb@suse.com>

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 15/21] lustre: obdclass: char obd_ioctl_getdata type.
  2019-02-07  0:03 ` [lustre-devel] [PATCH 15/21] lustre: obdclass: char obd_ioctl_getdata type NeilBrown
@ 2019-02-08  5:56   ` Andreas Dilger
  2019-02-11  0:52     ` NeilBrown
  2019-02-11  4:03   ` James Simmons
  1 sibling, 1 reply; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  5:56 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> Instead of having obd_ioctl_getdata() return the allocated
> data as a "char *", return it as it really is,
> struct obd_ioctl_data *
> 
> This avoids the need for extra variables and casts.
> 
> Signed-off-by: NeilBrown <neilb@suse.com>

Most of the patch looks like a no-op, except at one part below:

> @@ -1651,18 +1647,16 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> 		return rc;
> 	}
> 	case LL_IOC_MIGRATE: {
> -		char *buf = NULL;
> 		const char *filename;
> 		int namelen = 0;
> 		int len;
> 		int rc;
> 		int mdtidx;
> 
> -		rc = obd_ioctl_getdata(&buf, &len, (void __user *)arg);
> +		rc = obd_ioctl_getdata(&data, &len, (void __user *)arg);
> 		if (rc < 0)
> 			return rc;
> 
> -		data = (struct obd_ioctl_data *)buf;
> 		if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2 ||
> 		    !data->ioc_inllen1 || !data->ioc_inllen2) {
> 			rc = -EINVAL;
> @@ -1684,7 +1678,6 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> 
> 		rc = ll_migrate(inode, file, mdtidx, filename, namelen - 1);
> migrate_free:
> -		kvfree(buf);

This removes the call to kvfree(buf) but it isn't clear why, since the rest of
the patch is mostly variable renaming?

Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 16/21] lustre: obdclass: normalize a switch statement.
  2019-02-07  0:03 ` [lustre-devel] [PATCH 16/21] lustre: obdclass: normalize a switch statement NeilBrown
@ 2019-02-08  5:57   ` Andreas Dilger
  2019-02-11  4:03   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  5:57 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> Remove the unnecessary {}, and use "break" rather than
> "goto out;" for normal exit from the cases.
> 
> Signed-off-by: NeilBrown <neilb@suse.com>

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 17/21] lustre: obdclass: result of try_module_get() should not be ignored.
  2019-02-07  0:03 ` [lustre-devel] [PATCH 17/21] lustre: obdclass: result of try_module_get() should not be ignored NeilBrown
@ 2019-02-08  5:58   ` Andreas Dilger
  2019-02-11  4:22   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  5:58 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> If try_module_get() fails, the open must fail.
> 
> In practice this should be impossible, but it is
> best to make the code look right.
> 
> Signed-off-by: NeilBrown <neilb@suse.com>

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 18/21] lustre: move debug.c from obdclass to obdecho
  2019-02-07  0:03 ` [lustre-devel] [PATCH 18/21] lustre: move debug.c from obdclass to obdecho NeilBrown
@ 2019-02-08  6:02   ` Andreas Dilger
  2019-02-11  4:17   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  6:02 UTC (permalink / raw)
  To: lustre-devel


On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> The functions defined in debug.c are only used in
> obdecho, so move it there, and make the functions local
> to that unit.
> This allows lustre_debug.h to be removed.
> 
> Signed-off-by: NeilBrown <neilb@suse.com>

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 19/21] lustre: obdclass: avoid races in class_register_type()
  2019-02-07  0:03 ` [lustre-devel] [PATCH 19/21] lustre: obdclass: avoid races in class_register_type() NeilBrown
@ 2019-02-08  6:41   ` Andreas Dilger
  2019-02-11  0:58     ` NeilBrown
  2019-02-12  5:03   ` James Simmons
  1 sibling, 1 reply; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  6:41 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> If there are two parallel attempts to register the
> same class name, it could get registered twice.
> So re-check after allocation to make sure the name is
> still unique.

The patch itself seems reasonable, but I don't see how this
scenario could ever happen?  class_register_type() is only
called once per device type from the module init code, and
I don't think it is possible to insert the same module twice?

Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 21/21] lustre: make exp_refcount in obd_export a refcount_t
  2019-02-07  0:03 ` [lustre-devel] [PATCH 21/21] lustre: make exp_refcount in obd_export a refcount_t NeilBrown
@ 2019-02-08  7:07   ` Andreas Dilger
  2019-02-11  4:18   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: Andreas Dilger @ 2019-02-08  7:07 UTC (permalink / raw)
  To: lustre-devel

On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> 
> As this is used as a refcount, it should be declared
> as one.
> 
> Signed-off-by: NeilBrown <neilb@suse.com>

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

Cheers, Andreas
---
Andreas Dilger
Principal Lustre Architect
Whamcloud

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

* [lustre-devel] [PATCH 05/21] lustre: use list_first_entry() in lustre subdirectory.
  2019-02-08  0:31   ` Andreas Dilger
@ 2019-02-11  0:13     ` NeilBrown
  0 siblings, 0 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-11  0:13 UTC (permalink / raw)
  To: lustre-devel

On Fri, Feb 08 2019, Andreas Dilger wrote:

> On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
>> 
>> Convert
>>  list_entry(foo->next .....)
>> to
>>  list_first_entry(foo, ....)
>> 
>> in 'lustre'
>> 
>> In several cases the call is combined with
>> a list_empty() test and list_first_entry_or_null() is used
>> 
>> Signed-off-by: NeilBrown <neilb@suse.com>
>
> One question below:
>
>> @@ -912,9 +913,9 @@ static int ll_agl_thread(void *arg)
>> 
>> 	spin_lock(&plli->lli_agl_lock);
>> 	sai->sai_agl_valid = 0;
>> -	while (!list_empty(&sai->sai_agls)) {
>> -		clli = list_entry(sai->sai_agls.next,
>> -				  struct ll_inode_info, lli_agl_list);
>> +	while ((clli = list_first_entry_or_null(&sai->sai_agls,
>> +						struct ll_inode_info,
>> +						lli_agl_list)) != NULL) {
>
> Lustre coding style used to require explicit comparisons against NULL or 0
> to avoid subtle bugs when developers treat pointers like booleans, so I'm
> not against this, but the kernel style is to not do this, like:
>
> 	while ((clli = list_first_entry_or_null(&sai->sai_agls,
> 						struct ll_inode_info,
> 						lli_agl_list))) {
>
> Will there be grief when this is pushed upstream?  In that case, it might
> be better to just use the implicit "!= NULL" and avoid the complaints.
>

I don't think there will be grief.  I personally prefer the explicit
test, and I think I recall Linus once saying he did too.

If you have
  while (p = func()) {

The compile will warn that maybe you meant '=='.
So you need

  while ((p = func())) {

and the extra parentheses look odd.  Make it

   while ((p = func()) != NULL) {

clears it all up.

The pattern
  while.* = .* != NULL

occurs 589 times in the kernel at present including fs/* mm/* net/*
so we certainly would be alone in using it.
  

> Either way, the technical aspects of the patch are OK, so:
>
> Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

Thanks,
NeilBrown

>
>
> Cheers, Andreas
> ---
> Andreas Dilger
> Principal Lustre Architect
> Whamcloud
-------------- 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/20190211/6a5e0587/attachment.sig>

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

* [lustre-devel] [PATCH 01/21] lustre: obdclass: discard csi_end_io
  2019-02-07  0:03 ` [lustre-devel] [PATCH 01/21] lustre: obdclass: discard csi_end_io NeilBrown
  2019-02-07  0:20   ` Andreas Dilger
@ 2019-02-11  0:19   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: James Simmons @ 2019-02-11  0:19 UTC (permalink / raw)
  To: lustre-devel


> The csi_end_io field in "struct cl_sync_io" is always
> set to cl_sync_io_end(), which is a tiny function.
> This indirection doesn't help clarity, so remove it.
> 
> Inline the function in the one place where ->csi_end_io()
> is called, and discard the field.

Reviewed-by: James Simmons <jsimmonws@infradead.org>
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/include/cl_object.h |    7 +-----
>  drivers/staging/lustre/lustre/obdclass/cl_io.c    |   26 ++++++---------------
>  drivers/staging/lustre/lustre/obdclass/cl_lock.c  |    2 +-
>  drivers/staging/lustre/lustre/osc/osc_lock.c      |    2 +-
>  4 files changed, 10 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
> index b8ae41de7192..71ba73cdbb5e 100644
> --- a/drivers/staging/lustre/lustre/include/cl_object.h
> +++ b/drivers/staging/lustre/lustre/include/cl_object.h
> @@ -2395,18 +2395,13 @@ struct cl_sync_io {
>  	atomic_t		csi_barrier;
>  	/** completion to be signaled when transfer is complete. */
>  	wait_queue_head_t	csi_waitq;
> -	/** callback to invoke when this IO is finished */
> -	void			(*csi_end_io)(const struct lu_env *,
> -					      struct cl_sync_io *);
>  };
>  
> -void cl_sync_io_init(struct cl_sync_io *anchor, int nr,
> -		     void (*end)(const struct lu_env *, struct cl_sync_io *));
> +void cl_sync_io_init(struct cl_sync_io *anchor, int nr);
>  int  cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
>  		     long timeout);
>  void cl_sync_io_note(const struct lu_env *env, struct cl_sync_io *anchor,
>  		     int ioret);
> -void cl_sync_io_end(const struct lu_env *env, struct cl_sync_io *anchor);
>  
>  /** @} cl_sync_io */
>  
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
> index 09fd45d5394a..e9ad055f84b8 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
> @@ -668,7 +668,7 @@ int cl_io_submit_sync(const struct lu_env *env, struct cl_io *io,
>  		pg->cp_sync_io = anchor;
>  	}
>  
> -	cl_sync_io_init(anchor, queue->c2_qin.pl_nr, &cl_sync_io_end);
> +	cl_sync_io_init(anchor, queue->c2_qin.pl_nr);
>  	rc = cl_io_submit_rw(env, io, iot, queue);
>  	if (rc == 0) {
>  		/*
> @@ -1039,31 +1039,16 @@ void cl_req_attr_set(const struct lu_env *env, struct cl_object *obj,
>  }
>  EXPORT_SYMBOL(cl_req_attr_set);
>  
> -/* cl_sync_io_callback assumes the caller must call cl_sync_io_wait() to
> - * wait for the IO to finish.
> - */
> -void cl_sync_io_end(const struct lu_env *env, struct cl_sync_io *anchor)
> -{
> -	wake_up_all(&anchor->csi_waitq);
> -
> -	/* it's safe to nuke or reuse anchor now */
> -	atomic_set(&anchor->csi_barrier, 0);
> -}
> -EXPORT_SYMBOL(cl_sync_io_end);
> -
>  /**
>   * Initialize synchronous io wait anchor
>   */
> -void cl_sync_io_init(struct cl_sync_io *anchor, int nr,
> -		     void (*end)(const struct lu_env *, struct cl_sync_io *))
> +void cl_sync_io_init(struct cl_sync_io *anchor, int nr)
>  {
>  	memset(anchor, 0, sizeof(*anchor));
>  	init_waitqueue_head(&anchor->csi_waitq);
>  	atomic_set(&anchor->csi_sync_nr, nr);
>  	atomic_set(&anchor->csi_barrier, nr > 0);
>  	anchor->csi_sync_rc = 0;
> -	anchor->csi_end_io = end;
> -	LASSERT(end);
>  }
>  EXPORT_SYMBOL(cl_sync_io_init);
>  
> @@ -1120,8 +1105,11 @@ void cl_sync_io_note(const struct lu_env *env, struct cl_sync_io *anchor,
>  	 */
>  	LASSERT(atomic_read(&anchor->csi_sync_nr) > 0);
>  	if (atomic_dec_and_test(&anchor->csi_sync_nr)) {
> -		LASSERT(anchor->csi_end_io);
> -		anchor->csi_end_io(env, anchor);
> +
> +		wake_up_all(&anchor->csi_waitq);
> +		/* it's safe to nuke or reuse anchor now */
> +		atomic_set(&anchor->csi_barrier, 0);
> +
>  		/* Can't access anchor any more */
>  	}
>  }
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
> index d7bcb8c203dd..8133d992cc73 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
> @@ -189,7 +189,7 @@ int cl_lock_request(const struct lu_env *env, struct cl_io *io,
>  
>  	if ((enq_flags & CEF_ASYNC) && !(enq_flags & CEF_AGL)) {
>  		anchor = &cl_env_info(env)->clt_anchor;
> -		cl_sync_io_init(anchor, 1, cl_sync_io_end);
> +		cl_sync_io_init(anchor, 1);
>  	}
>  
>  	rc = cl_lock_enqueue(env, io, lock, anchor);
> diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c
> index 5a1717c7d132..da8c3978fab8 100644
> --- a/drivers/staging/lustre/lustre/osc/osc_lock.c
> +++ b/drivers/staging/lustre/lustre/osc/osc_lock.c
> @@ -877,7 +877,7 @@ static int osc_lock_enqueue_wait(const struct lu_env *env,
>  			continue;
>  
>  		/* wait for conflicting lock to be canceled */
> -		cl_sync_io_init(waiter, 1, cl_sync_io_end);
> +		cl_sync_io_init(waiter, 1);
>  		oscl->ols_owner = waiter;
>  
>  		spin_lock(&tmp_oscl->ols_lock);
> 
> 
> 

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

* [lustre-devel] [PATCH 02/21] lustre: obd_class: remove csi_barrier from struct cl_sync_io
  2019-02-08  0:09   ` Andreas Dilger
@ 2019-02-11  0:24     ` NeilBrown
  0 siblings, 0 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-11  0:24 UTC (permalink / raw)
  To: lustre-devel

On Fri, Feb 08 2019, Andreas Dilger wrote:

> On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
>> 
>> This flag is used to ensure that structure isn't freed before
>> the wakeup completes.  The same can be achieved using the
>> csi_waitq.lock and calling wake_up_all_locked().
>> 
>> Signed-off-by: NeilBrown <neilb@suse.com>
>> ---
>> drivers/staging/lustre/lustre/include/cl_object.h |    2 --
>> drivers/staging/lustre/lustre/obdclass/cl_io.c    |   16 +++++++---------
>> 2 files changed, 7 insertions(+), 11 deletions(-)
>> 
>> @@ -1080,11 +1079,10 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
>> 	} else {
>> 		rc = anchor->csi_sync_rc;
>> 	}
>> +	/* We take the lock to ensure that cl_sync_io_note() has finished */
>> +	spin_lock(&anchor->csi_waitq.lock);
>> 	LASSERT(atomic_read(&anchor->csi_sync_nr) == 0);
>> -
>> -	/* wait until cl_sync_io_note() has done wakeup */
>> -	while (unlikely(atomic_read(&anchor->csi_barrier) != 0))
>> -		cpu_relax();
>> +	spin_unlock(&anchor->csi_waitq.lock);
>> 
>> 	return rc;
>> }
>> @@ -1104,11 +1102,11 @@ void cl_sync_io_note(const struct lu_env *env, struct cl_sync_io *anchor,
>> 	 * IO.
>> 	 */
>> 	LASSERT(atomic_read(&anchor->csi_sync_nr) > 0);
>> -	if (atomic_dec_and_test(&anchor->csi_sync_nr)) {
>> +	if (atomic_dec_and_lock(&anchor->csi_sync_nr,
>> +				&anchor->csi_waitq.lock)) {
>> 
>> -		wake_up_all(&anchor->csi_waitq);
>> -		/* it's safe to nuke or reuse anchor now */
>> -		atomic_set(&anchor->csi_barrier, 0);
>> +		wake_up_all_locked(&anchor->csi_waitq);
>> +		spin_unlock(&anchor->csi_waitq.lock);
>
> Maybe a matching comment here that the lock is to synchronize with cl_sync_io_wait() cleanup?
> Either way,
>
Good idea.  I added

		/*
		 * Holding the lock across both the decrement and
		 * the wakeup ensures cl_sync_io_wait() doesn't complete
		 * before the wakeup completes.
		 */

> Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

Thanks,
NeilBrown

>
> Cheers, Andreas
> ---
> Andreas Dilger
> Principal Lustre Architect
> Whamcloud
-------------- 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/20190211/56192e20/attachment.sig>

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

* [lustre-devel] [PATCH 02/21] lustre: obd_class: remove csi_barrier from struct cl_sync_io
  2019-02-07  0:03 ` [lustre-devel] [PATCH 02/21] lustre: obd_class: remove csi_barrier from struct cl_sync_io NeilBrown
  2019-02-08  0:09   ` Andreas Dilger
@ 2019-02-11  0:34   ` James Simmons
  2019-02-11  1:09     ` NeilBrown
  1 sibling, 1 reply; 87+ messages in thread
From: James Simmons @ 2019-02-11  0:34 UTC (permalink / raw)
  To: lustre-devel


> This flag is used to ensure that structure isn't freed before
> the wakeup completes.  The same can be achieved using the
> csi_waitq.lock and calling wake_up_all_locked().
>

Reviewed-by: James Simmons <jsimmons@infradead.org>

> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/include/cl_object.h |    2 --
>  drivers/staging/lustre/lustre/obdclass/cl_io.c    |   16 +++++++---------
>  2 files changed, 7 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
> index 71ba73cdbb5e..13d79810dd39 100644
> --- a/drivers/staging/lustre/lustre/include/cl_object.h
> +++ b/drivers/staging/lustre/lustre/include/cl_object.h
> @@ -2391,8 +2391,6 @@ struct cl_sync_io {
>  	atomic_t		csi_sync_nr;
>  	/** error code. */
>  	int			csi_sync_rc;
> -	/** barrier of destroy this structure */
> -	atomic_t		csi_barrier;
>  	/** completion to be signaled when transfer is complete. */
>  	wait_queue_head_t	csi_waitq;
>  };
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
> index e9ad055f84b8..beac7e8bc92a 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
> @@ -1047,7 +1047,6 @@ void cl_sync_io_init(struct cl_sync_io *anchor, int nr)
>  	memset(anchor, 0, sizeof(*anchor));
>  	init_waitqueue_head(&anchor->csi_waitq);
>  	atomic_set(&anchor->csi_sync_nr, nr);
> -	atomic_set(&anchor->csi_barrier, nr > 0);
>  	anchor->csi_sync_rc = 0;
>  }
>  EXPORT_SYMBOL(cl_sync_io_init);
> @@ -1080,11 +1079,10 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
>  	} else {
>  		rc = anchor->csi_sync_rc;
>  	}
> +	/* We take the lock to ensure that cl_sync_io_note() has finished */
> +	spin_lock(&anchor->csi_waitq.lock);

I don't think I every seen any use the internal lock for the wait_queue
in such a method. Most creative approach.

>  	LASSERT(atomic_read(&anchor->csi_sync_nr) == 0);
> -
> -	/* wait until cl_sync_io_note() has done wakeup */
> -	while (unlikely(atomic_read(&anchor->csi_barrier) != 0))
> -		cpu_relax();
> +	spin_unlock(&anchor->csi_waitq.lock);
>  
>  	return rc;
>  }
> @@ -1104,11 +1102,11 @@ void cl_sync_io_note(const struct lu_env *env, struct cl_sync_io *anchor,
>  	 * IO.
>  	 */
>  	LASSERT(atomic_read(&anchor->csi_sync_nr) > 0);
> -	if (atomic_dec_and_test(&anchor->csi_sync_nr)) {
> +	if (atomic_dec_and_lock(&anchor->csi_sync_nr,
> +				&anchor->csi_waitq.lock)) {
>  
> -		wake_up_all(&anchor->csi_waitq);
> -		/* it's safe to nuke or reuse anchor now */
> -		atomic_set(&anchor->csi_barrier, 0);
> +		wake_up_all_locked(&anchor->csi_waitq);
> +		spin_unlock(&anchor->csi_waitq.lock);
>  
>  		/* Can't access anchor any more */
>  	}
> 
> 
> 

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

* [lustre-devel] [PATCH 07/21] lustre: use list_first_entry() in lnet/klnds subdirectory.
  2019-02-08  0:59   ` Andreas Dilger
@ 2019-02-11  0:34     ` NeilBrown
  0 siblings, 0 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-11  0:34 UTC (permalink / raw)
  To: lustre-devel

On Fri, Feb 08 2019, Andreas Dilger wrote:

> On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
>> 
>> Convert
>>  list_entry(foo->next .....)
>> to
>>  list_first_entry(foo, ....)
>> 
>> in 'lnet/klnds
>> 
>> In several cases the call is combined with a list_empty() test and
>> list_first_entry_or_null() is used
>> 
>> Signed-off-by: NeilBrown <neilb@suse.com>
>> 
>> @@ -1853,8 +1855,9 @@ static void kiblnd_destroy_pool_list(struct list_head *head)
>> {
>> 	struct kib_pool *pool;
>> 
>> -	while (!list_empty(head)) {
>> -		pool = list_entry(head->next, struct kib_pool, po_list);
>> +	while ((pool = list_first_entry_or_null(head,
>> +						struct kib_pool,
>> +						po_list)) != NULL) {
>> 		list_del(&pool->po_list);
>> 
>> 		LASSERT(pool->po_owner);
>> @@ -1869,7 +1872,7 @@ static void kiblnd_fail_poolset(struct kib_poolset *ps, struct list_head *zombie
>> 
>> 	spin_lock(&ps->ps_lock);
>> 	while (!list_empty(&ps->ps_pool_list)) {
>> -		struct kib_pool *po = list_entry(ps->ps_pool_list.next,
>> +		struct kib_pool *po = list_first_entry(&ps->ps_pool_list,
>> 					    struct kib_pool, po_list);
>> 		po->po_failed = 1;
>> 		list_del(&po->po_list);
>
> Why not use the same style as elsewhere in the code:
>
> 	while ((po = list_first_entry_or_null(&ps->ps_pool_list,
> 					      struct kib_pool,
> 					      po_list)) != NULL) {
>

No good reason - just fatigue probably.  I could automate most of
finding these, but automating the fixing of them didn't quite seem
worth the effort.  Maybe I should play with coccinelle...

I've merged:

diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
index df6b1b134709..d67a197e718d 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
@@ -1867,13 +1867,15 @@ static void kiblnd_destroy_pool_list(struct list_head *head)
 
 static void kiblnd_fail_poolset(struct kib_poolset *ps, struct list_head *zombies)
 {
+	struct kib_pool *po;
+
 	if (!ps->ps_net) /* initialized? */
 		return;
 
 	spin_lock(&ps->ps_lock);
-	while (!list_empty(&ps->ps_pool_list)) {
-		struct kib_pool *po = list_first_entry(&ps->ps_pool_list,
-					    struct kib_pool, po_list);
+	while ((po = list_first_entry_or_null(&ps->ps_pool_list,
+					      struct kib_pool,
+					      po_list)) == NULL) {
 		po->po_failed = 1;
 		list_del(&po->po_list);
 		if (!po->po_allocated)

Thanks,
NeilBrown
-------------- 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/20190211/bc4f596b/attachment.sig>

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

* [lustre-devel] [PATCH 03/21] lustre: obdclass: use list_sort() to sort a list.
  2019-02-07  0:03 ` [lustre-devel] [PATCH 03/21] lustre: obdclass: use list_sort() to sort a list NeilBrown
  2019-02-08  0:13   ` Andreas Dilger
@ 2019-02-11  0:39   ` James Simmons
  2019-02-11  1:05     ` NeilBrown
  1 sibling, 1 reply; 87+ messages in thread
From: James Simmons @ 2019-02-11  0:39 UTC (permalink / raw)
  To: lustre-devel


> Rather than a bespoke bubble-sort, use list_sort() to
> sort this linked list.

Reviewed-by: James Simmons <jsimmons@infradead.org>
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/obdclass/cl_io.c |   51 +++++-------------------
>  1 file changed, 10 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
> index beac7e8bc92a..7bf02350f19d 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
> @@ -42,6 +42,7 @@
>  #include <obd_support.h>
>  #include <lustre_fid.h>
>  #include <linux/list.h>
> +#include <linux/list_sort.h>
>  #include <linux/sched.h>
>  #include <cl_object.h>
>  #include "cl_internal.h"
> @@ -213,9 +214,15 @@ int cl_io_rw_init(const struct lu_env *env, struct cl_io *io,
>  }
>  EXPORT_SYMBOL(cl_io_rw_init);
>  
> -static int cl_lock_descr_sort(const struct cl_lock_descr *d0,
> -			      const struct cl_lock_descr *d1)
> +static int cl_lock_descr_cmp(void *priv,
> +			     struct list_head *a, struct list_head *b)
>  {
> +	const struct cl_io_lock_link *l0 = list_entry(a, struct cl_io_lock_link, cill_linkage);
> +	const struct cl_io_lock_link *l1 = list_entry(b, struct cl_io_lock_link, cill_linkage);
> +
> +	const struct cl_lock_descr *d0 = &l0->cill_descr;
> +	const struct cl_lock_descr *d1 = &l1->cill_descr;
> +
>  	return lu_fid_cmp(lu_object_fid(&d0->cld_obj->co_lu),
>  			  lu_object_fid(&d1->cld_obj->co_lu));
>  }
> @@ -225,45 +232,7 @@ static int cl_lock_descr_sort(const struct cl_lock_descr *d0,
>   */
>  static void cl_io_locks_sort(struct cl_io *io)
>  {
> -	int done = 0;
> -
> -	/* hidden treasure: bubble sort for now. */
> -	do {
> -		struct cl_io_lock_link *curr;
> -		struct cl_io_lock_link *prev;
> -		struct cl_io_lock_link *temp;
> -
> -		done = 1;
> -		prev = NULL;
> -
> -		list_for_each_entry_safe(curr, temp,
> -					 &io->ci_lockset.cls_todo,
> -					 cill_linkage) {
> -			if (prev) {
> -				switch (cl_lock_descr_sort(&prev->cill_descr,
> -							   &curr->cill_descr)) {
> -				case 0:
> -					/*
> -					 * IMPOSSIBLE: Identical locks are
> -					 *	     already removed at
> -					 *	     this point.
> -					 */
> -				default:
> -					LBUG();
> -				case 1:
> -					list_move_tail(&curr->cill_linkage,
> -						       &prev->cill_linkage);
> -					done = 0;
> -					continue; /* don't change prev: it's
> -						   * still "previous"
> -						   */
> -				case -1: /* already in order */
> -					break;
> -				}
> -			}
> -			prev = curr;
> -		}
> -	} while (!done);
> +	list_sort(NULL, &io->ci_lockset.cls_todo, cl_lock_descr_cmp);
>  }

While this fine cl_io_locks_sort() is discussed in one comment in 
cl_object.h and used once in cl_io.c. We could remove this one line
function completely and update the comment in cl_object.h.

>  static void cl_lock_descr_merge(struct cl_lock_descr *d0,
> 
> 
> 

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

* [lustre-devel] [PATCH 10/21] lustre: obdclass: use cl_object_for_each where appropriate
  2019-02-08  1:10   ` Andreas Dilger
@ 2019-02-11  0:42     ` NeilBrown
  2019-02-11  4:19       ` James Simmons
  2019-02-15 18:15       ` Andreas Dilger
  0 siblings, 2 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-11  0:42 UTC (permalink / raw)
  To: lustre-devel

On Fri, Feb 08 2019, Andreas Dilger wrote:

> On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
>> 
>> There are various places which have a list_for_each_entry()
>> where cl_object_for_each (or .._reverse) is more appropriate.
>> 
>> Several of these re-use the 'obj' function parameter as a loop
>> iterator, which is a little confusing.
>> 
>> Change these to use cl_object_for_each{_reverse}, and where needed,
>> introduce a new iterator variable 'o'.
>> 
>> Signed-off-by: NeilBrown <neilb@suse.com>
>> ---
>> drivers/staging/lustre/lustre/lov/lov_page.c       |    3 -
>> drivers/staging/lustre/lustre/obdclass/cl_lock.c   |    3 -
>> drivers/staging/lustre/lustre/obdclass/cl_object.c |   82 +++++++++-----------
>> drivers/staging/lustre/lustre/obdclass/cl_page.c   |   11 +--
>> 4 files changed, 44 insertions(+), 55 deletions(-)
>> 
>> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> index f724b2d62df1..d71a680660da 100644
>> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> @@ -190,16 +190,15 @@ EXPORT_SYMBOL(cl_object_attr_unlock);
>> int cl_object_attr_get(const struct lu_env *env, struct cl_object *obj,
>> 		       struct cl_attr *attr)
>> {
>> -	struct lu_object_header *top;
>> +	struct cl_object *o;
>> 	int result;
>> 
>> 	assert_spin_locked(cl_object_attr_guard(obj));
>> 
>> -	top = obj->co_lu.lo_header;
>> 	result = 0;
>
> May as well move the "result = 0" initialization to the declaration for
> all of these?  Another 5 fewer lines of code under your belt.

Yes, that seem good. New patch below.
Thanks,
NeilBrown


From: NeilBrown <neilb@suse.com>
Subject: [PATCH] lustre: obdclass: use cl_object_for_each where appropriate

There are various places which have a list_for_each_entry()
where cl_object_for_each (or .._reverse) is more appropriate.

Several of these re-use the 'obj' function parameter as a loop
iterator, which is a little confusing.

Change these to use cl_object_for_each{_reverse}, and where needed,
introduce a new iterator variable 'o'.

To further clean up these function, move initializtion of 'result'
to the variable declaration.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/lov/lov_page.c       |  3 +-
 drivers/staging/lustre/lustre/obdclass/cl_lock.c   |  3 +-
 drivers/staging/lustre/lustre/obdclass/cl_object.c | 97 ++++++++++------------
 drivers/staging/lustre/lustre/obdclass/cl_page.c   | 11 ++-
 4 files changed, 49 insertions(+), 65 deletions(-)

diff --git a/drivers/staging/lustre/lustre/lov/lov_page.c b/drivers/staging/lustre/lustre/lov/lov_page.c
index 08485a95ec01..e64b350601d2 100644
--- a/drivers/staging/lustre/lustre/lov/lov_page.c
+++ b/drivers/staging/lustre/lustre/lov/lov_page.c
@@ -103,8 +103,7 @@ int lov_page_init_composite(const struct lu_env *env, struct cl_object *obj,
 		return PTR_ERR(sub);
 
 	subobj = lovsub2cl(r0->lo_sub[stripe]);
-	list_for_each_entry(o, &subobj->co_lu.lo_header->loh_layers,
-			    co_lu.lo_linkage) {
+	cl_object_for_each(o, subobj) {
 		if (o->co_ops->coo_page_init) {
 			rc = o->co_ops->coo_page_init(sub->sub_env, o, page,
 						      cl_index(subobj, suboff));
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
index 8133d992cc73..fc5976d8b37b 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
@@ -103,8 +103,7 @@ int cl_lock_init(const struct lu_env *env, struct cl_lock *lock,
 	LASSERT(obj);
 
 	INIT_LIST_HEAD(&lock->cll_layers);
-	list_for_each_entry(scan, &obj->co_lu.lo_header->loh_layers,
-			    co_lu.lo_linkage) {
+	cl_object_for_each(scan, obj) {
 		result = scan->co_ops->coo_lock_init(env, scan, lock, io);
 		if (result != 0) {
 			cl_lock_fini(env, lock);
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
index f724b2d62df1..43bf1a422635 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
@@ -190,16 +190,14 @@ EXPORT_SYMBOL(cl_object_attr_unlock);
 int cl_object_attr_get(const struct lu_env *env, struct cl_object *obj,
 		       struct cl_attr *attr)
 {
-	struct lu_object_header *top;
-	int result;
+	struct cl_object *o;
+	int result = 0;
 
 	assert_spin_locked(cl_object_attr_guard(obj));
 
-	top = obj->co_lu.lo_header;
-	result = 0;
-	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
-		if (obj->co_ops->coo_attr_get) {
-			result = obj->co_ops->coo_attr_get(env, obj, attr);
+	cl_object_for_each(o, obj) {
+		if (o->co_ops->coo_attr_get) {
+			result = o->co_ops->coo_attr_get(env, o, attr);
 			if (result != 0) {
 				if (result > 0)
 					result = 0;
@@ -221,17 +219,15 @@ EXPORT_SYMBOL(cl_object_attr_get);
 int cl_object_attr_update(const struct lu_env *env, struct cl_object *obj,
 			  const struct cl_attr *attr, unsigned int v)
 {
-	struct lu_object_header *top;
-	int result;
+	struct cl_object *o;
+	int result = 0;
 
 	assert_spin_locked(cl_object_attr_guard(obj));
 
-	top = obj->co_lu.lo_header;
-	result = 0;
-	list_for_each_entry_reverse(obj, &top->loh_layers, co_lu.lo_linkage) {
-		if (obj->co_ops->coo_attr_update) {
-			result = obj->co_ops->coo_attr_update(env, obj, attr,
-							      v);
+	cl_object_for_each_reverse(o, obj) {
+		if (o->co_ops->coo_attr_update) {
+			result = o->co_ops->coo_attr_update(env, o, attr,
+							    v);
 			if (result != 0) {
 				if (result > 0)
 					result = 0;
@@ -254,19 +250,17 @@ EXPORT_SYMBOL(cl_object_attr_update);
 int cl_object_glimpse(const struct lu_env *env, struct cl_object *obj,
 		      struct ost_lvb *lvb)
 {
-	struct lu_object_header *top;
-	int result;
+	struct cl_object *o;
+	int result = 0;
 
-	top = obj->co_lu.lo_header;
-	result = 0;
-	list_for_each_entry_reverse(obj, &top->loh_layers, co_lu.lo_linkage) {
-		if (obj->co_ops->coo_glimpse) {
-			result = obj->co_ops->coo_glimpse(env, obj, lvb);
+	cl_object_for_each_reverse(o, obj) {
+		if (o->co_ops->coo_glimpse) {
+			result = o->co_ops->coo_glimpse(env, o, lvb);
 			if (result != 0)
 				break;
 		}
 	}
-	LU_OBJECT_HEADER(D_DLMTRACE, env, lu_object_top(top),
+	LU_OBJECT_HEADER(D_DLMTRACE, env, lu_object_top(obj->co_lu.lo_header),
 			 "size: %llu mtime: %llu atime: %llu ctime: %llu blocks: %llu\n",
 			 lvb->lvb_size, lvb->lvb_mtime, lvb->lvb_atime,
 			 lvb->lvb_ctime, lvb->lvb_blocks);
@@ -280,14 +274,12 @@ EXPORT_SYMBOL(cl_object_glimpse);
 int cl_conf_set(const struct lu_env *env, struct cl_object *obj,
 		const struct cl_object_conf *conf)
 {
-	struct lu_object_header *top;
-	int result;
+	struct cl_object *o;
+	int result = 0;
 
-	top = obj->co_lu.lo_header;
-	result = 0;
-	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
-		if (obj->co_ops->coo_conf_set) {
-			result = obj->co_ops->coo_conf_set(env, obj, conf);
+	cl_object_for_each(o, obj) {
+		if (o->co_ops->coo_conf_set) {
+			result = o->co_ops->coo_conf_set(env, o, conf);
 			if (result != 0)
 				break;
 		}
@@ -301,13 +293,10 @@ EXPORT_SYMBOL(cl_conf_set);
  */
 int cl_object_prune(const struct lu_env *env, struct cl_object *obj)
 {
-	struct lu_object_header *top;
 	struct cl_object *o;
-	int result;
+	int result = 0;
 
-	top = obj->co_lu.lo_header;
-	result = 0;
-	list_for_each_entry(o, &top->loh_layers, co_lu.lo_linkage) {
+	cl_object_for_each(o, obj) {
 		if (o->co_ops->coo_prune) {
 			result = o->co_ops->coo_prune(env, o);
 			if (result != 0)
@@ -325,14 +314,13 @@ EXPORT_SYMBOL(cl_object_prune);
 int cl_object_getstripe(const struct lu_env *env, struct cl_object *obj,
 			struct lov_user_md __user *uarg, size_t size)
 {
-	struct lu_object_header *top;
+	struct cl_object *o;
 	int result = 0;
 
-	top = obj->co_lu.lo_header;
-	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
-		if (obj->co_ops->coo_getstripe) {
-			result = obj->co_ops->coo_getstripe(env, obj, uarg,
-							    size);
+	cl_object_for_each(o, obj) {
+		if (o->co_ops->coo_getstripe) {
+			result = o->co_ops->coo_getstripe(env, o, uarg,
+							  size);
 			if (result)
 				break;
 		}
@@ -357,14 +345,13 @@ int cl_object_fiemap(const struct lu_env *env, struct cl_object *obj,
 		     struct ll_fiemap_info_key *key,
 		     struct fiemap *fiemap, size_t *buflen)
 {
-	struct lu_object_header *top;
+	struct cl_object *o;
 	int result = 0;
 
-	top = obj->co_lu.lo_header;
-	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
-		if (obj->co_ops->coo_fiemap) {
-			result = obj->co_ops->coo_fiemap(env, obj, key, fiemap,
-							 buflen);
+	cl_object_for_each(o, obj) {
+		if (o->co_ops->coo_fiemap) {
+			result = o->co_ops->coo_fiemap(env, o, key, fiemap,
+						       buflen);
 			if (result)
 				break;
 		}
@@ -376,11 +363,11 @@ EXPORT_SYMBOL(cl_object_fiemap);
 int cl_object_layout_get(const struct lu_env *env, struct cl_object *obj,
 			 struct cl_layout *cl)
 {
-	struct lu_object_header *top = obj->co_lu.lo_header;
+	struct cl_object *o;
 
-	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
-		if (obj->co_ops->coo_layout_get)
-			return obj->co_ops->coo_layout_get(env, obj, cl);
+	cl_object_for_each(o, obj) {
+		if (o->co_ops->coo_layout_get)
+			return o->co_ops->coo_layout_get(env, o, cl);
 	}
 
 	return -EOPNOTSUPP;
@@ -389,12 +376,12 @@ EXPORT_SYMBOL(cl_object_layout_get);
 
 loff_t cl_object_maxbytes(struct cl_object *obj)
 {
-	struct lu_object_header *top = obj->co_lu.lo_header;
+	struct cl_object *o;
 	loff_t maxbytes = LLONG_MAX;
 
-	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
-		if (obj->co_ops->coo_maxbytes)
-			maxbytes = min_t(loff_t, obj->co_ops->coo_maxbytes(obj),
+	cl_object_for_each(o, obj) {
+		if (o->co_ops->coo_maxbytes)
+			maxbytes = min_t(loff_t, o->co_ops->coo_maxbytes(o),
 					 maxbytes);
 	}
 
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
index 057318deaa4e..7d00a9233a3b 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
@@ -132,7 +132,7 @@ struct cl_page *cl_page_alloc(const struct lu_env *env,
 			      enum cl_page_type type)
 {
 	struct cl_page *page;
-	struct lu_object_header *head;
+	struct cl_object *o2;
 
 	page = kzalloc(cl_object_header(o)->coh_page_bufsize, GFP_NOFS);
 	if (page) {
@@ -149,11 +149,10 @@ struct cl_page *cl_page_alloc(const struct lu_env *env,
 		INIT_LIST_HEAD(&page->cp_layers);
 		INIT_LIST_HEAD(&page->cp_batch);
 		lu_ref_init(&page->cp_reference);
-		head = o->co_lu.lo_header;
-		list_for_each_entry(o, &head->loh_layers, co_lu.lo_linkage) {
-			if (o->co_ops->coo_page_init) {
-				result = o->co_ops->coo_page_init(env, o, page,
-								  ind);
+		cl_object_for_each(o2, o) {
+			if (o2->co_ops->coo_page_init) {
+				result = o2->co_ops->coo_page_init(env, o2, page,
+								   ind);
 				if (result != 0) {
 					__cl_page_delete(env, page);
 					cl_page_free(env, page);
-- 
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/20190211/2fe14071/attachment.sig>

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

* [lustre-devel] [PATCH 11/21] lustre: cl_object: remove vestigial debugging.
  2019-02-08  1:31   ` Andreas Dilger
@ 2019-02-11  0:48     ` NeilBrown
  0 siblings, 0 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-11  0:48 UTC (permalink / raw)
  To: lustre-devel

On Fri, Feb 08 2019, Andreas Dilger wrote:

> On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
>> 
>> cl_env_inc() and cl_env_dec() don't do anything,
>> so discard them.
>> 
>> Signed-off-by: NeilBrown <neilb@suse.com>
>
> It looks like these were being used for debugging page allocations,
> wrapped under CONFIG_DEBUG_PAGESTATE_TRACKING, but that was dropped
> from the upstream kernel.  It looks like you could also delete
> cs_page_inc() and cs_page_dec() along with enum cache_stat_item,
> since they are also wrapped under the same CONFIG value.

cs_page_inc/dec were never in driver/staging.
CS_PAGE_INC/DEC were for a while, but were removed nearly 4 years ago.

Commit 76c807210aea ("staging: lustre: cl_page: delete empty macros")

>
> Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

Thanks,
NeilBrown

>
>> ---
>> drivers/staging/lustre/lustre/obdclass/cl_object.c |   15 ---------------
>> 1 file changed, 15 deletions(-)
>> 
>> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> index d71a680660da..1e704078664e 100644
>> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> @@ -565,14 +565,6 @@ struct cl_env {
>> 	void		       *ce_debug;
>> };
>> 
>> -static void cl_env_inc(enum cache_stats_item item)
>> -{
>> -}
>> -
>> -static void cl_env_dec(enum cache_stats_item item)
>> -{
>> -}
>> -
>> static void cl_env_init0(struct cl_env *cle, void *debug)
>> {
>> 	LASSERT(cle->ce_ref == 0);
>> @@ -581,7 +573,6 @@ static void cl_env_init0(struct cl_env *cle, void *debug)
>> 
>> 	cle->ce_ref = 1;
>> 	cle->ce_debug = debug;
>> -	cl_env_inc(CS_busy);
>> }
>> 
>> static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
>> @@ -611,9 +602,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
>> 		if (rc != 0) {
>> 			kmem_cache_free(cl_env_kmem, cle);
>> 			env = ERR_PTR(rc);
>> -		} else {
>> -			cl_env_inc(CS_create);
>> -			cl_env_inc(CS_total);
>> 		}
>> 	} else {
>> 		env = ERR_PTR(-ENOMEM);
>> @@ -623,7 +611,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
>> 
>> static void cl_env_fini(struct cl_env *cle)
>> {
>> -	cl_env_dec(CS_total);
>> 	lu_context_fini(&cle->ce_lu.le_ctx);
>> 	lu_context_fini(&cle->ce_ses);
>> 	kmem_cache_free(cl_env_kmem, cle);
>> @@ -782,7 +769,6 @@ void cl_env_put(struct lu_env *env, u16 *refcheck)
>> 	if (--cle->ce_ref == 0) {
>> 		int cpu = get_cpu();
>> 
>> -		cl_env_dec(CS_busy);
>> 		cle->ce_debug = NULL;
>> 		cl_env_exit(cle);
>> 		/*
>> @@ -903,7 +889,6 @@ void cl_env_percpu_put(struct lu_env *env)
>> 	cle->ce_ref--;
>> 	LASSERT(cle->ce_ref == 0);
>> 
>> -	cl_env_dec(CS_busy);
>> 	cle->ce_debug = NULL;
>> 
>> 	put_cpu();
>> 
>> 
>
> Cheers, Andreas
> ---
> Andreas Dilger
> CTO Whamcloud
-------------- 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/20190211/f6ced620/attachment.sig>

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

* [lustre-devel] [PATCH 15/21] lustre: obdclass: char obd_ioctl_getdata type.
  2019-02-08  5:56   ` Andreas Dilger
@ 2019-02-11  0:52     ` NeilBrown
  0 siblings, 0 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-11  0:52 UTC (permalink / raw)
  To: lustre-devel

On Fri, Feb 08 2019, Andreas Dilger wrote:

> On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
>> 
>> Instead of having obd_ioctl_getdata() return the allocated
>> data as a "char *", return it as it really is,
>> struct obd_ioctl_data *
>> 
>> This avoids the need for extra variables and casts.
>> 
>> Signed-off-by: NeilBrown <neilb@suse.com>
>
> Most of the patch looks like a no-op, except at one part below:
>
>> @@ -1651,18 +1647,16 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
>> 		return rc;
>> 	}
>> 	case LL_IOC_MIGRATE: {
>> -		char *buf = NULL;
>> 		const char *filename;
>> 		int namelen = 0;
>> 		int len;
>> 		int rc;
>> 		int mdtidx;
>> 
>> -		rc = obd_ioctl_getdata(&buf, &len, (void __user *)arg);
>> +		rc = obd_ioctl_getdata(&data, &len, (void __user *)arg);
>> 		if (rc < 0)
>> 			return rc;
>> 
>> -		data = (struct obd_ioctl_data *)buf;
>> 		if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2 ||
>> 		    !data->ioc_inllen1 || !data->ioc_inllen2) {
>> 			rc = -EINVAL;
>> @@ -1684,7 +1678,6 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
>> 
>> 		rc = ll_migrate(inode, file, mdtidx, filename, namelen - 1);
>> migrate_free:
>> -		kvfree(buf);
>
> This removes the call to kvfree(buf) but it isn't clear why, since the rest of
> the patch is mostly variable renaming?

Thanks for catching that!  It should be:

 migrate_free:
-               kvfree(buf);
+               kvfree(data);
 
of course.  Fixed now.

NeilBrown
-------------- 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/20190211/9eda8de4/attachment.sig>

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

* [lustre-devel] [PATCH 19/21] lustre: obdclass: avoid races in class_register_type()
  2019-02-08  6:41   ` Andreas Dilger
@ 2019-02-11  0:58     ` NeilBrown
  0 siblings, 0 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-11  0:58 UTC (permalink / raw)
  To: lustre-devel

On Fri, Feb 08 2019, Andreas Dilger wrote:

> On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
>> 
>> If there are two parallel attempts to register the
>> same class name, it could get registered twice.
>> So re-check after allocation to make sure the name is
>> still unique.
>
> The patch itself seems reasonable, but I don't see how this
> scenario could ever happen?  class_register_type() is only
> called once per device type from the module init code, and
> I don't think it is possible to insert the same module twice?

I agree. I don't think it can happen.
By the same logic, the test

	if (class_search_type(name)) {
		CDEBUG(D_IOCTL, "Type %s already registered\n", name);
		return -EEXIST;
	}

at the start of class_register_type() is pointless, as it is not
possible for the same name to be registered twice.

But I think it is still good to have this test, and to fail-safe.
To me the test as it is "looks" prone to races, so I wanted to fix it.
When I'm analysining obscure bugs, it helps a lot to have code that is
"obviously correct" without having the understand (and double check)
various assumptions about usage which are necessary for it to be
correct.

So this patch isn't needed for correctness. It is needed (I think) to
make the code understandable and maintainable.

Thanks,
NeilBrown


>
> Cheers, Andreas
> ---
> Andreas Dilger
> Principal Lustre Architect
> Whamcloud
-------------- 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/20190211/28704704/attachment.sig>

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

* [lustre-devel] [PATCH 03/21] lustre: obdclass: use list_sort() to sort a list.
  2019-02-11  0:39   ` James Simmons
@ 2019-02-11  1:05     ` NeilBrown
  0 siblings, 0 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-11  1:05 UTC (permalink / raw)
  To: lustre-devel

On Mon, Feb 11 2019, James Simmons wrote:

>> Rather than a bespoke bubble-sort, use list_sort() to
>> sort this linked list.
>
> Reviewed-by: James Simmons <jsimmons@infradead.org>
>  
>> Signed-off-by: NeilBrown <neilb@suse.com>
>> ---
>>  drivers/staging/lustre/lustre/obdclass/cl_io.c |   51 +++++-------------------
>>  1 file changed, 10 insertions(+), 41 deletions(-)
>> 
>> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
>> index beac7e8bc92a..7bf02350f19d 100644
>> --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
>> +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
>> @@ -42,6 +42,7 @@
>>  #include <obd_support.h>
>>  #include <lustre_fid.h>
>>  #include <linux/list.h>
>> +#include <linux/list_sort.h>
>>  #include <linux/sched.h>
>>  #include <cl_object.h>
>>  #include "cl_internal.h"
>> @@ -213,9 +214,15 @@ int cl_io_rw_init(const struct lu_env *env, struct cl_io *io,
>>  }
>>  EXPORT_SYMBOL(cl_io_rw_init);
>>  
>> -static int cl_lock_descr_sort(const struct cl_lock_descr *d0,
>> -			      const struct cl_lock_descr *d1)
>> +static int cl_lock_descr_cmp(void *priv,
>> +			     struct list_head *a, struct list_head *b)
>>  {
>> +	const struct cl_io_lock_link *l0 = list_entry(a, struct cl_io_lock_link, cill_linkage);
>> +	const struct cl_io_lock_link *l1 = list_entry(b, struct cl_io_lock_link, cill_linkage);
>> +
>> +	const struct cl_lock_descr *d0 = &l0->cill_descr;
>> +	const struct cl_lock_descr *d1 = &l1->cill_descr;
>> +
>>  	return lu_fid_cmp(lu_object_fid(&d0->cld_obj->co_lu),
>>  			  lu_object_fid(&d1->cld_obj->co_lu));
>>  }
>> @@ -225,45 +232,7 @@ static int cl_lock_descr_sort(const struct cl_lock_descr *d0,
>>   */
>>  static void cl_io_locks_sort(struct cl_io *io)
>>  {
>> -	int done = 0;
>> -
>> -	/* hidden treasure: bubble sort for now. */
>> -	do {
>> -		struct cl_io_lock_link *curr;
>> -		struct cl_io_lock_link *prev;
>> -		struct cl_io_lock_link *temp;
>> -
>> -		done = 1;
>> -		prev = NULL;
>> -
>> -		list_for_each_entry_safe(curr, temp,
>> -					 &io->ci_lockset.cls_todo,
>> -					 cill_linkage) {
>> -			if (prev) {
>> -				switch (cl_lock_descr_sort(&prev->cill_descr,
>> -							   &curr->cill_descr)) {
>> -				case 0:
>> -					/*
>> -					 * IMPOSSIBLE: Identical locks are
>> -					 *	     already removed at
>> -					 *	     this point.
>> -					 */
>> -				default:
>> -					LBUG();
>> -				case 1:
>> -					list_move_tail(&curr->cill_linkage,
>> -						       &prev->cill_linkage);
>> -					done = 0;
>> -					continue; /* don't change prev: it's
>> -						   * still "previous"
>> -						   */
>> -				case -1: /* already in order */
>> -					break;
>> -				}
>> -			}
>> -			prev = curr;
>> -		}
>> -	} while (!done);
>> +	list_sort(NULL, &io->ci_lockset.cls_todo, cl_lock_descr_cmp);
>>  }
>
> While this fine cl_io_locks_sort() is discussed in one comment in 
> cl_object.h and used once in cl_io.c. We could remove this one line
> function completely and update the comment in cl_object.h.
>

Excellent idea.  New patch is below.
Thanks,
NeilBrown

From: NeilBrown <neilb@suse.com>
Subject: [PATCH] lustre: obdclass: use list_sort() to sort a list.

Rather than a bespoke bubble-sort, use list_sort() to
sort this linked list.

As this would become a 1-line function that is only called once,
call list_sort() directly from the one call site.

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/obdclass/cl_io.c | 63 ++++++--------------------
 1 file changed, 14 insertions(+), 49 deletions(-)

diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
index 5191fba8bbc0..c8a99b61ecd2 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -42,6 +42,7 @@
 #include <obd_support.h>
 #include <lustre_fid.h>
 #include <linux/list.h>
+#include <linux/list_sort.h>
 #include <linux/sched.h>
 #include <cl_object.h>
 #include "cl_internal.h"
@@ -213,57 +214,17 @@ int cl_io_rw_init(const struct lu_env *env, struct cl_io *io,
 }
 EXPORT_SYMBOL(cl_io_rw_init);
 
-static int cl_lock_descr_sort(const struct cl_lock_descr *d0,
-			      const struct cl_lock_descr *d1)
+static int cl_lock_descr_cmp(void *priv,
+			     struct list_head *a, struct list_head *b)
 {
-	return lu_fid_cmp(lu_object_fid(&d0->cld_obj->co_lu),
-			  lu_object_fid(&d1->cld_obj->co_lu));
-}
+	const struct cl_io_lock_link *l0 = list_entry(a, struct cl_io_lock_link, cill_linkage);
+	const struct cl_io_lock_link *l1 = list_entry(b, struct cl_io_lock_link, cill_linkage);
 
-/*
- * Sort locks in lexicographical order of their (fid, start-offset) pairs.
- */
-static void cl_io_locks_sort(struct cl_io *io)
-{
-	int done = 0;
+	const struct cl_lock_descr *d0 = &l0->cill_descr;
+	const struct cl_lock_descr *d1 = &l1->cill_descr;
 
-	/* hidden treasure: bubble sort for now. */
-	do {
-		struct cl_io_lock_link *curr;
-		struct cl_io_lock_link *prev;
-		struct cl_io_lock_link *temp;
-
-		done = 1;
-		prev = NULL;
-
-		list_for_each_entry_safe(curr, temp,
-					 &io->ci_lockset.cls_todo,
-					 cill_linkage) {
-			if (prev) {
-				switch (cl_lock_descr_sort(&prev->cill_descr,
-							   &curr->cill_descr)) {
-				case 0:
-					/*
-					 * IMPOSSIBLE: Identical locks are
-					 *	     already removed at
-					 *	     this point.
-					 */
-				default:
-					LBUG();
-				case 1:
-					list_move_tail(&curr->cill_linkage,
-						       &prev->cill_linkage);
-					done = 0;
-					continue; /* don't change prev: it's
-						   * still "previous"
-						   */
-				case -1: /* already in order */
-					break;
-				}
-			}
-			prev = curr;
-		}
-	} while (!done);
+	return lu_fid_cmp(lu_object_fid(&d0->cld_obj->co_lu),
+			  lu_object_fid(&d1->cld_obj->co_lu));
 }
 
 static void cl_lock_descr_merge(struct cl_lock_descr *d0,
@@ -347,7 +308,11 @@ int cl_io_lock(const struct lu_env *env, struct cl_io *io)
 	}
 
 	if (result == 0) {
-		cl_io_locks_sort(io);
+		/*
+		 * Sort locks in lexicographical order of their (fid,
+		 * start-offset) pairs to avoid deadlocks.
+		 */
+		list_sort(NULL, &io->ci_lockset.cls_todo, cl_lock_descr_cmp);
 		result = cl_lockset_lock(env, io, &io->ci_lockset);
 	}
 	if (result != 0)
-- 
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/20190211/b7a2ccca/attachment-0001.sig>

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

* [lustre-devel] [PATCH 02/21] lustre: obd_class: remove csi_barrier from struct cl_sync_io
  2019-02-11  0:34   ` James Simmons
@ 2019-02-11  1:09     ` NeilBrown
  0 siblings, 0 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-11  1:09 UTC (permalink / raw)
  To: lustre-devel

On Mon, Feb 11 2019, James Simmons wrote:

>> This flag is used to ensure that structure isn't freed before
>> the wakeup completes.  The same can be achieved using the
>> csi_waitq.lock and calling wake_up_all_locked().
>>
>
> Reviewed-by: James Simmons <jsimmons@infradead.org>
>
>> Signed-off-by: NeilBrown <neilb@suse.com>
>> ---
>>  drivers/staging/lustre/lustre/include/cl_object.h |    2 --
>>  drivers/staging/lustre/lustre/obdclass/cl_io.c    |   16 +++++++---------
>>  2 files changed, 7 insertions(+), 11 deletions(-)
>> 
>> diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
>> index 71ba73cdbb5e..13d79810dd39 100644
>> --- a/drivers/staging/lustre/lustre/include/cl_object.h
>> +++ b/drivers/staging/lustre/lustre/include/cl_object.h
>> @@ -2391,8 +2391,6 @@ struct cl_sync_io {
>>  	atomic_t		csi_sync_nr;
>>  	/** error code. */
>>  	int			csi_sync_rc;
>> -	/** barrier of destroy this structure */
>> -	atomic_t		csi_barrier;
>>  	/** completion to be signaled when transfer is complete. */
>>  	wait_queue_head_t	csi_waitq;
>>  };
>> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
>> index e9ad055f84b8..beac7e8bc92a 100644
>> --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
>> +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
>> @@ -1047,7 +1047,6 @@ void cl_sync_io_init(struct cl_sync_io *anchor, int nr)
>>  	memset(anchor, 0, sizeof(*anchor));
>>  	init_waitqueue_head(&anchor->csi_waitq);
>>  	atomic_set(&anchor->csi_sync_nr, nr);
>> -	atomic_set(&anchor->csi_barrier, nr > 0);
>>  	anchor->csi_sync_rc = 0;
>>  }
>>  EXPORT_SYMBOL(cl_sync_io_init);
>> @@ -1080,11 +1079,10 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
>>  	} else {
>>  		rc = anchor->csi_sync_rc;
>>  	}
>> +	/* We take the lock to ensure that cl_sync_io_note() has finished */
>> +	spin_lock(&anchor->csi_waitq.lock);
>
> I don't think I every seen any use the internal lock for the wait_queue
> in such a method. Most creative approach.

You need to get more :-)

There is a macro
   wait_event_interruptible_locked()
which explicitly supports this model.  Only used 4 times in the kernel
so not very popular yet.
The various forms of wake_up_locked are used a bit more often.
I don't remember where I first saw it.
It is a neat idea!

Thanks,
NeilBrown



>
>>  	LASSERT(atomic_read(&anchor->csi_sync_nr) == 0);
>> -
>> -	/* wait until cl_sync_io_note() has done wakeup */
>> -	while (unlikely(atomic_read(&anchor->csi_barrier) != 0))
>> -		cpu_relax();
>> +	spin_unlock(&anchor->csi_waitq.lock);
>>  
>>  	return rc;
>>  }
>> @@ -1104,11 +1102,11 @@ void cl_sync_io_note(const struct lu_env *env, struct cl_sync_io *anchor,
>>  	 * IO.
>>  	 */
>>  	LASSERT(atomic_read(&anchor->csi_sync_nr) > 0);
>> -	if (atomic_dec_and_test(&anchor->csi_sync_nr)) {
>> +	if (atomic_dec_and_lock(&anchor->csi_sync_nr,
>> +				&anchor->csi_waitq.lock)) {
>>  
>> -		wake_up_all(&anchor->csi_waitq);
>> -		/* it's safe to nuke or reuse anchor now */
>> -		atomic_set(&anchor->csi_barrier, 0);
>> +		wake_up_all_locked(&anchor->csi_waitq);
>> +		spin_unlock(&anchor->csi_waitq.lock);
>>  
>>  		/* Can't access anchor any more */
>>  	}
>> 
>> 
>> 
-------------- 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/20190211/19836194/attachment.sig>

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

* [lustre-devel] [PATCH 04/21] lustre: use list*entry macros in place of container_of()
  2019-02-07  0:03 ` [lustre-devel] [PATCH 04/21] lustre: use list*entry macros in place of container_of() NeilBrown
  2019-02-08  0:25   ` Andreas Dilger
@ 2019-02-11  1:32   ` James Simmons
  2019-02-11  3:14     ` NeilBrown
  1 sibling, 1 reply; 87+ messages in thread
From: James Simmons @ 2019-02-11  1:32 UTC (permalink / raw)
  To: lustre-devel


> There are a number of places that use container_of() but where
> list_first_entry(), or list_last_entry() make the meaning more clear.
> So change them over.

I have to say normally the patches you see genernally use the basic
functionality of the linux list implementation. I wonder if a deep
dive on LUG's developers day would be a good idea.

Reviewed-by: James Simmons <jsimmons@infradead.org>
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |    4 ++--
>  drivers/staging/lustre/lustre/obdclass/cl_io.c     |    4 ++--
>  drivers/staging/lustre/lustre/obdclass/cl_object.c |   13 ++++++++-----
>  drivers/staging/lustre/lustre/obdclass/cl_page.c   |    4 ++--
>  drivers/staging/lustre/lustre/obdclass/lu_object.c |    7 +++----
>  5 files changed, 17 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
> index 85c5047f4ba2..74c7644d6ef8 100644
> --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
> +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
> @@ -987,8 +987,8 @@ struct ldlm_namespace *ldlm_namespace_first_locked(enum ldlm_side client)
>  {
>  	LASSERT(mutex_is_locked(ldlm_namespace_lock(client)));
>  	LASSERT(!list_empty(ldlm_namespace_list(client)));
> -	return container_of(ldlm_namespace_list(client)->next,
> -		struct ldlm_namespace, ns_list_chain);
> +	return list_first_entry(ldlm_namespace_list(client),
> +				struct ldlm_namespace, ns_list_chain);
>  }
>  
>  /** Create and initialize new resource. */
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
> index 7bf02350f19d..34b4e63e7d1a 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
> @@ -93,8 +93,8 @@ void cl_io_fini(const struct lu_env *env, struct cl_io *io)
>  	LINVRNT(cl_io_invariant(io));
>  
>  	while (!list_empty(&io->ci_layers)) {
> -		slice = container_of(io->ci_layers.prev, struct cl_io_slice,
> -				     cis_linkage);
> +		slice = list_last_entry(&io->ci_layers, struct cl_io_slice,
> +					cis_linkage);
>  		list_del_init(&slice->cis_linkage);
>  		if (slice->cis_iop->op[io->ci_type].cio_fini)
>  			slice->cis_iop->op[io->ci_type].cio_fini(env, slice);
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> index 05d784ae7a6c..f724b2d62df1 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> @@ -649,8 +649,8 @@ static struct lu_env *cl_env_obtain(void *debug)
>  	if (cl_envs[cpu].cec_count > 0) {
>  		int rc;
>  
> -		cle = container_of(cl_envs[cpu].cec_envs.next, struct cl_env,
> -				   ce_linkage);
> +		cle = list_first_entry(&cl_envs[cpu].cec_envs, struct cl_env,
> +				       ce_linkage);
>  		list_del_init(&cle->ce_linkage);
>  		cl_envs[cpu].cec_count--;
>  		read_unlock(&cl_envs[cpu].cec_guard);
> @@ -748,9 +748,12 @@ unsigned int cl_env_cache_purge(unsigned int nr)
>  
>  	for_each_possible_cpu(i) {
>  		write_lock(&cl_envs[i].cec_guard);
> -		for (; !list_empty(&cl_envs[i].cec_envs) && nr > 0; --nr) {
> -			cle = container_of(cl_envs[i].cec_envs.next,
> -					   struct cl_env, ce_linkage);
> +		for (; nr >0 &&
> +			     (cle = list_first_entry_or_null(
> +				     &cl_envs[i].cec_envs,
> +				     struct cl_env,
> +				     ce_linkage)) != NULL;
> +		     --nr) {
>  			list_del_init(&cle->ce_linkage);
>  			LASSERT(cl_envs[i].cec_count > 0);
>  			cl_envs[i].cec_count--;
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
> index b1b4dc7ea22f..d025ea55818f 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
> @@ -690,8 +690,8 @@ int cl_page_is_vmlocked(const struct lu_env *env, const struct cl_page *pg)
>  	const struct cl_page_slice *slice;
>  	int result;
>  
> -	slice = container_of(pg->cp_layers.next,
> -			     const struct cl_page_slice, cpl_linkage);
> +	slice = list_first_entry(&pg->cp_layers,
> +				 const struct cl_page_slice, cpl_linkage);
>  	PASSERT(env, pg, slice->cpl_ops->cpo_is_vmlocked);
>  	/*
>  	 * Call ->cpo_is_vmlocked() directly instead of going through
> diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c
> index 3bd48748f46c..639c298b6a90 100644
> --- a/drivers/staging/lustre/lustre/obdclass/lu_object.c
> +++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c
> @@ -349,7 +349,7 @@ static void lu_object_free(const struct lu_env *env, struct lu_object *o)
>  		 * lives as long as possible and ->loo_object_free() methods
>  		 * can look at its contents.
>  		 */
> -		o = container_of(splice.prev, struct lu_object, lo_linkage);
> +		o = list_last_entry(&splice, struct lu_object, lo_linkage);
>  		list_del_init(&o->lo_linkage);
>  		o->lo_ops->loo_object_free(env, o);
>  	}
> @@ -432,9 +432,8 @@ int lu_site_purge_objects(const struct lu_env *env, struct lu_site *s,
>  		 * Free everything on the dispose list. This is safe against
>  		 * races due to the reasons described in lu_object_put().
>  		 */
> -		while (!list_empty(&dispose)) {
> -			h = container_of(dispose.next,
> -					 struct lu_object_header, loh_lru);
> +		while ((h = list_first_entry_or_null(
> +				&dispose, struct lu_object_header, loh_lru)) != NULL) {
>  			list_del_init(&h->loh_lru);
>  			lu_object_free(env, lu_object_top(h));
>  			lprocfs_counter_incr(s->ls_stats, LU_SS_LRU_PURGED);
> 
> 
> 

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

* [lustre-devel] [PATCH 05/21] lustre: use list_first_entry() in lustre subdirectory.
  2019-02-07  0:03 ` [lustre-devel] [PATCH 05/21] lustre: use list_first_entry() in lustre subdirectory NeilBrown
  2019-02-08  0:31   ` Andreas Dilger
@ 2019-02-11  1:45   ` James Simmons
  2019-02-11  3:08     ` NeilBrown
  1 sibling, 1 reply; 87+ messages in thread
From: James Simmons @ 2019-02-11  1:45 UTC (permalink / raw)
  To: lustre-devel


> Convert
>   list_entry(foo->next .....)
> to
>   list_first_entry(foo, ....)
> 
> in 'lustre'
> 
> In several cases the call is combined with
> a list_empty() test and list_first_entry_or_null() is used

Nak. One of the changes below breaks things.

> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/include/cl_object.h  |    2 -
>  drivers/staging/lustre/lustre/llite/statahead.c    |   23 ++++----
>  drivers/staging/lustre/lustre/lov/lov_io.c         |    9 +--
>  drivers/staging/lustre/lustre/obdclass/cl_page.c   |    9 +--
>  drivers/staging/lustre/lustre/obdclass/genops.c    |   22 ++++---
>  .../staging/lustre/lustre/obdclass/lustre_peer.c   |    5 +-
>  drivers/staging/lustre/lustre/osc/osc_cache.c      |   17 +++---
>  drivers/staging/lustre/lustre/osc/osc_lock.c       |    5 +-
>  drivers/staging/lustre/lustre/osc/osc_page.c       |   17 +++---
>  drivers/staging/lustre/lustre/osc/osc_request.c    |    8 +--
>  drivers/staging/lustre/lustre/ptlrpc/client.c      |    8 +--
>  drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c    |    6 +-
>  .../staging/lustre/lustre/ptlrpc/pack_generic.c    |    4 +
>  drivers/staging/lustre/lustre/ptlrpc/sec_gc.c      |    6 +-
>  drivers/staging/lustre/lustre/ptlrpc/service.c     |   59 ++++++++++----------
>  15 files changed, 101 insertions(+), 99 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
> index 13d79810dd39..53fd8d469e55 100644
> --- a/drivers/staging/lustre/lustre/include/cl_object.h
> +++ b/drivers/staging/lustre/lustre/include/cl_object.h
> @@ -2335,7 +2335,7 @@ static inline struct cl_page *cl_page_list_last(struct cl_page_list *plist)
>  static inline struct cl_page *cl_page_list_first(struct cl_page_list *plist)
>  {
>  	LASSERT(plist->pl_nr > 0);
> -	return list_entry(plist->pl_pages.next, struct cl_page, cp_batch);
> +	return list_first_entry(&plist->pl_pages, struct cl_page, cp_batch);
>  }
>  
>  /**

...

> diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
> index 5b97f2a1fea1..a69736dfe8b7 100644
> --- a/drivers/staging/lustre/lustre/ptlrpc/service.c
> +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
> @@ -299,9 +299,9 @@ ptlrpc_server_post_idle_rqbds(struct ptlrpc_service_part *svcpt)
>  			return posted;
>  		}
>  
> -		rqbd = list_entry(svcpt->scp_rqbd_idle.next,
> -				  struct ptlrpc_request_buffer_desc,
> -				  rqbd_list);
> +		rqbd = list_first_entry(&svcpt->scp_rqbd_idle,
> +					struct ptlrpc_request_buffer_desc,
> +					rqbd_list);
>  		list_del(&rqbd->rqbd_list);
>  
>  		/* assume we will post successfully */
> @@ -769,9 +769,9 @@ static void ptlrpc_server_drop_request(struct ptlrpc_request *req)
>  		 * I expect only about 1 or 2 rqbds need to be recycled here
>  		 */
>  		while (svcpt->scp_hist_nrqbds > svc->srv_hist_nrqbds_cpt_max) {
> -			rqbd = list_entry(svcpt->scp_hist_rqbds.next,
> -					  struct ptlrpc_request_buffer_desc,
> -					  rqbd_list);
> +			rqbd = list_first_entry(&svcpt->scp_hist_rqbds,
> +						struct ptlrpc_request_buffer_desc,
> +						rqbd_list);
>  
>  			list_del(&rqbd->rqbd_list);
>  			svcpt->scp_hist_nrqbds--;
> @@ -1240,9 +1240,9 @@ static void ptlrpc_at_check_timed(struct ptlrpc_service_part *svcpt)
>  	/* we took additional refcount so entries can't be deleted from list, no
>  	 * locking is needed
>  	 */
> -	while (!list_empty(&work_list)) {
> -		rq = list_entry(work_list.next, struct ptlrpc_request,
> -				rq_timed_list);
> +	while ((rq = list_first_entry_or_null(&work_list,
> +					      struct ptlrpc_request,
> +					      rq_timed_list)) != NULL) {
>  		list_del_init(&rq->rq_timed_list);
>  
>  		if (ptlrpc_at_send_early_reply(rq) == 0)
> @@ -1485,8 +1485,8 @@ ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt,
>  		return 0;
>  	}
>  
> -	req = list_entry(svcpt->scp_req_incoming.next,
> -			 struct ptlrpc_request, rq_list);
> +	req = list_first_entry(&svcpt->scp_req_incoming,
> +			       struct ptlrpc_request, rq_list);
>  	list_del_init(&req->rq_list);
>  	svcpt->scp_nreqs_incoming--;
>  	/* Consider this still a "queued" request as far as stats are
> @@ -2345,9 +2345,9 @@ static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt)
>  
>  	wake_up_all(&svcpt->scp_waitq);
>  
> -	while (!list_empty(&svcpt->scp_threads)) {
> -		thread = list_entry(svcpt->scp_threads.next,
> -				    struct ptlrpc_thread, t_link);
> +	while ((thread = list_first_entry_or_null(&svcpt->scp_threads,
> +						  struct ptlrpc_thread,
> +						  t_link)) != NULL) {
>  		if (thread_is_stopped(thread)) {
>  			list_del(&thread->t_link);
>  			list_add(&thread->t_link, &zombie);
> @@ -2365,9 +2365,9 @@ static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt)
>  
>  	spin_unlock(&svcpt->scp_lock);
>  
> -	while (!list_empty(&zombie)) {
> -		thread = list_entry(zombie.next,
> -				    struct ptlrpc_thread, t_link);
> +	while ((thread = list_first_entry(&zombie,
> +					  struct ptlrpc_thread,
> +					  t_link)) != NULL) {
>  		list_del(&thread->t_link);
>  		kfree(thread);
>  	}

The above change causes sanity tests 77j: client only supporting ADLER32
to fail with:

2019-02-07 18:38:26 [ 4346.464550] Lustre: Unmounted lustre-client
2019-02-07 18:38:26 [ 4346.471990] BUG: unable to handle kernel paging 
request at ffffeb02001c89c8
2019-02-07 18:38:26 [ 4346.480489] #PF error: [normal kernel read fault]
2019-02-07 18:38:26 [ 4346.486719] PGD 0 P4D 0
2019-02-07 18:38:26 [ 4346.490758] Oops: 0000 [#1] PREEMPT SMP PTI
2019-02-07 18:38:26 [ 4346.496420] CPU: 0 PID: 2478 Comm: kworker/0:1 
Tainted: G        WC        5.0.0-rc4+ #1
2019-02-07 18:38:26 [ 4346.505976] Hardware name: Supermicro 
SYS-6028TR-HTFR/X10DRT-HIBF, BIOS 2.0b 08/12/2016
2019-02-07 18:38:26 [ 4346.515461] Workqueue: obd_zombid 
obd_zombie_imp_cull [obdclass]
2019-02-07 18:38:26 [ 4346.522917] RIP: 0010:kfree+0x52/0x1b0


> @@ -2707,9 +2707,9 @@ ptlrpc_service_purge_all(struct ptlrpc_service *svc)
>  			break;
>  
>  		spin_lock(&svcpt->scp_rep_lock);
> -		while (!list_empty(&svcpt->scp_rep_active)) {
> -			rs = list_entry(svcpt->scp_rep_active.next,
> -					struct ptlrpc_reply_state, rs_list);
> +		while ((rs = list_first_entry_or_null(&svcpt->scp_rep_active,
> +						      struct ptlrpc_reply_state,
> +						      rs_list)) != NULL) {
>  			spin_lock(&rs->rs_lock);
>  			ptlrpc_schedule_difficult_reply(rs);
>  			spin_unlock(&rs->rs_lock);
> @@ -2720,10 +2720,9 @@ ptlrpc_service_purge_all(struct ptlrpc_service *svc)
>  		 * all unlinked) and no service threads, so I'm the only
>  		 * thread noodling the request queue now
>  		 */
> -		while (!list_empty(&svcpt->scp_req_incoming)) {
> -			req = list_entry(svcpt->scp_req_incoming.next,
> -					 struct ptlrpc_request, rq_list);
> -
> +		while ((req = list_first_entry_or_null(&svcpt->scp_req_incoming,
> +						       struct ptlrpc_request,
> +						       rq_list)) != NULL) {
>  			list_del(&req->rq_list);
>  			svcpt->scp_nreqs_incoming--;
>  			ptlrpc_server_finish_request(svcpt, req);
> @@ -2747,17 +2746,17 @@ ptlrpc_service_purge_all(struct ptlrpc_service *svc)
>  		 */
>  
>  		while (!list_empty(&svcpt->scp_rqbd_idle)) {
> -			rqbd = list_entry(svcpt->scp_rqbd_idle.next,
> -					  struct ptlrpc_request_buffer_desc,
> -					  rqbd_list);
> +			rqbd = list_first_entry(&svcpt->scp_rqbd_idle,
> +						struct ptlrpc_request_buffer_desc,
> +						rqbd_list);
>  			ptlrpc_free_rqbd(rqbd);
>  		}
>  		ptlrpc_wait_replies(svcpt);
>  
>  		while (!list_empty(&svcpt->scp_rep_idle)) {
> -			rs = list_entry(svcpt->scp_rep_idle.next,
> -					struct ptlrpc_reply_state,
> -					rs_list);
> +			rs = list_first_entry(&svcpt->scp_rep_idle,
> +					      struct ptlrpc_reply_state,
> +					      rs_list);
>  			list_del(&rs->rs_list);
>  			kvfree(rs);
>  		}
> 
> 
> 

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

* [lustre-devel] [PATCH 06/21] lustre: use list_first_entry() in lnet/lnet subdirectory.
  2019-02-07  0:03 ` [lustre-devel] [PATCH 06/21] lustre: use list_first_entry() in lnet/lnet subdirectory NeilBrown
  2019-02-08  0:44   ` Andreas Dilger
@ 2019-02-11  1:46   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: James Simmons @ 2019-02-11  1:46 UTC (permalink / raw)
  To: lustre-devel


> Convert
>   list_entry(foo->next .....)
> to
>   list_first_entry(foo, ....)
> 
> in 'lnet/lnet'
> 
> In several cases the call is combined with
> a list_empty() test and list_first_entry_or_null() is used
> 
> In one case, list_splice_init() is used.

Reviewed-by: James Simmons <jsimmons@infradead.org>

> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lnet/lnet/api-ni.c     |  111 ++++++++++++-------------
>  drivers/staging/lustre/lnet/lnet/config.c     |   22 ++---
>  drivers/staging/lustre/lnet/lnet/lib-move.c   |   53 ++++++------
>  drivers/staging/lustre/lnet/lnet/lib-msg.c    |   16 ++--
>  drivers/staging/lustre/lnet/lnet/lib-ptl.c    |    7 +-
>  drivers/staging/lustre/lnet/lnet/net_fault.c  |   24 +++--
>  drivers/staging/lustre/lnet/lnet/nidstrings.c |    9 +-
>  drivers/staging/lustre/lnet/lnet/peer.c       |   24 +++--
>  drivers/staging/lustre/lnet/lnet/router.c     |   13 ++-
>  9 files changed, 141 insertions(+), 138 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c
> index 64b8bef91915..671591a092ac 100644
> --- a/drivers/staging/lustre/lnet/lnet/api-ni.c
> +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c
> @@ -812,8 +812,8 @@ lnet_net2ni_locked(u32 net_id, int cpt)
>  
>  	list_for_each_entry(net, &the_lnet.ln_nets, net_list) {
>  		if (net->net_id == net_id) {
> -			ni = list_entry(net->net_ni_list.next, struct lnet_ni,
> -					ni_netlist);
> +			ni = list_first_entry(&net->net_ni_list, struct lnet_ni,
> +					      ni_netlist);
>  			return ni;
>  		}
>  	}
> @@ -1504,12 +1504,12 @@ lnet_clear_zombies_nis_locked(struct lnet_net *net)
>  	 * list and shut them down in guaranteed thread context
>  	 */
>  	i = 2;
> -	while (!list_empty(zombie_list)) {
> +	while ((ni = list_first_entry_or_null(zombie_list,
> +					      struct lnet_ni,
> +					      ni_netlist)) != NULL) {
>  		int *ref;
>  		int j;
>  
> -		ni = list_entry(zombie_list->next,
> -				struct lnet_ni, ni_netlist);
>  		list_del_init(&ni->ni_netlist);
>  		/* the ni should be in deleting state. If it's not it's
>  		 * a bug */
> @@ -1583,9 +1583,9 @@ lnet_shutdown_lndnet(struct lnet_net *net)
>  
>  	list_del_init(&net->net_list);
>  
> -	while (!list_empty(&net->net_ni_list)) {
> -		ni = list_entry(net->net_ni_list.next,
> -				struct lnet_ni, ni_netlist);
> +	while ((ni = list_first_entry_or_null(&net->net_ni_list,
> +					      struct lnet_ni,
> +					      ni_netlist)) != NULL) {
>  		lnet_net_unlock(LNET_LOCK_EX);
>  		lnet_shutdown_lndni(ni);
>  		lnet_net_lock(LNET_LOCK_EX);
> @@ -1622,16 +1622,12 @@ lnet_shutdown_lndnets(void)
>  	lnet_net_lock(LNET_LOCK_EX);
>  	the_lnet.ln_state = LNET_STATE_STOPPING;
>  
> -	while (!list_empty(&the_lnet.ln_nets)) {
> -		/*
> -		 * move the nets to the zombie list to avoid them being
> -		 * picked up for new work. LONET is also included in the
> -		 * Nets that will be moved to the zombie list
> -		 */
> -		net = list_entry(the_lnet.ln_nets.next,
> -				 struct lnet_net, net_list);
> -		list_move(&net->net_list, &the_lnet.ln_net_zombie);
> -	}
> +	/*
> +	 * move the nets to the zombie list to avoid them being
> +	 * picked up for new work. LONET is also included in the
> +	 * Nets that will be moved to the zombie list
> +	 */
> +	list_splice_init(&the_lnet.ln_nets, &the_lnet.ln_net_zombie);
>  
>  	/* Drop the cached loopback Net. */
>  	if (the_lnet.ln_loni) {
> @@ -1641,11 +1637,10 @@ lnet_shutdown_lndnets(void)
>  	lnet_net_unlock(LNET_LOCK_EX);
>  
>  	/* iterate through the net zombie list and delete each net */
> -	while (!list_empty(&the_lnet.ln_net_zombie)) {
> -		net = list_entry(the_lnet.ln_net_zombie.next,
> -				 struct lnet_net, net_list);
> +	while ((net = list_first_entry_or_null(&the_lnet.ln_net_zombie,
> +					       struct lnet_net,
> +					       net_list)) != NULL)
>  		lnet_shutdown_lndnet(net);
> -	}
>  
>  	lnet_net_lock(LNET_LOCK_EX);
>  	the_lnet.ln_state = LNET_STATE_SHUTDOWN;
> @@ -1833,9 +1828,9 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun)
>  		goto failed0;
>  	}
>  
> -	while (!list_empty(&net->net_ni_added)) {
> -		ni = list_entry(net->net_ni_added.next, struct lnet_ni,
> -				ni_netlist);
> +	while ((ni = list_first_entry_or_null(&net->net_ni_added,
> +					      struct lnet_ni,
> +					      ni_netlist)) != NULL) {
>  		list_del_init(&ni->ni_netlist);
>  
>  		/* make sure that the the NI we're about to start
> @@ -1902,12 +1897,10 @@ lnet_startup_lndnet(struct lnet_net *net, struct lnet_lnd_tunables *tun)
>  	 * shutdown the new NIs that are being started up
>  	 * free the NET being started
>  	 */
> -	while (!list_empty(&local_ni_list)) {
> -		ni = list_entry(local_ni_list.next, struct lnet_ni,
> -				ni_netlist);
> -
> +	while ((ni = list_first_entry_or_null(&local_ni_list,
> +					      struct lnet_ni,
> +					      ni_netlist)) != NULL)
>  		lnet_shutdown_lndni(ni);
> -	}
>  
>  failed0:
>  	lnet_net_free(net);
> @@ -1931,8 +1924,9 @@ lnet_startup_lndnets(struct list_head *netlist)
>  	the_lnet.ln_state = LNET_STATE_RUNNING;
>  	lnet_net_unlock(LNET_LOCK_EX);
>  
> -	while (!list_empty(netlist)) {
> -		net = list_entry(netlist->next, struct lnet_net, net_list);
> +	while ((net = list_first_entry_or_null(netlist,
> +					       struct lnet_net,
> +					       net_list)) != NULL) {
>  		list_del_init(&net->net_list);
>  
>  		rc = lnet_startup_lndnet(net, NULL);
> @@ -2022,11 +2016,13 @@ int lnet_lib_init(void)
>   */
>  void lnet_lib_exit(void)
>  {
> +	struct lnet_lnd *lnd;
>  	LASSERT(!the_lnet.ln_refcount);
>  
> -	while (!list_empty(&the_lnet.ln_lnds))
> -		lnet_unregister_lnd(list_entry(the_lnet.ln_lnds.next,
> -					       struct lnet_lnd, lnd_list));
> +	while ((lnd = list_first_entry_or_null(&the_lnet.ln_lnds,
> +					       struct lnet_lnd,
> +					       lnd_list)) != NULL)
> +		lnet_unregister_lnd(lnd);
>  	lnet_destroy_locks();
>  }
>  
> @@ -2172,10 +2168,9 @@ LNetNIInit(lnet_pid_t requested_pid)
>  	lnet_unprepare();
>  	LASSERT(rc < 0);
>  	mutex_unlock(&the_lnet.ln_api_mutex);
> -	while (!list_empty(&net_head)) {
> -		struct lnet_net *net;
> -
> -		net = list_entry(net_head.next, struct lnet_net, net_list);
> +	while ((net = list_first_entry_or_null(&net_head,
> +					       struct lnet_net,
> +					       net_list)) != NULL) {
>  		list_del_init(&net->net_list);
>  		lnet_net_free(net);
>  	}
> @@ -2411,10 +2406,11 @@ lnet_get_next_ni_locked(struct lnet_net *mynet, struct lnet_ni *prev)
>  
>  	if (!prev) {
>  		if (!net)
> -			net = list_entry(the_lnet.ln_nets.next, struct lnet_net,
> -					 net_list);
> -		ni = list_entry(net->net_ni_list.next, struct lnet_ni,
> -				ni_netlist);
> +			net = list_first_entry(&the_lnet.ln_nets,
> +					       struct lnet_net,
> +					       net_list);
> +		ni = list_first_entry(&net->net_ni_list, struct lnet_ni,
> +				      ni_netlist);
>  
>  		return ni;
>  	}
> @@ -2432,17 +2428,17 @@ lnet_get_next_ni_locked(struct lnet_net *mynet, struct lnet_ni *prev)
>  			return NULL;
>  
>  		/* get the next net */
> -		net = list_entry(prev->ni_net->net_list.next, struct lnet_net,
> -				 net_list);
> +		net = list_first_entry(&prev->ni_net->net_list, struct lnet_net,
> +				       net_list);
>  		/* get the ni on it */
> -		ni = list_entry(net->net_ni_list.next, struct lnet_ni,
> -				ni_netlist);
> +		ni = list_first_entry(&net->net_ni_list, struct lnet_ni,
> +				      ni_netlist);
>  
>  		return ni;
>  	}
>  
>  	/* there are more nis left */
> -	ni = list_entry(prev->ni_netlist.next, struct lnet_ni, ni_netlist);
> +	ni = list_first_entry(&prev->ni_netlist, struct lnet_ni, ni_netlist);
>  
>  	return ni;
>  }
> @@ -2637,8 +2633,9 @@ static int lnet_handle_legacy_ip2nets(char *ip2nets,
>  		return rc;
>  
>  	mutex_lock(&the_lnet.ln_api_mutex);
> -	while (!list_empty(&net_head)) {
> -		net = list_entry(net_head.next, struct lnet_net, net_list);
> +	while ((net = list_first_entry_or_null(&net_head,
> +					       struct lnet_net,
> +					       net_list)) != NULL) {
>  		list_del_init(&net->net_list);
>  		rc = lnet_add_net_common(net, tun);
>  		if (rc < 0)
> @@ -2648,8 +2645,9 @@ static int lnet_handle_legacy_ip2nets(char *ip2nets,
>  out:
>  	mutex_unlock(&the_lnet.ln_api_mutex);
>  
> -	while (!list_empty(&net_head)) {
> -		net = list_entry(net_head.next, struct lnet_net, net_list);
> +	while ((net = list_first_entry_or_null(&net_head,
> +					       struct lnet_net,
> +					       net_list)) != NULL) {
>  		list_del_init(&net->net_list);
>  		lnet_net_free(net);
>  	}
> @@ -2819,7 +2817,7 @@ lnet_dyn_add_net(struct lnet_ioctl_config_data *conf)
>  		goto out_unlock_clean;
>  	}
>  
> -	net = list_entry(net_head.next, struct lnet_net, net_list);
> +	net = list_first_entry(&net_head, struct lnet_net, net_list);
>  	list_del_init(&net->net_list);
>  
>  	LASSERT(lnet_net_unique(net->net_id, &the_lnet.ln_nets, NULL));
> @@ -2839,9 +2837,10 @@ lnet_dyn_add_net(struct lnet_ioctl_config_data *conf)
>  
>  out_unlock_clean:
>  	mutex_unlock(&the_lnet.ln_api_mutex);
> -	while (!list_empty(&net_head)) {
> -		/* net_head list is empty in success case */
> -		net = list_entry(net_head.next, struct lnet_net, net_list);
> +	/* net_head list is empty in success case */
> +	while ((net = list_first_entry_or_null(&net_head,
> +					       struct lnet_net,
> +					       net_list)) != NULL) {
>  		list_del_init(&net->net_list);
>  		lnet_net_free(net);
>  	}
> diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c
> index ecf656bce73f..f34844465d01 100644
> --- a/drivers/staging/lustre/lnet/lnet/config.c
> +++ b/drivers/staging/lustre/lnet/lnet/config.c
> @@ -817,8 +817,9 @@ lnet_parse_networks(struct list_head *netlist, char *networks,
>  	lnet_syntax("networks", networks, (int)(str - tokens), strlen(str));
>  failed:
>  	/* free the net list and all the nis on each net */
> -	while (!list_empty(netlist)) {
> -		net = list_entry(netlist->next, struct lnet_net, net_list);
> +	while ((net = list_first_entry_or_null(netlist,
> +					       struct lnet_net,
> +					       net_list)) != NULL) {
>  
>  		list_del_init(&net->net_list);
>  		lnet_net_free(net);
> @@ -875,9 +876,8 @@ lnet_free_text_bufs(struct list_head *tbs)
>  {
>  	struct lnet_text_buf *ltb;
>  
> -	while (!list_empty(tbs)) {
> -		ltb = list_entry(tbs->next, struct lnet_text_buf, ltb_list);
> -
> +	while ((ltb = list_first_entry_or_null(tbs, struct lnet_text_buf,
> +					       ltb_list)) != NULL) {
>  		list_del(&ltb->ltb_list);
>  		lnet_free_text_buf(ltb);
>  	}
> @@ -1239,8 +1239,8 @@ lnet_parse_route_tbs(struct list_head *tbs, int *im_a_router)
>  {
>  	struct lnet_text_buf *ltb;
>  
> -	while (!list_empty(tbs)) {
> -		ltb = list_entry(tbs->next, struct lnet_text_buf, ltb_list);
> +	while ((ltb = list_first_entry_or_null(tbs, struct lnet_text_buf,
> +					       ltb_list)) != NULL) {
>  
>  		if (lnet_parse_route(ltb->ltb_text, im_a_router) < 0) {
>  			lnet_free_text_bufs(tbs);
> @@ -1383,7 +1383,7 @@ lnet_splitnets(char *source, struct list_head *nets)
>  	LASSERT(!list_empty(nets));
>  	LASSERT(nets->next == nets->prev);     /* single entry */
>  
> -	tb = list_entry(nets->next, struct lnet_text_buf, ltb_list);
> +	tb = list_first_entry(nets, struct lnet_text_buf, ltb_list);
>  
>  	for (;;) {
>  		sep = strchr(tb->ltb_text, ',');
> @@ -1478,9 +1478,9 @@ lnet_match_networks(char **networksp, char *ip2nets, u32 *ipaddrs, int nip)
>  	len = 0;
>  	rc = 0;
>  
> -	while (!list_empty(&raw_entries)) {
> -		tb = list_entry(raw_entries.next, struct lnet_text_buf,
> -				ltb_list);
> +	while ((tb = list_first_entry_or_null(&raw_entries,
> +					      struct lnet_text_buf,
> +					      ltb_list)) != NULL) {
>  		strncpy(source, tb->ltb_text, sizeof(source));
>  		source[sizeof(source) - 1] = '\0';
>  
> diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c
> index 92c6a34b44e6..185ea51d2771 100644
> --- a/drivers/staging/lustre/lnet/lnet/lib-move.c
> +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c
> @@ -185,9 +185,9 @@ lnet_fail_nid(lnet_nid_t nid, unsigned int threshold)
>  
>  	lnet_net_unlock(0);
>  
> -	while (!list_empty(&cull)) {
> -		tp = list_entry(cull.next, struct lnet_test_peer, tp_list);
> -
> +	while ((tp = list_first_entry_or_null(&cull,
> +					      struct lnet_test_peer,
> +					      tp_list)) != NULL) {
>  		list_del(&tp->tp_list);
>  		kfree(tp);
>  	}
> @@ -244,8 +244,9 @@ fail_peer(lnet_nid_t nid, int outgoing)
>  
>  	lnet_net_unlock(0);
>  
> -	while (!list_empty(&cull)) {
> -		tp = list_entry(cull.next, struct lnet_test_peer, tp_list);
> +	while ((tp = list_first_entry_or_null(&cull,
> +					      struct lnet_test_peer,
> +					      tp_list)) != NULL) {
>  		list_del(&tp->tp_list);
>  
>  		kfree(tp);
> @@ -889,7 +890,7 @@ lnet_post_routed_recv_locked(struct lnet_msg *msg, int do_recv)
>  	}
>  
>  	LASSERT(!list_empty(&rbp->rbp_bufs));
> -	rb = list_entry(rbp->rbp_bufs.next, struct lnet_rtrbuf, rb_list);
> +	rb = list_first_entry(&rbp->rbp_bufs, struct lnet_rtrbuf, rb_list);
>  	list_del(&rb->rb_list);
>  
>  	msg->msg_niov = rbp->rbp_npages;
> @@ -926,8 +927,8 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg)
>  		tq->tq_credits++;
>  		atomic_inc(&ni->ni_tx_credits);
>  		if (tq->tq_credits <= 0) {
> -			msg2 = list_entry(tq->tq_delayed.next,
> -					  struct lnet_msg, msg_list);
> +			msg2 = list_first_entry(&tq->tq_delayed,
> +						struct lnet_msg, msg_list);
>  			list_del(&msg2->msg_list);
>  
>  			LASSERT(msg2->msg_txni == ni);
> @@ -953,8 +954,8 @@ lnet_return_tx_credits_locked(struct lnet_msg *msg)
>  		if (txpeer->lpni_txcredits <= 0) {
>  			int msg2_cpt;
>  
> -			msg2 = list_entry(txpeer->lpni_txq.next,
> -					  struct lnet_msg, msg_list);
> +			msg2 = list_first_entry(&txpeer->lpni_txq,
> +						struct lnet_msg, msg_list);
>  			list_del(&msg2->msg_list);
>  			spin_unlock(&txpeer->lpni_lock);
>  
> @@ -1015,8 +1016,8 @@ lnet_schedule_blocked_locked(struct lnet_rtrbufpool *rbp)
>  
>  	if (list_empty(&rbp->rbp_msgs))
>  		return;
> -	msg = list_entry(rbp->rbp_msgs.next,
> -			 struct lnet_msg, msg_list);
> +	msg = list_first_entry(&rbp->rbp_msgs,
> +			       struct lnet_msg, msg_list);
>  	list_del(&msg->msg_list);
>  
>  	(void)lnet_post_routed_recv_locked(msg, 1);
> @@ -1117,8 +1118,8 @@ lnet_return_rx_credits_locked(struct lnet_msg *msg)
>  			spin_unlock(&rxpeer->lpni_lock);
>  			lnet_drop_routed_msgs_locked(&drop, msg->msg_rx_cpt);
>  		} else if (rxpeer->lpni_rtrcredits <= 0) {
> -			msg2 = list_entry(rxpeer->lpni_rtrq.next,
> -					  struct lnet_msg, msg_list);
> +			msg2 = list_first_entry(&rxpeer->lpni_rtrq,
> +						struct lnet_msg, msg_list);
>  			list_del(&msg2->msg_list);
>  			spin_unlock(&rxpeer->lpni_lock);
>  			(void)lnet_post_routed_recv_locked(msg2, 1);
> @@ -1553,8 +1554,8 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid,
>  				       libcfs_net2str(best_lpni->lpni_net->net_id));
>  				return -EHOSTUNREACH;
>  			}
> -			lpni = list_entry(peer_net->lpn_peer_nis.next,
> -					  struct lnet_peer_ni,
> +			lpni = list_first_entry(&peer_net->lpn_peer_nis,
> +						struct lnet_peer_ni,
>  					  lpni_peer_nis);
>  		}
>  		/* Set preferred NI if necessary. */
> @@ -1595,9 +1596,9 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid,
>  		if (!local_net && !routing && !local_found) {
>  			struct lnet_peer_ni *net_gw;
>  
> -			lpni = list_entry(peer_net->lpn_peer_nis.next,
> -					  struct lnet_peer_ni,
> -					  lpni_peer_nis);
> +			lpni = list_first_entry(&peer_net->lpn_peer_nis,
> +						struct lnet_peer_ni,
> +						lpni_peer_nis);
>  
>  			net_gw = lnet_find_route_locked(NULL,
>  							lpni->lpni_nid,
> @@ -2620,11 +2621,12 @@ EXPORT_SYMBOL(lnet_parse);
>  void
>  lnet_drop_delayed_msg_list(struct list_head *head, char *reason)
>  {
> -	while (!list_empty(head)) {
> +	struct lnet_msg *msg;
> +
> +	while ((msg = list_first_entry_or_null(head, struct lnet_msg,
> +					       msg_list)) != NULL) {
>  		struct lnet_process_id id = { 0 };
> -		struct lnet_msg *msg;
>  
> -		msg = list_entry(head->next, struct lnet_msg, msg_list);
>  		list_del(&msg->msg_list);
>  
>  		id.nid = msg->msg_hdr.src_nid;
> @@ -2662,11 +2664,12 @@ lnet_drop_delayed_msg_list(struct list_head *head, char *reason)
>  void
>  lnet_recv_delayed_msg_list(struct list_head *head)
>  {
> -	while (!list_empty(head)) {
> -		struct lnet_msg *msg;
> +	struct lnet_msg *msg;
> +
> +	while ((msg = list_first_entry_or_null(head, struct lnet_msg,
> +					       msg_list)) != NULL) {
>  		struct lnet_process_id id;
>  
> -		msg = list_entry(head->next, struct lnet_msg, msg_list);
>  		list_del(&msg->msg_list);
>  
>  		/*
> diff --git a/drivers/staging/lustre/lnet/lnet/lib-msg.c b/drivers/staging/lustre/lnet/lnet/lib-msg.c
> index b9e9257a4c5a..02620fe2a0fa 100644
> --- a/drivers/staging/lustre/lnet/lnet/lib-msg.c
> +++ b/drivers/staging/lustre/lnet/lnet/lib-msg.c
> @@ -528,10 +528,9 @@ lnet_finalize(struct lnet_msg *msg, int status)
>  
>  	container->msc_finalizers[my_slot] = current;
>  
> -	while (!list_empty(&container->msc_finalizing)) {
> -		msg = list_entry(container->msc_finalizing.next,
> -				 struct lnet_msg, msg_list);
> -
> +	while ((msg = list_first_entry_or_null(&container->msc_finalizing,
> +					       struct lnet_msg,
> +					       msg_list)) != NULL) {
>  		list_del(&msg->msg_list);
>  
>  		/*
> @@ -561,15 +560,14 @@ void
>  lnet_msg_container_cleanup(struct lnet_msg_container *container)
>  {
>  	int count = 0;
> +	struct lnet_msg *msg;
>  
>  	if (!container->msc_init)
>  		return;
>  
> -	while (!list_empty(&container->msc_active)) {
> -		struct lnet_msg *msg;
> -
> -		msg = list_entry(container->msc_active.next,
> -				 struct lnet_msg, msg_activelist);
> +	while ((msg = list_first_entry_or_null(&container->msc_active,
> +					       struct lnet_msg,
> +					       msg_activelist)) != NULL) {
>  		LASSERT(msg->msg_onactivelist);
>  		msg->msg_onactivelist = 0;
>  		list_del(&msg->msg_activelist);
> diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c
> index ea232c76b64d..4a12d86e6d64 100644
> --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c
> +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c
> @@ -767,9 +767,10 @@ lnet_ptl_cleanup(struct lnet_portal *ptl)
>  		mhash = mtable->mt_mhash;
>  		/* cleanup ME */
>  		for (j = 0; j < LNET_MT_HASH_SIZE + 1; j++) {
> -			while (!list_empty(&mhash[j])) {
> -				me = list_entry(mhash[j].next,
> -						struct lnet_me, me_list);
> +			while ((me = list_first_entry_or_null(&mhash[j],
> +							      struct lnet_me,
> +							      me_list))
> +			       != NULL) {
>  				CERROR("Active ME %p on exit\n", me);
>  				list_del(&me->me_list);
>  				kfree(me);
> diff --git a/drivers/staging/lustre/lnet/lnet/net_fault.c b/drivers/staging/lustre/lnet/lnet/net_fault.c
> index 4234ce1ce539..130a7c90965d 100644
> --- a/drivers/staging/lustre/lnet/lnet/net_fault.c
> +++ b/drivers/staging/lustre/lnet/lnet/net_fault.c
> @@ -581,8 +581,8 @@ delayed_msg_check(struct lnet_delay_rule *rule, bool all,
>  		 * dequeued some timedout messages, update timer for the
>  		 * next delayed message on rule
>  		 */
> -		msg = list_entry(rule->dl_msg_list.next,
> -				 struct lnet_msg, msg_list);
> +		msg = list_first_entry(&rule->dl_msg_list,
> +				       struct lnet_msg, msg_list);
>  		rule->dl_msg_send = msg->msg_delay_send;
>  		mod_timer(&rule->dl_timer, rule->dl_msg_send);
>  	}
> @@ -594,12 +594,12 @@ delayed_msg_process(struct list_head *msg_list, bool drop)
>  {
>  	struct lnet_msg	*msg;
>  
> -	while (!list_empty(msg_list)) {
> +	while ((msg = list_first_entry_or_null(msg_list, struct lnet_msg,
> +					       msg_list)) != NULL) {
>  		struct lnet_ni *ni;
>  		int cpt;
>  		int rc;
>  
> -		msg = list_entry(msg_list->next, struct lnet_msg, msg_list);
>  		LASSERT(msg->msg_rxpeer);
>  		LASSERT(msg->msg_rxni);
>  
> @@ -653,16 +653,16 @@ lnet_delay_rule_check(void)
>  			break;
>  
>  		spin_lock_bh(&delay_dd.dd_lock);
> -		if (list_empty(&delay_dd.dd_sched_rules)) {
> -			spin_unlock_bh(&delay_dd.dd_lock);
> -			break;
> -		}
> -
> -		rule = list_entry(delay_dd.dd_sched_rules.next,
> -				  struct lnet_delay_rule, dl_sched_link);
> -		list_del_init(&rule->dl_sched_link);
> +		rule = list_first_entry_or_null(&delay_dd.dd_sched_rules,
> +						struct lnet_delay_rule,
> +						dl_sched_link);
> +		if (!rule)
> +			list_del_init(&rule->dl_sched_link);
>  		spin_unlock_bh(&delay_dd.dd_lock);
>  
> +		if (!rule)
> +			break;
> +
>  		delayed_msg_check(rule, false, &msgs);
>  		delay_rule_decref(rule); /* -1 for delay_dd.dd_sched_rules */
>  	}
> diff --git a/drivers/staging/lustre/lnet/lnet/nidstrings.c b/drivers/staging/lustre/lnet/lnet/nidstrings.c
> index 8f3d87c5467c..2df9ce4995f3 100644
> --- a/drivers/staging/lustre/lnet/lnet/nidstrings.c
> +++ b/drivers/staging/lustre/lnet/lnet/nidstrings.c
> @@ -282,10 +282,11 @@ parse_nidrange(struct cfs_lstr *src, struct list_head *nidlist)
>  static void
>  free_addrranges(struct list_head *list)
>  {
> -	while (!list_empty(list)) {
> -		struct addrrange *ar;
> +	struct addrrange *ar;
>  
> -		ar = list_entry(list->next, struct addrrange, ar_link);
> +	while ((ar = list_first_entry_or_null(list,
> +					      struct addrrange,
> +					      ar_link)) != NULL) {
>  
>  		cfs_expr_list_free_list(&ar->ar_numaddr_ranges);
>  		list_del(&ar->ar_link);
> @@ -960,7 +961,7 @@ libcfs_num_match(u32 addr, struct list_head *numaddr)
>  	struct cfs_expr_list *el;
>  
>  	LASSERT(!list_empty(numaddr));
> -	el = list_entry(numaddr->next, struct cfs_expr_list, el_link);
> +	el = list_first_entry(numaddr, struct cfs_expr_list, el_link);
>  
>  	return cfs_expr_list_match(addr, el);
>  }
> diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c
> index dfe1f3d09bc6..ade7f23b3bf4 100644
> --- a/drivers/staging/lustre/lnet/lnet/peer.c
> +++ b/drivers/staging/lustre/lnet/lnet/peer.c
> @@ -649,12 +649,12 @@ lnet_get_next_peer_ni_locked(struct lnet_peer *peer,
>  			if (list_empty(&peer->lp_peer_nets))
>  				return NULL;
>  
> -			net = list_entry(peer->lp_peer_nets.next,
> -					 struct lnet_peer_net,
> -					 lpn_peer_nets);
> +			net = list_first_entry(&peer->lp_peer_nets,
> +					       struct lnet_peer_net,
> +					       lpn_peer_nets);
>  		}
> -		lpni = list_entry(net->lpn_peer_nis.next, struct lnet_peer_ni,
> -				  lpni_peer_nis);
> +		lpni = list_first_entry(&net->lpn_peer_nis, struct lnet_peer_ni,
> +					lpni_peer_nis);
>  
>  		return lpni;
>  	}
> @@ -678,19 +678,19 @@ lnet_get_next_peer_ni_locked(struct lnet_peer *peer,
>  			return NULL;
>  
>  		/* get the next net */
> -		net = list_entry(prev->lpni_peer_net->lpn_peer_nets.next,
> -				 struct lnet_peer_net,
> -				 lpn_peer_nets);
> +		net = list_first_entry(&prev->lpni_peer_net->lpn_peer_nets,
> +				       struct lnet_peer_net,
> +				       lpn_peer_nets);
>  		/* get the ni on it */
> -		lpni = list_entry(net->lpn_peer_nis.next, struct lnet_peer_ni,
> -				  lpni_peer_nis);
> +		lpni = list_first_entry(&net->lpn_peer_nis, struct lnet_peer_ni,
> +					lpni_peer_nis);
>  
>  		return lpni;
>  	}
>  
>  	/* there are more nis left */
> -	lpni = list_entry(prev->lpni_peer_nis.next,
> -			  struct lnet_peer_ni, lpni_peer_nis);
> +	lpni = list_first_entry(&prev->lpni_peer_nis,
> +				struct lnet_peer_ni, lpni_peer_nis);
>  
>  	return lpni;
>  }
> diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c
> index 463b123e0e5c..bcde61d2a984 100644
> --- a/drivers/staging/lustre/lnet/lnet/router.c
> +++ b/drivers/staging/lustre/lnet/lnet/router.c
> @@ -1220,9 +1220,9 @@ lnet_prune_rc_data(int wait_unlink)
>  
>  		lnet_net_unlock(LNET_LOCK_EX);
>  
> -		while (!list_empty(&head)) {
> -			rcd = list_entry(head.next,
> -					 struct lnet_rc_data, rcd_list);
> +		while ((rcd = list_first_entry_or_null(&head,
> +						       struct lnet_rc_data,
> +						       rcd_list)) != NULL) {
>  			list_del_init(&rcd->rcd_list);
>  			lnet_destroy_rc_data(rcd);
>  		}
> @@ -1397,7 +1397,7 @@ lnet_rtrpool_free_bufs(struct lnet_rtrbufpool *rbp, int cpt)
>  
>  	/* Free buffers on the free list. */
>  	while (!list_empty(&tmp)) {
> -		rb = list_entry(tmp.next, struct lnet_rtrbuf, rb_list);
> +		rb = list_first_entry(&tmp, struct lnet_rtrbuf, rb_list);
>  		list_del(&rb->rb_list);
>  		lnet_destroy_rtrbuf(rb, npages);
>  	}
> @@ -1481,8 +1481,9 @@ lnet_rtrpool_adjust_bufs(struct lnet_rtrbufpool *rbp, int nbufs, int cpt)
>  	return 0;
>  
>  failed:
> -	while (!list_empty(&rb_list)) {
> -		rb = list_entry(rb_list.next, struct lnet_rtrbuf, rb_list);
> +	while ((rb = list_first_entry_or_null(&rb_list,
> +					      struct lnet_rtrbuf,
> +					      rb_list)) != NULL) {
>  		list_del(&rb->rb_list);
>  		lnet_destroy_rtrbuf(rb, npages);
>  	}
> 
> 
> 

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

* [lustre-devel] [PATCH 07/21] lustre: use list_first_entry() in lnet/klnds subdirectory.
  2019-02-07  0:03 ` [lustre-devel] [PATCH 07/21] lustre: use list_first_entry() in lnet/klnds subdirectory NeilBrown
  2019-02-08  0:59   ` Andreas Dilger
@ 2019-02-11  1:47   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: James Simmons @ 2019-02-11  1:47 UTC (permalink / raw)
  To: lustre-devel


> Convert
>   list_entry(foo->next .....)
> to
>   list_first_entry(foo, ....)
> 
> in 'lnet/klnds
> 
> In several cases the call is combined with a list_empty() test and
> list_first_entry_or_null() is used

tested on IB with no problems.

Reviewed-by: James Simmons <jsimmons@infradead.org>
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c    |   19 +++--
>  .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c |   61 ++++++++-------
>  .../staging/lustre/lnet/klnds/socklnd/socklnd.c    |    9 +-
>  .../staging/lustre/lnet/klnds/socklnd/socklnd_cb.c |   79 ++++++++++----------
>  .../lustre/lnet/klnds/socklnd/socklnd_proto.c      |    4 +
>  5 files changed, 88 insertions(+), 84 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
> index 74b21fe2c091..df6b1b134709 100644
> --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
> +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
> @@ -1386,8 +1386,8 @@ static void kiblnd_destroy_fmr_pool_list(struct list_head *head)
>  {
>  	struct kib_fmr_pool *fpo;
>  
> -	while (!list_empty(head)) {
> -		fpo = list_entry(head->next, struct kib_fmr_pool, fpo_list);
> +	while ((fpo = list_first_entry_or_null(head, struct kib_fmr_pool,
> +					       fpo_list)) != NULL) {
>  		list_del(&fpo->fpo_list);
>  		kiblnd_destroy_fmr_pool(fpo);
>  	}
> @@ -1544,14 +1544,16 @@ static int kiblnd_create_fmr_pool(struct kib_fmr_poolset *fps,
>  static void kiblnd_fail_fmr_poolset(struct kib_fmr_poolset *fps,
>  				    struct list_head *zombies)
>  {
> +	struct kib_fmr_pool *fpo;
> +
>  	if (!fps->fps_net) /* initialized? */
>  		return;
>  
>  	spin_lock(&fps->fps_lock);
>  
> -	while (!list_empty(&fps->fps_pool_list)) {
> -		struct kib_fmr_pool *fpo = list_entry(fps->fps_pool_list.next,
> -						 struct kib_fmr_pool, fpo_list);
> +	while ((fpo = list_first_entry_or_null(&fps->fps_pool_list,
> +					       struct kib_fmr_pool,
> +					       fpo_list)) != NULL) {
>  		fpo->fpo_failed = 1;
>  		list_del(&fpo->fpo_list);
>  		if (!fpo->fpo_map_count)
> @@ -1853,8 +1855,9 @@ static void kiblnd_destroy_pool_list(struct list_head *head)
>  {
>  	struct kib_pool *pool;
>  
> -	while (!list_empty(head)) {
> -		pool = list_entry(head->next, struct kib_pool, po_list);
> +	while ((pool = list_first_entry_or_null(head,
> +						struct kib_pool,
> +						po_list)) != NULL) {
>  		list_del(&pool->po_list);
>  
>  		LASSERT(pool->po_owner);
> @@ -1869,7 +1872,7 @@ static void kiblnd_fail_poolset(struct kib_poolset *ps, struct list_head *zombie
>  
>  	spin_lock(&ps->ps_lock);
>  	while (!list_empty(&ps->ps_pool_list)) {
> -		struct kib_pool *po = list_entry(ps->ps_pool_list.next,
> +		struct kib_pool *po = list_first_entry(&ps->ps_pool_list,
>  					    struct kib_pool, po_list);
>  		po->po_failed = 1;
>  		list_del(&po->po_list);
> diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
> index ad1726098ea3..b9585f607463 100644
> --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
> +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
> @@ -98,9 +98,9 @@ kiblnd_txlist_done(struct list_head *txlist, int status)
>  {
>  	struct kib_tx *tx;
>  
> -	while (!list_empty(txlist)) {
> -		tx = list_entry(txlist->next, struct kib_tx, tx_list);
> -
> +	while ((tx = list_first_entry_or_null(txlist,
> +					      struct kib_tx,
> +					      tx_list)) != NULL) {
>  		list_del(&tx->tx_list);
>  		/* complete now */
>  		tx->tx_waiting = 0;
> @@ -958,9 +958,9 @@ kiblnd_check_sends_locked(struct kib_conn *conn)
>  	LASSERT(conn->ibc_reserved_credits >= 0);
>  
>  	while (conn->ibc_reserved_credits > 0 &&
> -	       !list_empty(&conn->ibc_tx_queue_rsrvd)) {
> -		tx = list_entry(conn->ibc_tx_queue_rsrvd.next,
> -				struct kib_tx, tx_list);
> +	       (tx = list_first_entry_or_null(
> +		       &conn->ibc_tx_queue_rsrvd,
> +		       struct kib_tx, tx_list)) != NULL) {
>  		list_del(&tx->tx_list);
>  		list_add_tail(&tx->tx_list, &conn->ibc_tx_queue);
>  		conn->ibc_reserved_credits--;
> @@ -983,17 +983,17 @@ kiblnd_check_sends_locked(struct kib_conn *conn)
>  
>  		if (!list_empty(&conn->ibc_tx_queue_nocred)) {
>  			credit = 0;
> -			tx = list_entry(conn->ibc_tx_queue_nocred.next,
> -					struct kib_tx, tx_list);
> +			tx = list_first_entry(&conn->ibc_tx_queue_nocred,
> +					      struct kib_tx, tx_list);
>  		} else if (!list_empty(&conn->ibc_tx_noops)) {
>  			LASSERT(!IBLND_OOB_CAPABLE(ver));
>  			credit = 1;
> -			tx = list_entry(conn->ibc_tx_noops.next,
> -					struct kib_tx, tx_list);
> +			tx = list_first_entry(&conn->ibc_tx_noops,
> +					      struct kib_tx, tx_list);
>  		} else if (!list_empty(&conn->ibc_tx_queue)) {
>  			credit = 1;
> -			tx = list_entry(conn->ibc_tx_queue.next,
> -					struct kib_tx, tx_list);
> +			tx = list_first_entry(&conn->ibc_tx_queue,
> +					      struct kib_tx, tx_list);
>  		} else {
>  			break;
>  		}
> @@ -2013,9 +2013,9 @@ kiblnd_handle_early_rxs(struct kib_conn *conn)
>  	LASSERT(conn->ibc_state >= IBLND_CONN_ESTABLISHED);
>  
>  	write_lock_irqsave(&kiblnd_data.kib_global_lock, flags);
> -	while (!list_empty(&conn->ibc_early_rxs)) {
> -		rx = list_entry(conn->ibc_early_rxs.next,
> -				struct kib_rx, rx_list);
> +	while ((rx = list_first_entry_or_null(&conn->ibc_early_rxs,
> +					      struct kib_rx,
> +					      rx_list)) != NULL) {
>  		list_del(&rx->rx_list);
>  		write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags);
>  
> @@ -3311,8 +3311,9 @@ kiblnd_check_conns(int idx)
>  	 * NOOP, but there were no non-blocking tx descs
>  	 * free to do it last time...
>  	 */
> -	while (!list_empty(&checksends)) {
> -		conn = list_entry(checksends.next, struct kib_conn, ibc_connd_list);
> +	while ((conn = list_first_entry_or_null(&checksends,
> +						struct kib_conn,
> +						ibc_connd_list)) != NULL) {
>  		list_del(&conn->ibc_connd_list);
>  
>  		spin_lock(&conn->ibc_lock);
> @@ -3370,11 +3371,12 @@ kiblnd_connd(void *arg)
>  
>  		dropped_lock = 0;
>  
> -		if (!list_empty(&kiblnd_data.kib_connd_zombies)) {
> +		conn = list_first_entry_or_null(
> +			&kiblnd_data.kib_connd_zombies,
> +			struct kib_conn, ibc_list);
> +		if (conn) {
>  			struct kib_peer_ni *peer_ni = NULL;
>  
> -			conn = list_entry(kiblnd_data.kib_connd_zombies.next,
> -					  struct kib_conn, ibc_list);
>  			list_del(&conn->ibc_list);
>  			if (conn->ibc_reconnect) {
>  				peer_ni = conn->ibc_peer;
> @@ -3401,9 +3403,9 @@ kiblnd_connd(void *arg)
>  					      &kiblnd_data.kib_reconn_wait);
>  		}
>  
> -		if (!list_empty(&kiblnd_data.kib_connd_conns)) {
> -			conn = list_entry(kiblnd_data.kib_connd_conns.next,
> -					  struct kib_conn, ibc_list);
> +		conn = list_first_entry_or_null(&kiblnd_data.kib_connd_conns,
> +						struct kib_conn, ibc_list);
> +		if (conn) {
>  			list_del(&conn->ibc_list);
>  
>  			spin_unlock_irqrestore(lock, flags);
> @@ -3423,11 +3425,11 @@ kiblnd_connd(void *arg)
>  						 &kiblnd_data.kib_reconn_list);
>  			}
>  
> -			if (list_empty(&kiblnd_data.kib_reconn_list))
> +			conn = list_first_entry_or_null(&kiblnd_data.kib_reconn_list,
> +							struct kib_conn, ibc_list);
> +			if (!conn)
>  				break;
>  
> -			conn = list_entry(kiblnd_data.kib_reconn_list.next,
> -					  struct kib_conn, ibc_list);
>  			list_del(&conn->ibc_list);
>  
>  			spin_unlock_irqrestore(lock, flags);
> @@ -3636,9 +3638,10 @@ kiblnd_scheduler(void *arg)
>  
>  		did_something = 0;
>  
> -		if (!list_empty(&sched->ibs_conns)) {
> -			conn = list_entry(sched->ibs_conns.next, struct kib_conn,
> -					  ibc_sched_list);
> +		conn = list_first_entry_or_null(&sched->ibs_conns,
> +						struct kib_conn,
> +						ibc_sched_list);
> +		if (conn) {
>  			/* take over kib_sched_conns' ref on conn... */
>  			LASSERT(conn->ibc_scheduled);
>  			list_del(&conn->ibc_sched_list);
> diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
> index 785f76cf9067..08feaf7ce33a 100644
> --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
> +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
> @@ -1566,9 +1566,8 @@ ksocknal_finalize_zcreq(struct ksock_conn *conn)
>  
>  	spin_unlock(&peer_ni->ksnp_lock);
>  
> -	while (!list_empty(&zlist)) {
> -		tx = list_entry(zlist.next, struct ksock_tx, tx_zc_list);
> -
> +	while ((tx = list_first_entry_or_null(&zlist, struct ksock_tx,
> +					      tx_zc_list)) != NULL) {
>  		list_del(&tx->tx_zc_list);
>  		ksocknal_tx_decref(tx);
>  	}
> @@ -2267,8 +2266,8 @@ ksocknal_free_buffers(void)
>  		list_del_init(&ksocknal_data.ksnd_idle_noop_txs);
>  		spin_unlock(&ksocknal_data.ksnd_tx_lock);
>  
> -		while (!list_empty(&zlist)) {
> -			tx = list_entry(zlist.next, struct ksock_tx, tx_list);
> +		while ((tx = list_first_entry_or_null(&zlist, struct ksock_tx,
> +						      tx_list)) != NULL) {
>  			list_del(&tx->tx_list);
>  			kfree(tx);
>  		}
> diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
> index 8e20f430a3f3..208b8d360d5c 100644
> --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
> +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
> @@ -36,9 +36,9 @@ ksocknal_alloc_tx(int type, int size)
>  		/* searching for a noop tx in free list */
>  		spin_lock(&ksocknal_data.ksnd_tx_lock);
>  
> -		if (!list_empty(&ksocknal_data.ksnd_idle_noop_txs)) {
> -			tx = list_entry(ksocknal_data.ksnd_idle_noop_txs.next,
> -					struct ksock_tx, tx_list);
> +		tx = list_first_entry_or_null(&ksocknal_data.ksnd_idle_noop_txs,
> +					      struct ksock_tx, tx_list);
> +		if (tx) {
>  			LASSERT(tx->tx_desc_size == size);
>  			list_del(&tx->tx_list);
>  		}
> @@ -347,8 +347,8 @@ ksocknal_txlist_done(struct lnet_ni *ni, struct list_head *txlist, int error)
>  {
>  	struct ksock_tx *tx;
>  
> -	while (!list_empty(txlist)) {
> -		tx = list_entry(txlist->next, struct ksock_tx, tx_list);
> +	while ((tx = list_first_entry_or_null(txlist, struct ksock_tx,
> +					      tx_list)) != NULL) {
>  
>  		if (error && tx->tx_lnetmsg) {
>  			CNETERR("Deleting packet type %d len %d %s->%s\n",
> @@ -1322,9 +1322,10 @@ int ksocknal_scheduler(void *arg)
>  
>  		/* Ensure I progress everything semi-fairly */
>  
> -		if (!list_empty(&sched->kss_rx_conns)) {
> -			conn = list_entry(sched->kss_rx_conns.next,
> -					  struct ksock_conn, ksnc_rx_list);
> +		conn = list_first_entry_or_null(&sched->kss_rx_conns,
> +						struct ksock_conn,
> +						ksnc_rx_list);
> +		if (conn) {
>  			list_del(&conn->ksnc_rx_list);
>  
>  			LASSERT(conn->ksnc_rx_scheduled);
> @@ -1378,16 +1379,17 @@ int ksocknal_scheduler(void *arg)
>  				list_del_init(&sched->kss_zombie_noop_txs);
>  			}
>  
> -			conn = list_entry(sched->kss_tx_conns.next,
> -					  struct ksock_conn, ksnc_tx_list);
> +			conn = list_first_entry(&sched->kss_tx_conns,
> +						struct ksock_conn,
> +						ksnc_tx_list);
>  			list_del(&conn->ksnc_tx_list);
>  
>  			LASSERT(conn->ksnc_tx_scheduled);
>  			LASSERT(conn->ksnc_tx_ready);
>  			LASSERT(!list_empty(&conn->ksnc_tx_queue));
>  
> -			tx = list_entry(conn->ksnc_tx_queue.next,
> -					struct ksock_tx, tx_list);
> +			tx = list_first_entry(&conn->ksnc_tx_queue,
> +					      struct ksock_tx, tx_list);
>  
>  			if (conn->ksnc_tx_carrier == tx)
>  				ksocknal_next_tx_carrier(conn);
> @@ -1900,8 +1902,8 @@ ksocknal_connect(struct ksock_route *route)
>  		 * connection for V1.x and V2.x
>  		 */
>  		if (!list_empty(&peer_ni->ksnp_conns)) {
> -			conn = list_entry(peer_ni->ksnp_conns.next,
> -					  struct ksock_conn, ksnc_list);
> +			conn = list_first_entry(&peer_ni->ksnp_conns,
> +						struct ksock_conn, ksnc_list);
>  			LASSERT(conn->ksnc_proto == &ksocknal_protocol_v3x);
>  		}
>  
> @@ -2082,10 +2084,10 @@ ksocknal_connd(void *arg)
>  			dropped_lock = 1;
>  		}
>  
> -		if (!list_empty(&ksocknal_data.ksnd_connd_connreqs)) {
> +		cr = list_first_entry_or_null(&ksocknal_data.ksnd_connd_connreqs,
> +					      struct ksock_connreq, ksncr_list);
> +		if (cr) {
>  			/* Connection accepted by the listener */
> -			cr = list_entry(ksocknal_data.ksnd_connd_connreqs.next,
> -					struct ksock_connreq, ksncr_list);
>  
>  			list_del(&cr->ksncr_list);
>  			spin_unlock_bh(connd_lock);
> @@ -2246,9 +2248,9 @@ ksocknal_flush_stale_txs(struct ksock_peer *peer_ni)
>  
>  	write_lock_bh(&ksocknal_data.ksnd_global_lock);
>  
> -	while (!list_empty(&peer_ni->ksnp_tx_queue)) {
> -		tx = list_entry(peer_ni->ksnp_tx_queue.next, struct ksock_tx,
> -				tx_list);
> +	while ((tx = list_first_entry_or_null(&peer_ni->ksnp_tx_queue,
> +					      struct ksock_tx,
> +					      tx_list)) != NULL) {
>  
>  		if (ktime_get_seconds() < tx->tx_deadline)
>  			break;
> @@ -2372,19 +2374,16 @@ ksocknal_check_peer_timeouts(int idx)
>  		 * we can't process stale txs right here because we're
>  		 * holding only shared lock
>  		 */
> -		if (!list_empty(&peer_ni->ksnp_tx_queue)) {
> -			tx = list_entry(peer_ni->ksnp_tx_queue.next,
> -					struct ksock_tx, tx_list);
> -
> -			if (ktime_get_seconds() >= tx->tx_deadline) {
> -				ksocknal_peer_addref(peer_ni);
> -				read_unlock(&ksocknal_data.ksnd_global_lock);
> +		tx = list_first_entry_or_null(&peer_ni->ksnp_tx_queue,
> +					      struct ksock_tx, tx_list);
> +		if (tx && ktime_get_seconds() >= tx->tx_deadline) {
> +			ksocknal_peer_addref(peer_ni);
> +			read_unlock(&ksocknal_data.ksnd_global_lock);
>  
> -				ksocknal_flush_stale_txs(peer_ni);
> +			ksocknal_flush_stale_txs(peer_ni);
>  
> -				ksocknal_peer_decref(peer_ni);
> -				goto again;
> -			}
> +			ksocknal_peer_decref(peer_ni);
> +			goto again;
>  		}
>  
>  		if (list_empty(&peer_ni->ksnp_zc_req_list))
> @@ -2449,9 +2448,9 @@ ksocknal_reaper(void *arg)
>  	spin_lock_bh(&ksocknal_data.ksnd_reaper_lock);
>  
>  	while (!ksocknal_data.ksnd_shuttingdown) {
> -		if (!list_empty(&ksocknal_data.ksnd_deathrow_conns)) {
> -			conn = list_entry(ksocknal_data.ksnd_deathrow_conns.next,
> -					  struct ksock_conn, ksnc_list);
> +		conn = list_first_entry_or_null(&ksocknal_data.ksnd_deathrow_conns,
> +						struct ksock_conn, ksnc_list);
> +		if (conn) {
>  			list_del(&conn->ksnc_list);
>  
>  			spin_unlock_bh(&ksocknal_data.ksnd_reaper_lock);
> @@ -2463,9 +2462,9 @@ ksocknal_reaper(void *arg)
>  			continue;
>  		}
>  
> -		if (!list_empty(&ksocknal_data.ksnd_zombie_conns)) {
> -			conn = list_entry(ksocknal_data.ksnd_zombie_conns.next,
> -					  struct ksock_conn, ksnc_list);
> +		conn = list_first_entry_or_null(&ksocknal_data.ksnd_zombie_conns,
> +						struct ksock_conn, ksnc_list);
> +		if (conn) {
>  			list_del(&conn->ksnc_list);
>  
>  			spin_unlock_bh(&ksocknal_data.ksnd_reaper_lock);
> @@ -2486,9 +2485,9 @@ ksocknal_reaper(void *arg)
>  
>  		/* reschedule all the connections that stalled with ENOMEM... */
>  		nenomem_conns = 0;
> -		while (!list_empty(&enomem_conns)) {
> -			conn = list_entry(enomem_conns.next, struct ksock_conn,
> -					  ksnc_tx_list);
> +		while ((conn = list_first_entry_or_null(&enomem_conns,
> +							struct ksock_conn,
> +							ksnc_tx_list)) != NULL) {
>  			list_del(&conn->ksnc_tx_list);
>  
>  			sched = conn->ksnc_scheduler;
> diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
> index c694feceaaf2..e8b95affee96 100644
> --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
> +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
> @@ -447,8 +447,8 @@ ksocknal_handle_zcack(struct ksock_conn *conn, u64 cookie1, u64 cookie2)
>  
>  	spin_unlock(&peer_ni->ksnp_lock);
>  
> -	while (!list_empty(&zlist)) {
> -		tx = list_entry(zlist.next, struct ksock_tx, tx_zc_list);
> +	while ((tx = list_first_entry_or_null(&zlist, struct ksock_tx,
> +					      tx_zc_list)) != NULL) {
>  		list_del(&tx->tx_zc_list);
>  		ksocknal_tx_decref(tx);
>  	}
> 
> 
> 

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

* [lustre-devel] [PATCH 08/21] lustre: use list_first_entry() throughout
  2019-02-07  0:03 ` [lustre-devel] [PATCH 08/21] lustre: use list_first_entry() throughout NeilBrown
  2019-02-08  1:06   ` Andreas Dilger
@ 2019-02-11  1:48   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: James Simmons @ 2019-02-11  1:48 UTC (permalink / raw)
  To: lustre-devel


> Convert
>   list_entry(foo->next .....)
> to
>   list_first_entry(foo, ....)
> 
> in remainder of lustre.
> 
> In several cases the call is combined with a list_empty() test and
> list_first_entry_or_null() is used

Reviewed-by: James Simmons <jsimmons@infradead.org>
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lnet/libcfs/libcfs_string.c |   12 +++--
>  drivers/staging/lustre/lnet/selftest/conrpc.c      |    5 +-
>  drivers/staging/lustre/lnet/selftest/console.c     |   39 ++++++++----------
>  drivers/staging/lustre/lnet/selftest/framework.c   |   44 ++++++++++----------
>  drivers/staging/lustre/lnet/selftest/rpc.c         |   27 ++++++------
>  drivers/staging/lustre/lnet/selftest/timer.c       |    4 +-
>  6 files changed, 62 insertions(+), 69 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lnet/libcfs/libcfs_string.c b/drivers/staging/lustre/lnet/libcfs/libcfs_string.c
> index 5fb85247525d..ae17b4d44cac 100644
> --- a/drivers/staging/lustre/lnet/libcfs/libcfs_string.c
> +++ b/drivers/staging/lustre/lnet/libcfs/libcfs_string.c
> @@ -468,11 +468,11 @@ EXPORT_SYMBOL(cfs_expr_list_values);
>  void
>  cfs_expr_list_free(struct cfs_expr_list *expr_list)
>  {
> -	while (!list_empty(&expr_list->el_exprs)) {
> -		struct cfs_range_expr *expr;
> +	struct cfs_range_expr *expr;
>  
> -		expr = list_entry(expr_list->el_exprs.next,
> -				  struct cfs_range_expr, re_link);
> +	while ((expr = list_first_entry_or_null(&expr_list->el_exprs,
> +						struct cfs_range_expr,
> +						re_link)) != NULL) {
>  		list_del(&expr->re_link);
>  		kfree(expr);
>  	}
> @@ -553,8 +553,8 @@ cfs_expr_list_free_list(struct list_head *list)
>  {
>  	struct cfs_expr_list *el;
>  
> -	while (!list_empty(list)) {
> -		el = list_entry(list->next, struct cfs_expr_list, el_link);
> +	while ((el = list_first_entry_or_null(list, struct cfs_expr_list,
> +					      el_link)) != NULL) {
>  		list_del(&el->el_link);
>  		cfs_expr_list_free(el);
>  	}
> diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c
> index d9bcfa8c92ae..af0d2aa3b6e8 100644
> --- a/drivers/staging/lustre/lnet/selftest/conrpc.c
> +++ b/drivers/staging/lustre/lnet/selftest/conrpc.c
> @@ -1362,9 +1362,8 @@ lstcon_rpc_cleanup_wait(void)
>  
>  	spin_unlock(&console_session.ses_rpc_lock);
>  
> -	while (!list_empty(&zlist)) {
> -		crpc = list_entry(zlist.next, struct lstcon_rpc, crp_link);
> -
> +	while ((crpc = list_first_entry_or_null(&zlist, struct lstcon_rpc,
> +					       crp_link)) != NULL) {
>  		list_del(&crpc->crp_link);
>  		kfree(crpc);
>  	}
> diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c
> index 045d79f44321..abc342c6a842 100644
> --- a/drivers/staging/lustre/lnet/selftest/console.c
> +++ b/drivers/staging/lustre/lnet/selftest/console.c
> @@ -330,11 +330,10 @@ lstcon_group_move(struct lstcon_group *old, struct lstcon_group *new)
>  {
>  	struct lstcon_ndlink *ndl;
>  
> -	while (!list_empty(&old->grp_ndl_list)) {
> -		ndl = list_entry(old->grp_ndl_list.next,
> -				 struct lstcon_ndlink, ndl_link);
> +	while ((ndl = list_first_entry_or_null(&old->grp_ndl_list,
> +					       struct lstcon_ndlink,
> +					       ndl_link)) != NULL)
>  		lstcon_group_ndlink_move(old, new, ndl);
> -	}
>  }
>  
>  static int
> @@ -1095,9 +1094,9 @@ lstcon_batch_destroy(struct lstcon_batch *bat)
>  
>  	list_del(&bat->bat_link);
>  
> -	while (!list_empty(&bat->bat_test_list)) {
> -		test = list_entry(bat->bat_test_list.next,
> -				  struct lstcon_test, tes_link);
> +	while ((test = list_first_entry_or_null(&bat->bat_test_list,
> +						struct lstcon_test,
> +						tes_link)) != NULL) {
>  		LASSERT(list_empty(&test->tes_trans_list));
>  
>  		list_del(&test->tes_link);
> @@ -1110,17 +1109,17 @@ lstcon_batch_destroy(struct lstcon_batch *bat)
>  
>  	LASSERT(list_empty(&bat->bat_trans_list));
>  
> -	while (!list_empty(&bat->bat_cli_list)) {
> -		ndl = list_entry(bat->bat_cli_list.next,
> -				 struct lstcon_ndlink, ndl_link);
> +	while ((ndl = list_first_entry_or_null(&bat->bat_cli_list,
> +					       struct lstcon_ndlink,
> +					       ndl_link)) != NULL) {
>  		list_del_init(&ndl->ndl_link);
>  
>  		lstcon_ndlink_release(ndl);
>  	}
>  
> -	while (!list_empty(&bat->bat_srv_list)) {
> -		ndl = list_entry(bat->bat_srv_list.next,
> -				 struct lstcon_ndlink, ndl_link);
> +	while ((ndl = list_first_entry_or_null(&bat->bat_srv_list,
> +					       struct lstcon_ndlink,
> +					       ndl_link)) != NULL) {
>  		list_del_init(&ndl->ndl_link);
>  
>  		lstcon_ndlink_release(ndl);
> @@ -1844,17 +1843,15 @@ lstcon_session_end(void)
>  	console_session.ses_feats_updated = 0;
>  
>  	/* destroy all batches */
> -	while (!list_empty(&console_session.ses_bat_list)) {
> -		bat = list_entry(console_session.ses_bat_list.next,
> -				 struct lstcon_batch, bat_link);
> -
> +	while ((bat = list_first_entry_or_null(&console_session.ses_bat_list,
> +					       struct lstcon_batch,
> +					       bat_link)) != NULL)
>  		lstcon_batch_destroy(bat);
> -	}
>  
>  	/* destroy all groups */
> -	while (!list_empty(&console_session.ses_grp_list)) {
> -		grp = list_entry(console_session.ses_grp_list.next,
> -				 struct lstcon_group, grp_link);
> +	while ((grp = list_first_entry_or_null(&console_session.ses_grp_list,
> +					       struct lstcon_group,
> +					       grp_link)) != NULL) {
>  		LASSERT(grp->grp_ref == 1);
>  
>  		lstcon_group_decref(grp);
> diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c
> index a82efc394659..958f627580e7 100644
> --- a/drivers/staging/lustre/lnet/selftest/framework.c
> +++ b/drivers/staging/lustre/lnet/selftest/framework.c
> @@ -628,16 +628,16 @@ sfw_destroy_test_instance(struct sfw_test_instance *tsi)
>  	LASSERT(list_empty(&tsi->tsi_active_rpcs));
>  	LASSERT(!sfw_test_active(tsi));
>  
> -	while (!list_empty(&tsi->tsi_units)) {
> -		tsu = list_entry(tsi->tsi_units.next,
> -				 struct sfw_test_unit, tsu_list);
> +	while ((tsu = list_first_entry_or_null(&tsi->tsi_units,
> +					       struct sfw_test_unit,
> +					       tsu_list)) != NULL) {
>  		list_del(&tsu->tsu_list);
>  		kfree(tsu);
>  	}
>  
> -	while (!list_empty(&tsi->tsi_free_rpcs)) {
> -		rpc = list_entry(tsi->tsi_free_rpcs.next,
> -				 struct srpc_client_rpc, crpc_list);
> +	while ((rpc = list_first_entry_or_null(&tsi->tsi_free_rpcs,
> +					       struct srpc_client_rpc,
> +					       crpc_list)) != NULL) {
>  		list_del(&rpc->crpc_list);
>  		kfree(rpc);
>  	}
> @@ -655,9 +655,9 @@ sfw_destroy_batch(struct sfw_batch *tsb)
>  	LASSERT(!sfw_batch_active(tsb));
>  	LASSERT(list_empty(&tsb->bat_list));
>  
> -	while (!list_empty(&tsb->bat_tests)) {
> -		tsi = list_entry(tsb->bat_tests.next,
> -				 struct sfw_test_instance, tsi_list);
> +	while ((tsi = list_first_entry_or_null(&tsb->bat_tests,
> +					       struct sfw_test_instance,
> +					       tsi_list)) != NULL) {
>  		list_del_init(&tsi->tsi_list);
>  		sfw_destroy_test_instance(tsi);
>  	}
> @@ -673,9 +673,9 @@ sfw_destroy_session(struct sfw_session *sn)
>  	LASSERT(list_empty(&sn->sn_list));
>  	LASSERT(sn != sfw_data.fw_session);
>  
> -	while (!list_empty(&sn->sn_batches)) {
> -		batch = list_entry(sn->sn_batches.next,
> -				   struct sfw_batch, bat_list);
> +	while ((batch = list_first_entry_or_null(&sn->sn_batches,
> +						 struct sfw_batch,
> +						 bat_list)) != NULL) {
>  		list_del_init(&batch->bat_list);
>  		sfw_destroy_batch(batch);
>  	}
> @@ -1389,8 +1389,8 @@ sfw_create_rpc(struct lnet_process_id peer, int service,
>  	LASSERT(service <= SRPC_FRAMEWORK_SERVICE_MAX_ID);
>  
>  	if (!nbulkiov && !list_empty(&sfw_data.fw_zombie_rpcs)) {
> -		rpc = list_entry(sfw_data.fw_zombie_rpcs.next,
> -				 struct srpc_client_rpc, crpc_list);
> +		rpc = list_first_entry(&sfw_data.fw_zombie_rpcs,
> +				       struct srpc_client_rpc, crpc_list);
>  		list_del(&rpc->crpc_list);
>  
>  		srpc_init_client_rpc(rpc, peer, service, 0, 0,
> @@ -1722,6 +1722,7 @@ sfw_shutdown(void)
>  {
>  	struct srpc_service *sv;
>  	struct sfw_test_case	*tsc;
> +	struct srpc_client_rpc *rpc;
>  	int i;
>  
>  	spin_lock(&sfw_data.fw_lock);
> @@ -1757,11 +1758,9 @@ sfw_shutdown(void)
>  		srpc_remove_service(sv);
>  	}
>  
> -	while (!list_empty(&sfw_data.fw_zombie_rpcs)) {
> -		struct srpc_client_rpc *rpc;
> -
> -		rpc = list_entry(sfw_data.fw_zombie_rpcs.next,
> -				 struct srpc_client_rpc, crpc_list);
> +	while ((rpc = list_first_entry_or_null(&sfw_data.fw_zombie_rpcs,
> +					       struct srpc_client_rpc,
> +					       crpc_list)) != NULL) {
>  		list_del(&rpc->crpc_list);
>  
>  		kfree(rpc);
> @@ -1775,10 +1774,9 @@ sfw_shutdown(void)
>  		srpc_wait_service_shutdown(sv);
>  	}
>  
> -	while (!list_empty(&sfw_data.fw_tests)) {
> -		tsc = list_entry(sfw_data.fw_tests.next,
> -				 struct sfw_test_case, tsc_list);
> -
> +	while ((tsc = list_first_entry_or_null(&sfw_data.fw_tests,
> +					       struct sfw_test_case,
> +					       tsc_list)) != NULL) {
>  		srpc_wait_service_shutdown(tsc->tsc_srv_service);
>  
>  		list_del(&tsc->tsc_list);
> diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c
> index 2a3010774dbe..abb6f8fb011e 100644
> --- a/drivers/staging/lustre/lnet/selftest/rpc.c
> +++ b/drivers/staging/lustre/lnet/selftest/rpc.c
> @@ -210,9 +210,9 @@ srpc_service_fini(struct srpc_service *svc)
>  			else
>  				break;
>  
> -			while (!list_empty(q)) {
> -				buf = list_entry(q->next, struct srpc_buffer,
> -						 buf_list);
> +			while ((buf = list_first_entry_or_null(
> +					q, struct srpc_buffer,
> +					buf_list)) != NULL) {
>  				list_del(&buf->buf_list);
>  				kfree(buf);
>  			}
> @@ -220,10 +220,9 @@ srpc_service_fini(struct srpc_service *svc)
>  
>  		LASSERT(list_empty(&scd->scd_rpc_active));
>  
> -		while (!list_empty(&scd->scd_rpc_free)) {
> -			rpc = list_entry(scd->scd_rpc_free.next,
> -					 struct srpc_server_rpc,
> -					 srpc_list);
> +		while ((rpc = list_first_entry_or_null(&scd->scd_rpc_free,
> +						       struct srpc_server_rpc,
> +						       srpc_list)) != NULL) {
>  			list_del(&rpc->srpc_list);
>  			kfree(rpc);
>  		}
> @@ -674,8 +673,8 @@ srpc_finish_service(struct srpc_service *sv)
>  			continue;
>  		}
>  
> -		rpc = list_entry(scd->scd_rpc_active.next,
> -				 struct srpc_server_rpc, srpc_list);
> +		rpc = list_first_entry(&scd->scd_rpc_active,
> +				       struct srpc_server_rpc, srpc_list);
>  		CNETERR("Active RPC %p on shutdown: sv %s, peer %s, wi %s, ev fired %d type %d status %d lnet %d\n",
>  			rpc, sv->sv_name, libcfs_id2str(rpc->srpc_peer),
>  			swi_state2str(rpc->srpc_wi.swi_state),
> @@ -943,8 +942,8 @@ srpc_server_rpc_done(struct srpc_server_rpc *rpc, int status)
>  	LASSERT(rpc->srpc_ev.ev_fired);
>  
>  	if (!sv->sv_shuttingdown && !list_empty(&scd->scd_buf_blocked)) {
> -		buffer = list_entry(scd->scd_buf_blocked.next,
> -				    struct srpc_buffer, buf_list);
> +		buffer = list_first_entry(&scd->scd_buf_blocked,
> +					  struct srpc_buffer, buf_list);
>  		list_del(&buffer->buf_list);
>  
>  		srpc_init_server_rpc(rpc, scd, buffer);
> @@ -1535,9 +1534,9 @@ srpc_lnet_ev_handler(struct lnet_event *ev)
>  		}
>  
>  		if (!list_empty(&scd->scd_rpc_free)) {
> -			srpc = list_entry(scd->scd_rpc_free.next,
> -					  struct srpc_server_rpc,
> -					  srpc_list);
> +			srpc = list_first_entry(&scd->scd_rpc_free,
> +						struct srpc_server_rpc,
> +						srpc_list);
>  			list_del(&srpc->srpc_list);
>  
>  			srpc_init_server_rpc(srpc, scd, buffer);
> diff --git a/drivers/staging/lustre/lnet/selftest/timer.c b/drivers/staging/lustre/lnet/selftest/timer.c
> index c83473ebb368..bb61e3aa11e9 100644
> --- a/drivers/staging/lustre/lnet/selftest/timer.c
> +++ b/drivers/staging/lustre/lnet/selftest/timer.c
> @@ -125,8 +125,8 @@ stt_expire_list(struct list_head *slot, time64_t now)
>  	int expired = 0;
>  	struct stt_timer *timer;
>  
> -	while (!list_empty(slot)) {
> -		timer = list_entry(slot->next, struct stt_timer, stt_list);
> +	while ((timer = list_first_entry_or_null(slot, struct stt_timer,
> +						 stt_list)) != NULL) {
>  
>  		if (timer->stt_expires > now)
>  			break;
> 
> 
> 

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

* [lustre-devel] [PATCH 09/21] lustre: use list_last_entry() throughout
  2019-02-07  0:03 ` [lustre-devel] [PATCH 09/21] lustre: use list_last_entry() throughout NeilBrown
  2019-02-08  1:07   ` Andreas Dilger
@ 2019-02-11  1:48   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: James Simmons @ 2019-02-11  1:48 UTC (permalink / raw)
  To: lustre-devel


> Convert
>   list_entry(foo->prev .....)
> to
>   list_last_entry(foo, ....)
> 
> throughout lustre.

Reviewed-by: James Simmons <jsimmons@infradead.org>
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/include/cl_object.h |    2 +-
>  drivers/staging/lustre/lustre/ptlrpc/client.c     |    6 +++---
>  drivers/staging/lustre/lustre/ptlrpc/service.c    |    5 +++--
>  3 files changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
> index 53fd8d469e55..bf7678aed6bf 100644
> --- a/drivers/staging/lustre/lustre/include/cl_object.h
> +++ b/drivers/staging/lustre/lustre/include/cl_object.h
> @@ -2329,7 +2329,7 @@ do {									\
>  static inline struct cl_page *cl_page_list_last(struct cl_page_list *plist)
>  {
>  	LASSERT(plist->pl_nr > 0);
> -	return list_entry(plist->pl_pages.prev, struct cl_page, cp_batch);
> +	return list_last_entry(&plist->pl_pages, struct cl_page, cp_batch);
>  }
>  
>  static inline struct cl_page *cl_page_list_first(struct cl_page_list *plist)
> diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
> index a78d49621c42..b2b11047ea19 100644
> --- a/drivers/staging/lustre/lustre/ptlrpc/client.c
> +++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
> @@ -1464,9 +1464,9 @@ static int after_reply(struct ptlrpc_request *req)
>  		if (!list_empty(&imp->imp_replay_list)) {
>  			struct ptlrpc_request *last;
>  
> -			last = list_entry(imp->imp_replay_list.prev,
> -					  struct ptlrpc_request,
> -					  rq_replay_list);
> +			last = list_last_entry(&imp->imp_replay_list,
> +					       struct ptlrpc_request,
> +					       rq_replay_list);
>  			/*
>  			 * Requests with rq_replay stay on the list even if no
>  			 * commit is expected.
> diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
> index a69736dfe8b7..35a59e5a5e9d 100644
> --- a/drivers/staging/lustre/lustre/ptlrpc/service.c
> +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
> @@ -2255,8 +2255,9 @@ static int ptlrpc_hr_main(void *arg)
>  		while (!list_empty(&replies)) {
>  			struct ptlrpc_reply_state *rs;
>  
> -			rs = list_entry(replies.prev, struct ptlrpc_reply_state,
> -					rs_list);
> +			rs = list_last_entry(&replies,
> +					     struct ptlrpc_reply_state,
> +					     rs_list);
>  			list_del_init(&rs->rs_list);
>  			ptlrpc_handle_rs(rs);
>  		}
> 
> 
> 

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

* [lustre-devel] [PATCH 10/21] lustre: obdclass: use cl_object_for_each where appropriate
  2019-02-07  0:03 ` [lustre-devel] [PATCH 10/21] lustre: obdclass: use cl_object_for_each where appropriate NeilBrown
  2019-02-08  1:10   ` Andreas Dilger
@ 2019-02-11  1:57   ` James Simmons
  2019-02-11  3:19     ` NeilBrown
  1 sibling, 1 reply; 87+ messages in thread
From: James Simmons @ 2019-02-11  1:57 UTC (permalink / raw)
  To: lustre-devel


> There are various places which have a list_for_each_entry()
> where cl_object_for_each (or .._reverse) is more appropriate.
> 
> Several of these re-use the 'obj' function parameter as a loop
> iterator, which is a little confusing.
> 
> Change these to use cl_object_for_each{_reverse}, and where needed,
> introduce a new iterator variable 'o'.

Surprised the reverse wasn't done in that the cl_* macro was
removed :-) 

Reviewed-by: James Simmons <jsimmons@infradead.org>
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/lov/lov_page.c       |    3 -
>  drivers/staging/lustre/lustre/obdclass/cl_lock.c   |    3 -
>  drivers/staging/lustre/lustre/obdclass/cl_object.c |   82 +++++++++-----------
>  drivers/staging/lustre/lustre/obdclass/cl_page.c   |   11 +--
>  4 files changed, 44 insertions(+), 55 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/lov/lov_page.c b/drivers/staging/lustre/lustre/lov/lov_page.c
> index 08485a95ec01..e64b350601d2 100644
> --- a/drivers/staging/lustre/lustre/lov/lov_page.c
> +++ b/drivers/staging/lustre/lustre/lov/lov_page.c
> @@ -103,8 +103,7 @@ int lov_page_init_composite(const struct lu_env *env, struct cl_object *obj,
>  		return PTR_ERR(sub);
>  
>  	subobj = lovsub2cl(r0->lo_sub[stripe]);
> -	list_for_each_entry(o, &subobj->co_lu.lo_header->loh_layers,
> -			    co_lu.lo_linkage) {
> +	cl_object_for_each(o, subobj) {
>  		if (o->co_ops->coo_page_init) {
>  			rc = o->co_ops->coo_page_init(sub->sub_env, o, page,
>  						      cl_index(subobj, suboff));
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
> index 8133d992cc73..fc5976d8b37b 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
> @@ -103,8 +103,7 @@ int cl_lock_init(const struct lu_env *env, struct cl_lock *lock,
>  	LASSERT(obj);
>  
>  	INIT_LIST_HEAD(&lock->cll_layers);
> -	list_for_each_entry(scan, &obj->co_lu.lo_header->loh_layers,
> -			    co_lu.lo_linkage) {
> +	cl_object_for_each(scan, obj) {
>  		result = scan->co_ops->coo_lock_init(env, scan, lock, io);
>  		if (result != 0) {
>  			cl_lock_fini(env, lock);
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> index f724b2d62df1..d71a680660da 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> @@ -190,16 +190,15 @@ EXPORT_SYMBOL(cl_object_attr_unlock);
>  int cl_object_attr_get(const struct lu_env *env, struct cl_object *obj,
>  		       struct cl_attr *attr)
>  {
> -	struct lu_object_header *top;
> +	struct cl_object *o;
>  	int result;
>  
>  	assert_spin_locked(cl_object_attr_guard(obj));
>  
> -	top = obj->co_lu.lo_header;
>  	result = 0;
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_attr_get) {
> -			result = obj->co_ops->coo_attr_get(env, obj, attr);
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_attr_get) {
> +			result = o->co_ops->coo_attr_get(env, o, attr);
>  			if (result != 0) {
>  				if (result > 0)
>  					result = 0;
> @@ -221,17 +220,16 @@ EXPORT_SYMBOL(cl_object_attr_get);
>  int cl_object_attr_update(const struct lu_env *env, struct cl_object *obj,
>  			  const struct cl_attr *attr, unsigned int v)
>  {
> -	struct lu_object_header *top;
> +	struct cl_object *o;
>  	int result;
>  
>  	assert_spin_locked(cl_object_attr_guard(obj));
>  
> -	top = obj->co_lu.lo_header;
>  	result = 0;
> -	list_for_each_entry_reverse(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_attr_update) {
> -			result = obj->co_ops->coo_attr_update(env, obj, attr,
> -							      v);
> +	cl_object_for_each_reverse(o, obj) {
> +		if (o->co_ops->coo_attr_update) {
> +			result = o->co_ops->coo_attr_update(env, o, attr,
> +							    v);
>  			if (result != 0) {
>  				if (result > 0)
>  					result = 0;
> @@ -254,19 +252,18 @@ EXPORT_SYMBOL(cl_object_attr_update);
>  int cl_object_glimpse(const struct lu_env *env, struct cl_object *obj,
>  		      struct ost_lvb *lvb)
>  {
> -	struct lu_object_header *top;
> +	struct cl_object *o;
>  	int result;
>  
> -	top = obj->co_lu.lo_header;
>  	result = 0;
> -	list_for_each_entry_reverse(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_glimpse) {
> -			result = obj->co_ops->coo_glimpse(env, obj, lvb);
> +	cl_object_for_each_reverse(o, obj) {
> +		if (o->co_ops->coo_glimpse) {
> +			result = o->co_ops->coo_glimpse(env, o, lvb);
>  			if (result != 0)
>  				break;
>  		}
>  	}
> -	LU_OBJECT_HEADER(D_DLMTRACE, env, lu_object_top(top),
> +	LU_OBJECT_HEADER(D_DLMTRACE, env, lu_object_top(obj->co_lu.lo_header),
>  			 "size: %llu mtime: %llu atime: %llu ctime: %llu blocks: %llu\n",
>  			 lvb->lvb_size, lvb->lvb_mtime, lvb->lvb_atime,
>  			 lvb->lvb_ctime, lvb->lvb_blocks);
> @@ -280,14 +277,13 @@ EXPORT_SYMBOL(cl_object_glimpse);
>  int cl_conf_set(const struct lu_env *env, struct cl_object *obj,
>  		const struct cl_object_conf *conf)
>  {
> -	struct lu_object_header *top;
> +	struct cl_object *o;
>  	int result;
>  
> -	top = obj->co_lu.lo_header;
>  	result = 0;
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_conf_set) {
> -			result = obj->co_ops->coo_conf_set(env, obj, conf);
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_conf_set) {
> +			result = o->co_ops->coo_conf_set(env, o, conf);
>  			if (result != 0)
>  				break;
>  		}
> @@ -301,13 +297,11 @@ EXPORT_SYMBOL(cl_conf_set);
>   */
>  int cl_object_prune(const struct lu_env *env, struct cl_object *obj)
>  {
> -	struct lu_object_header *top;
>  	struct cl_object *o;
>  	int result;
>  
> -	top = obj->co_lu.lo_header;
>  	result = 0;
> -	list_for_each_entry(o, &top->loh_layers, co_lu.lo_linkage) {
> +	cl_object_for_each(o, obj) {
>  		if (o->co_ops->coo_prune) {
>  			result = o->co_ops->coo_prune(env, o);
>  			if (result != 0)
> @@ -325,14 +319,13 @@ EXPORT_SYMBOL(cl_object_prune);
>  int cl_object_getstripe(const struct lu_env *env, struct cl_object *obj,
>  			struct lov_user_md __user *uarg, size_t size)
>  {
> -	struct lu_object_header *top;
> +	struct cl_object *o;
>  	int result = 0;
>  
> -	top = obj->co_lu.lo_header;
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_getstripe) {
> -			result = obj->co_ops->coo_getstripe(env, obj, uarg,
> -							    size);
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_getstripe) {
> +			result = o->co_ops->coo_getstripe(env, o, uarg,
> +							  size);
>  			if (result)
>  				break;
>  		}
> @@ -357,14 +350,13 @@ int cl_object_fiemap(const struct lu_env *env, struct cl_object *obj,
>  		     struct ll_fiemap_info_key *key,
>  		     struct fiemap *fiemap, size_t *buflen)
>  {
> -	struct lu_object_header *top;
> +	struct cl_object *o;
>  	int result = 0;
>  
> -	top = obj->co_lu.lo_header;
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_fiemap) {
> -			result = obj->co_ops->coo_fiemap(env, obj, key, fiemap,
> -							 buflen);
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_fiemap) {
> +			result = o->co_ops->coo_fiemap(env, o, key, fiemap,
> +						       buflen);
>  			if (result)
>  				break;
>  		}
> @@ -376,11 +368,11 @@ EXPORT_SYMBOL(cl_object_fiemap);
>  int cl_object_layout_get(const struct lu_env *env, struct cl_object *obj,
>  			 struct cl_layout *cl)
>  {
> -	struct lu_object_header *top = obj->co_lu.lo_header;
> +	struct cl_object *o;
>  
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_layout_get)
> -			return obj->co_ops->coo_layout_get(env, obj, cl);
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_layout_get)
> +			return o->co_ops->coo_layout_get(env, o, cl);
>  	}
>  
>  	return -EOPNOTSUPP;
> @@ -389,12 +381,12 @@ EXPORT_SYMBOL(cl_object_layout_get);
>  
>  loff_t cl_object_maxbytes(struct cl_object *obj)
>  {
> -	struct lu_object_header *top = obj->co_lu.lo_header;
> +	struct cl_object *o;
>  	loff_t maxbytes = LLONG_MAX;
>  
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_maxbytes)
> -			maxbytes = min_t(loff_t, obj->co_ops->coo_maxbytes(obj),
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_maxbytes)
> +			maxbytes = min_t(loff_t, o->co_ops->coo_maxbytes(o),
>  					 maxbytes);
>  	}
>  
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
> index 057318deaa4e..7d00a9233a3b 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
> @@ -132,7 +132,7 @@ struct cl_page *cl_page_alloc(const struct lu_env *env,
>  			      enum cl_page_type type)
>  {
>  	struct cl_page *page;
> -	struct lu_object_header *head;
> +	struct cl_object *o2;
>  
>  	page = kzalloc(cl_object_header(o)->coh_page_bufsize, GFP_NOFS);
>  	if (page) {
> @@ -149,11 +149,10 @@ struct cl_page *cl_page_alloc(const struct lu_env *env,
>  		INIT_LIST_HEAD(&page->cp_layers);
>  		INIT_LIST_HEAD(&page->cp_batch);
>  		lu_ref_init(&page->cp_reference);
> -		head = o->co_lu.lo_header;
> -		list_for_each_entry(o, &head->loh_layers, co_lu.lo_linkage) {
> -			if (o->co_ops->coo_page_init) {
> -				result = o->co_ops->coo_page_init(env, o, page,
> -								  ind);
> +		cl_object_for_each(o2, o) {
> +			if (o2->co_ops->coo_page_init) {
> +				result = o2->co_ops->coo_page_init(env, o2, page,
> +								   ind);
>  				if (result != 0) {
>  					__cl_page_delete(env, page);
>  					cl_page_free(env, page);
> 
> 
> 

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

* [lustre-devel] [PATCH 11/21] lustre: cl_object: remove vestigial debugging.
  2019-02-07  0:03 ` [lustre-devel] [PATCH 11/21] lustre: cl_object: remove vestigial debugging NeilBrown
  2019-02-08  1:31   ` Andreas Dilger
@ 2019-02-11  2:04   ` James Simmons
  2019-02-11  3:25     ` NeilBrown
  1 sibling, 1 reply; 87+ messages in thread
From: James Simmons @ 2019-02-11  2:04 UTC (permalink / raw)
  To: lustre-devel


> cl_env_inc() and cl_env_dec() don't do anything,
> so discard them.

I don't know about this one. I saw Andreas response as well. 
So this was apart of "LU-744 obdclass: revise stats for cl_object cache"
In the end it was turned off by default in the OpenSFS branch since it
made performance take a hit. To enable in OpenSFS branch you have to run
./configure --enable-pgstate-track. We have a few like this for Lustre so
I was going to bring this up. Do we want to remove this work for both the
upstream client as well as OpenSFS tree or properly implement this by
making it a Kconfig option when CONFIG_LUSTRE_DEBUG_EXPENSIVE_CHECK is
enabled? Its just a matter of porting OpenSFS commit 
5cae09a2409dcd396a1ee7be1eca7d3bbf77365e

What do you think?

> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/obdclass/cl_object.c |   15 ---------------
>  1 file changed, 15 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> index d71a680660da..1e704078664e 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> @@ -565,14 +565,6 @@ struct cl_env {
>  	void		       *ce_debug;
>  };
>  
> -static void cl_env_inc(enum cache_stats_item item)
> -{
> -}
> -
> -static void cl_env_dec(enum cache_stats_item item)
> -{
> -}
> -
>  static void cl_env_init0(struct cl_env *cle, void *debug)
>  {
>  	LASSERT(cle->ce_ref == 0);
> @@ -581,7 +573,6 @@ static void cl_env_init0(struct cl_env *cle, void *debug)
>  
>  	cle->ce_ref = 1;
>  	cle->ce_debug = debug;
> -	cl_env_inc(CS_busy);
>  }
>  
>  static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
> @@ -611,9 +602,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
>  		if (rc != 0) {
>  			kmem_cache_free(cl_env_kmem, cle);
>  			env = ERR_PTR(rc);
> -		} else {
> -			cl_env_inc(CS_create);
> -			cl_env_inc(CS_total);
>  		}
>  	} else {
>  		env = ERR_PTR(-ENOMEM);
> @@ -623,7 +611,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
>  
>  static void cl_env_fini(struct cl_env *cle)
>  {
> -	cl_env_dec(CS_total);
>  	lu_context_fini(&cle->ce_lu.le_ctx);
>  	lu_context_fini(&cle->ce_ses);
>  	kmem_cache_free(cl_env_kmem, cle);
> @@ -782,7 +769,6 @@ void cl_env_put(struct lu_env *env, u16 *refcheck)
>  	if (--cle->ce_ref == 0) {
>  		int cpu = get_cpu();
>  
> -		cl_env_dec(CS_busy);
>  		cle->ce_debug = NULL;
>  		cl_env_exit(cle);
>  		/*
> @@ -903,7 +889,6 @@ void cl_env_percpu_put(struct lu_env *env)
>  	cle->ce_ref--;
>  	LASSERT(cle->ce_ref == 0);
>  
> -	cl_env_dec(CS_busy);
>  	cle->ce_debug = NULL;
>  
>  	put_cpu();
> 
> 
> 

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

* [lustre-devel] [PATCH 05/21] lustre: use list_first_entry() in lustre subdirectory.
  2019-02-11  1:45   ` James Simmons
@ 2019-02-11  3:08     ` NeilBrown
  0 siblings, 0 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-11  3:08 UTC (permalink / raw)
  To: lustre-devel

On Mon, Feb 11 2019, James Simmons wrote:

>> Convert
>>   list_entry(foo->next .....)
>> to
>>   list_first_entry(foo, ....)
>> 
>> in 'lustre'
>> 
>> In several cases the call is combined with
>> a list_empty() test and list_first_entry_or_null() is used
>
> Nak. One of the changes below breaks things.
>
>> Signed-off-by: NeilBrown <neilb@suse.com>
>> ---
>>  drivers/staging/lustre/lustre/include/cl_object.h  |    2 -
>>  drivers/staging/lustre/lustre/llite/statahead.c    |   23 ++++----
>>  drivers/staging/lustre/lustre/lov/lov_io.c         |    9 +--
>>  drivers/staging/lustre/lustre/obdclass/cl_page.c   |    9 +--
>>  drivers/staging/lustre/lustre/obdclass/genops.c    |   22 ++++---
>>  .../staging/lustre/lustre/obdclass/lustre_peer.c   |    5 +-
>>  drivers/staging/lustre/lustre/osc/osc_cache.c      |   17 +++---
>>  drivers/staging/lustre/lustre/osc/osc_lock.c       |    5 +-
>>  drivers/staging/lustre/lustre/osc/osc_page.c       |   17 +++---
>>  drivers/staging/lustre/lustre/osc/osc_request.c    |    8 +--
>>  drivers/staging/lustre/lustre/ptlrpc/client.c      |    8 +--
>>  drivers/staging/lustre/lustre/ptlrpc/nrs_fifo.c    |    6 +-
>>  .../staging/lustre/lustre/ptlrpc/pack_generic.c    |    4 +
>>  drivers/staging/lustre/lustre/ptlrpc/sec_gc.c      |    6 +-
>>  drivers/staging/lustre/lustre/ptlrpc/service.c     |   59 ++++++++++----------
>>  15 files changed, 101 insertions(+), 99 deletions(-)
>> 
>> diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
>> index 13d79810dd39..53fd8d469e55 100644
>> --- a/drivers/staging/lustre/lustre/include/cl_object.h
>> +++ b/drivers/staging/lustre/lustre/include/cl_object.h
>> @@ -2335,7 +2335,7 @@ static inline struct cl_page *cl_page_list_last(struct cl_page_list *plist)
>>  static inline struct cl_page *cl_page_list_first(struct cl_page_list *plist)
>>  {
>>  	LASSERT(plist->pl_nr > 0);
>> -	return list_entry(plist->pl_pages.next, struct cl_page, cp_batch);
>> +	return list_first_entry(&plist->pl_pages, struct cl_page, cp_batch);
>>  }
>>  
>>  /**
>
> ...
>
>> diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
>> index 5b97f2a1fea1..a69736dfe8b7 100644
>> --- a/drivers/staging/lustre/lustre/ptlrpc/service.c
>> +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
>> @@ -299,9 +299,9 @@ ptlrpc_server_post_idle_rqbds(struct ptlrpc_service_part *svcpt)
>>  			return posted;
>>  		}
>>  
>> -		rqbd = list_entry(svcpt->scp_rqbd_idle.next,
>> -				  struct ptlrpc_request_buffer_desc,
>> -				  rqbd_list);
>> +		rqbd = list_first_entry(&svcpt->scp_rqbd_idle,
>> +					struct ptlrpc_request_buffer_desc,
>> +					rqbd_list);
>>  		list_del(&rqbd->rqbd_list);
>>  
>>  		/* assume we will post successfully */
>> @@ -769,9 +769,9 @@ static void ptlrpc_server_drop_request(struct ptlrpc_request *req)
>>  		 * I expect only about 1 or 2 rqbds need to be recycled here
>>  		 */
>>  		while (svcpt->scp_hist_nrqbds > svc->srv_hist_nrqbds_cpt_max) {
>> -			rqbd = list_entry(svcpt->scp_hist_rqbds.next,
>> -					  struct ptlrpc_request_buffer_desc,
>> -					  rqbd_list);
>> +			rqbd = list_first_entry(&svcpt->scp_hist_rqbds,
>> +						struct ptlrpc_request_buffer_desc,
>> +						rqbd_list);
>>  
>>  			list_del(&rqbd->rqbd_list);
>>  			svcpt->scp_hist_nrqbds--;
>> @@ -1240,9 +1240,9 @@ static void ptlrpc_at_check_timed(struct ptlrpc_service_part *svcpt)
>>  	/* we took additional refcount so entries can't be deleted from list, no
>>  	 * locking is needed
>>  	 */
>> -	while (!list_empty(&work_list)) {
>> -		rq = list_entry(work_list.next, struct ptlrpc_request,
>> -				rq_timed_list);
>> +	while ((rq = list_first_entry_or_null(&work_list,
>> +					      struct ptlrpc_request,
>> +					      rq_timed_list)) != NULL) {
>>  		list_del_init(&rq->rq_timed_list);
>>  
>>  		if (ptlrpc_at_send_early_reply(rq) == 0)
>> @@ -1485,8 +1485,8 @@ ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt,
>>  		return 0;
>>  	}
>>  
>> -	req = list_entry(svcpt->scp_req_incoming.next,
>> -			 struct ptlrpc_request, rq_list);
>> +	req = list_first_entry(&svcpt->scp_req_incoming,
>> +			       struct ptlrpc_request, rq_list);
>>  	list_del_init(&req->rq_list);
>>  	svcpt->scp_nreqs_incoming--;
>>  	/* Consider this still a "queued" request as far as stats are
>> @@ -2345,9 +2345,9 @@ static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt)
>>  
>>  	wake_up_all(&svcpt->scp_waitq);
>>  
>> -	while (!list_empty(&svcpt->scp_threads)) {
>> -		thread = list_entry(svcpt->scp_threads.next,
>> -				    struct ptlrpc_thread, t_link);
>> +	while ((thread = list_first_entry_or_null(&svcpt->scp_threads,
>> +						  struct ptlrpc_thread,
>> +						  t_link)) != NULL) {
>>  		if (thread_is_stopped(thread)) {
>>  			list_del(&thread->t_link);
>>  			list_add(&thread->t_link, &zombie);
>> @@ -2365,9 +2365,9 @@ static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt)
>>  
>>  	spin_unlock(&svcpt->scp_lock);
>>  
>> -	while (!list_empty(&zombie)) {
>> -		thread = list_entry(zombie.next,
>> -				    struct ptlrpc_thread, t_link);
>> +	while ((thread = list_first_entry(&zombie,
>> +					  struct ptlrpc_thread,
>> +					  t_link)) != NULL) {
>>  		list_del(&thread->t_link);
>>  		kfree(thread);
>>  	}
>
> The above change causes sanity tests 77j: client only supporting ADLER32
> to fail with:
>
> 2019-02-07 18:38:26 [ 4346.464550] Lustre: Unmounted lustre-client
> 2019-02-07 18:38:26 [ 4346.471990] BUG: unable to handle kernel paging 
> request at ffffeb02001c89c8
> 2019-02-07 18:38:26 [ 4346.480489] #PF error: [normal kernel read fault]
> 2019-02-07 18:38:26 [ 4346.486719] PGD 0 P4D 0
> 2019-02-07 18:38:26 [ 4346.490758] Oops: 0000 [#1] PREEMPT SMP PTI
> 2019-02-07 18:38:26 [ 4346.496420] CPU: 0 PID: 2478 Comm: kworker/0:1 
> Tainted: G        WC        5.0.0-rc4+ #1
> 2019-02-07 18:38:26 [ 4346.505976] Hardware name: Supermicro 
> SYS-6028TR-HTFR/X10DRT-HIBF, BIOS 2.0b 08/12/2016
> 2019-02-07 18:38:26 [ 4346.515461] Workqueue: obd_zombid 
> obd_zombie_imp_cull [obdclass]
> 2019-02-07 18:38:26 [ 4346.522917] RIP: 0010:kfree+0x52/0x1b0
>

Thanks so much for testing and finding this.
The above should, of course, be

>> +	while ((thread = list_first_entry_or_null(&zombie,
>> +					  struct ptlrpc_thread,
>> +					  t_link)) != NULL) {

(with _or_null).  I've fixed it in my tree.

Thanks,
NeilBrown
-------------- 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/20190211/423431a2/attachment-0001.sig>

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

* [lustre-devel] [PATCH 04/21] lustre: use list*entry macros in place of container_of()
  2019-02-11  1:32   ` James Simmons
@ 2019-02-11  3:14     ` NeilBrown
  0 siblings, 0 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-11  3:14 UTC (permalink / raw)
  To: lustre-devel

On Mon, Feb 11 2019, James Simmons wrote:

>> There are a number of places that use container_of() but where
>> list_first_entry(), or list_last_entry() make the meaning more clear.
>> So change them over.
>
> I have to say normally the patches you see genernally use the basic
> functionality of the linux list implementation. I wonder if a deep
> dive on LUG's developers day would be a good idea.

It is possible to take the "new macro for subtly different case"
exercise too far, though in this particular case, I think using
replacing container_of with list_entry is a clear win.

Maybe a broader discussion would help

>
> Reviewed-by: James Simmons <jsimmons@infradead.org>

Thanks,
NeilBrown

>  
>> Signed-off-by: NeilBrown <neilb@suse.com>
>> ---
>>  drivers/staging/lustre/lustre/ldlm/ldlm_resource.c |    4 ++--
>>  drivers/staging/lustre/lustre/obdclass/cl_io.c     |    4 ++--
>>  drivers/staging/lustre/lustre/obdclass/cl_object.c |   13 ++++++++-----
>>  drivers/staging/lustre/lustre/obdclass/cl_page.c   |    4 ++--
>>  drivers/staging/lustre/lustre/obdclass/lu_object.c |    7 +++----
>>  5 files changed, 17 insertions(+), 15 deletions(-)
>> 
>> diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
>> index 85c5047f4ba2..74c7644d6ef8 100644
>> --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
>> +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
>> @@ -987,8 +987,8 @@ struct ldlm_namespace *ldlm_namespace_first_locked(enum ldlm_side client)
>>  {
>>  	LASSERT(mutex_is_locked(ldlm_namespace_lock(client)));
>>  	LASSERT(!list_empty(ldlm_namespace_list(client)));
>> -	return container_of(ldlm_namespace_list(client)->next,
>> -		struct ldlm_namespace, ns_list_chain);
>> +	return list_first_entry(ldlm_namespace_list(client),
>> +				struct ldlm_namespace, ns_list_chain);
>>  }
>>  
>>  /** Create and initialize new resource. */
>> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
>> index 7bf02350f19d..34b4e63e7d1a 100644
>> --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
>> +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
>> @@ -93,8 +93,8 @@ void cl_io_fini(const struct lu_env *env, struct cl_io *io)
>>  	LINVRNT(cl_io_invariant(io));
>>  
>>  	while (!list_empty(&io->ci_layers)) {
>> -		slice = container_of(io->ci_layers.prev, struct cl_io_slice,
>> -				     cis_linkage);
>> +		slice = list_last_entry(&io->ci_layers, struct cl_io_slice,
>> +					cis_linkage);
>>  		list_del_init(&slice->cis_linkage);
>>  		if (slice->cis_iop->op[io->ci_type].cio_fini)
>>  			slice->cis_iop->op[io->ci_type].cio_fini(env, slice);
>> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> index 05d784ae7a6c..f724b2d62df1 100644
>> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> @@ -649,8 +649,8 @@ static struct lu_env *cl_env_obtain(void *debug)
>>  	if (cl_envs[cpu].cec_count > 0) {
>>  		int rc;
>>  
>> -		cle = container_of(cl_envs[cpu].cec_envs.next, struct cl_env,
>> -				   ce_linkage);
>> +		cle = list_first_entry(&cl_envs[cpu].cec_envs, struct cl_env,
>> +				       ce_linkage);
>>  		list_del_init(&cle->ce_linkage);
>>  		cl_envs[cpu].cec_count--;
>>  		read_unlock(&cl_envs[cpu].cec_guard);
>> @@ -748,9 +748,12 @@ unsigned int cl_env_cache_purge(unsigned int nr)
>>  
>>  	for_each_possible_cpu(i) {
>>  		write_lock(&cl_envs[i].cec_guard);
>> -		for (; !list_empty(&cl_envs[i].cec_envs) && nr > 0; --nr) {
>> -			cle = container_of(cl_envs[i].cec_envs.next,
>> -					   struct cl_env, ce_linkage);
>> +		for (; nr >0 &&
>> +			     (cle = list_first_entry_or_null(
>> +				     &cl_envs[i].cec_envs,
>> +				     struct cl_env,
>> +				     ce_linkage)) != NULL;
>> +		     --nr) {
>>  			list_del_init(&cle->ce_linkage);
>>  			LASSERT(cl_envs[i].cec_count > 0);
>>  			cl_envs[i].cec_count--;
>> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
>> index b1b4dc7ea22f..d025ea55818f 100644
>> --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
>> +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
>> @@ -690,8 +690,8 @@ int cl_page_is_vmlocked(const struct lu_env *env, const struct cl_page *pg)
>>  	const struct cl_page_slice *slice;
>>  	int result;
>>  
>> -	slice = container_of(pg->cp_layers.next,
>> -			     const struct cl_page_slice, cpl_linkage);
>> +	slice = list_first_entry(&pg->cp_layers,
>> +				 const struct cl_page_slice, cpl_linkage);
>>  	PASSERT(env, pg, slice->cpl_ops->cpo_is_vmlocked);
>>  	/*
>>  	 * Call ->cpo_is_vmlocked() directly instead of going through
>> diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c
>> index 3bd48748f46c..639c298b6a90 100644
>> --- a/drivers/staging/lustre/lustre/obdclass/lu_object.c
>> +++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c
>> @@ -349,7 +349,7 @@ static void lu_object_free(const struct lu_env *env, struct lu_object *o)
>>  		 * lives as long as possible and ->loo_object_free() methods
>>  		 * can look at its contents.
>>  		 */
>> -		o = container_of(splice.prev, struct lu_object, lo_linkage);
>> +		o = list_last_entry(&splice, struct lu_object, lo_linkage);
>>  		list_del_init(&o->lo_linkage);
>>  		o->lo_ops->loo_object_free(env, o);
>>  	}
>> @@ -432,9 +432,8 @@ int lu_site_purge_objects(const struct lu_env *env, struct lu_site *s,
>>  		 * Free everything on the dispose list. This is safe against
>>  		 * races due to the reasons described in lu_object_put().
>>  		 */
>> -		while (!list_empty(&dispose)) {
>> -			h = container_of(dispose.next,
>> -					 struct lu_object_header, loh_lru);
>> +		while ((h = list_first_entry_or_null(
>> +				&dispose, struct lu_object_header, loh_lru)) != NULL) {
>>  			list_del_init(&h->loh_lru);
>>  			lu_object_free(env, lu_object_top(h));
>>  			lprocfs_counter_incr(s->ls_stats, LU_SS_LRU_PURGED);
>> 
>> 
>> 
-------------- 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/20190211/b5cb43a0/attachment.sig>

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

* [lustre-devel] [PATCH 10/21] lustre: obdclass: use cl_object_for_each where appropriate
  2019-02-11  1:57   ` James Simmons
@ 2019-02-11  3:19     ` NeilBrown
  0 siblings, 0 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-11  3:19 UTC (permalink / raw)
  To: lustre-devel

On Mon, Feb 11 2019, James Simmons wrote:

>> There are various places which have a list_for_each_entry()
>> where cl_object_for_each (or .._reverse) is more appropriate.
>> 
>> Several of these re-use the 'obj' function parameter as a loop
>> iterator, which is a little confusing.
>> 
>> Change these to use cl_object_for_each{_reverse}, and where needed,
>> introduce a new iterator variable 'o'.
>
> Surprised the reverse wasn't done in that the cl_* macro was
> removed :-) 

Hmmm.... maybe .....
But
   ->co_lu.lo_header->loh_layers

is sufficiently scary looking that hiding it in a macro seems like a
good idea.

>
> Reviewed-by: James Simmons <jsimmons@infradead.org>

Thanks,
NeilBrown


>  
>> Signed-off-by: NeilBrown <neilb@suse.com>
>> ---
>>  drivers/staging/lustre/lustre/lov/lov_page.c       |    3 -
>>  drivers/staging/lustre/lustre/obdclass/cl_lock.c   |    3 -
>>  drivers/staging/lustre/lustre/obdclass/cl_object.c |   82 +++++++++-----------
>>  drivers/staging/lustre/lustre/obdclass/cl_page.c   |   11 +--
>>  4 files changed, 44 insertions(+), 55 deletions(-)
>> 
>> diff --git a/drivers/staging/lustre/lustre/lov/lov_page.c b/drivers/staging/lustre/lustre/lov/lov_page.c
>> index 08485a95ec01..e64b350601d2 100644
>> --- a/drivers/staging/lustre/lustre/lov/lov_page.c
>> +++ b/drivers/staging/lustre/lustre/lov/lov_page.c
>> @@ -103,8 +103,7 @@ int lov_page_init_composite(const struct lu_env *env, struct cl_object *obj,
>>  		return PTR_ERR(sub);
>>  
>>  	subobj = lovsub2cl(r0->lo_sub[stripe]);
>> -	list_for_each_entry(o, &subobj->co_lu.lo_header->loh_layers,
>> -			    co_lu.lo_linkage) {
>> +	cl_object_for_each(o, subobj) {
>>  		if (o->co_ops->coo_page_init) {
>>  			rc = o->co_ops->coo_page_init(sub->sub_env, o, page,
>>  						      cl_index(subobj, suboff));
>> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
>> index 8133d992cc73..fc5976d8b37b 100644
>> --- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c
>> +++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
>> @@ -103,8 +103,7 @@ int cl_lock_init(const struct lu_env *env, struct cl_lock *lock,
>>  	LASSERT(obj);
>>  
>>  	INIT_LIST_HEAD(&lock->cll_layers);
>> -	list_for_each_entry(scan, &obj->co_lu.lo_header->loh_layers,
>> -			    co_lu.lo_linkage) {
>> +	cl_object_for_each(scan, obj) {
>>  		result = scan->co_ops->coo_lock_init(env, scan, lock, io);
>>  		if (result != 0) {
>>  			cl_lock_fini(env, lock);
>> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> index f724b2d62df1..d71a680660da 100644
>> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> @@ -190,16 +190,15 @@ EXPORT_SYMBOL(cl_object_attr_unlock);
>>  int cl_object_attr_get(const struct lu_env *env, struct cl_object *obj,
>>  		       struct cl_attr *attr)
>>  {
>> -	struct lu_object_header *top;
>> +	struct cl_object *o;
>>  	int result;
>>  
>>  	assert_spin_locked(cl_object_attr_guard(obj));
>>  
>> -	top = obj->co_lu.lo_header;
>>  	result = 0;
>> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
>> -		if (obj->co_ops->coo_attr_get) {
>> -			result = obj->co_ops->coo_attr_get(env, obj, attr);
>> +	cl_object_for_each(o, obj) {
>> +		if (o->co_ops->coo_attr_get) {
>> +			result = o->co_ops->coo_attr_get(env, o, attr);
>>  			if (result != 0) {
>>  				if (result > 0)
>>  					result = 0;
>> @@ -221,17 +220,16 @@ EXPORT_SYMBOL(cl_object_attr_get);
>>  int cl_object_attr_update(const struct lu_env *env, struct cl_object *obj,
>>  			  const struct cl_attr *attr, unsigned int v)
>>  {
>> -	struct lu_object_header *top;
>> +	struct cl_object *o;
>>  	int result;
>>  
>>  	assert_spin_locked(cl_object_attr_guard(obj));
>>  
>> -	top = obj->co_lu.lo_header;
>>  	result = 0;
>> -	list_for_each_entry_reverse(obj, &top->loh_layers, co_lu.lo_linkage) {
>> -		if (obj->co_ops->coo_attr_update) {
>> -			result = obj->co_ops->coo_attr_update(env, obj, attr,
>> -							      v);
>> +	cl_object_for_each_reverse(o, obj) {
>> +		if (o->co_ops->coo_attr_update) {
>> +			result = o->co_ops->coo_attr_update(env, o, attr,
>> +							    v);
>>  			if (result != 0) {
>>  				if (result > 0)
>>  					result = 0;
>> @@ -254,19 +252,18 @@ EXPORT_SYMBOL(cl_object_attr_update);
>>  int cl_object_glimpse(const struct lu_env *env, struct cl_object *obj,
>>  		      struct ost_lvb *lvb)
>>  {
>> -	struct lu_object_header *top;
>> +	struct cl_object *o;
>>  	int result;
>>  
>> -	top = obj->co_lu.lo_header;
>>  	result = 0;
>> -	list_for_each_entry_reverse(obj, &top->loh_layers, co_lu.lo_linkage) {
>> -		if (obj->co_ops->coo_glimpse) {
>> -			result = obj->co_ops->coo_glimpse(env, obj, lvb);
>> +	cl_object_for_each_reverse(o, obj) {
>> +		if (o->co_ops->coo_glimpse) {
>> +			result = o->co_ops->coo_glimpse(env, o, lvb);
>>  			if (result != 0)
>>  				break;
>>  		}
>>  	}
>> -	LU_OBJECT_HEADER(D_DLMTRACE, env, lu_object_top(top),
>> +	LU_OBJECT_HEADER(D_DLMTRACE, env, lu_object_top(obj->co_lu.lo_header),
>>  			 "size: %llu mtime: %llu atime: %llu ctime: %llu blocks: %llu\n",
>>  			 lvb->lvb_size, lvb->lvb_mtime, lvb->lvb_atime,
>>  			 lvb->lvb_ctime, lvb->lvb_blocks);
>> @@ -280,14 +277,13 @@ EXPORT_SYMBOL(cl_object_glimpse);
>>  int cl_conf_set(const struct lu_env *env, struct cl_object *obj,
>>  		const struct cl_object_conf *conf)
>>  {
>> -	struct lu_object_header *top;
>> +	struct cl_object *o;
>>  	int result;
>>  
>> -	top = obj->co_lu.lo_header;
>>  	result = 0;
>> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
>> -		if (obj->co_ops->coo_conf_set) {
>> -			result = obj->co_ops->coo_conf_set(env, obj, conf);
>> +	cl_object_for_each(o, obj) {
>> +		if (o->co_ops->coo_conf_set) {
>> +			result = o->co_ops->coo_conf_set(env, o, conf);
>>  			if (result != 0)
>>  				break;
>>  		}
>> @@ -301,13 +297,11 @@ EXPORT_SYMBOL(cl_conf_set);
>>   */
>>  int cl_object_prune(const struct lu_env *env, struct cl_object *obj)
>>  {
>> -	struct lu_object_header *top;
>>  	struct cl_object *o;
>>  	int result;
>>  
>> -	top = obj->co_lu.lo_header;
>>  	result = 0;
>> -	list_for_each_entry(o, &top->loh_layers, co_lu.lo_linkage) {
>> +	cl_object_for_each(o, obj) {
>>  		if (o->co_ops->coo_prune) {
>>  			result = o->co_ops->coo_prune(env, o);
>>  			if (result != 0)
>> @@ -325,14 +319,13 @@ EXPORT_SYMBOL(cl_object_prune);
>>  int cl_object_getstripe(const struct lu_env *env, struct cl_object *obj,
>>  			struct lov_user_md __user *uarg, size_t size)
>>  {
>> -	struct lu_object_header *top;
>> +	struct cl_object *o;
>>  	int result = 0;
>>  
>> -	top = obj->co_lu.lo_header;
>> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
>> -		if (obj->co_ops->coo_getstripe) {
>> -			result = obj->co_ops->coo_getstripe(env, obj, uarg,
>> -							    size);
>> +	cl_object_for_each(o, obj) {
>> +		if (o->co_ops->coo_getstripe) {
>> +			result = o->co_ops->coo_getstripe(env, o, uarg,
>> +							  size);
>>  			if (result)
>>  				break;
>>  		}
>> @@ -357,14 +350,13 @@ int cl_object_fiemap(const struct lu_env *env, struct cl_object *obj,
>>  		     struct ll_fiemap_info_key *key,
>>  		     struct fiemap *fiemap, size_t *buflen)
>>  {
>> -	struct lu_object_header *top;
>> +	struct cl_object *o;
>>  	int result = 0;
>>  
>> -	top = obj->co_lu.lo_header;
>> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
>> -		if (obj->co_ops->coo_fiemap) {
>> -			result = obj->co_ops->coo_fiemap(env, obj, key, fiemap,
>> -							 buflen);
>> +	cl_object_for_each(o, obj) {
>> +		if (o->co_ops->coo_fiemap) {
>> +			result = o->co_ops->coo_fiemap(env, o, key, fiemap,
>> +						       buflen);
>>  			if (result)
>>  				break;
>>  		}
>> @@ -376,11 +368,11 @@ EXPORT_SYMBOL(cl_object_fiemap);
>>  int cl_object_layout_get(const struct lu_env *env, struct cl_object *obj,
>>  			 struct cl_layout *cl)
>>  {
>> -	struct lu_object_header *top = obj->co_lu.lo_header;
>> +	struct cl_object *o;
>>  
>> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
>> -		if (obj->co_ops->coo_layout_get)
>> -			return obj->co_ops->coo_layout_get(env, obj, cl);
>> +	cl_object_for_each(o, obj) {
>> +		if (o->co_ops->coo_layout_get)
>> +			return o->co_ops->coo_layout_get(env, o, cl);
>>  	}
>>  
>>  	return -EOPNOTSUPP;
>> @@ -389,12 +381,12 @@ EXPORT_SYMBOL(cl_object_layout_get);
>>  
>>  loff_t cl_object_maxbytes(struct cl_object *obj)
>>  {
>> -	struct lu_object_header *top = obj->co_lu.lo_header;
>> +	struct cl_object *o;
>>  	loff_t maxbytes = LLONG_MAX;
>>  
>> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
>> -		if (obj->co_ops->coo_maxbytes)
>> -			maxbytes = min_t(loff_t, obj->co_ops->coo_maxbytes(obj),
>> +	cl_object_for_each(o, obj) {
>> +		if (o->co_ops->coo_maxbytes)
>> +			maxbytes = min_t(loff_t, o->co_ops->coo_maxbytes(o),
>>  					 maxbytes);
>>  	}
>>  
>> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
>> index 057318deaa4e..7d00a9233a3b 100644
>> --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
>> +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
>> @@ -132,7 +132,7 @@ struct cl_page *cl_page_alloc(const struct lu_env *env,
>>  			      enum cl_page_type type)
>>  {
>>  	struct cl_page *page;
>> -	struct lu_object_header *head;
>> +	struct cl_object *o2;
>>  
>>  	page = kzalloc(cl_object_header(o)->coh_page_bufsize, GFP_NOFS);
>>  	if (page) {
>> @@ -149,11 +149,10 @@ struct cl_page *cl_page_alloc(const struct lu_env *env,
>>  		INIT_LIST_HEAD(&page->cp_layers);
>>  		INIT_LIST_HEAD(&page->cp_batch);
>>  		lu_ref_init(&page->cp_reference);
>> -		head = o->co_lu.lo_header;
>> -		list_for_each_entry(o, &head->loh_layers, co_lu.lo_linkage) {
>> -			if (o->co_ops->coo_page_init) {
>> -				result = o->co_ops->coo_page_init(env, o, page,
>> -								  ind);
>> +		cl_object_for_each(o2, o) {
>> +			if (o2->co_ops->coo_page_init) {
>> +				result = o2->co_ops->coo_page_init(env, o2, page,
>> +								   ind);
>>  				if (result != 0) {
>>  					__cl_page_delete(env, page);
>>  					cl_page_free(env, page);
>> 
>> 
>> 
-------------- 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/20190211/0b2e036b/attachment.sig>

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

* [lustre-devel] [PATCH 11/21] lustre: cl_object: remove vestigial debugging.
  2019-02-11  2:04   ` James Simmons
@ 2019-02-11  3:25     ` NeilBrown
  2019-02-12  5:19       ` James Simmons
  0 siblings, 1 reply; 87+ messages in thread
From: NeilBrown @ 2019-02-11  3:25 UTC (permalink / raw)
  To: lustre-devel

On Mon, Feb 11 2019, James Simmons wrote:

>> cl_env_inc() and cl_env_dec() don't do anything,
>> so discard them.
>
> I don't know about this one. I saw Andreas response as well. 
> So this was apart of "LU-744 obdclass: revise stats for cl_object cache"
> In the end it was turned off by default in the OpenSFS branch since it
> made performance take a hit. To enable in OpenSFS branch you have to run
> ./configure --enable-pgstate-track. We have a few like this for Lustre so
> I was going to bring this up. Do we want to remove this work for both the
> upstream client as well as OpenSFS tree or properly implement this by
> making it a Kconfig option when CONFIG_LUSTRE_DEBUG_EXPENSIVE_CHECK is
> enabled? Its just a matter of porting OpenSFS commit 
> 5cae09a2409dcd396a1ee7be1eca7d3bbf77365e
>
> What do you think?

How useful are these stats?
Stats that are never compiled in aren't likely to tell you much :-)

Has any thought been given to per-cpu stats counting?  That seems to be
the preferred approach for high-frequency accounting.

I think having a CONFIG option to enable expensive consistency checks is
a good idea - developers will enable it when they don't care about
performance.
Having a CONFIG option for expensive performance stats seems... weird.
Who would use it, and how meaningful would the number be?

NeilBrown


>
>> Signed-off-by: NeilBrown <neilb@suse.com>
>> ---
>>  drivers/staging/lustre/lustre/obdclass/cl_object.c |   15 ---------------
>>  1 file changed, 15 deletions(-)
>> 
>> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> index d71a680660da..1e704078664e 100644
>> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> @@ -565,14 +565,6 @@ struct cl_env {
>>  	void		       *ce_debug;
>>  };
>>  
>> -static void cl_env_inc(enum cache_stats_item item)
>> -{
>> -}
>> -
>> -static void cl_env_dec(enum cache_stats_item item)
>> -{
>> -}
>> -
>>  static void cl_env_init0(struct cl_env *cle, void *debug)
>>  {
>>  	LASSERT(cle->ce_ref == 0);
>> @@ -581,7 +573,6 @@ static void cl_env_init0(struct cl_env *cle, void *debug)
>>  
>>  	cle->ce_ref = 1;
>>  	cle->ce_debug = debug;
>> -	cl_env_inc(CS_busy);
>>  }
>>  
>>  static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
>> @@ -611,9 +602,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
>>  		if (rc != 0) {
>>  			kmem_cache_free(cl_env_kmem, cle);
>>  			env = ERR_PTR(rc);
>> -		} else {
>> -			cl_env_inc(CS_create);
>> -			cl_env_inc(CS_total);
>>  		}
>>  	} else {
>>  		env = ERR_PTR(-ENOMEM);
>> @@ -623,7 +611,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
>>  
>>  static void cl_env_fini(struct cl_env *cle)
>>  {
>> -	cl_env_dec(CS_total);
>>  	lu_context_fini(&cle->ce_lu.le_ctx);
>>  	lu_context_fini(&cle->ce_ses);
>>  	kmem_cache_free(cl_env_kmem, cle);
>> @@ -782,7 +769,6 @@ void cl_env_put(struct lu_env *env, u16 *refcheck)
>>  	if (--cle->ce_ref == 0) {
>>  		int cpu = get_cpu();
>>  
>> -		cl_env_dec(CS_busy);
>>  		cle->ce_debug = NULL;
>>  		cl_env_exit(cle);
>>  		/*
>> @@ -903,7 +889,6 @@ void cl_env_percpu_put(struct lu_env *env)
>>  	cle->ce_ref--;
>>  	LASSERT(cle->ce_ref == 0);
>>  
>> -	cl_env_dec(CS_busy);
>>  	cle->ce_debug = NULL;
>>  
>>  	put_cpu();
>> 
>> 
>> 
-------------- 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/20190211/2862da0b/attachment.sig>

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

* [lustre-devel] [PATCH 13/21] lustre: make cp_ref in cl_page a refcount_t
  2019-02-07  0:03 ` [lustre-devel] [PATCH 13/21] lustre: make cp_ref in cl_page a refcount_t NeilBrown
  2019-02-08  5:45   ` Andreas Dilger
@ 2019-02-11  4:00   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: James Simmons @ 2019-02-11  4:00 UTC (permalink / raw)
  To: lustre-devel


> As this is used as a refcount, it should be declared
> as one.

Reviewed-by: James Simmons <jsimmons@infradead.org>
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/include/cl_object.h |    4 ++--
>  drivers/staging/lustre/lustre/llite/vvp_page.c    |    9 +++++----
>  drivers/staging/lustre/lustre/obdclass/cl_page.c  |   14 +++++++-------
>  3 files changed, 14 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
> index bf7678aed6bf..c2273c3100e8 100644
> --- a/drivers/staging/lustre/lustre/include/cl_object.h
> +++ b/drivers/staging/lustre/lustre/include/cl_object.h
> @@ -717,7 +717,7 @@ enum cl_page_type {
>   */
>  struct cl_page {
>  	/** Reference counter. */
> -	atomic_t			 cp_ref;
> +	refcount_t			 cp_ref;
>  	/** An object this page is a part of. Immutable after creation. */
>  	struct cl_object		*cp_obj;
>  	/** vmpage */
> @@ -1021,7 +1021,7 @@ static inline struct page *cl_page_vmpage(struct cl_page *page)
>   */
>  static inline bool __page_in_use(const struct cl_page *page, int refc)
>  {
> -	return (atomic_read(&page->cp_ref) > refc + 1);
> +	return (refcount_read(&page->cp_ref) > refc + 1);
>  }
>  
>  /**
> diff --git a/drivers/staging/lustre/lustre/llite/vvp_page.c b/drivers/staging/lustre/lustre/llite/vvp_page.c
> index 77bf923f2578..ec0d93313f55 100644
> --- a/drivers/staging/lustre/lustre/llite/vvp_page.c
> +++ b/drivers/staging/lustre/lustre/llite/vvp_page.c
> @@ -157,15 +157,16 @@ static void vvp_page_delete(const struct lu_env *env,
>  	struct inode *inode = vmpage->mapping->host;
>  	struct cl_object *obj = slice->cpl_obj;
>  	struct cl_page *page = slice->cpl_page;
> -	int refc;
>  
>  	LASSERT(PageLocked(vmpage));
>  	LASSERT((struct cl_page *)vmpage->private == page);
>  	LASSERT(inode == vvp_object_inode(obj));
>  
>  	/* Drop the reference count held in vvp_page_init */
> -	refc = atomic_dec_return(&page->cp_ref);
> -	LASSERTF(refc >= 1, "page = %p, refc = %d\n", page, refc);
> +	if (refcount_dec_and_test(&page->cp_ref)) {
> +		/* It mustn't reach zero here! */
> +		LASSERTF(0, "page = %p, refc reached zero\n", page);
> +	}
>  
>  	ClearPagePrivate(vmpage);
>  	vmpage->private = 0;
> @@ -507,7 +508,7 @@ int vvp_page_init(const struct lu_env *env, struct cl_object *obj,
>  
>  	if (page->cp_type == CPT_CACHEABLE) {
>  		/* in cache, decref in vvp_page_delete */
> -		atomic_inc(&page->cp_ref);
> +		refcount_inc(&page->cp_ref);
>  		SetPagePrivate(vmpage);
>  		vmpage->private = (unsigned long)page;
>  		cl_page_slice_add(page, &vpg->vpg_cl, obj, index,
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
> index 31ded52e0499..f0ece7e9a4ac 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
> @@ -67,8 +67,8 @@ static void __cl_page_delete(const struct lu_env *env, struct cl_page *pg);
>   */
>  static void cl_page_get_trust(struct cl_page *page)
>  {
> -	LASSERT(atomic_read(&page->cp_ref) > 0);
> -	atomic_inc(&page->cp_ref);
> +	LASSERT(refcount_read(&page->cp_ref) > 0);
> +	refcount_inc(&page->cp_ref);
>  }
>  
>  /**
> @@ -135,7 +135,7 @@ struct cl_page *cl_page_alloc(const struct lu_env *env,
>  	if (page) {
>  		int result = 0;
>  
> -		atomic_set(&page->cp_ref, 1);
> +		refcount_set(&page->cp_ref, 1);
>  		page->cp_obj = o;
>  		cl_object_get(o);
>  		lu_object_ref_add_at(&o->co_lu, &page->cp_obj_ref, "cl_page",
> @@ -310,12 +310,12 @@ EXPORT_SYMBOL(cl_page_get);
>  void cl_page_put(const struct lu_env *env, struct cl_page *page)
>  {
>  	CL_PAGE_HEADER(D_TRACE, env, page, "%d\n",
> -		       atomic_read(&page->cp_ref));
> +		       refcount_read(&page->cp_ref));
>  
> -	if (atomic_dec_and_test(&page->cp_ref)) {
> +	if (refcount_dec_and_test(&page->cp_ref)) {
>  		LASSERT(page->cp_state == CPS_FREEING);
>  
> -		LASSERT(atomic_read(&page->cp_ref) == 0);
> +		LASSERT(refcount_read(&page->cp_ref) == 0);
>  		PASSERT(env, page, !page->cp_owner);
>  		PASSERT(env, page, list_empty(&page->cp_batch));
>  		/*
> @@ -869,7 +869,7 @@ void cl_page_header_print(const struct lu_env *env, void *cookie,
>  {
>  	(*printer)(env, cookie,
>  		   "page@%p[%d %p %d %d %p]\n",
> -		   pg, atomic_read(&pg->cp_ref), pg->cp_obj,
> +		   pg, refcount_read(&pg->cp_ref), pg->cp_obj,
>  		   pg->cp_state, pg->cp_type,
>  		   pg->cp_owner);
>  }
> 
> 
> 

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

* [lustre-devel] [PATCH 12/21] lustre: cl_page.c: remove PINVRNT()
  2019-02-07  0:03 ` [lustre-devel] [PATCH 12/21] lustre: cl_page.c: remove PINVRNT() NeilBrown
  2019-02-08  5:43   ` Andreas Dilger
@ 2019-02-11  4:01   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: James Simmons @ 2019-02-11  4:01 UTC (permalink / raw)
  To: lustre-devel



On Thu, 7 Feb 2019, NeilBrown wrote:

> This macro does nothing (it once was like 'assert'),
> so remove it.

Reviewed-by: James Simmons <jsimmons@infradead.org>
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/obdclass/cl_page.c |   33 ----------------------
>  1 file changed, 33 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
> index 7d00a9233a3b..31ded52e0499 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
> @@ -55,9 +55,6 @@ static void __cl_page_delete(const struct lu_env *env, struct cl_page *pg);
>  		}							   \
>  	} while (0)
>  
> -# define PINVRNT(env, page, exp) \
> -	((void)sizeof(env), (void)sizeof(page), (void)sizeof !!(exp))
> -
>  /**
>   * Internal version of cl_page_get().
>   *
> @@ -382,8 +379,6 @@ void __cl_page_disown(const struct lu_env *env,
>  	enum cl_page_state state;
>  
>  	state = pg->cp_state;
> -	PINVRNT(env, pg, state == CPS_OWNED || state == CPS_FREEING);
> -	PINVRNT(env, pg, cl_page_invariant(pg) || state == CPS_FREEING);
>  	cl_page_owner_clear(pg);
>  
>  	if (state == CPS_OWNED)
> @@ -437,8 +432,6 @@ static int __cl_page_own(const struct lu_env *env, struct cl_io *io,
>  	const struct cl_page_slice *slice;
>  	int result = 0;
>  
> -	PINVRNT(env, pg, !cl_page_is_owned(pg, io));
> -
>  	io = cl_io_top(io);
>  
>  	if (pg->cp_state == CPS_FREEING) {
> @@ -468,7 +461,6 @@ static int __cl_page_own(const struct lu_env *env, struct cl_io *io,
>  		}
>  	}
>  out:
> -	PINVRNT(env, pg, ergo(result == 0, cl_page_invariant(pg)));
>  	return result;
>  }
>  
> @@ -510,8 +502,6 @@ void cl_page_assume(const struct lu_env *env,
>  {
>  	const struct cl_page_slice *slice;
>  
> -	PINVRNT(env, pg, cl_object_same(pg->cp_obj, io->ci_obj));
> -
>  	io = cl_io_top(io);
>  
>  	list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) {
> @@ -542,9 +532,6 @@ void cl_page_unassume(const struct lu_env *env,
>  {
>  	const struct cl_page_slice *slice;
>  
> -	PINVRNT(env, pg, cl_page_is_owned(pg, io));
> -	PINVRNT(env, pg, cl_page_invariant(pg));
> -
>  	io = cl_io_top(io);
>  	cl_page_owner_clear(pg);
>  	cl_page_state_set(env, pg, CPS_CACHED);
> @@ -570,9 +557,6 @@ EXPORT_SYMBOL(cl_page_unassume);
>  void cl_page_disown(const struct lu_env *env,
>  		    struct cl_io *io, struct cl_page *pg)
>  {
> -	PINVRNT(env, pg, cl_page_is_owned(pg, io) ||
> -		pg->cp_state == CPS_FREEING);
> -
>  	io = cl_io_top(io);
>  	__cl_page_disown(env, io, pg);
>  }
> @@ -593,9 +577,6 @@ void cl_page_discard(const struct lu_env *env,
>  {
>  	const struct cl_page_slice *slice;
>  
> -	PINVRNT(env, pg, cl_page_is_owned(pg, io));
> -	PINVRNT(env, pg, cl_page_invariant(pg));
> -
>  	list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) {
>  		if (slice->cpl_ops->cpo_discard)
>  			(*slice->cpl_ops->cpo_discard)(env, slice, io);
> @@ -652,7 +633,6 @@ static void __cl_page_delete(const struct lu_env *env, struct cl_page *pg)
>   */
>  void cl_page_delete(const struct lu_env *env, struct cl_page *pg)
>  {
> -	PINVRNT(env, pg, cl_page_invariant(pg));
>  	__cl_page_delete(env, pg);
>  }
>  EXPORT_SYMBOL(cl_page_delete);
> @@ -670,8 +650,6 @@ void cl_page_export(const struct lu_env *env, struct cl_page *pg, int uptodate)
>  {
>  	const struct cl_page_slice *slice;
>  
> -	PINVRNT(env, pg, cl_page_invariant(pg));
> -
>  	list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) {
>  		if (slice->cpl_ops->cpo_export)
>  			(*slice->cpl_ops->cpo_export)(env, slice, uptodate);
> @@ -730,10 +708,6 @@ int cl_page_prep(const struct lu_env *env, struct cl_io *io,
>  	const struct cl_page_slice *slice;
>  	int result = 0;
>  
> -	PINVRNT(env, pg, cl_page_is_owned(pg, io));
> -	PINVRNT(env, pg, cl_page_invariant(pg));
> -	PINVRNT(env, pg, crt < CRT_NR);
> -
>  	/*
>  	 * XXX this has to be called bottom-to-top, so that llite can set up
>  	 * PG_writeback without risking other layers deciding to skip this
> @@ -819,8 +793,6 @@ int cl_page_make_ready(const struct lu_env *env, struct cl_page *pg,
>  	const struct cl_page_slice *sli;
>  	int result = 0;
>  
> -	PINVRNT(env, pg, crt < CRT_NR);
> -
>  	if (crt >= CRT_NR)
>  		return -EINVAL;
>  
> @@ -856,9 +828,6 @@ int cl_page_flush(const struct lu_env *env, struct cl_io *io,
>  	const struct cl_page_slice *slice;
>  	int result = 0;
>  
> -	PINVRNT(env, pg, cl_page_is_owned(pg, io));
> -	PINVRNT(env, pg, cl_page_invariant(pg));
> -
>  	 list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) {
>  		if (slice->cpl_ops->cpo_flush)
>  			result = (*slice->cpl_ops->cpo_flush)(env, slice, io);
> @@ -883,8 +852,6 @@ void cl_page_clip(const struct lu_env *env, struct cl_page *pg,
>  {
>  	const struct cl_page_slice *slice;
>  
> -	PINVRNT(env, pg, cl_page_invariant(pg));
> -
>  	CL_PAGE_HEADER(D_TRACE, env, pg, "%d %d\n", from, to);
>  
>  	list_for_each_entry(slice, &pg->cp_layers, cpl_linkage) {
> 
> 
> 

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

* [lustre-devel] [PATCH 14/21] lustre: make ccc_users in cl_client_cache a refcount_t
  2019-02-07  0:03 ` [lustre-devel] [PATCH 14/21] lustre: make ccc_users in cl_client_cache " NeilBrown
  2019-02-08  5:46   ` Andreas Dilger
@ 2019-02-11  4:01   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: James Simmons @ 2019-02-11  4:01 UTC (permalink / raw)
  To: lustre-devel


> As this is used as a refcount, it should be declared
> as one.

Reviewed-by: James Simmons <jsimmons@infradead.org>
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/include/cl_object.h |    2 +-
>  drivers/staging/lustre/lustre/llite/lproc_llite.c |    2 +-
>  drivers/staging/lustre/lustre/obdclass/cl_page.c  |    6 +++---
>  drivers/staging/lustre/lustre/osc/osc_page.c      |    4 ++--
>  drivers/staging/lustre/lustre/osc/osc_request.c   |    2 +-
>  5 files changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
> index c2273c3100e8..05be85306663 100644
> --- a/drivers/staging/lustre/lustre/include/cl_object.h
> +++ b/drivers/staging/lustre/lustre/include/cl_object.h
> @@ -2181,7 +2181,7 @@ struct cl_client_cache {
>  	 * # of client cache refcount
>  	 * # of users (OSCs) + 2 (held by llite and lov)
>  	 */
> -	atomic_t		ccc_users;
> +	refcount_t		ccc_users;
>  	/**
>  	 * # of threads are doing shrinking
>  	 */
> diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c
> index 001bed90f4da..8215296dc15d 100644
> --- a/drivers/staging/lustre/lustre/llite/lproc_llite.c
> +++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c
> @@ -467,7 +467,7 @@ static int ll_max_cached_mb_seq_show(struct seq_file *m, void *v)
>  		   "used_mb: %ld\n"
>  		   "unused_mb: %ld\n"
>  		   "reclaim_count: %u\n",
> -		   atomic_read(&cache->ccc_users),
> +		   refcount_read(&cache->ccc_users),
>  		   max_cached_mb,
>  		   max_cached_mb - unused_mb,
>  		   unused_mb,
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
> index f0ece7e9a4ac..7dcd3aff229f 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
> @@ -960,7 +960,7 @@ struct cl_client_cache *cl_cache_init(unsigned long lru_page_max)
>  		return NULL;
>  
>  	/* Initialize cache data */
> -	atomic_set(&cache->ccc_users, 1);
> +	refcount_set(&cache->ccc_users, 1);
>  	cache->ccc_lru_max = lru_page_max;
>  	atomic_long_set(&cache->ccc_lru_left, lru_page_max);
>  	spin_lock_init(&cache->ccc_lru_lock);
> @@ -978,7 +978,7 @@ EXPORT_SYMBOL(cl_cache_init);
>   */
>  void cl_cache_incref(struct cl_client_cache *cache)
>  {
> -	atomic_inc(&cache->ccc_users);
> +	refcount_inc(&cache->ccc_users);
>  }
>  EXPORT_SYMBOL(cl_cache_incref);
>  
> @@ -989,7 +989,7 @@ EXPORT_SYMBOL(cl_cache_incref);
>   */
>  void cl_cache_decref(struct cl_client_cache *cache)
>  {
> -	if (atomic_dec_and_test(&cache->ccc_users))
> +	if (refcount_dec_and_test(&cache->ccc_users))
>  		kfree(cache);
>  }
>  EXPORT_SYMBOL(cl_cache_decref);
> diff --git a/drivers/staging/lustre/lustre/osc/osc_page.c b/drivers/staging/lustre/lustre/osc/osc_page.c
> index 135bfe5e1b37..ce911b82512d 100644
> --- a/drivers/staging/lustre/lustre/osc/osc_page.c
> +++ b/drivers/staging/lustre/lustre/osc/osc_page.c
> @@ -346,7 +346,7 @@ static int osc_cache_too_much(struct client_obd *cli)
>  	long pages = atomic_long_read(&cli->cl_lru_in_list);
>  	unsigned long budget;
>  
> -	budget = cache->ccc_lru_max / (atomic_read(&cache->ccc_users) - 2);
> +	budget = cache->ccc_lru_max / (refcount_read(&cache->ccc_users) - 2);
>  
>  	/* if it's going to run out LRU slots, we should free some, but not
>  	 * too much to maintain fairness among OSCs.
> @@ -707,7 +707,7 @@ static long osc_lru_reclaim(struct client_obd *cli, unsigned long npages)
>  	cache->ccc_lru_shrinkers++;
>  	list_move_tail(&cli->cl_lru_osc, &cache->ccc_lru);
>  
> -	max_scans = atomic_read(&cache->ccc_users) - 2;
> +	max_scans = refcount_read(&cache->ccc_users) - 2;
>  	while (--max_scans > 0 &&
>  	       (cli = list_first_entry_or_null(&cache->ccc_lru,
>  					       struct client_obd,
> diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
> index 9e72fa8f68b3..0dfc506f6d01 100644
> --- a/drivers/staging/lustre/lustre/osc/osc_request.c
> +++ b/drivers/staging/lustre/lustre/osc/osc_request.c
> @@ -2959,7 +2959,7 @@ static int osc_cleanup(struct obd_device *obd)
>  
>  	/* lru cleanup */
>  	if (cli->cl_cache) {
> -		LASSERT(atomic_read(&cli->cl_cache->ccc_users) > 0);
> +		LASSERT(refcount_read(&cli->cl_cache->ccc_users) > 0);
>  		spin_lock(&cli->cl_cache->ccc_lru_lock);
>  		list_del_init(&cli->cl_lru_osc);
>  		spin_unlock(&cli->cl_cache->ccc_lru_lock);
> 
> 
> 

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

* [lustre-devel] [PATCH 15/21] lustre: obdclass: char obd_ioctl_getdata type.
  2019-02-07  0:03 ` [lustre-devel] [PATCH 15/21] lustre: obdclass: char obd_ioctl_getdata type NeilBrown
  2019-02-08  5:56   ` Andreas Dilger
@ 2019-02-11  4:03   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: James Simmons @ 2019-02-11  4:03 UTC (permalink / raw)
  To: lustre-devel


> Instead of having obd_ioctl_getdata() return the allocated
> data as a "char *", return it as it really is,
>  struct obd_ioctl_data *
> 
> This avoids the need for extra variables and casts.

I think this needs the fix Andreas pointed out.
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/include/obd_class.h  |    3 ++-
>  drivers/staging/lustre/lustre/llite/dir.c          |   17 +++++------------
>  drivers/staging/lustre/lustre/llite/llite_lib.c    |    8 +++-----
>  drivers/staging/lustre/lustre/lov/lov_obd.c        |   15 ++++++---------
>  drivers/staging/lustre/lustre/obdclass/class_obd.c |   18 ++++++++----------
>  5 files changed, 24 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h
> index 30b3e2c69f83..32d4ab6e78a0 100644
> --- a/drivers/staging/lustre/lustre/include/obd_class.h
> +++ b/drivers/staging/lustre/lustre/include/obd_class.h
> @@ -1697,6 +1697,7 @@ struct root_squash_info {
>  };
>  
>  /* linux-module.c */
> -int obd_ioctl_getdata(char **buf, int *len, void __user *arg);
> +struct obd_ioctl_data;
> +int obd_ioctl_getdata(struct obd_ioctl_data **data, int *len, void __user *arg);
>  
>  #endif /* __LINUX_OBD_CLASS_H */
> diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c
> index fd1af4a5cdad..0c49244eaee8 100644
> --- a/drivers/staging/lustre/lustre/llite/dir.c
> +++ b/drivers/staging/lustre/lustre/llite/dir.c
> @@ -1130,13 +1130,11 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
>  	}
>  	case IOC_MDC_LOOKUP: {
>  		int namelen, len = 0;
> -		char *buf = NULL;
>  		char *filename;
>  
> -		rc = obd_ioctl_getdata(&buf, &len, (void __user *)arg);
> +		rc = obd_ioctl_getdata(&data, &len, (void __user *)arg);
>  		if (rc)
>  			return rc;
> -		data = (void *)buf;
>  
>  		filename = data->ioc_inlbuf1;
>  		namelen = strlen(filename);
> @@ -1155,12 +1153,11 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
>  			goto out_free;
>  		}
>  out_free:
> -		kvfree(buf);
> +		kvfree(data);
>  		return rc;
>  	}
>  	case LL_IOC_LMV_SETSTRIPE: {
>  		struct lmv_user_md  *lum;
> -		char *buf = NULL;
>  		char *filename;
>  		int namelen = 0;
>  		int lumlen = 0;
> @@ -1168,11 +1165,10 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
>  		int len;
>  		int rc;
>  
> -		rc = obd_ioctl_getdata(&buf, &len, (void __user *)arg);
> +		rc = obd_ioctl_getdata(&data, &len, (void __user *)arg);
>  		if (rc)
>  			return rc;
>  
> -		data = (void *)buf;
>  		if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2 ||
>  		    data->ioc_inllen1 == 0 || data->ioc_inllen2 == 0) {
>  			rc = -EINVAL;
> @@ -1205,7 +1201,7 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
>  #endif
>  		rc = ll_dir_setdirstripe(dentry, lum, filename, mode);
>  lmv_out_free:
> -		kvfree(buf);
> +		kvfree(data);
>  		return rc;
>  	}
>  	case LL_IOC_LMV_SET_DEFAULT_STRIPE: {
> @@ -1651,18 +1647,16 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
>  		return rc;
>  	}
>  	case LL_IOC_MIGRATE: {
> -		char *buf = NULL;
>  		const char *filename;
>  		int namelen = 0;
>  		int len;
>  		int rc;
>  		int mdtidx;
>  
> -		rc = obd_ioctl_getdata(&buf, &len, (void __user *)arg);
> +		rc = obd_ioctl_getdata(&data, &len, (void __user *)arg);
>  		if (rc < 0)
>  			return rc;
>  
> -		data = (struct obd_ioctl_data *)buf;
>  		if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2 ||
>  		    !data->ioc_inllen1 || !data->ioc_inllen2) {
>  			rc = -EINVAL;
> @@ -1684,7 +1678,6 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
>  
>  		rc = ll_migrate(inode, file, mdtidx, filename, namelen - 1);
>  migrate_free:
> -		kvfree(buf);
>  
>  		return rc;
>  	}
> diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
> index 8e09fdd7a96e..e2417cd5aaed 100644
> --- a/drivers/staging/lustre/lustre/llite/llite_lib.c
> +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
> @@ -2295,7 +2295,6 @@ int ll_obd_statfs(struct inode *inode, void __user *arg)
>  {
>  	struct ll_sb_info *sbi = NULL;
>  	struct obd_export *exp;
> -	char *buf = NULL;
>  	struct obd_ioctl_data *data = NULL;
>  	u32 type;
>  	int len = 0, rc;
> @@ -2311,11 +2310,10 @@ int ll_obd_statfs(struct inode *inode, void __user *arg)
>  		goto out_statfs;
>  	}
>  
> -	rc = obd_ioctl_getdata(&buf, &len, arg);
> +	rc = obd_ioctl_getdata(&data, &len, arg);
>  	if (rc)
>  		goto out_statfs;
>  
> -	data = (void *)buf;
>  	if (!data->ioc_inlbuf1 || !data->ioc_inlbuf2 ||
>  	    !data->ioc_pbuf1 || !data->ioc_pbuf2) {
>  		rc = -EINVAL;
> @@ -2340,11 +2338,11 @@ int ll_obd_statfs(struct inode *inode, void __user *arg)
>  		goto out_statfs;
>  	}
>  
> -	rc = obd_iocontrol(IOC_OBD_STATFS, exp, len, buf, NULL);
> +	rc = obd_iocontrol(IOC_OBD_STATFS, exp, len, data, NULL);
>  	if (rc)
>  		goto out_statfs;
>  out_statfs:
> -	kvfree(buf);
> +	kvfree(data);
>  	return rc;
>  }
>  
> diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c
> index 04d0a9ed1d05..fd769c39b482 100644
> --- a/drivers/staging/lustre/lustre/lov/lov_obd.c
> +++ b/drivers/staging/lustre/lustre/lov/lov_obd.c
> @@ -1039,27 +1039,24 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
>  	case OBD_IOC_LOV_GET_CONFIG: {
>  		struct obd_ioctl_data *data;
>  		struct lov_desc *desc;
> -		char *buf = NULL;
>  		u32 *genp;
>  
>  		len = 0;
> -		if (obd_ioctl_getdata(&buf, &len, uarg))
> +		if (obd_ioctl_getdata(&data, &len, uarg))
>  			return -EINVAL;
>  
> -		data = (struct obd_ioctl_data *)buf;
> -
>  		if (sizeof(*desc) > data->ioc_inllen1) {
> -			kvfree(buf);
> +			kvfree(data);
>  			return -EINVAL;
>  		}
>  
>  		if (sizeof(uuidp->uuid) * count > data->ioc_inllen2) {
> -			kvfree(buf);
> +			kvfree(data);
>  			return -EINVAL;
>  		}
>  
>  		if (sizeof(u32) * count > data->ioc_inllen3) {
> -			kvfree(buf);
> +			kvfree(data);
>  			return -EINVAL;
>  		}
>  
> @@ -1076,9 +1073,9 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
>  			*genp = lov->lov_tgts[i]->ltd_gen;
>  		}
>  
> -		if (copy_to_user(uarg, buf, len))
> +		if (copy_to_user(uarg, data, len))
>  			rc = -EFAULT;
> -		kvfree(buf);
> +		kvfree(data);
>  		break;
>  	}
>  	case OBD_IOC_QUOTACTL: {
> diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c
> index b859ab19b9f6..2ef4fd41cdd0 100644
> --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
> +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
> @@ -230,7 +230,7 @@ static int obd_ioctl_is_invalid(struct obd_ioctl_data *data)
>  }
>  
>  /* buffer MUST be at least the size of obd_ioctl_hdr */
> -int obd_ioctl_getdata(char **buf, int *len, void __user *arg)
> +int obd_ioctl_getdata(struct obd_ioctl_data **datap, int *len, void __user *arg)
>  {
>  	struct obd_ioctl_data *data;
>  	struct obd_ioctl_hdr hdr;
> @@ -262,16 +262,16 @@ int obd_ioctl_getdata(char **buf, int *len, void __user *arg)
>  	 * obdfilter-survey is an example, which relies on ioctl. So we'd
>  	 * better avoid vmalloc on ioctl path. LU-66
>  	 */
> -	*buf = kvzalloc(hdr.ioc_len, GFP_KERNEL);
> -	if (!*buf) {
> +	data = kvzalloc(hdr.ioc_len, GFP_KERNEL);
> +	if (!data) {
>  		CERROR("Cannot allocate control buffer of len %d\n",
>  		       hdr.ioc_len);
>  		return -EINVAL;
>  	}
>  	*len = hdr.ioc_len;
> -	data = (struct obd_ioctl_data *)*buf;
> +	*datap = data;
>  
> -	if (copy_from_user(*buf, arg, hdr.ioc_len)) {
> +	if (copy_from_user(data, arg, hdr.ioc_len)) {
>  		err = -EFAULT;
>  		goto free_buf;
>  	}
> @@ -308,14 +308,13 @@ int obd_ioctl_getdata(char **buf, int *len, void __user *arg)
>  	return 0;
>  
>  free_buf:
> -	kvfree(*buf);
> +	kvfree(data);
>  	return err;
>  }
>  EXPORT_SYMBOL(obd_ioctl_getdata);
>  
>  int class_handle_ioctl(unsigned int cmd, unsigned long arg)
>  {
> -	char *buf = NULL;
>  	struct obd_ioctl_data *data;
>  	struct libcfs_debug_ioctl_data *debug_data;
>  	struct obd_device *obd = NULL;
> @@ -330,11 +329,10 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
>  	}
>  
>  	CDEBUG(D_IOCTL, "cmd = %x\n", cmd);
> -	if (obd_ioctl_getdata(&buf, &len, (void __user *)arg)) {
> +	if (obd_ioctl_getdata(&data, &len, (void __user *)arg)) {
>  		CERROR("OBD ioctl: data error\n");
>  		return -EINVAL;
>  	}
> -	data = (struct obd_ioctl_data *)buf;
>  
>  	switch (cmd) {
>  	case OBD_IOC_PROCESS_CFG: {
> @@ -545,7 +543,7 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
>  	}
>  
>   out:
> -	kvfree(buf);
> +	kvfree(data);
>  	return err;
>  } /* class_handle_ioctl */
>  
> 
> 
> 

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

* [lustre-devel] [PATCH 16/21] lustre: obdclass: normalize a switch statement.
  2019-02-07  0:03 ` [lustre-devel] [PATCH 16/21] lustre: obdclass: normalize a switch statement NeilBrown
  2019-02-08  5:57   ` Andreas Dilger
@ 2019-02-11  4:03   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: James Simmons @ 2019-02-11  4:03 UTC (permalink / raw)
  To: lustre-devel


> Remove the unnecessary {}, and use "break" rather than
> "goto out;" for normal exit from the cases.

Reviewed-by: James Simmons <jsimmons@infradead.org>
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/obdclass/class_obd.c |   10 ++++------
>  1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c
> index 2ef4fd41cdd0..48d1dabafa65 100644
> --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
> +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
> @@ -518,7 +518,7 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
>  	}
>  
>  	switch (cmd) {
> -	case OBD_IOC_NO_TRANSNO: {
> +	case OBD_IOC_NO_TRANSNO:
>  		if (!obd->obd_attached) {
>  			CERROR("Device %d not attached\n", obd->obd_minor);
>  			err = -ENODEV;
> @@ -528,18 +528,16 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
>  		       obd->obd_name);
>  		obd->obd_no_transno = 1;
>  		err = 0;
> -		goto out;
> -	}
> +		break;
>  
> -	default: {
> +	default:
>  		err = obd_iocontrol(cmd, obd->obd_self_export, len, data, NULL);
>  		if (err)
>  			goto out;
>  
>  		if (copy_to_user((void __user *)arg, data, len))
>  			err = -EFAULT;
> -		goto out;
> -	}
> +		break;
>  	}
>  
>   out:
> 
> 
> 

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

* [lustre-devel] [PATCH 18/21] lustre: move debug.c from obdclass to obdecho
  2019-02-07  0:03 ` [lustre-devel] [PATCH 18/21] lustre: move debug.c from obdclass to obdecho NeilBrown
  2019-02-08  6:02   ` Andreas Dilger
@ 2019-02-11  4:17   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: James Simmons @ 2019-02-11  4:17 UTC (permalink / raw)
  To: lustre-devel


> The functions defined in debug.c are only used in
> obdecho, so move it there, and make the functions local
> to that unit.
> This allows lustre_debug.h to be removed.

Reviewed-by: James Simmons <jsimmons@infradead.org>
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  .../staging/lustre/lustre/include/lustre_debug.h   |   52 -----------
>  .../staging/lustre/lustre/llite/llite_internal.h   |    2 
>  drivers/staging/lustre/lustre/obdclass/Makefile    |    2 
>  drivers/staging/lustre/lustre/obdclass/class_obd.c |    1 
>  drivers/staging/lustre/lustre/obdclass/debug.c     |   96 --------------------
>  drivers/staging/lustre/lustre/obdecho/Makefile     |    2 
>  drivers/staging/lustre/lustre/obdecho/debug.c      |   96 ++++++++++++++++++++
>  .../staging/lustre/lustre/obdecho/echo_client.c    |    1 
>  .../staging/lustre/lustre/obdecho/echo_internal.h  |    4 +
>  drivers/staging/lustre/lustre/osc/osc_request.c    |    1 
>  drivers/staging/lustre/lustre/ptlrpc/layout.c      |    1 
>  11 files changed, 103 insertions(+), 155 deletions(-)
>  delete mode 100644 drivers/staging/lustre/lustre/include/lustre_debug.h
>  delete mode 100644 drivers/staging/lustre/lustre/obdclass/debug.c
>  create mode 100644 drivers/staging/lustre/lustre/obdecho/debug.c
> 
> diff --git a/drivers/staging/lustre/lustre/include/lustre_debug.h b/drivers/staging/lustre/lustre/include/lustre_debug.h
> deleted file mode 100644
> index b9414fc73f00..000000000000
> --- a/drivers/staging/lustre/lustre/include/lustre_debug.h
> +++ /dev/null
> @@ -1,52 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -/*
> - * GPL HEADER START
> - *
> - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 only,
> - * as published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful, but
> - * WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> - * General Public License version 2 for more details (a copy is included
> - * in the LICENSE file that accompanied this code).
> - *
> - * You should have received a copy of the GNU General Public License
> - * version 2 along with this program; If not, see
> - * http://www.gnu.org/licenses/gpl-2.0.html
> - *
> - * GPL HEADER END
> - */
> -/*
> - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
> - * Use is subject to license terms.
> - *
> - * Copyright (c) 2011, Intel Corporation.
> - */
> -/*
> - * This file is part of Lustre, http://www.lustre.org/
> - * Lustre is a trademark of Sun Microsystems, Inc.
> - */
> -
> -#ifndef _LUSTRE_DEBUG_H
> -#define _LUSTRE_DEBUG_H
> -
> -/** \defgroup debug debug
> - *
> - * @{
> - */
> -
> -#include <lustre_net.h>
> -#include <obd.h>
> -
> -/* lib/debug.c */
> -int dump_req(struct ptlrpc_request *req);
> -int block_debug_setup(void *addr, int len, u64 off, u64 id);
> -int block_debug_check(char *who, void *addr, int len, u64 off, u64 id);
> -
> -/** @} debug */
> -
> -#endif
> diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h
> index bf7e46fe9ec6..c8860904bdd4 100644
> --- a/drivers/staging/lustre/lustre/llite/llite_internal.h
> +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h
> @@ -33,7 +33,7 @@
>  
>  #ifndef LLITE_INTERNAL_H
>  #define LLITE_INTERNAL_H
> -#include <lustre_debug.h>
> +#include <obd.h>
>  #include <uapi/linux/lustre/lustre_ver.h>
>  #include <lustre_disk.h>	/* for s2sbi */
>  #include <lustre_linkea.h>
> diff --git a/drivers/staging/lustre/lustre/obdclass/Makefile b/drivers/staging/lustre/lustre/obdclass/Makefile
> index b1fac48b3adc..1669c24a0b03 100644
> --- a/drivers/staging/lustre/lustre/obdclass/Makefile
> +++ b/drivers/staging/lustre/lustre/obdclass/Makefile
> @@ -4,7 +4,7 @@ ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
>  
>  obj-$(CONFIG_LUSTRE_FS) += obdclass.o
>  
> -obdclass-y := llog.o llog_cat.o llog_obd.o llog_swab.o class_obd.o debug.o \
> +obdclass-y := llog.o llog_cat.o llog_obd.o llog_swab.o class_obd.o \
>  	      genops.o obd_sysfs.o lprocfs_status.o lprocfs_counters.o \
>  	      lustre_handles.o lustre_peer.o statfs_pack.o linkea.o \
>  	      obdo.o obd_config.o obd_mount.o lu_object.o lu_ref.o \
> diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c
> index 982d47b6f50e..4a717a29e385 100644
> --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
> +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
> @@ -41,7 +41,6 @@
>  #include <obd_support.h>
>  #include <obd_class.h>
>  #include <uapi/linux/lnet/lnetctl.h>
> -#include <lustre_debug.h>
>  #include <lustre_kernelcomm.h>
>  #include <lprocfs_status.h>
>  #include <linux/list.h>
> diff --git a/drivers/staging/lustre/lustre/obdclass/debug.c b/drivers/staging/lustre/lustre/obdclass/debug.c
> deleted file mode 100644
> index 2e526c7389d8..000000000000
> --- a/drivers/staging/lustre/lustre/obdclass/debug.c
> +++ /dev/null
> @@ -1,96 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -/*
> - * GPL HEADER START
> - *
> - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 only,
> - * as published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful, but
> - * WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> - * General Public License version 2 for more details (a copy is included
> - * in the LICENSE file that accompanied this code).
> - *
> - * You should have received a copy of the GNU General Public License
> - * version 2 along with this program; If not, see
> - * http://www.gnu.org/licenses/gpl-2.0.html
> - *
> - * GPL HEADER END
> - */
> -/*
> - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
> - * Use is subject to license terms.
> - *
> - * Copyright (c) 2011, 2012, Intel Corporation.
> - */
> -/*
> - * This file is part of Lustre, http://www.lustre.org/
> - * Lustre is a trademark of Sun Microsystems, Inc.
> - *
> - * lustre/obdclass/debug.c
> - *
> - * Helper routines for dumping data structs for debugging.
> - */
> -
> -#define DEBUG_SUBSYSTEM D_OTHER
> -
> -#include <asm/unaligned.h>
> -
> -#include <obd_support.h>
> -#include <lustre_debug.h>
> -#include <lustre_net.h>
> -
> -#define LPDS sizeof(u64)
> -int block_debug_setup(void *addr, int len, u64 off, u64 id)
> -{
> -	LASSERT(addr);
> -
> -	put_unaligned_le64(off, addr);
> -	put_unaligned_le64(id, addr + LPDS);
> -	addr += len - LPDS - LPDS;
> -	put_unaligned_le64(off, addr);
> -	put_unaligned_le64(id, addr + LPDS);
> -
> -	return 0;
> -}
> -EXPORT_SYMBOL(block_debug_setup);
> -
> -int block_debug_check(char *who, void *addr, int end, u64 off, u64 id)
> -{
> -	u64 ne_off;
> -	int err = 0;
> -
> -	LASSERT(addr);
> -
> -	ne_off = le64_to_cpu(off);
> -	id = le64_to_cpu(id);
> -	if (memcmp(addr, (char *)&ne_off, LPDS)) {
> -		CDEBUG(D_ERROR, "%s: id %#llx offset %llu off: %#llx != %#llx\n",
> -		       who, id, off, *(u64 *)addr, ne_off);
> -		err = -EINVAL;
> -	}
> -	if (memcmp(addr + LPDS, (char *)&id, LPDS)) {
> -		CDEBUG(D_ERROR, "%s: id %#llx offset %llu id: %#llx != %#llx\n",
> -		       who, id, off, *(u64 *)(addr + LPDS), id);
> -		err = -EINVAL;
> -	}
> -
> -	addr += end - LPDS - LPDS;
> -	if (memcmp(addr, (char *)&ne_off, LPDS)) {
> -		CDEBUG(D_ERROR, "%s: id %#llx offset %llu end off: %#llx != %#llx\n",
> -		       who, id, off, *(u64 *)addr, ne_off);
> -		err = -EINVAL;
> -	}
> -	if (memcmp(addr + LPDS, (char *)&id, LPDS)) {
> -		CDEBUG(D_ERROR, "%s: id %#llx offset %llu end id: %#llx != %#llx\n",
> -		       who, id, off, *(u64 *)(addr + LPDS), id);
> -		err = -EINVAL;
> -	}
> -
> -	return err;
> -}
> -EXPORT_SYMBOL(block_debug_check);
> -#undef LPDS
> diff --git a/drivers/staging/lustre/lustre/obdecho/Makefile b/drivers/staging/lustre/lustre/obdecho/Makefile
> index ff85ef1db70a..0a02efae036d 100644
> --- a/drivers/staging/lustre/lustre/obdecho/Makefile
> +++ b/drivers/staging/lustre/lustre/obdecho/Makefile
> @@ -2,4 +2,4 @@ ccflags-y += -I$(srctree)/drivers/staging/lustre/include
>  ccflags-y += -I$(srctree)/drivers/staging/lustre/lustre/include
>  
>  obj-$(CONFIG_LUSTRE_FS) += obdecho.o
> -obdecho-y := echo_client.o
> +obdecho-y := echo_client.o debug.o
> diff --git a/drivers/staging/lustre/lustre/obdecho/debug.c b/drivers/staging/lustre/lustre/obdecho/debug.c
> new file mode 100644
> index 000000000000..149aca54c776
> --- /dev/null
> +++ b/drivers/staging/lustre/lustre/obdecho/debug.c
> @@ -0,0 +1,96 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * GPL HEADER START
> + *
> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 only,
> + * as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License version 2 for more details (a copy is included
> + * in the LICENSE file that accompanied this code).
> + *
> + * You should have received a copy of the GNU General Public License
> + * version 2 along with this program; If not, see
> + * http://www.gnu.org/licenses/gpl-2.0.html
> + *
> + * GPL HEADER END
> + */
> +/*
> + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
> + * Use is subject to license terms.
> + *
> + * Copyright (c) 2011, 2012, Intel Corporation.
> + */
> +/*
> + * This file is part of Lustre, http://www.lustre.org/
> + * Lustre is a trademark of Sun Microsystems, Inc.
> + *
> + * lustre/obdclass/debug.c
> + *
> + * Helper routines for dumping data structs for debugging.
> + */
> +
> +#define DEBUG_SUBSYSTEM D_OTHER
> +
> +#include <asm/unaligned.h>
> +
> +#include <obd_support.h>
> +#include "echo_internal.h"
> +#include <lustre_net.h>
> +
> +#define LPDS sizeof(u64)
> +int block_debug_setup(void *addr, int len, u64 off, u64 id)
> +{
> +	LASSERT(addr);
> +
> +	put_unaligned_le64(off, addr);
> +	put_unaligned_le64(id, addr + LPDS);
> +	addr += len - LPDS - LPDS;
> +	put_unaligned_le64(off, addr);
> +	put_unaligned_le64(id, addr + LPDS);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(block_debug_setup);
> +
> +int block_debug_check(char *who, void *addr, int end, u64 off, u64 id)
> +{
> +	u64 ne_off;
> +	int err = 0;
> +
> +	LASSERT(addr);
> +
> +	ne_off = le64_to_cpu(off);
> +	id = le64_to_cpu(id);
> +	if (memcmp(addr, (char *)&ne_off, LPDS)) {
> +		CDEBUG(D_ERROR, "%s: id %#llx offset %llu off: %#llx != %#llx\n",
> +		       who, id, off, *(u64 *)addr, ne_off);
> +		err = -EINVAL;
> +	}
> +	if (memcmp(addr + LPDS, (char *)&id, LPDS)) {
> +		CDEBUG(D_ERROR, "%s: id %#llx offset %llu id: %#llx != %#llx\n",
> +		       who, id, off, *(u64 *)(addr + LPDS), id);
> +		err = -EINVAL;
> +	}
> +
> +	addr += end - LPDS - LPDS;
> +	if (memcmp(addr, (char *)&ne_off, LPDS)) {
> +		CDEBUG(D_ERROR, "%s: id %#llx offset %llu end off: %#llx != %#llx\n",
> +		       who, id, off, *(u64 *)addr, ne_off);
> +		err = -EINVAL;
> +	}
> +	if (memcmp(addr + LPDS, (char *)&id, LPDS)) {
> +		CDEBUG(D_ERROR, "%s: id %#llx offset %llu end id: %#llx != %#llx\n",
> +		       who, id, off, *(u64 *)(addr + LPDS), id);
> +		err = -EINVAL;
> +	}
> +
> +	return err;
> +}
> +EXPORT_SYMBOL(block_debug_check);
> +#undef LPDS
> diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c
> index 1ebd98513239..1b7d98c649b6 100644
> --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c
> +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c
> @@ -37,7 +37,6 @@
>  #include <obd.h>
>  #include <obd_support.h>
>  #include <obd_class.h>
> -#include <lustre_debug.h>
>  #include <lprocfs_status.h>
>  #include <cl_object.h>
>  #include <lustre_fid.h>
> diff --git a/drivers/staging/lustre/lustre/obdecho/echo_internal.h b/drivers/staging/lustre/lustre/obdecho/echo_internal.h
> index 8094a94f605c..f9bb0b91d399 100644
> --- a/drivers/staging/lustre/lustre/obdecho/echo_internal.h
> +++ b/drivers/staging/lustre/lustre/obdecho/echo_internal.h
> @@ -39,4 +39,8 @@
>  /* block size to use for data verification */
>  #define OBD_ECHO_BLOCK_SIZE	(4 << 10)
>  
> +/* debug.c */
> +int block_debug_setup(void *addr, int len, u64 off, u64 id);
> +int block_debug_check(char *who, void *addr, int len, u64 off, u64 id);
> +
>  #endif
> diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
> index 0dfc506f6d01..3fedfaf249c4 100644
> --- a/drivers/staging/lustre/lustre/osc/osc_request.c
> +++ b/drivers/staging/lustre/lustre/osc/osc_request.c
> @@ -45,7 +45,6 @@
>  #include <lustre_ha.h>
>  #include <lprocfs_status.h>
>  #include <uapi/linux/lustre/lustre_ioctl.h>
> -#include <lustre_debug.h>
>  #include <lustre_obdo.h>
>  #include <uapi/linux/lustre/lustre_param.h>
>  #include <lustre_fid.h>
> diff --git a/drivers/staging/lustre/lustre/ptlrpc/layout.c b/drivers/staging/lustre/lustre/ptlrpc/layout.c
> index f1f7d70b9790..d9f2b3d9e526 100644
> --- a/drivers/staging/lustre/lustre/ptlrpc/layout.c
> +++ b/drivers/staging/lustre/lustre/ptlrpc/layout.c
> @@ -50,7 +50,6 @@
>  #include <uapi/linux/lustre/lustre_idl.h>
>  
>  #include <llog_swab.h>
> -#include <lustre_debug.h>
>  #include <lustre_swab.h>
>  #include <uapi/linux/lustre/lustre_ver.h>
>  #include <obd.h>
> 
> 
> 

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

* [lustre-devel] [PATCH 21/21] lustre: make exp_refcount in obd_export a refcount_t
  2019-02-07  0:03 ` [lustre-devel] [PATCH 21/21] lustre: make exp_refcount in obd_export a refcount_t NeilBrown
  2019-02-08  7:07   ` Andreas Dilger
@ 2019-02-11  4:18   ` James Simmons
  1 sibling, 0 replies; 87+ messages in thread
From: James Simmons @ 2019-02-11  4:18 UTC (permalink / raw)
  To: lustre-devel


> As this is used as a refcount, it should be declared
> as one.

Reviewed-by: James Simmons <jsimmons@infradead.org>
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  .../staging/lustre/lustre/include/lustre_export.h  |    2 +-
>  drivers/staging/lustre/lustre/ldlm/ldlm_lock.c     |   10 +++++-----
>  drivers/staging/lustre/lustre/obdclass/genops.c    |   15 ++++++++-------
>  .../staging/lustre/lustre/obdecho/echo_client.c    |    2 +-
>  drivers/staging/lustre/lustre/ptlrpc/service.c     |    4 ++--
>  5 files changed, 17 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/include/lustre_export.h b/drivers/staging/lustre/lustre/include/lustre_export.h
> index 63fa656eb7ba..fb34e0b7de35 100644
> --- a/drivers/staging/lustre/lustre/include/lustre_export.h
> +++ b/drivers/staging/lustre/lustre/include/lustre_export.h
> @@ -67,7 +67,7 @@ struct obd_export {
>  	 * what export they are talking to.
>  	 */
>  	struct portals_handle		exp_handle;
> -	atomic_t			exp_refcount;
> +	refcount_t			exp_refcount;
>  	/**
>  	 * Set of counters below is to track where export references are
>  	 * kept. The exp_rpc_count is used for reconnect handling also,
> diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
> index cea0e22d064b..f2433dc0e558 100644
> --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
> +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
> @@ -1998,7 +1998,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
>  				   ldlm_lockname[lock->l_req_mode],
>  				   lock->l_flags, nid,
>  				   lock->l_remote_handle.cookie,
> -				   exp ? atomic_read(&exp->exp_refcount) : -99,
> +				   exp ? refcount_read(&exp->exp_refcount) : -99,
>  				   lock->l_pid, lock->l_callback_timeout,
>  				   lock->l_lvb_type);
>  		va_end(args);
> @@ -2024,7 +2024,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
>  				   lock->l_req_extent.end,
>  				   lock->l_flags, nid,
>  				   lock->l_remote_handle.cookie,
> -				   exp ? atomic_read(&exp->exp_refcount) : -99,
> +				   exp ? refcount_read(&exp->exp_refcount) : -99,
>  				   lock->l_pid, lock->l_callback_timeout,
>  				   lock->l_lvb_type);
>  		break;
> @@ -2046,7 +2046,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
>  				   lock->l_policy_data.l_flock.end,
>  				   lock->l_flags, nid,
>  				   lock->l_remote_handle.cookie,
> -				   exp ? atomic_read(&exp->exp_refcount) : -99,
> +				   exp ? refcount_read(&exp->exp_refcount) : -99,
>  				   lock->l_pid, lock->l_callback_timeout);
>  		break;
>  
> @@ -2065,7 +2065,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
>  				   ldlm_typename[resource->lr_type],
>  				   lock->l_flags, nid,
>  				   lock->l_remote_handle.cookie,
> -				   exp ? atomic_read(&exp->exp_refcount) : -99,
> +				   exp ? refcount_read(&exp->exp_refcount) : -99,
>  				   lock->l_pid, lock->l_callback_timeout,
>  				   lock->l_lvb_type);
>  		break;
> @@ -2084,7 +2084,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
>  				   ldlm_typename[resource->lr_type],
>  				   lock->l_flags, nid,
>  				   lock->l_remote_handle.cookie,
> -				   exp ? atomic_read(&exp->exp_refcount) : -99,
> +				   exp ? refcount_read(&exp->exp_refcount) : -99,
>  				   lock->l_pid, lock->l_callback_timeout,
>  				   lock->l_lvb_type);
>  		break;
> diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
> index dad21d9fa328..39919f1c5b71 100644
> --- a/drivers/staging/lustre/lustre/obdclass/genops.c
> +++ b/drivers/staging/lustre/lustre/obdclass/genops.c
> @@ -757,7 +757,7 @@ static void class_export_destroy(struct obd_export *exp)
>  {
>  	struct obd_device *obd = exp->exp_obd;
>  
> -	LASSERT_ATOMIC_ZERO(&exp->exp_refcount);
> +	LASSERT(refcount_read(&exp->exp_refcount) == 0);
>  	LASSERT(obd);
>  
>  	CDEBUG(D_IOCTL, "destroying export %p/%s for %s\n", exp,
> @@ -793,20 +793,21 @@ static struct portals_handle_ops export_handle_ops = {
>  
>  struct obd_export *class_export_get(struct obd_export *exp)
>  {
> -	atomic_inc(&exp->exp_refcount);
> +	refcount_inc(&exp->exp_refcount);
>  	CDEBUG(D_INFO, "GETting export %p : new refcount %d\n", exp,
> -	       atomic_read(&exp->exp_refcount));
> +	       refcount_read(&exp->exp_refcount));
>  	return exp;
>  }
>  EXPORT_SYMBOL(class_export_get);
>  
>  void class_export_put(struct obd_export *exp)
>  {
> -	LASSERT_ATOMIC_GT_LT(&exp->exp_refcount, 0, LI_POISON);
> +	LASSERT(refcount_read(&exp->exp_refcount) >  0);
> +	LASSERT(refcount_read(&exp->exp_refcount) < LI_POISON);
>  	CDEBUG(D_INFO, "PUTting export %p : new refcount %d\n", exp,
> -	       atomic_read(&exp->exp_refcount) - 1);
> +	       refcount_read(&exp->exp_refcount) - 1);
>  
> -	if (atomic_dec_and_test(&exp->exp_refcount)) {
> +	if (refcount_dec_and_test(&exp->exp_refcount)) {
>  		struct obd_device *obd = exp->exp_obd;
>  
>  		CDEBUG(D_IOCTL, "final put %p/%s\n",
> @@ -856,7 +857,7 @@ static struct obd_export *__class_new_export(struct obd_device *obd,
>  
>  	export->exp_conn_cnt = 0;
>  	/* 2 = class_handle_hash + last */
> -	atomic_set(&export->exp_refcount, 2);
> +	refcount_set(&export->exp_refcount, 2);
>  	atomic_set(&export->exp_rpc_count, 0);
>  	atomic_set(&export->exp_cb_count, 0);
>  	atomic_set(&export->exp_locks_count, 0);
> diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c
> index 1b7d98c649b6..317123fd27cb 100644
> --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c
> +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c
> @@ -1638,7 +1638,7 @@ static int echo_client_cleanup(struct obd_device *obddev)
>  		return -EBUSY;
>  	}
>  
> -	LASSERT(atomic_read(&ec->ec_exp->exp_refcount) > 0);
> +	LASSERT(refcount_read(&ec->ec_exp->exp_refcount) > 0);
>  	rc = obd_disconnect(ec->ec_exp);
>  	if (rc != 0)
>  		CERROR("fail to disconnect device: %d\n", rc);
> diff --git a/drivers/staging/lustre/lustre/ptlrpc/service.c b/drivers/staging/lustre/lustre/ptlrpc/service.c
> index 35a59e5a5e9d..b7d44fc21d73 100644
> --- a/drivers/staging/lustre/lustre/ptlrpc/service.c
> +++ b/drivers/staging/lustre/lustre/ptlrpc/service.c
> @@ -1697,7 +1697,7 @@ ptlrpc_server_handle_request(struct ptlrpc_service_part *svcpt,
>  	       (request->rq_export ?
>  		(char *)request->rq_export->exp_client_uuid.uuid : "0"),
>  	       (request->rq_export ?
> -		atomic_read(&request->rq_export->exp_refcount) : -99),
> +		refcount_read(&request->rq_export->exp_refcount) : -99),
>  	       lustre_msg_get_status(request->rq_reqmsg), request->rq_xid,
>  	       libcfs_id2str(request->rq_peer),
>  	       lustre_msg_get_opc(request->rq_reqmsg));
> @@ -1741,7 +1741,7 @@ ptlrpc_server_handle_request(struct ptlrpc_service_part *svcpt,
>  	       (request->rq_export ?
>  		(char *)request->rq_export->exp_client_uuid.uuid : "0"),
>  	       (request->rq_export ?
> -		atomic_read(&request->rq_export->exp_refcount) : -99),
> +		refcount_read(&request->rq_export->exp_refcount) : -99),
>  	       lustre_msg_get_status(request->rq_reqmsg),
>  	       request->rq_xid,
>  	       libcfs_id2str(request->rq_peer),
> 
> 
> 

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

* [lustre-devel] [PATCH 10/21] lustre: obdclass: use cl_object_for_each where appropriate
  2019-02-11  0:42     ` NeilBrown
@ 2019-02-11  4:19       ` James Simmons
  2019-02-15 18:15       ` Andreas Dilger
  1 sibling, 0 replies; 87+ messages in thread
From: James Simmons @ 2019-02-11  4:19 UTC (permalink / raw)
  To: lustre-devel

> On Fri, Feb 08 2019, Andreas Dilger wrote:
> 
> > On Feb 6, 2019, at 17:03, NeilBrown <neilb@suse.com> wrote:
> >> 
> >> There are various places which have a list_for_each_entry()
> >> where cl_object_for_each (or .._reverse) is more appropriate.
> >> 
> >> Several of these re-use the 'obj' function parameter as a loop
> >> iterator, which is a little confusing.
> >> 
> >> Change these to use cl_object_for_each{_reverse}, and where needed,
> >> introduce a new iterator variable 'o'.
> >> 
> >> Signed-off-by: NeilBrown <neilb@suse.com>
> >> ---
> >> drivers/staging/lustre/lustre/lov/lov_page.c       |    3 -
> >> drivers/staging/lustre/lustre/obdclass/cl_lock.c   |    3 -
> >> drivers/staging/lustre/lustre/obdclass/cl_object.c |   82 +++++++++-----------
> >> drivers/staging/lustre/lustre/obdclass/cl_page.c   |   11 +--
> >> 4 files changed, 44 insertions(+), 55 deletions(-)
> >> 
> >> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> >> index f724b2d62df1..d71a680660da 100644
> >> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
> >> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> >> @@ -190,16 +190,15 @@ EXPORT_SYMBOL(cl_object_attr_unlock);
> >> int cl_object_attr_get(const struct lu_env *env, struct cl_object *obj,
> >> 		       struct cl_attr *attr)
> >> {
> >> -	struct lu_object_header *top;
> >> +	struct cl_object *o;
> >> 	int result;
> >> 
> >> 	assert_spin_locked(cl_object_attr_guard(obj));
> >> 
> >> -	top = obj->co_lu.lo_header;
> >> 	result = 0;
> >
> > May as well move the "result = 0" initialization to the declaration for
> > all of these?  Another 5 fewer lines of code under your belt.
> 
> Yes, that seem good. New patch below.
> Thanks,
> NeilBrown
> 
> 
> From: NeilBrown <neilb@suse.com>
> Subject: [PATCH] lustre: obdclass: use cl_object_for_each where appropriate
> 
> There are various places which have a list_for_each_entry()
> where cl_object_for_each (or .._reverse) is more appropriate.
> 
> Several of these re-use the 'obj' function parameter as a loop
> iterator, which is a little confusing.
> 
> Change these to use cl_object_for_each{_reverse}, and where needed,
> introduce a new iterator variable 'o'.
> 
> To further clean up these function, move initializtion of 'result'
> to the variable declaration.

Good with this version as well.

Reviewed-by: James Simmons <jsimmons@infradead.org>
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/lov/lov_page.c       |  3 +-
>  drivers/staging/lustre/lustre/obdclass/cl_lock.c   |  3 +-
>  drivers/staging/lustre/lustre/obdclass/cl_object.c | 97 ++++++++++------------
>  drivers/staging/lustre/lustre/obdclass/cl_page.c   | 11 ++-
>  4 files changed, 49 insertions(+), 65 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/lov/lov_page.c b/drivers/staging/lustre/lustre/lov/lov_page.c
> index 08485a95ec01..e64b350601d2 100644
> --- a/drivers/staging/lustre/lustre/lov/lov_page.c
> +++ b/drivers/staging/lustre/lustre/lov/lov_page.c
> @@ -103,8 +103,7 @@ int lov_page_init_composite(const struct lu_env *env, struct cl_object *obj,
>  		return PTR_ERR(sub);
>  
>  	subobj = lovsub2cl(r0->lo_sub[stripe]);
> -	list_for_each_entry(o, &subobj->co_lu.lo_header->loh_layers,
> -			    co_lu.lo_linkage) {
> +	cl_object_for_each(o, subobj) {
>  		if (o->co_ops->coo_page_init) {
>  			rc = o->co_ops->coo_page_init(sub->sub_env, o, page,
>  						      cl_index(subobj, suboff));
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
> index 8133d992cc73..fc5976d8b37b 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
> @@ -103,8 +103,7 @@ int cl_lock_init(const struct lu_env *env, struct cl_lock *lock,
>  	LASSERT(obj);
>  
>  	INIT_LIST_HEAD(&lock->cll_layers);
> -	list_for_each_entry(scan, &obj->co_lu.lo_header->loh_layers,
> -			    co_lu.lo_linkage) {
> +	cl_object_for_each(scan, obj) {
>  		result = scan->co_ops->coo_lock_init(env, scan, lock, io);
>  		if (result != 0) {
>  			cl_lock_fini(env, lock);
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> index f724b2d62df1..43bf1a422635 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> @@ -190,16 +190,14 @@ EXPORT_SYMBOL(cl_object_attr_unlock);
>  int cl_object_attr_get(const struct lu_env *env, struct cl_object *obj,
>  		       struct cl_attr *attr)
>  {
> -	struct lu_object_header *top;
> -	int result;
> +	struct cl_object *o;
> +	int result = 0;
>  
>  	assert_spin_locked(cl_object_attr_guard(obj));
>  
> -	top = obj->co_lu.lo_header;
> -	result = 0;
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_attr_get) {
> -			result = obj->co_ops->coo_attr_get(env, obj, attr);
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_attr_get) {
> +			result = o->co_ops->coo_attr_get(env, o, attr);
>  			if (result != 0) {
>  				if (result > 0)
>  					result = 0;
> @@ -221,17 +219,15 @@ EXPORT_SYMBOL(cl_object_attr_get);
>  int cl_object_attr_update(const struct lu_env *env, struct cl_object *obj,
>  			  const struct cl_attr *attr, unsigned int v)
>  {
> -	struct lu_object_header *top;
> -	int result;
> +	struct cl_object *o;
> +	int result = 0;
>  
>  	assert_spin_locked(cl_object_attr_guard(obj));
>  
> -	top = obj->co_lu.lo_header;
> -	result = 0;
> -	list_for_each_entry_reverse(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_attr_update) {
> -			result = obj->co_ops->coo_attr_update(env, obj, attr,
> -							      v);
> +	cl_object_for_each_reverse(o, obj) {
> +		if (o->co_ops->coo_attr_update) {
> +			result = o->co_ops->coo_attr_update(env, o, attr,
> +							    v);
>  			if (result != 0) {
>  				if (result > 0)
>  					result = 0;
> @@ -254,19 +250,17 @@ EXPORT_SYMBOL(cl_object_attr_update);
>  int cl_object_glimpse(const struct lu_env *env, struct cl_object *obj,
>  		      struct ost_lvb *lvb)
>  {
> -	struct lu_object_header *top;
> -	int result;
> +	struct cl_object *o;
> +	int result = 0;
>  
> -	top = obj->co_lu.lo_header;
> -	result = 0;
> -	list_for_each_entry_reverse(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_glimpse) {
> -			result = obj->co_ops->coo_glimpse(env, obj, lvb);
> +	cl_object_for_each_reverse(o, obj) {
> +		if (o->co_ops->coo_glimpse) {
> +			result = o->co_ops->coo_glimpse(env, o, lvb);
>  			if (result != 0)
>  				break;
>  		}
>  	}
> -	LU_OBJECT_HEADER(D_DLMTRACE, env, lu_object_top(top),
> +	LU_OBJECT_HEADER(D_DLMTRACE, env, lu_object_top(obj->co_lu.lo_header),
>  			 "size: %llu mtime: %llu atime: %llu ctime: %llu blocks: %llu\n",
>  			 lvb->lvb_size, lvb->lvb_mtime, lvb->lvb_atime,
>  			 lvb->lvb_ctime, lvb->lvb_blocks);
> @@ -280,14 +274,12 @@ EXPORT_SYMBOL(cl_object_glimpse);
>  int cl_conf_set(const struct lu_env *env, struct cl_object *obj,
>  		const struct cl_object_conf *conf)
>  {
> -	struct lu_object_header *top;
> -	int result;
> +	struct cl_object *o;
> +	int result = 0;
>  
> -	top = obj->co_lu.lo_header;
> -	result = 0;
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_conf_set) {
> -			result = obj->co_ops->coo_conf_set(env, obj, conf);
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_conf_set) {
> +			result = o->co_ops->coo_conf_set(env, o, conf);
>  			if (result != 0)
>  				break;
>  		}
> @@ -301,13 +293,10 @@ EXPORT_SYMBOL(cl_conf_set);
>   */
>  int cl_object_prune(const struct lu_env *env, struct cl_object *obj)
>  {
> -	struct lu_object_header *top;
>  	struct cl_object *o;
> -	int result;
> +	int result = 0;
>  
> -	top = obj->co_lu.lo_header;
> -	result = 0;
> -	list_for_each_entry(o, &top->loh_layers, co_lu.lo_linkage) {
> +	cl_object_for_each(o, obj) {
>  		if (o->co_ops->coo_prune) {
>  			result = o->co_ops->coo_prune(env, o);
>  			if (result != 0)
> @@ -325,14 +314,13 @@ EXPORT_SYMBOL(cl_object_prune);
>  int cl_object_getstripe(const struct lu_env *env, struct cl_object *obj,
>  			struct lov_user_md __user *uarg, size_t size)
>  {
> -	struct lu_object_header *top;
> +	struct cl_object *o;
>  	int result = 0;
>  
> -	top = obj->co_lu.lo_header;
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_getstripe) {
> -			result = obj->co_ops->coo_getstripe(env, obj, uarg,
> -							    size);
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_getstripe) {
> +			result = o->co_ops->coo_getstripe(env, o, uarg,
> +							  size);
>  			if (result)
>  				break;
>  		}
> @@ -357,14 +345,13 @@ int cl_object_fiemap(const struct lu_env *env, struct cl_object *obj,
>  		     struct ll_fiemap_info_key *key,
>  		     struct fiemap *fiemap, size_t *buflen)
>  {
> -	struct lu_object_header *top;
> +	struct cl_object *o;
>  	int result = 0;
>  
> -	top = obj->co_lu.lo_header;
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_fiemap) {
> -			result = obj->co_ops->coo_fiemap(env, obj, key, fiemap,
> -							 buflen);
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_fiemap) {
> +			result = o->co_ops->coo_fiemap(env, o, key, fiemap,
> +						       buflen);
>  			if (result)
>  				break;
>  		}
> @@ -376,11 +363,11 @@ EXPORT_SYMBOL(cl_object_fiemap);
>  int cl_object_layout_get(const struct lu_env *env, struct cl_object *obj,
>  			 struct cl_layout *cl)
>  {
> -	struct lu_object_header *top = obj->co_lu.lo_header;
> +	struct cl_object *o;
>  
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_layout_get)
> -			return obj->co_ops->coo_layout_get(env, obj, cl);
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_layout_get)
> +			return o->co_ops->coo_layout_get(env, o, cl);
>  	}
>  
>  	return -EOPNOTSUPP;
> @@ -389,12 +376,12 @@ EXPORT_SYMBOL(cl_object_layout_get);
>  
>  loff_t cl_object_maxbytes(struct cl_object *obj)
>  {
> -	struct lu_object_header *top = obj->co_lu.lo_header;
> +	struct cl_object *o;
>  	loff_t maxbytes = LLONG_MAX;
>  
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_maxbytes)
> -			maxbytes = min_t(loff_t, obj->co_ops->coo_maxbytes(obj),
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_maxbytes)
> +			maxbytes = min_t(loff_t, o->co_ops->coo_maxbytes(o),
>  					 maxbytes);
>  	}
>  
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
> index 057318deaa4e..7d00a9233a3b 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
> @@ -132,7 +132,7 @@ struct cl_page *cl_page_alloc(const struct lu_env *env,
>  			      enum cl_page_type type)
>  {
>  	struct cl_page *page;
> -	struct lu_object_header *head;
> +	struct cl_object *o2;
>  
>  	page = kzalloc(cl_object_header(o)->coh_page_bufsize, GFP_NOFS);
>  	if (page) {
> @@ -149,11 +149,10 @@ struct cl_page *cl_page_alloc(const struct lu_env *env,
>  		INIT_LIST_HEAD(&page->cp_layers);
>  		INIT_LIST_HEAD(&page->cp_batch);
>  		lu_ref_init(&page->cp_reference);
> -		head = o->co_lu.lo_header;
> -		list_for_each_entry(o, &head->loh_layers, co_lu.lo_linkage) {
> -			if (o->co_ops->coo_page_init) {
> -				result = o->co_ops->coo_page_init(env, o, page,
> -								  ind);
> +		cl_object_for_each(o2, o) {
> +			if (o2->co_ops->coo_page_init) {
> +				result = o2->co_ops->coo_page_init(env, o2, page,
> +								   ind);
>  				if (result != 0) {
>  					__cl_page_delete(env, page);
>  					cl_page_free(env, page);
> -- 
> 2.14.0.rc0.dirty
> 
> 

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

* [lustre-devel] [PATCH 17/21] lustre: obdclass: result of try_module_get() should not be ignored.
  2019-02-07  0:03 ` [lustre-devel] [PATCH 17/21] lustre: obdclass: result of try_module_get() should not be ignored NeilBrown
  2019-02-08  5:58   ` Andreas Dilger
@ 2019-02-11  4:22   ` James Simmons
  2019-02-11  5:01     ` NeilBrown
  1 sibling, 1 reply; 87+ messages in thread
From: James Simmons @ 2019-02-11  4:22 UTC (permalink / raw)
  To: lustre-devel


> If try_module_get() fails, the open must fail.
> 
> In practice this should be impossible, but it is
> best to make the code look right.

I remembar having discussion with Greg about this approach in libcfs.
He though it was racey to do this in general. The discussion was a
while ago so I need to dig up the thread. In the end we remove the
whole module handling in the xxx_open() and such.
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/obdclass/class_obd.c |    3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c
> index 48d1dabafa65..982d47b6f50e 100644
> --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
> +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
> @@ -548,8 +548,7 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
>  /*  opening /dev/obd */
>  static int obd_class_open(struct inode *inode, struct file *file)
>  {
> -	try_module_get(THIS_MODULE);
> -	return 0;
> +	return try_module_get(THIS_MODULE) ? 0 : -ENODEV;
>  }
>  
>  /*  closing /dev/obd */
> 
> 
> 

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

* [lustre-devel] [PATCH 17/21] lustre: obdclass: result of try_module_get() should not be ignored.
  2019-02-11  4:22   ` James Simmons
@ 2019-02-11  5:01     ` NeilBrown
  2019-02-11  5:09       ` [lustre-devel] [PATCH] lustre: don't manage module refs in obd_class_open/close NeilBrown
  0 siblings, 1 reply; 87+ messages in thread
From: NeilBrown @ 2019-02-11  5:01 UTC (permalink / raw)
  To: lustre-devel

On Mon, Feb 11 2019, James Simmons wrote:

>> If try_module_get() fails, the open must fail.
>> 
>> In practice this should be impossible, but it is
>> best to make the code look right.
>
> I remembar having discussion with Greg about this approach in libcfs.
> He though it was racey to do this in general. The discussion was a
> while ago so I need to dig up the thread. In the end we remove the
> whole module handling in the xxx_open() and such.

Yes, you are right. This should just be removed.
This is a chardev, and the .owner of a chardev will always have a
reference held while the device is open - cdev_get/cdev_put ensure that.

We can just get rid of the obd_class_open and obd_class_release.

I'll drop this patch and replace it.

Thanks,
NeilBrown


>  
>> Signed-off-by: NeilBrown <neilb@suse.com>
>> ---
>>  drivers/staging/lustre/lustre/obdclass/class_obd.c |    3 +--
>>  1 file changed, 1 insertion(+), 2 deletions(-)
>> 
>> diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c
>> index 48d1dabafa65..982d47b6f50e 100644
>> --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
>> +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
>> @@ -548,8 +548,7 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
>>  /*  opening /dev/obd */
>>  static int obd_class_open(struct inode *inode, struct file *file)
>>  {
>> -	try_module_get(THIS_MODULE);
>> -	return 0;
>> +	return try_module_get(THIS_MODULE) ? 0 : -ENODEV;
>>  }
>>  
>>  /*  closing /dev/obd */
>> 
>> 
>> 
-------------- 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/20190211/319ccd7c/attachment.sig>

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

* [lustre-devel] [PATCH] lustre: don't manage module refs in obd_class_open/close.
  2019-02-11  5:01     ` NeilBrown
@ 2019-02-11  5:09       ` NeilBrown
  2019-02-12  4:17         ` James Simmons
  0 siblings, 1 reply; 87+ messages in thread
From: NeilBrown @ 2019-02-11  5:09 UTC (permalink / raw)
  To: lustre-devel


Core Linux code for managed char-devs ensures that the relevant
module is held active which a char-dev is open - see cdev_get()
and cdev_put().
So there is no need for lustre/obd_class to manage the module
ref count as well.

As this is all that obd_class_open and obd_class_close do, those
functions can be removed.

Signed-off-by: NeilBrown <neilb@suse.com>
---
 drivers/staging/lustre/lustre/obdclass/class_obd.c | 18 +-----------------
 1 file changed, 1 insertion(+), 17 deletions(-)

diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c
index 84c077ec0116..b8fc74044fe3 100644
--- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
+++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
@@ -544,20 +544,6 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
 	return err;
 } /* class_handle_ioctl */
 
-/*  opening /dev/obd */
-static int obd_class_open(struct inode *inode, struct file *file)
-{
-	try_module_get(THIS_MODULE);
-	return 0;
-}
-
-/*  closing /dev/obd */
-static int obd_class_release(struct inode *inode, struct file *file)
-{
-	module_put(THIS_MODULE);
-	return 0;
-}
-
 /* to control /dev/obd */
 static long obd_class_ioctl(struct file *filp, unsigned int cmd,
 			    unsigned long arg)
@@ -575,9 +561,7 @@ static long obd_class_ioctl(struct file *filp, unsigned int cmd,
 /* declare character device */
 static const struct file_operations obd_psdev_fops = {
 	.owner		= THIS_MODULE,
-	.unlocked_ioctl	= obd_class_ioctl,	/* unlocked_ioctl */
-	.open		= obd_class_open,	/* open */
-	.release	= obd_class_release,	/* release */
+	.unlocked_ioctl	= obd_class_ioctl,
 };
 
 /* modules setup */
-- 
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/20190211/14de1c7b/attachment.sig>

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

* [lustre-devel] [PATCH] lustre: don't manage module refs in obd_class_open/close.
  2019-02-11  5:09       ` [lustre-devel] [PATCH] lustre: don't manage module refs in obd_class_open/close NeilBrown
@ 2019-02-12  4:17         ` James Simmons
  0 siblings, 0 replies; 87+ messages in thread
From: James Simmons @ 2019-02-12  4:17 UTC (permalink / raw)
  To: lustre-devel


> Core Linux code for managed char-devs ensures that the relevant
> module is held active which a char-dev is open - see cdev_get()
> and cdev_put().
> So there is no need for lustre/obd_class to manage the module
> ref count as well.
> 
> As this is all that obd_class_open and obd_class_close do, those
> functions can be removed.

I was planning to do this but didn't get around to it. Thanks.

Reviewed-by: James Simmons <jsimmons@infradead.org>
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/obdclass/class_obd.c | 18 +-----------------
>  1 file changed, 1 insertion(+), 17 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c
> index 84c077ec0116..b8fc74044fe3 100644
> --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
> +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
> @@ -544,20 +544,6 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg)
>  	return err;
>  } /* class_handle_ioctl */
>  
> -/*  opening /dev/obd */
> -static int obd_class_open(struct inode *inode, struct file *file)
> -{
> -	try_module_get(THIS_MODULE);
> -	return 0;
> -}
> -
> -/*  closing /dev/obd */
> -static int obd_class_release(struct inode *inode, struct file *file)
> -{
> -	module_put(THIS_MODULE);
> -	return 0;
> -}
> -
>  /* to control /dev/obd */
>  static long obd_class_ioctl(struct file *filp, unsigned int cmd,
>  			    unsigned long arg)
> @@ -575,9 +561,7 @@ static long obd_class_ioctl(struct file *filp, unsigned int cmd,
>  /* declare character device */
>  static const struct file_operations obd_psdev_fops = {
>  	.owner		= THIS_MODULE,
> -	.unlocked_ioctl	= obd_class_ioctl,	/* unlocked_ioctl */
> -	.open		= obd_class_open,	/* open */
> -	.release	= obd_class_release,	/* release */
> +	.unlocked_ioctl	= obd_class_ioctl,
>  };
>  
>  /* modules setup */
> -- 
> 2.14.0.rc0.dirty
> 
> 

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

* [lustre-devel] [PATCH 19/21] lustre: obdclass: avoid races in class_register_type()
  2019-02-07  0:03 ` [lustre-devel] [PATCH 19/21] lustre: obdclass: avoid races in class_register_type() NeilBrown
  2019-02-08  6:41   ` Andreas Dilger
@ 2019-02-12  5:03   ` James Simmons
  2019-02-14  3:43     ` NeilBrown
  1 sibling, 1 reply; 87+ messages in thread
From: James Simmons @ 2019-02-12  5:03 UTC (permalink / raw)
  To: lustre-devel


> If there are two parallel attempts to register the
> same class name, it could get registered twice.
> So re-check after allocation to make sure the name is
> still unique.
> 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/obdclass/genops.c |   29 +++++++++++++++--------
>  1 file changed, 19 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
> index 382eaf519a79..a174f538dd0d 100644
> --- a/drivers/staging/lustre/lustre/obdclass/genops.c
> +++ b/drivers/staging/lustre/lustre/obdclass/genops.c
> @@ -86,17 +86,23 @@ static void obd_device_free(struct obd_device *obd)
>  	kmem_cache_free(obd_device_cachep, obd);
>  }
>  
> -static struct obd_type *class_search_type(const char *name)
> +static struct obd_type *__class_search_type(const char *name)
>  {
>  	struct obd_type *type;
>  
> -	spin_lock(&obd_types_lock);
>  	list_for_each_entry(type, &obd_types, typ_chain) {

This change is fine but we really don't need typ_chain anymore.
We have a list of obd_types already due to the power of kobjects!!!!

We can do an

static struct obd_type *class_search_type(const char *name)
{
	struct kobject *kobj;
	struct obd_type *type;

	kobj = kset_find_obj(lustre_kset, name);

	return "some_mapping from kobj to type"

Hmm. This kobj is not embedded in struct obd_types. Might need more
surgery to make that work.

> -		if (strcmp(type->typ_name, name) == 0) {
> -			spin_unlock(&obd_types_lock);
> +		if (strcmp(type->typ_name, name) == 0)
>  			return type;
> -		}
>  	}
> +	return NULL;
> +}
> +
> +static struct obd_type *class_search_type(const char *name)
> +{
> +	struct obd_type *type;
> +
> +	spin_lock(&obd_types_lock);
> +	type = __class_search_type(name);
>  	spin_unlock(&obd_types_lock);
>  	return NULL;
>  }
> @@ -214,19 +220,22 @@ int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops,
>  	if (ldt) {
>  		type->typ_lu = ldt;
>  		rc = lu_device_type_init(ldt);
> -		if (rc != 0) {
> -			kobject_put(type->typ_kobj);
> +		if (rc != 0)
>  			goto failed;
> -		}
>  	}
>  
> +	INIT_LIST_HEAD(&type->typ_chain);
>  	spin_lock(&obd_types_lock);
> -	list_add(&type->typ_chain, &obd_types);
> +	if (__class_search_type(name) == NULL)
> +		list_add(&type->typ_chain, &obd_types);
>  	spin_unlock(&obd_types_lock);
>  
> -	return 0;
> +	if (!list_empty(&type->typ_chain))
> +		return 0;
>  
>  failed:
> +	if (!IS_ERR_OR_NULL(type->typ_kobj))
> +		kobject_put(type->typ_kobj);
>  	kfree(type->typ_name);
>  	kfree(type->typ_md_ops);
>  	kfree(type->typ_dt_ops);
> 
> 
> 

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

* [lustre-devel] [PATCH 11/21] lustre: cl_object: remove vestigial debugging.
  2019-02-11  3:25     ` NeilBrown
@ 2019-02-12  5:19       ` James Simmons
  2019-02-12 13:56         ` Patrick Farrell
  2019-02-12 22:12         ` NeilBrown
  0 siblings, 2 replies; 87+ messages in thread
From: James Simmons @ 2019-02-12  5:19 UTC (permalink / raw)
  To: lustre-devel


> >> cl_env_inc() and cl_env_dec() don't do anything,
> >> so discard them.
> >
> > I don't know about this one. I saw Andreas response as well. 
> > So this was apart of "LU-744 obdclass: revise stats for cl_object cache"
> > In the end it was turned off by default in the OpenSFS branch since it
> > made performance take a hit. To enable in OpenSFS branch you have to run
> > ./configure --enable-pgstate-track. We have a few like this for Lustre so
> > I was going to bring this up. Do we want to remove this work for both the
> > upstream client as well as OpenSFS tree or properly implement this by
> > making it a Kconfig option when CONFIG_LUSTRE_DEBUG_EXPENSIVE_CHECK is
> > enabled? Its just a matter of porting OpenSFS commit 
> > 5cae09a2409dcd396a1ee7be1eca7d3bbf77365e
> >
> > What do you think?
> 
> How useful are these stats?
> Stats that are never compiled in aren't likely to tell you much :-)
> 
> Has any thought been given to per-cpu stats counting?  That seems to be
> the preferred approach for high-frequency accounting.
> 
> I think having a CONFIG option to enable expensive consistency checks is
> a good idea - developers will enable it when they don't care about
> performance.
> Having a CONFIG option for expensive performance stats seems... weird.
> Who would use it, and how meaningful would the number be?

Which per-cpu stats are you talking about? I know perf can do this kind of
profiling with performance counters but I don't think you can use those
with cl_pages specifically. I know the lustre developers really dislike
trace point but this could be one of those cases where it makes sense.
 
> NeilBrown
> 
> 
> >
> >> Signed-off-by: NeilBrown <neilb@suse.com>
> >> ---
> >>  drivers/staging/lustre/lustre/obdclass/cl_object.c |   15 ---------------
> >>  1 file changed, 15 deletions(-)
> >> 
> >> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> >> index d71a680660da..1e704078664e 100644
> >> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
> >> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> >> @@ -565,14 +565,6 @@ struct cl_env {
> >>  	void		       *ce_debug;
> >>  };
> >>  
> >> -static void cl_env_inc(enum cache_stats_item item)
> >> -{
> >> -}
> >> -
> >> -static void cl_env_dec(enum cache_stats_item item)
> >> -{
> >> -}
> >> -
> >>  static void cl_env_init0(struct cl_env *cle, void *debug)
> >>  {
> >>  	LASSERT(cle->ce_ref == 0);
> >> @@ -581,7 +573,6 @@ static void cl_env_init0(struct cl_env *cle, void *debug)
> >>  
> >>  	cle->ce_ref = 1;
> >>  	cle->ce_debug = debug;
> >> -	cl_env_inc(CS_busy);
> >>  }
> >>  
> >>  static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
> >> @@ -611,9 +602,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
> >>  		if (rc != 0) {
> >>  			kmem_cache_free(cl_env_kmem, cle);
> >>  			env = ERR_PTR(rc);
> >> -		} else {
> >> -			cl_env_inc(CS_create);
> >> -			cl_env_inc(CS_total);
> >>  		}
> >>  	} else {
> >>  		env = ERR_PTR(-ENOMEM);
> >> @@ -623,7 +611,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
> >>  
> >>  static void cl_env_fini(struct cl_env *cle)
> >>  {
> >> -	cl_env_dec(CS_total);
> >>  	lu_context_fini(&cle->ce_lu.le_ctx);
> >>  	lu_context_fini(&cle->ce_ses);
> >>  	kmem_cache_free(cl_env_kmem, cle);
> >> @@ -782,7 +769,6 @@ void cl_env_put(struct lu_env *env, u16 *refcheck)
> >>  	if (--cle->ce_ref == 0) {
> >>  		int cpu = get_cpu();
> >>  
> >> -		cl_env_dec(CS_busy);
> >>  		cle->ce_debug = NULL;
> >>  		cl_env_exit(cle);
> >>  		/*
> >> @@ -903,7 +889,6 @@ void cl_env_percpu_put(struct lu_env *env)
> >>  	cle->ce_ref--;
> >>  	LASSERT(cle->ce_ref == 0);
> >>  
> >> -	cl_env_dec(CS_busy);
> >>  	cle->ce_debug = NULL;
> >>  
> >>  	put_cpu();
> >> 
> >> 
> >> 
> 

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

* [lustre-devel] [PATCH 11/21] lustre: cl_object: remove vestigial debugging.
  2019-02-12  5:19       ` James Simmons
@ 2019-02-12 13:56         ` Patrick Farrell
  2019-02-12 22:12         ` NeilBrown
  1 sibling, 0 replies; 87+ messages in thread
From: Patrick Farrell @ 2019-02-12 13:56 UTC (permalink / raw)
  To: lustre-devel

If this state tracking has been off for as long as it has (I?ve never come across it before), I feel like it can probably go without a fight.  I just don?t think the info provided is particularly important/useful.

Trace points or even really just blunter tracing tools can probably get the desired info in a pinch...

- Patrick
________________________________
From: lustre-devel <lustre-devel-bounces@lists.lustre.org> on behalf of James Simmons <jsimmons@infradead.org>
Sent: Monday, February 11, 2019 11:19:45 PM
To: NeilBrown
Cc: Lustre Development List
Subject: Re: [lustre-devel] [PATCH 11/21] lustre: cl_object: remove vestigial debugging.


> >> cl_env_inc() and cl_env_dec() don't do anything,
> >> so discard them.
> >
> > I don't know about this one. I saw Andreas response as well.
> > So this was apart of "LU-744 obdclass: revise stats for cl_object cache"
> > In the end it was turned off by default in the OpenSFS branch since it
> > made performance take a hit. To enable in OpenSFS branch you have to run
> > ./configure --enable-pgstate-track. We have a few like this for Lustre so
> > I was going to bring this up. Do we want to remove this work for both the
> > upstream client as well as OpenSFS tree or properly implement this by
> > making it a Kconfig option when CONFIG_LUSTRE_DEBUG_EXPENSIVE_CHECK is
> > enabled? Its just a matter of porting OpenSFS commit
> > 5cae09a2409dcd396a1ee7be1eca7d3bbf77365e
> >
> > What do you think?
>
> How useful are these stats?
> Stats that are never compiled in aren't likely to tell you much :-)
>
> Has any thought been given to per-cpu stats counting?  That seems to be
> the preferred approach for high-frequency accounting.
>
> I think having a CONFIG option to enable expensive consistency checks is
> a good idea - developers will enable it when they don't care about
> performance.
> Having a CONFIG option for expensive performance stats seems... weird.
> Who would use it, and how meaningful would the number be?

Which per-cpu stats are you talking about? I know perf can do this kind of
profiling with performance counters but I don't think you can use those
with cl_pages specifically. I know the lustre developers really dislike
trace point but this could be one of those cases where it makes sense.

> NeilBrown
>
>
> >
> >> Signed-off-by: NeilBrown <neilb@suse.com>
> >> ---
> >>  drivers/staging/lustre/lustre/obdclass/cl_object.c |   15 ---------------
> >>  1 file changed, 15 deletions(-)
> >>
> >> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> >> index d71a680660da..1e704078664e 100644
> >> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
> >> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> >> @@ -565,14 +565,6 @@ struct cl_env {
> >>     void                   *ce_debug;
> >>  };
> >>
> >> -static void cl_env_inc(enum cache_stats_item item)
> >> -{
> >> -}
> >> -
> >> -static void cl_env_dec(enum cache_stats_item item)
> >> -{
> >> -}
> >> -
> >>  static void cl_env_init0(struct cl_env *cle, void *debug)
> >>  {
> >>     LASSERT(cle->ce_ref == 0);
> >> @@ -581,7 +573,6 @@ static void cl_env_init0(struct cl_env *cle, void *debug)
> >>
> >>     cle->ce_ref = 1;
> >>     cle->ce_debug = debug;
> >> -  cl_env_inc(CS_busy);
> >>  }
> >>
> >>  static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
> >> @@ -611,9 +602,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
> >>             if (rc != 0) {
> >>                     kmem_cache_free(cl_env_kmem, cle);
> >>                     env = ERR_PTR(rc);
> >> -          } else {
> >> -                  cl_env_inc(CS_create);
> >> -                  cl_env_inc(CS_total);
> >>             }
> >>     } else {
> >>             env = ERR_PTR(-ENOMEM);
> >> @@ -623,7 +611,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
> >>
> >>  static void cl_env_fini(struct cl_env *cle)
> >>  {
> >> -  cl_env_dec(CS_total);
> >>     lu_context_fini(&cle->ce_lu.le_ctx);
> >>     lu_context_fini(&cle->ce_ses);
> >>     kmem_cache_free(cl_env_kmem, cle);
> >> @@ -782,7 +769,6 @@ void cl_env_put(struct lu_env *env, u16 *refcheck)
> >>     if (--cle->ce_ref == 0) {
> >>             int cpu = get_cpu();
> >>
> >> -          cl_env_dec(CS_busy);
> >>             cle->ce_debug = NULL;
> >>             cl_env_exit(cle);
> >>             /*
> >> @@ -903,7 +889,6 @@ void cl_env_percpu_put(struct lu_env *env)
> >>     cle->ce_ref--;
> >>     LASSERT(cle->ce_ref == 0);
> >>
> >> -  cl_env_dec(CS_busy);
> >>     cle->ce_debug = NULL;
> >>
> >>     put_cpu();
> >>
> >>
> >>
>
_______________________________________________
lustre-devel mailing list
lustre-devel at lists.lustre.org
http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lustre.org/pipermail/lustre-devel-lustre.org/attachments/20190212/d263ed91/attachment-0001.html>

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

* [lustre-devel] [PATCH 11/21] lustre: cl_object: remove vestigial debugging.
  2019-02-12  5:19       ` James Simmons
  2019-02-12 13:56         ` Patrick Farrell
@ 2019-02-12 22:12         ` NeilBrown
  2019-02-13  0:19           ` James Simmons
  1 sibling, 1 reply; 87+ messages in thread
From: NeilBrown @ 2019-02-12 22:12 UTC (permalink / raw)
  To: lustre-devel

On Tue, Feb 12 2019, James Simmons wrote:

>> >> cl_env_inc() and cl_env_dec() don't do anything,
>> >> so discard them.
>> >
>> > I don't know about this one. I saw Andreas response as well. 
>> > So this was apart of "LU-744 obdclass: revise stats for cl_object cache"
>> > In the end it was turned off by default in the OpenSFS branch since it
>> > made performance take a hit. To enable in OpenSFS branch you have to run
>> > ./configure --enable-pgstate-track. We have a few like this for Lustre so
>> > I was going to bring this up. Do we want to remove this work for both the
>> > upstream client as well as OpenSFS tree or properly implement this by
>> > making it a Kconfig option when CONFIG_LUSTRE_DEBUG_EXPENSIVE_CHECK is
>> > enabled? Its just a matter of porting OpenSFS commit 
>> > 5cae09a2409dcd396a1ee7be1eca7d3bbf77365e
>> >
>> > What do you think?
>> 
>> How useful are these stats?
>> Stats that are never compiled in aren't likely to tell you much :-)
>> 
>> Has any thought been given to per-cpu stats counting?  That seems to be
>> the preferred approach for high-frequency accounting.
>> 
>> I think having a CONFIG option to enable expensive consistency checks is
>> a good idea - developers will enable it when they don't care about
>> performance.
>> Having a CONFIG option for expensive performance stats seems... weird.
>> Who would use it, and how meaningful would the number be?
>
> Which per-cpu stats are you talking about?

include/linux/percpu_counter.h I guess - or something similar.

NeilBrown



>                                             I know perf can do this kind of
> profiling with performance counters but I don't think you can use those
> with cl_pages specifically. I know the lustre developers really dislike
> trace point but this could be one of those cases where it makes sense.
>  
>> NeilBrown
>> 
>> 
>> >
>> >> Signed-off-by: NeilBrown <neilb@suse.com>
>> >> ---
>> >>  drivers/staging/lustre/lustre/obdclass/cl_object.c |   15 ---------------
>> >>  1 file changed, 15 deletions(-)
>> >> 
>> >> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> >> index d71a680660da..1e704078664e 100644
>> >> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> >> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> >> @@ -565,14 +565,6 @@ struct cl_env {
>> >>  	void		       *ce_debug;
>> >>  };
>> >>  
>> >> -static void cl_env_inc(enum cache_stats_item item)
>> >> -{
>> >> -}
>> >> -
>> >> -static void cl_env_dec(enum cache_stats_item item)
>> >> -{
>> >> -}
>> >> -
>> >>  static void cl_env_init0(struct cl_env *cle, void *debug)
>> >>  {
>> >>  	LASSERT(cle->ce_ref == 0);
>> >> @@ -581,7 +573,6 @@ static void cl_env_init0(struct cl_env *cle, void *debug)
>> >>  
>> >>  	cle->ce_ref = 1;
>> >>  	cle->ce_debug = debug;
>> >> -	cl_env_inc(CS_busy);
>> >>  }
>> >>  
>> >>  static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
>> >> @@ -611,9 +602,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
>> >>  		if (rc != 0) {
>> >>  			kmem_cache_free(cl_env_kmem, cle);
>> >>  			env = ERR_PTR(rc);
>> >> -		} else {
>> >> -			cl_env_inc(CS_create);
>> >> -			cl_env_inc(CS_total);
>> >>  		}
>> >>  	} else {
>> >>  		env = ERR_PTR(-ENOMEM);
>> >> @@ -623,7 +611,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
>> >>  
>> >>  static void cl_env_fini(struct cl_env *cle)
>> >>  {
>> >> -	cl_env_dec(CS_total);
>> >>  	lu_context_fini(&cle->ce_lu.le_ctx);
>> >>  	lu_context_fini(&cle->ce_ses);
>> >>  	kmem_cache_free(cl_env_kmem, cle);
>> >> @@ -782,7 +769,6 @@ void cl_env_put(struct lu_env *env, u16 *refcheck)
>> >>  	if (--cle->ce_ref == 0) {
>> >>  		int cpu = get_cpu();
>> >>  
>> >> -		cl_env_dec(CS_busy);
>> >>  		cle->ce_debug = NULL;
>> >>  		cl_env_exit(cle);
>> >>  		/*
>> >> @@ -903,7 +889,6 @@ void cl_env_percpu_put(struct lu_env *env)
>> >>  	cle->ce_ref--;
>> >>  	LASSERT(cle->ce_ref == 0);
>> >>  
>> >> -	cl_env_dec(CS_busy);
>> >>  	cle->ce_debug = NULL;
>> >>  
>> >>  	put_cpu();
>> >> 
>> >> 
>> >> 
>> 
-------------- 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/20190213/5a778fd0/attachment.sig>

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

* [lustre-devel] [PATCH 11/21] lustre: cl_object: remove vestigial debugging.
  2019-02-12 22:12         ` NeilBrown
@ 2019-02-13  0:19           ` James Simmons
  2019-02-13  0:29             ` NeilBrown
  0 siblings, 1 reply; 87+ messages in thread
From: James Simmons @ 2019-02-13  0:19 UTC (permalink / raw)
  To: lustre-devel


> >> >> cl_env_inc() and cl_env_dec() don't do anything,
> >> >> so discard them.
> >> >
> >> > I don't know about this one. I saw Andreas response as well. 
> >> > So this was apart of "LU-744 obdclass: revise stats for cl_object cache"
> >> > In the end it was turned off by default in the OpenSFS branch since it
> >> > made performance take a hit. To enable in OpenSFS branch you have to run
> >> > ./configure --enable-pgstate-track. We have a few like this for Lustre so
> >> > I was going to bring this up. Do we want to remove this work for both the
> >> > upstream client as well as OpenSFS tree or properly implement this by
> >> > making it a Kconfig option when CONFIG_LUSTRE_DEBUG_EXPENSIVE_CHECK is
> >> > enabled? Its just a matter of porting OpenSFS commit 
> >> > 5cae09a2409dcd396a1ee7be1eca7d3bbf77365e
> >> >
> >> > What do you think?
> >> 
> >> How useful are these stats?
> >> Stats that are never compiled in aren't likely to tell you much :-)
> >> 
> >> Has any thought been given to per-cpu stats counting?  That seems to be
> >> the preferred approach for high-frequency accounting.
> >> 
> >> I think having a CONFIG option to enable expensive consistency checks is
> >> a good idea - developers will enable it when they don't care about
> >> performance.
> >> Having a CONFIG option for expensive performance stats seems... weird.
> >> Who would use it, and how meaningful would the number be?
> >
> > Which per-cpu stats are you talking about?
> 
> include/linux/percpu_counter.h I guess - or something similar.

Ouch 4K per counter. This would crush our clients. Does this scale well?
I also looked at the page counter which also atomic counting orientated.
I expect that too also to struggle. The page counter don't match as well
as what these cl_page stats monitor.

> >                                             I know perf can do this kind of
> > profiling with performance counters but I don't think you can use those
> > with cl_pages specifically. I know the lustre developers really dislike
> > trace point but this could be one of those cases where it makes sense.
> >  
> >> NeilBrown
> >> 
> >> 
> >> >
> >> >> Signed-off-by: NeilBrown <neilb@suse.com>
> >> >> ---
> >> >>  drivers/staging/lustre/lustre/obdclass/cl_object.c |   15 ---------------
> >> >>  1 file changed, 15 deletions(-)
> >> >> 
> >> >> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> >> >> index d71a680660da..1e704078664e 100644
> >> >> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
> >> >> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> >> >> @@ -565,14 +565,6 @@ struct cl_env {
> >> >>  	void		       *ce_debug;
> >> >>  };
> >> >>  
> >> >> -static void cl_env_inc(enum cache_stats_item item)
> >> >> -{
> >> >> -}
> >> >> -
> >> >> -static void cl_env_dec(enum cache_stats_item item)
> >> >> -{
> >> >> -}
> >> >> -
> >> >>  static void cl_env_init0(struct cl_env *cle, void *debug)
> >> >>  {
> >> >>  	LASSERT(cle->ce_ref == 0);
> >> >> @@ -581,7 +573,6 @@ static void cl_env_init0(struct cl_env *cle, void *debug)
> >> >>  
> >> >>  	cle->ce_ref = 1;
> >> >>  	cle->ce_debug = debug;
> >> >> -	cl_env_inc(CS_busy);
> >> >>  }
> >> >>  
> >> >>  static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
> >> >> @@ -611,9 +602,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
> >> >>  		if (rc != 0) {
> >> >>  			kmem_cache_free(cl_env_kmem, cle);
> >> >>  			env = ERR_PTR(rc);
> >> >> -		} else {
> >> >> -			cl_env_inc(CS_create);
> >> >> -			cl_env_inc(CS_total);
> >> >>  		}
> >> >>  	} else {
> >> >>  		env = ERR_PTR(-ENOMEM);
> >> >> @@ -623,7 +611,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
> >> >>  
> >> >>  static void cl_env_fini(struct cl_env *cle)
> >> >>  {
> >> >> -	cl_env_dec(CS_total);
> >> >>  	lu_context_fini(&cle->ce_lu.le_ctx);
> >> >>  	lu_context_fini(&cle->ce_ses);
> >> >>  	kmem_cache_free(cl_env_kmem, cle);
> >> >> @@ -782,7 +769,6 @@ void cl_env_put(struct lu_env *env, u16 *refcheck)
> >> >>  	if (--cle->ce_ref == 0) {
> >> >>  		int cpu = get_cpu();
> >> >>  
> >> >> -		cl_env_dec(CS_busy);
> >> >>  		cle->ce_debug = NULL;
> >> >>  		cl_env_exit(cle);
> >> >>  		/*
> >> >> @@ -903,7 +889,6 @@ void cl_env_percpu_put(struct lu_env *env)
> >> >>  	cle->ce_ref--;
> >> >>  	LASSERT(cle->ce_ref == 0);
> >> >>  
> >> >> -	cl_env_dec(CS_busy);
> >> >>  	cle->ce_debug = NULL;
> >> >>  
> >> >>  	put_cpu();
> >> >> 
> >> >> 
> >> >> 
> >> 
> 

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

* [lustre-devel] [PATCH 11/21] lustre: cl_object: remove vestigial debugging.
  2019-02-13  0:19           ` James Simmons
@ 2019-02-13  0:29             ` NeilBrown
  0 siblings, 0 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-13  0:29 UTC (permalink / raw)
  To: lustre-devel

On Wed, Feb 13 2019, James Simmons wrote:

>> >> >> cl_env_inc() and cl_env_dec() don't do anything,
>> >> >> so discard them.
>> >> >
>> >> > I don't know about this one. I saw Andreas response as well. 
>> >> > So this was apart of "LU-744 obdclass: revise stats for cl_object cache"
>> >> > In the end it was turned off by default in the OpenSFS branch since it
>> >> > made performance take a hit. To enable in OpenSFS branch you have to run
>> >> > ./configure --enable-pgstate-track. We have a few like this for Lustre so
>> >> > I was going to bring this up. Do we want to remove this work for both the
>> >> > upstream client as well as OpenSFS tree or properly implement this by
>> >> > making it a Kconfig option when CONFIG_LUSTRE_DEBUG_EXPENSIVE_CHECK is
>> >> > enabled? Its just a matter of porting OpenSFS commit 
>> >> > 5cae09a2409dcd396a1ee7be1eca7d3bbf77365e
>> >> >
>> >> > What do you think?
>> >> 
>> >> How useful are these stats?
>> >> Stats that are never compiled in aren't likely to tell you much :-)
>> >> 
>> >> Has any thought been given to per-cpu stats counting?  That seems to be
>> >> the preferred approach for high-frequency accounting.
>> >> 
>> >> I think having a CONFIG option to enable expensive consistency checks is
>> >> a good idea - developers will enable it when they don't care about
>> >> performance.
>> >> Having a CONFIG option for expensive performance stats seems... weird.
>> >> Who would use it, and how meaningful would the number be?
>> >
>> > Which per-cpu stats are you talking about?
>> 
>> include/linux/percpu_counter.h I guess - or something similar.
>
> Ouch 4K per counter. This would crush our clients. Does this scale well?
> I also looked at the page counter which also atomic counting orientated.
> I expect that too also to struggle. The page counter don't match as well
> as what these cl_page stats monitor.

Why?  How many counters are there?
enum cl_page_state defines 5 per "site".
enum cache_stats_item defines 5, which  think are global.
That makes 4, to order of 16K.  That isn't all that much.

NeilBrown


>
>> >                                             I know perf can do this kind of
>> > profiling with performance counters but I don't think you can use those
>> > with cl_pages specifically. I know the lustre developers really dislike
>> > trace point but this could be one of those cases where it makes sense.
>> >  
>> >> NeilBrown
>> >> 
>> >> 
>> >> >
>> >> >> Signed-off-by: NeilBrown <neilb@suse.com>
>> >> >> ---
>> >> >>  drivers/staging/lustre/lustre/obdclass/cl_object.c |   15 ---------------
>> >> >>  1 file changed, 15 deletions(-)
>> >> >> 
>> >> >> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> >> >> index d71a680660da..1e704078664e 100644
>> >> >> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> >> >> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
>> >> >> @@ -565,14 +565,6 @@ struct cl_env {
>> >> >>  	void		       *ce_debug;
>> >> >>  };
>> >> >>  
>> >> >> -static void cl_env_inc(enum cache_stats_item item)
>> >> >> -{
>> >> >> -}
>> >> >> -
>> >> >> -static void cl_env_dec(enum cache_stats_item item)
>> >> >> -{
>> >> >> -}
>> >> >> -
>> >> >>  static void cl_env_init0(struct cl_env *cle, void *debug)
>> >> >>  {
>> >> >>  	LASSERT(cle->ce_ref == 0);
>> >> >> @@ -581,7 +573,6 @@ static void cl_env_init0(struct cl_env *cle, void *debug)
>> >> >>  
>> >> >>  	cle->ce_ref = 1;
>> >> >>  	cle->ce_debug = debug;
>> >> >> -	cl_env_inc(CS_busy);
>> >> >>  }
>> >> >>  
>> >> >>  static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
>> >> >> @@ -611,9 +602,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
>> >> >>  		if (rc != 0) {
>> >> >>  			kmem_cache_free(cl_env_kmem, cle);
>> >> >>  			env = ERR_PTR(rc);
>> >> >> -		} else {
>> >> >> -			cl_env_inc(CS_create);
>> >> >> -			cl_env_inc(CS_total);
>> >> >>  		}
>> >> >>  	} else {
>> >> >>  		env = ERR_PTR(-ENOMEM);
>> >> >> @@ -623,7 +611,6 @@ static struct lu_env *cl_env_new(u32 ctx_tags, u32 ses_tags, void *debug)
>> >> >>  
>> >> >>  static void cl_env_fini(struct cl_env *cle)
>> >> >>  {
>> >> >> -	cl_env_dec(CS_total);
>> >> >>  	lu_context_fini(&cle->ce_lu.le_ctx);
>> >> >>  	lu_context_fini(&cle->ce_ses);
>> >> >>  	kmem_cache_free(cl_env_kmem, cle);
>> >> >> @@ -782,7 +769,6 @@ void cl_env_put(struct lu_env *env, u16 *refcheck)
>> >> >>  	if (--cle->ce_ref == 0) {
>> >> >>  		int cpu = get_cpu();
>> >> >>  
>> >> >> -		cl_env_dec(CS_busy);
>> >> >>  		cle->ce_debug = NULL;
>> >> >>  		cl_env_exit(cle);
>> >> >>  		/*
>> >> >> @@ -903,7 +889,6 @@ void cl_env_percpu_put(struct lu_env *env)
>> >> >>  	cle->ce_ref--;
>> >> >>  	LASSERT(cle->ce_ref == 0);
>> >> >>  
>> >> >> -	cl_env_dec(CS_busy);
>> >> >>  	cle->ce_debug = NULL;
>> >> >>  
>> >> >>  	put_cpu();
>> >> >> 
>> >> >> 
>> >> >> 
>> >> 
>> 
-------------- 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/20190213/97d7afdd/attachment.sig>

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

* [lustre-devel] [PATCH 20/21] lustre: obdclass: fix module load locking.
  2019-02-07  0:03 ` [lustre-devel] [PATCH 20/21] lustre: obdclass: fix module load locking NeilBrown
@ 2019-02-13  1:53   ` James Simmons
  0 siblings, 0 replies; 87+ messages in thread
From: James Simmons @ 2019-02-13  1:53 UTC (permalink / raw)
  To: lustre-devel


> Safe module loading requires that we try_module_get() in a context
> where the module cannot be unloaded, typically prodected by
> a spinlock that module-unload has to take.
> This doesn't currently happen in class_get_type().
> 
> There is a per-type spinlock, but it is almost entirely unused, and
> cannot be used to protect the module from being unloaded.
> 
> So discard ->obd_type_lock, and ensure that __class_search_type() and
> try_module_get() are both called while obd_types_lock is held - this
> prevent class_unregister_type() from completing (so the 'type' won't get
> freed.  That is always called from a module-unload function - if it
> has got that far, try_module_get() will fail.
> 
> So also check the return status of try_module_get().

Reviewed-by: James Simmons <jsimmons@infradead.org>
 
> Signed-off-by: NeilBrown <neilb@suse.com>
> ---
>  drivers/staging/lustre/lustre/include/obd.h     |    1 -
>  drivers/staging/lustre/lustre/obdclass/genops.c |   24 ++++++++++++++---------
>  2 files changed, 15 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h
> index 171d2c214be6..463ab680b524 100644
> --- a/drivers/staging/lustre/lustre/include/obd.h
> +++ b/drivers/staging/lustre/lustre/include/obd.h
> @@ -106,7 +106,6 @@ struct obd_type {
>  	char			*typ_name;
>  	int			 typ_refcnt;
>  	struct lu_device_type	*typ_lu;
> -	spinlock_t		 obd_type_lock;
>  	struct kobject		*typ_kobj;
>  };
>  
> diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
> index a174f538dd0d..dad21d9fa328 100644
> --- a/drivers/staging/lustre/lustre/obdclass/genops.c
> +++ b/drivers/staging/lustre/lustre/obdclass/genops.c
> @@ -109,35 +109,42 @@ static struct obd_type *class_search_type(const char *name)
>  
>  static struct obd_type *class_get_type(const char *name)
>  {
> -	struct obd_type *type = class_search_type(name);
> +	struct obd_type *type;
> +
> +	spin_lock(&obd_types_lock);
> +	type = __class_search_type(name);
>  
>  	if (!type) {
>  		const char *modname = name;
>  
> +		spin_unlock(&obd_types_lock);
>  		if (!request_module("%s", modname)) {
>  			CDEBUG(D_INFO, "Loaded module '%s'\n", modname);
> -			type = class_search_type(name);
>  		} else {
>  			LCONSOLE_ERROR_MSG(0x158, "Can't load module '%s'\n",
>  					   modname);
>  		}
> +		spin_lock(&obd_types_lock);
> +		type = __class_search_type(name);
>  	}
>  	if (type) {
> -		spin_lock(&type->obd_type_lock);
> -		type->typ_refcnt++;
> -		try_module_get(type->typ_dt_ops->owner);
> -		spin_unlock(&type->obd_type_lock);
> +		if (try_module_get(type->typ_dt_ops->owner))
> +			type->typ_refcnt++;
> +		else
> +			type = NULL;
>  	}
> +	spin_unlock(&obd_types_lock);
>  	return type;
>  }
>  
>  void class_put_type(struct obd_type *type)
>  {
>  	LASSERT(type);
> -	spin_lock(&type->obd_type_lock);
> +	spin_lock(&obd_types_lock);
> +	LASSERT(type->typ_refcnt > 0);
>  	type->typ_refcnt--;
>  	module_put(type->typ_dt_ops->owner);
> -	spin_unlock(&type->obd_type_lock);
> +	spin_unlock(&obd_types_lock);
>  }
>  
>  static void class_sysfs_release(struct kobject *kobj)
> @@ -206,7 +213,6 @@ int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops,
>  	if (md_ops)
>  		*type->typ_md_ops = *md_ops;
>  	strcpy(type->typ_name, name);
> -	spin_lock_init(&type->obd_type_lock);
>  
>  	type->typ_debugfs_entry = debugfs_create_dir(type->typ_name,
>  						     debugfs_lustre_root);
> 
> 
> 

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

* [lustre-devel] [PATCH 19/21] lustre: obdclass: avoid races in class_register_type()
  2019-02-12  5:03   ` James Simmons
@ 2019-02-14  3:43     ` NeilBrown
  0 siblings, 0 replies; 87+ messages in thread
From: NeilBrown @ 2019-02-14  3:43 UTC (permalink / raw)
  To: lustre-devel

On Tue, Feb 12 2019, James Simmons wrote:

>> If there are two parallel attempts to register the
>> same class name, it could get registered twice.
>> So re-check after allocation to make sure the name is
>> still unique.
>> 
>> Signed-off-by: NeilBrown <neilb@suse.com>
>> ---
>>  drivers/staging/lustre/lustre/obdclass/genops.c |   29 +++++++++++++++--------
>>  1 file changed, 19 insertions(+), 10 deletions(-)
>> 
>> diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
>> index 382eaf519a79..a174f538dd0d 100644
>> --- a/drivers/staging/lustre/lustre/obdclass/genops.c
>> +++ b/drivers/staging/lustre/lustre/obdclass/genops.c
>> @@ -86,17 +86,23 @@ static void obd_device_free(struct obd_device *obd)
>>  	kmem_cache_free(obd_device_cachep, obd);
>>  }
>>  
>> -static struct obd_type *class_search_type(const char *name)
>> +static struct obd_type *__class_search_type(const char *name)
>>  {
>>  	struct obd_type *type;
>>  
>> -	spin_lock(&obd_types_lock);
>>  	list_for_each_entry(type, &obd_types, typ_chain) {
>
> This change is fine but we really don't need typ_chain anymore.
> We have a list of obd_types already due to the power of kobjects!!!!
>
> We can do an
>
> static struct obd_type *class_search_type(const char *name)
> {
> 	struct kobject *kobj;
> 	struct obd_type *type;
>
> 	kobj = kset_find_obj(lustre_kset, name);
>
> 	return "some_mapping from kobj to type"
>
> Hmm. This kobj is not embedded in struct obd_types. Might need more
> surgery to make that work.
>

Well.... that was a fun rabbit-hole to fall down.
I now have 8 patches where before I had two - definitely a better
result. typ_chain and several other fields are gone.

I'll post them in my next series which will probably go out tomorrow.

Thanks,
NeilBrown
-------------- 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/20190214/1bf34af3/attachment.sig>

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

* [lustre-devel] [PATCH 10/21] lustre: obdclass: use cl_object_for_each where appropriate
  2019-02-11  0:42     ` NeilBrown
  2019-02-11  4:19       ` James Simmons
@ 2019-02-15 18:15       ` Andreas Dilger
  1 sibling, 0 replies; 87+ messages in thread
From: Andreas Dilger @ 2019-02-15 18:15 UTC (permalink / raw)
  To: lustre-devel

On Feb 10, 2019, at 17:42, NeilBrown <neilb@suse.com> wrote:
> From: NeilBrown <neilb@suse.com>
> Subject: [PATCH] lustre: obdclass: use cl_object_for_each where appropriate
> 
> There are various places which have a list_for_each_entry()
> where cl_object_for_each (or .._reverse) is more appropriate.
> 
> Several of these re-use the 'obj' function parameter as a loop
> iterator, which is a little confusing.
> 
> Change these to use cl_object_for_each{_reverse}, and where needed,
> introduce a new iterator variable 'o'.
> 
> To further clean up these function, move initializtion of 'result'
> to the variable declaration.
> 
> Signed-off-by: NeilBrown <neilb@suse.com>

Reviewed-by: Andreas Dilger <adilger@whamcloud.com>

> ---
> drivers/staging/lustre/lustre/lov/lov_page.c       |  3 +-
> drivers/staging/lustre/lustre/obdclass/cl_lock.c   |  3 +-
> drivers/staging/lustre/lustre/obdclass/cl_object.c | 97 ++++++++++------------
> drivers/staging/lustre/lustre/obdclass/cl_page.c   | 11 ++-
> 4 files changed, 49 insertions(+), 65 deletions(-)
> 
> diff --git a/drivers/staging/lustre/lustre/lov/lov_page.c b/drivers/staging/lustre/lustre/lov/lov_page.c
> index 08485a95ec01..e64b350601d2 100644
> --- a/drivers/staging/lustre/lustre/lov/lov_page.c
> +++ b/drivers/staging/lustre/lustre/lov/lov_page.c
> @@ -103,8 +103,7 @@ int lov_page_init_composite(const struct lu_env *env, struct cl_object *obj,
> 		return PTR_ERR(sub);
> 
> 	subobj = lovsub2cl(r0->lo_sub[stripe]);
> -	list_for_each_entry(o, &subobj->co_lu.lo_header->loh_layers,
> -			    co_lu.lo_linkage) {
> +	cl_object_for_each(o, subobj) {
> 		if (o->co_ops->coo_page_init) {
> 			rc = o->co_ops->coo_page_init(sub->sub_env, o, page,
> 						      cl_index(subobj, suboff));
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
> index 8133d992cc73..fc5976d8b37b 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c
> @@ -103,8 +103,7 @@ int cl_lock_init(const struct lu_env *env, struct cl_lock *lock,
> 	LASSERT(obj);
> 
> 	INIT_LIST_HEAD(&lock->cll_layers);
> -	list_for_each_entry(scan, &obj->co_lu.lo_header->loh_layers,
> -			    co_lu.lo_linkage) {
> +	cl_object_for_each(scan, obj) {
> 		result = scan->co_ops->coo_lock_init(env, scan, lock, io);
> 		if (result != 0) {
> 			cl_lock_fini(env, lock);
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> index f724b2d62df1..43bf1a422635 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
> @@ -190,16 +190,14 @@ EXPORT_SYMBOL(cl_object_attr_unlock);
> int cl_object_attr_get(const struct lu_env *env, struct cl_object *obj,
> 		       struct cl_attr *attr)
> {
> -	struct lu_object_header *top;
> -	int result;
> +	struct cl_object *o;
> +	int result = 0;
> 
> 	assert_spin_locked(cl_object_attr_guard(obj));
> 
> -	top = obj->co_lu.lo_header;
> -	result = 0;
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_attr_get) {
> -			result = obj->co_ops->coo_attr_get(env, obj, attr);
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_attr_get) {
> +			result = o->co_ops->coo_attr_get(env, o, attr);
> 			if (result != 0) {
> 				if (result > 0)
> 					result = 0;
> @@ -221,17 +219,15 @@ EXPORT_SYMBOL(cl_object_attr_get);
> int cl_object_attr_update(const struct lu_env *env, struct cl_object *obj,
> 			  const struct cl_attr *attr, unsigned int v)
> {
> -	struct lu_object_header *top;
> -	int result;
> +	struct cl_object *o;
> +	int result = 0;
> 
> 	assert_spin_locked(cl_object_attr_guard(obj));
> 
> -	top = obj->co_lu.lo_header;
> -	result = 0;
> -	list_for_each_entry_reverse(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_attr_update) {
> -			result = obj->co_ops->coo_attr_update(env, obj, attr,
> -							      v);
> +	cl_object_for_each_reverse(o, obj) {
> +		if (o->co_ops->coo_attr_update) {
> +			result = o->co_ops->coo_attr_update(env, o, attr,
> +							    v);
> 			if (result != 0) {
> 				if (result > 0)
> 					result = 0;
> @@ -254,19 +250,17 @@ EXPORT_SYMBOL(cl_object_attr_update);
> int cl_object_glimpse(const struct lu_env *env, struct cl_object *obj,
> 		      struct ost_lvb *lvb)
> {
> -	struct lu_object_header *top;
> -	int result;
> +	struct cl_object *o;
> +	int result = 0;
> 
> -	top = obj->co_lu.lo_header;
> -	result = 0;
> -	list_for_each_entry_reverse(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_glimpse) {
> -			result = obj->co_ops->coo_glimpse(env, obj, lvb);
> +	cl_object_for_each_reverse(o, obj) {
> +		if (o->co_ops->coo_glimpse) {
> +			result = o->co_ops->coo_glimpse(env, o, lvb);
> 			if (result != 0)
> 				break;
> 		}
> 	}
> -	LU_OBJECT_HEADER(D_DLMTRACE, env, lu_object_top(top),
> +	LU_OBJECT_HEADER(D_DLMTRACE, env, lu_object_top(obj->co_lu.lo_header),
> 			 "size: %llu mtime: %llu atime: %llu ctime: %llu blocks: %llu\n",
> 			 lvb->lvb_size, lvb->lvb_mtime, lvb->lvb_atime,
> 			 lvb->lvb_ctime, lvb->lvb_blocks);
> @@ -280,14 +274,12 @@ EXPORT_SYMBOL(cl_object_glimpse);
> int cl_conf_set(const struct lu_env *env, struct cl_object *obj,
> 		const struct cl_object_conf *conf)
> {
> -	struct lu_object_header *top;
> -	int result;
> +	struct cl_object *o;
> +	int result = 0;
> 
> -	top = obj->co_lu.lo_header;
> -	result = 0;
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_conf_set) {
> -			result = obj->co_ops->coo_conf_set(env, obj, conf);
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_conf_set) {
> +			result = o->co_ops->coo_conf_set(env, o, conf);
> 			if (result != 0)
> 				break;
> 		}
> @@ -301,13 +293,10 @@ EXPORT_SYMBOL(cl_conf_set);
>  */
> int cl_object_prune(const struct lu_env *env, struct cl_object *obj)
> {
> -	struct lu_object_header *top;
> 	struct cl_object *o;
> -	int result;
> +	int result = 0;
> 
> -	top = obj->co_lu.lo_header;
> -	result = 0;
> -	list_for_each_entry(o, &top->loh_layers, co_lu.lo_linkage) {
> +	cl_object_for_each(o, obj) {
> 		if (o->co_ops->coo_prune) {
> 			result = o->co_ops->coo_prune(env, o);
> 			if (result != 0)
> @@ -325,14 +314,13 @@ EXPORT_SYMBOL(cl_object_prune);
> int cl_object_getstripe(const struct lu_env *env, struct cl_object *obj,
> 			struct lov_user_md __user *uarg, size_t size)
> {
> -	struct lu_object_header *top;
> +	struct cl_object *o;
> 	int result = 0;
> 
> -	top = obj->co_lu.lo_header;
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_getstripe) {
> -			result = obj->co_ops->coo_getstripe(env, obj, uarg,
> -							    size);
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_getstripe) {
> +			result = o->co_ops->coo_getstripe(env, o, uarg,
> +							  size);
> 			if (result)
> 				break;
> 		}
> @@ -357,14 +345,13 @@ int cl_object_fiemap(const struct lu_env *env, struct cl_object *obj,
> 		     struct ll_fiemap_info_key *key,
> 		     struct fiemap *fiemap, size_t *buflen)
> {
> -	struct lu_object_header *top;
> +	struct cl_object *o;
> 	int result = 0;
> 
> -	top = obj->co_lu.lo_header;
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_fiemap) {
> -			result = obj->co_ops->coo_fiemap(env, obj, key, fiemap,
> -							 buflen);
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_fiemap) {
> +			result = o->co_ops->coo_fiemap(env, o, key, fiemap,
> +						       buflen);
> 			if (result)
> 				break;
> 		}
> @@ -376,11 +363,11 @@ EXPORT_SYMBOL(cl_object_fiemap);
> int cl_object_layout_get(const struct lu_env *env, struct cl_object *obj,
> 			 struct cl_layout *cl)
> {
> -	struct lu_object_header *top = obj->co_lu.lo_header;
> +	struct cl_object *o;
> 
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_layout_get)
> -			return obj->co_ops->coo_layout_get(env, obj, cl);
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_layout_get)
> +			return o->co_ops->coo_layout_get(env, o, cl);
> 	}
> 
> 	return -EOPNOTSUPP;
> @@ -389,12 +376,12 @@ EXPORT_SYMBOL(cl_object_layout_get);
> 
> loff_t cl_object_maxbytes(struct cl_object *obj)
> {
> -	struct lu_object_header *top = obj->co_lu.lo_header;
> +	struct cl_object *o;
> 	loff_t maxbytes = LLONG_MAX;
> 
> -	list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
> -		if (obj->co_ops->coo_maxbytes)
> -			maxbytes = min_t(loff_t, obj->co_ops->coo_maxbytes(obj),
> +	cl_object_for_each(o, obj) {
> +		if (o->co_ops->coo_maxbytes)
> +			maxbytes = min_t(loff_t, o->co_ops->coo_maxbytes(o),
> 					 maxbytes);
> 	}
> 
> diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
> index 057318deaa4e..7d00a9233a3b 100644
> --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
> +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
> @@ -132,7 +132,7 @@ struct cl_page *cl_page_alloc(const struct lu_env *env,
> 			      enum cl_page_type type)
> {
> 	struct cl_page *page;
> -	struct lu_object_header *head;
> +	struct cl_object *o2;
> 
> 	page = kzalloc(cl_object_header(o)->coh_page_bufsize, GFP_NOFS);
> 	if (page) {
> @@ -149,11 +149,10 @@ struct cl_page *cl_page_alloc(const struct lu_env *env,
> 		INIT_LIST_HEAD(&page->cp_layers);
> 		INIT_LIST_HEAD(&page->cp_batch);
> 		lu_ref_init(&page->cp_reference);
> -		head = o->co_lu.lo_header;
> -		list_for_each_entry(o, &head->loh_layers, co_lu.lo_linkage) {
> -			if (o->co_ops->coo_page_init) {
> -				result = o->co_ops->coo_page_init(env, o, page,
> -								  ind);
> +		cl_object_for_each(o2, o) {
> +			if (o2->co_ops->coo_page_init) {
> +				result = o2->co_ops->coo_page_init(env, o2, page,
> +								   ind);
> 				if (result != 0) {
> 					__cl_page_delete(env, page);
> 					cl_page_free(env, page);
> -- 
> 2.14.0.rc0.dirty

Cheers, Andreas
---
Andreas Dilger
CTO Whamcloud

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

end of thread, other threads:[~2019-02-15 18:15 UTC | newest]

Thread overview: 87+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-07  0:03 [lustre-devel] [PATCH 00/21] lustre: Assorted cleanups for obdclass NeilBrown
2019-02-07  0:03 ` [lustre-devel] [PATCH 02/21] lustre: obd_class: remove csi_barrier from struct cl_sync_io NeilBrown
2019-02-08  0:09   ` Andreas Dilger
2019-02-11  0:24     ` NeilBrown
2019-02-11  0:34   ` James Simmons
2019-02-11  1:09     ` NeilBrown
2019-02-07  0:03 ` [lustre-devel] [PATCH 05/21] lustre: use list_first_entry() in lustre subdirectory NeilBrown
2019-02-08  0:31   ` Andreas Dilger
2019-02-11  0:13     ` NeilBrown
2019-02-11  1:45   ` James Simmons
2019-02-11  3:08     ` NeilBrown
2019-02-07  0:03 ` [lustre-devel] [PATCH 03/21] lustre: obdclass: use list_sort() to sort a list NeilBrown
2019-02-08  0:13   ` Andreas Dilger
2019-02-11  0:39   ` James Simmons
2019-02-11  1:05     ` NeilBrown
2019-02-07  0:03 ` [lustre-devel] [PATCH 06/21] lustre: use list_first_entry() in lnet/lnet subdirectory NeilBrown
2019-02-08  0:44   ` Andreas Dilger
2019-02-11  1:46   ` James Simmons
2019-02-07  0:03 ` [lustre-devel] [PATCH 01/21] lustre: obdclass: discard csi_end_io NeilBrown
2019-02-07  0:20   ` Andreas Dilger
2019-02-11  0:19   ` James Simmons
2019-02-07  0:03 ` [lustre-devel] [PATCH 04/21] lustre: use list*entry macros in place of container_of() NeilBrown
2019-02-08  0:25   ` Andreas Dilger
2019-02-11  1:32   ` James Simmons
2019-02-11  3:14     ` NeilBrown
2019-02-07  0:03 ` [lustre-devel] [PATCH 13/21] lustre: make cp_ref in cl_page a refcount_t NeilBrown
2019-02-08  5:45   ` Andreas Dilger
2019-02-11  4:00   ` James Simmons
2019-02-07  0:03 ` [lustre-devel] [PATCH 14/21] lustre: make ccc_users in cl_client_cache " NeilBrown
2019-02-08  5:46   ` Andreas Dilger
2019-02-11  4:01   ` James Simmons
2019-02-07  0:03 ` [lustre-devel] [PATCH 08/21] lustre: use list_first_entry() throughout NeilBrown
2019-02-08  1:06   ` Andreas Dilger
2019-02-11  1:48   ` James Simmons
2019-02-07  0:03 ` [lustre-devel] [PATCH 20/21] lustre: obdclass: fix module load locking NeilBrown
2019-02-13  1:53   ` James Simmons
2019-02-07  0:03 ` [lustre-devel] [PATCH 17/21] lustre: obdclass: result of try_module_get() should not be ignored NeilBrown
2019-02-08  5:58   ` Andreas Dilger
2019-02-11  4:22   ` James Simmons
2019-02-11  5:01     ` NeilBrown
2019-02-11  5:09       ` [lustre-devel] [PATCH] lustre: don't manage module refs in obd_class_open/close NeilBrown
2019-02-12  4:17         ` James Simmons
2019-02-07  0:03 ` [lustre-devel] [PATCH 19/21] lustre: obdclass: avoid races in class_register_type() NeilBrown
2019-02-08  6:41   ` Andreas Dilger
2019-02-11  0:58     ` NeilBrown
2019-02-12  5:03   ` James Simmons
2019-02-14  3:43     ` NeilBrown
2019-02-07  0:03 ` [lustre-devel] [PATCH 11/21] lustre: cl_object: remove vestigial debugging NeilBrown
2019-02-08  1:31   ` Andreas Dilger
2019-02-11  0:48     ` NeilBrown
2019-02-11  2:04   ` James Simmons
2019-02-11  3:25     ` NeilBrown
2019-02-12  5:19       ` James Simmons
2019-02-12 13:56         ` Patrick Farrell
2019-02-12 22:12         ` NeilBrown
2019-02-13  0:19           ` James Simmons
2019-02-13  0:29             ` NeilBrown
2019-02-07  0:03 ` [lustre-devel] [PATCH 21/21] lustre: make exp_refcount in obd_export a refcount_t NeilBrown
2019-02-08  7:07   ` Andreas Dilger
2019-02-11  4:18   ` James Simmons
2019-02-07  0:03 ` [lustre-devel] [PATCH 10/21] lustre: obdclass: use cl_object_for_each where appropriate NeilBrown
2019-02-08  1:10   ` Andreas Dilger
2019-02-11  0:42     ` NeilBrown
2019-02-11  4:19       ` James Simmons
2019-02-15 18:15       ` Andreas Dilger
2019-02-11  1:57   ` James Simmons
2019-02-11  3:19     ` NeilBrown
2019-02-07  0:03 ` [lustre-devel] [PATCH 18/21] lustre: move debug.c from obdclass to obdecho NeilBrown
2019-02-08  6:02   ` Andreas Dilger
2019-02-11  4:17   ` James Simmons
2019-02-07  0:03 ` [lustre-devel] [PATCH 09/21] lustre: use list_last_entry() throughout NeilBrown
2019-02-08  1:07   ` Andreas Dilger
2019-02-11  1:48   ` James Simmons
2019-02-07  0:03 ` [lustre-devel] [PATCH 07/21] lustre: use list_first_entry() in lnet/klnds subdirectory NeilBrown
2019-02-08  0:59   ` Andreas Dilger
2019-02-11  0:34     ` NeilBrown
2019-02-11  1:47   ` James Simmons
2019-02-07  0:03 ` [lustre-devel] [PATCH 16/21] lustre: obdclass: normalize a switch statement NeilBrown
2019-02-08  5:57   ` Andreas Dilger
2019-02-11  4:03   ` James Simmons
2019-02-07  0:03 ` [lustre-devel] [PATCH 12/21] lustre: cl_page.c: remove PINVRNT() NeilBrown
2019-02-08  5:43   ` Andreas Dilger
2019-02-11  4:01   ` James Simmons
2019-02-07  0:03 ` [lustre-devel] [PATCH 15/21] lustre: obdclass: char obd_ioctl_getdata type NeilBrown
2019-02-08  5:56   ` Andreas Dilger
2019-02-11  0:52     ` NeilBrown
2019-02-11  4:03   ` 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.