public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: green@linuxhacker.ru
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	devel@driverdev.osuosl.org,
	Andreas Dilger <andreas.dilger@intel.com>
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Lustre Development List <lustre-devel@lists.lustre.org>,
	Jinshan Xiong <jinshan.xiong@intel.com>,
	Oleg Drokin <green@linuxhacker.ru>
Subject: [PATCH 18/43] staging/lustre/clio: generalize cl_sync_io
Date: Wed, 30 Mar 2016 12:47:50 -0400	[thread overview]
Message-ID: <1459356495-2794775-19-git-send-email-green@linuxhacker.ru> (raw)
In-Reply-To: <1459356495-2794775-1-git-send-email-green@linuxhacker.ru>

From: Jinshan Xiong <jinshan.xiong@intel.com>

To make cl_sync_io interfaces not just wait for pages, but to be
a generic synchronization mechanism.

Also remove cl_io_cancel that became not used.

Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com>
Reviewed-on: http://review.whamcloud.com/8656
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4198
Reviewed-by: Bobi Jam <bobijam@gmail.com>
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Signed-off-by: Oleg Drokin <green@linuxhacker.ru>
---
 drivers/staging/lustre/lustre/include/cl_object.h | 13 ++--
 drivers/staging/lustre/lustre/obdclass/cl_io.c    | 74 +++++++++++------------
 drivers/staging/lustre/lustre/obdclass/cl_page.c  |  2 +-
 3 files changed, 44 insertions(+), 45 deletions(-)

diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h
index 69b40f5..91261b1 100644
--- a/drivers/staging/lustre/lustre/include/cl_object.h
+++ b/drivers/staging/lustre/lustre/include/cl_object.h
@@ -3125,13 +3125,18 @@ 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 nrpages);
-int  cl_sync_io_wait(const struct lu_env *env, struct cl_io *io,
-		     struct cl_page_list *queue, struct cl_sync_io *anchor,
+void cl_sync_io_init(struct cl_sync_io *anchor, int nr,
+		     void (*end)(const struct lu_env *, struct cl_sync_io *));
+int  cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
 		     long timeout);
-void cl_sync_io_note(struct cl_sync_io *anchor, int ioret);
+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 65d6cee..6a8dd9f 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -800,6 +800,9 @@ int cl_io_submit_rw(const struct lu_env *env, struct cl_io *io,
 }
 EXPORT_SYMBOL(cl_io_submit_rw);
 
+static void cl_page_list_assume(const struct lu_env *env,
+				struct cl_io *io, struct cl_page_list *plist);
+
 /**
  * Submit a sync_io and wait for the IO to be finished, or error happens.
  * If \a timeout is zero, it means to wait for the IO unconditionally.
@@ -817,7 +820,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_init(anchor, queue->c2_qin.pl_nr, &cl_sync_io_end);
 	rc = cl_io_submit_rw(env, io, iot, queue);
 	if (rc == 0) {
 		/*
@@ -828,12 +831,12 @@ int cl_io_submit_sync(const struct lu_env *env, struct cl_io *io,
 		 */
 		cl_page_list_for_each(pg, &queue->c2_qin) {
 			pg->cp_sync_io = NULL;
-			cl_sync_io_note(anchor, 1);
+			cl_sync_io_note(env, anchor, 1);
 		}
 
 		/* wait for the IO to be finished. */
-		rc = cl_sync_io_wait(env, io, &queue->c2_qout,
-				     anchor, timeout);
+		rc = cl_sync_io_wait(env, anchor, timeout);
+		cl_page_list_assume(env, io, &queue->c2_qout);
 	} else {
 		LASSERT(list_empty(&queue->c2_qout.pl_pages));
 		cl_page_list_for_each(pg, &queue->c2_qin)
@@ -844,25 +847,6 @@ int cl_io_submit_sync(const struct lu_env *env, struct cl_io *io,
 EXPORT_SYMBOL(cl_io_submit_sync);
 
 /**
- * Cancel an IO which has been submitted by cl_io_submit_rw.
- */
-static int cl_io_cancel(const struct lu_env *env, struct cl_io *io,
-			struct cl_page_list *queue)
-{
-	struct cl_page *page;
-	int result = 0;
-
-	CERROR("Canceling ongoing page transmission\n");
-	cl_page_list_for_each(page, queue) {
-		int rc;
-
-		rc = cl_page_cancel(env, page);
-		result = result ?: rc;
-	}
-	return result;
-}
-
-/**
  * Main io loop.
  *
  * Pumps io through iterations calling
@@ -1433,25 +1417,38 @@ void cl_req_attr_set(const struct lu_env *env, struct cl_req *req,
 }
 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, for transfer of \a nrpages pages.
+ * Initialize synchronous io wait anchor
  */
-void cl_sync_io_init(struct cl_sync_io *anchor, int nrpages)
+void cl_sync_io_init(struct cl_sync_io *anchor, int nr,
+		     void (*end)(const struct lu_env *, struct cl_sync_io *))
 {
 	init_waitqueue_head(&anchor->csi_waitq);
-	atomic_set(&anchor->csi_sync_nr, nrpages);
-	atomic_set(&anchor->csi_barrier, nrpages > 0);
+	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);
 
 /**
- * Wait until all transfer completes. Transfer completion routine has to call
- * cl_sync_io_note() for every page.
+ * Wait until all IO completes. Transfer completion routine has to call
+ * cl_sync_io_note() for every entity.
  */
-int cl_sync_io_wait(const struct lu_env *env, struct cl_io *io,
-		    struct cl_page_list *queue, struct cl_sync_io *anchor,
+int cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
 		    long timeout)
 {
 	struct l_wait_info lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(timeout),
@@ -1464,11 +1461,9 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_io *io,
 			  atomic_read(&anchor->csi_sync_nr) == 0,
 			  &lwi);
 	if (rc < 0) {
-		CERROR("SYNC IO failed with error: %d, try to cancel %d remaining pages\n",
+		CERROR("IO failed: %d, still wait for %d remaining entries\n",
 		       rc, atomic_read(&anchor->csi_sync_nr));
 
-		(void)cl_io_cancel(env, io, queue);
-
 		lwi = (struct l_wait_info) { 0 };
 		(void)l_wait_event(anchor->csi_waitq,
 				   atomic_read(&anchor->csi_sync_nr) == 0,
@@ -1477,14 +1472,12 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_io *io,
 		rc = anchor->csi_sync_rc;
 	}
 	LASSERT(atomic_read(&anchor->csi_sync_nr) == 0);
-	cl_page_list_assume(env, io, queue);
 
 	/* wait until cl_sync_io_note() has done wakeup */
 	while (unlikely(atomic_read(&anchor->csi_barrier) != 0)) {
 		cpu_relax();
 	}
 
-	POISON(anchor, 0x5a, sizeof(*anchor));
 	return rc;
 }
 EXPORT_SYMBOL(cl_sync_io_wait);
@@ -1492,7 +1485,8 @@ EXPORT_SYMBOL(cl_sync_io_wait);
 /**
  * Indicate that transfer of a single page completed.
  */
-void cl_sync_io_note(struct cl_sync_io *anchor, int ioret)
+void cl_sync_io_note(const struct lu_env *env, struct cl_sync_io *anchor,
+		     int ioret)
 {
 	if (anchor->csi_sync_rc == 0 && ioret < 0)
 		anchor->csi_sync_rc = ioret;
@@ -1503,9 +1497,9 @@ void cl_sync_io_note(struct cl_sync_io *anchor, int ioret)
 	 */
 	LASSERT(atomic_read(&anchor->csi_sync_nr) > 0);
 	if (atomic_dec_and_test(&anchor->csi_sync_nr)) {
-		wake_up_all(&anchor->csi_waitq);
-		/* it's safe to nuke or reuse anchor now */
-		atomic_set(&anchor->csi_barrier, 0);
+		LASSERT(anchor->csi_end_io);
+		anchor->csi_end_io(env, anchor);
+		/* Can't access anchor any more */
 	}
 }
 EXPORT_SYMBOL(cl_sync_io_note);
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c
index 506a9f9..ad7f0ae 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_page.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c
@@ -887,7 +887,7 @@ void cl_page_completion(const struct lu_env *env,
 	cl_page_put(env, pg);
 
 	if (anchor)
-		cl_sync_io_note(anchor, ioret);
+		cl_sync_io_note(env, anchor, ioret);
 }
 EXPORT_SYMBOL(cl_page_completion);
 
-- 
2.1.0

  parent reply	other threads:[~2016-03-30 16:49 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-30 16:47 [PATCH 00/43] Lustre IO stack simplifications and cleanups green
2016-03-30 16:47 ` [PATCH 01/43] staging/lustre/obdclass: limit lu_site hash table size green
2016-03-30 16:47 ` [PATCH 02/43] staging/lustre: Get rid of CFS_PAGE_MASK green
2016-03-30 16:47 ` [PATCH 03/43] staging/lustre: merge lclient/*.c into llite/ green
2016-03-30 16:47 ` [PATCH 04/43] staging/lustre: Reintroduce global env list green
2016-03-30 16:47 ` [PATCH 05/43] staging/lustre/osc: Adjustment on osc LRU for performance green
2016-03-30 16:47 ` [PATCH 06/43] staging/lustre/osc: to drop LRU pages with cl_lru_work green
2016-03-30 16:47 ` [PATCH 07/43] staging/lustre/clio: collapse layer of cl_page green
2016-03-30 16:47 ` [PATCH 08/43] staging/lustre/obdclass: Add a preallocated percpu cl_env green
2016-03-30 16:47 ` [PATCH 09/43] staging/lustre/clio: add pages into writeback cache in batches green
2016-03-30 16:47 ` [PATCH 10/43] staging/lustre/osc: add weight function for DLM lock green
2016-03-30 16:47 ` [PATCH 11/43] staging/lustre/clio: remove stackable cl_page completely green
2016-03-30 16:47 ` [PATCH 12/43] staging/lustre/clio: optimize read ahead code green
2016-03-30 16:47 ` [PATCH 13/43] staging/lustre/llite: remove lli_lvb green
2016-03-30 16:47 ` [PATCH 14/43] staging/lustre/lmv: remove lmv_init_{lock,unlock}() green
2016-03-30 16:47 ` [PATCH 15/43] staging/lustre/obd: remove struct client_obd_lock green
2016-03-30 16:47 ` [PATCH 16/43] staging/lustre/llite: remove some cl wrappers green
2016-03-30 16:47 ` [PATCH 17/43] staging/lustre: Remove struct ll_iattr green
2016-03-30 16:47 ` green [this message]
2016-03-30 16:47 ` [PATCH 19/43] staging/lustre/clio: cl_lock simplification green
2016-03-30 16:47 ` [PATCH 20/43] staging/lustre: update comments after " green
2016-03-30 16:47 ` [PATCH 21/43] staging/lustre/llite: clip page correctly for vvp_io_commit_sync green
2016-03-30 16:47 ` [PATCH 22/43] staging/lustre/llite: deadlock for page write green
2016-03-30 16:47 ` [PATCH 23/43] staging/lustre/llite: make sure we do cl_page_clip on the last page green
2016-03-30 16:47 ` [PATCH 24/43] staging/lustre/llite: merge lclient.h into llite/vvp_internal.h green
2016-03-30 16:47 ` [PATCH 25/43] staging/lustre/llite: rename ccc_device to vvp_device green
2016-03-30 16:47 ` [PATCH 26/43] staging/lustre/llite: rename ccc_object to vvp_object green
2016-03-30 16:47 ` [PATCH 27/43] staging/lustre/llite: rename ccc_page to vvp_page green
2016-03-30 16:48 ` [PATCH 28/43] staging/lustre/llite: rename ccc_lock to vvp_lock green
2016-03-30 16:48 ` [PATCH 29/43] staging/lustre:llite: remove struct ll_ra_read green
2016-03-30 16:48 ` [PATCH 30/43] staging/lustre/llite: merge ccc_io and vvp_io green
2016-03-30 16:48 ` [PATCH 31/43] staging/lustre/llite: use vui prefix for struct vvp_io members green
2016-03-30 16:48 ` [PATCH 32/43] staging/lustre/llite: move vvp_io functions to vvp_io.c green
2016-03-30 16:48 ` [PATCH 33/43] staging/lustre/llite: rename ccc_req to vvp_req green
2016-03-30 16:48 ` [PATCH 34/43] staging/lustre/llite: Rename struct ccc_grouplock to ll_grouplock green
2016-03-30 16:48 ` [PATCH 35/43] staging/lustre/llite: Rename struct vvp_thread_info to ll_thread_info green
2016-03-30 23:13   ` kbuild test robot
2016-03-30 23:39     ` [lustre-devel] " Oleg Drokin
2016-03-30 16:48 ` [PATCH 36/43] staging/lustre/llite: rename struct ccc_thread_info to vvp_thread_info green
2016-03-30 16:48 ` [PATCH 37/43] staging/lustre/llite: Remove ccc_global_{init,fini}() green
2016-03-30 16:48 ` [PATCH 38/43] staging/lustre/llite: Move ll_dirent_type_get and make it static green
2016-03-30 16:48 ` [PATCH 39/43] staging/lustre/llite: Move several declarations to llite_internal.h green
2016-03-30 16:48 ` [PATCH 40/43] staging/lustre/llite: Remove unused vui_local_lock field green
2016-03-30 16:48 ` [PATCH 41/43] staging/lustre/ldlm: ELC picks locks in a safer policy green
2016-03-30 16:48 ` [PATCH 42/43] staging/lustre/ldlm: revert changes to ldlm_cancel_aged_policy() green
2016-03-30 16:48 ` [PATCH 43/43] staging/lustre/ldlm: restore the ELC for enqueue green

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1459356495-2794775-19-git-send-email-green@linuxhacker.ru \
    --to=green@linuxhacker.ru \
    --cc=andreas.dilger@intel.com \
    --cc=devel@driverdev.osuosl.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jinshan.xiong@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lustre-devel@lists.lustre.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox