linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Oleg Drokin <green@linuxhacker.ru>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	linux-kernel@vger.kernel.org, devel@driverdev.osuosl.org
Cc: Jinshan Xiong <jinshan.xiong@intel.com>,
	Oleg Drokin <oleg.drokin@intel.com>
Subject: [PATCH 26/47] staging/lustre/llite: access layout version under a lock
Date: Sun, 27 Apr 2014 13:06:50 -0400	[thread overview]
Message-ID: <1398618431-29757-27-git-send-email-green@linuxhacker.ru> (raw)
In-Reply-To: <1398618431-29757-1-git-send-email-green@linuxhacker.ru>

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

We used to access layout version under the protection of ldlm
lock, this introduces extra overhead for dlm lock matching.

In this patch, lli_layout_lock is introduced to access the layout
version. Also, when a layout lock is losing, we should tear down
mmap of the correspoding inode to avoid stale data accessing in the
future.

This is part of technical verification of replication.

Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com>
Reviewed-on: http://review.whamcloud.com/8689
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3254
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Reviewed-by: Bobi Jam <bobijam@gmail.com>
Signed-off-by: Oleg Drokin <oleg.drokin@intel.com>
---
 drivers/staging/lustre/lustre/llite/file.c         | 22 ++++-----------
 .../staging/lustre/lustre/llite/llite_internal.h   | 21 ++++++++++++++-
 drivers/staging/lustre/lustre/llite/llite_lib.c    |  3 ++-
 drivers/staging/lustre/lustre/llite/vvp_io.c       |  2 +-
 drivers/staging/lustre/lustre/llite/vvp_object.c   | 31 ++++++++++++++++------
 5 files changed, 51 insertions(+), 28 deletions(-)

diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c
index 166321c..e3bc2b0 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -3436,7 +3436,7 @@ static int ll_layout_lock_set(struct lustre_handle *lockh, ldlm_mode_t mode,
 		if (lvb_ready) {
 			/* layout_gen must be valid if layout lock is not
 			 * cancelled and stripe has already set */
-			*gen = lli->lli_layout_gen;
+			*gen = ll_layout_version_get(lli);
 			rc = 0;
 		}
 		GOTO(out, rc);
@@ -3534,32 +3534,20 @@ int ll_layout_refresh(struct inode *inode, __u32 *gen)
 	};
 	int rc;
 
-	*gen = lli->lli_layout_gen;
-	if (!(sbi->ll_flags & LL_SBI_LAYOUT_LOCK))
+	*gen = ll_layout_version_get(lli);
+	if (!(sbi->ll_flags & LL_SBI_LAYOUT_LOCK) || *gen != LL_LAYOUT_GEN_NONE)
 		return 0;
 
 	/* sanity checks */
 	LASSERT(fid_is_sane(ll_inode2fid(inode)));
 	LASSERT(S_ISREG(inode->i_mode));
 
-	/* mostly layout lock is caching on the local side, so try to match
-	 * it before grabbing layout lock mutex. */
-	mode = ll_take_md_lock(inode, MDS_INODELOCK_LAYOUT, &lockh, 0,
-			       LCK_CR | LCK_CW | LCK_PR | LCK_PW);
-	if (mode != 0) { /* hit cached lock */
-		rc = ll_layout_lock_set(&lockh, mode, inode, gen, false);
-		if (rc == 0)
-			return 0;
-
-		/* better hold lli_layout_mutex to try again otherwise
-		 * it will have starvation problem. */
-	}
-
 	/* take layout lock mutex to enqueue layout lock exclusively. */
 	mutex_lock(&lli->lli_layout_mutex);
 
 again:
-	/* try again. Maybe somebody else has done this. */
+	/* mostly layout lock is caching on the local side, so try to match
+	 * it before grabbing layout lock mutex. */
 	mode = ll_take_md_lock(inode, MDS_INODELOCK_LAYOUT, &lockh, 0,
 			       LCK_CR | LCK_CW | LCK_PR | LCK_PW);
 	if (mode != 0) { /* hit cached lock */
diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h
index 4663e82..d2f8250 100644
--- a/drivers/staging/lustre/lustre/llite/llite_internal.h
+++ b/drivers/staging/lustre/lustre/llite/llite_internal.h
@@ -280,14 +280,33 @@ struct ll_inode_info {
 
 	/* mutex to request for layout lock exclusively. */
 	struct mutex			lli_layout_mutex;
-	/* valid only inside LAYOUT ibits lock, protected by lli_layout_mutex */
+	/* Layout version, protected by lli_layout_lock */
 	__u32				lli_layout_gen;
+	spinlock_t			lli_layout_lock;
 
 	struct rw_semaphore		lli_xattrs_list_rwsem;
 	struct mutex			lli_xattrs_enq_lock;
 	struct list_head		lli_xattrs;/* ll_xattr_entry->xe_list */
 };
 
+static inline __u32 ll_layout_version_get(struct ll_inode_info *lli)
+{
+	__u32 gen;
+
+	spin_lock(&lli->lli_layout_lock);
+	gen = lli->lli_layout_gen;
+	spin_unlock(&lli->lli_layout_lock);
+
+	return gen;
+}
+
+static inline void ll_layout_version_set(struct ll_inode_info *lli, __u32 gen)
+{
+	spin_lock(&lli->lli_layout_lock);
+	lli->lli_layout_gen = gen;
+	spin_unlock(&lli->lli_layout_lock);
+}
+
 int ll_xattr_cache_destroy(struct inode *inode);
 
 int ll_xattr_cache_get(struct inode *inode,
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
index 582fafc..befc30b 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -966,7 +966,8 @@ void ll_lli_init(struct ll_inode_info *lli)
 	mutex_init(&lli->lli_och_mutex);
 	spin_lock_init(&lli->lli_agl_lock);
 	lli->lli_has_smd = false;
-	lli->lli_layout_gen = LL_LAYOUT_GEN_NONE;
+	spin_lock_init(&lli->lli_layout_lock);
+	ll_layout_version_set(lli, LL_LAYOUT_GEN_NONE);
 	lli->lli_clob = NULL;
 
 	init_rwsem(&lli->lli_xattrs_list_rwsem);
diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c
index c7d7009..5156ab8 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_io.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_io.c
@@ -80,7 +80,7 @@ static bool can_populate_pages(const struct lu_env *env, struct cl_io *io,
 	case CIT_WRITE:
 		/* don't need lock here to check lli_layout_gen as we have held
 		 * extent lock and GROUP lock has to hold to swap layout */
-		if (lli->lli_layout_gen != cio->cui_layout_gen) {
+		if (ll_layout_version_get(lli) != cio->cui_layout_gen) {
 			io->ci_need_restart = 1;
 			/* this will return application a short read/write */
 			io->ci_continue = 0;
diff --git a/drivers/staging/lustre/lustre/llite/vvp_object.c b/drivers/staging/lustre/lustre/llite/vvp_object.c
index 25973de..554a5dd 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_object.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_object.c
@@ -126,7 +126,22 @@ int vvp_conf_set(const struct lu_env *env, struct cl_object *obj,
 	struct ll_inode_info *lli = ll_i2info(conf->coc_inode);
 
 	if (conf->coc_opc == OBJECT_CONF_INVALIDATE) {
-		lli->lli_layout_gen = LL_LAYOUT_GEN_NONE;
+		CDEBUG(D_VFSTRACE, DFID ": losing layout lock\n",
+		       PFID(&lli->lli_fid));
+
+		ll_layout_version_set(lli, LL_LAYOUT_GEN_NONE);
+
+		/* Clean up page mmap for this inode.
+		 * The reason for us to do this is that if the page has
+		 * already been installed into memory space, the process
+		 * can access it without interacting with lustre, so this
+		 * page may be stale due to layout change, and the process
+		 * will never be notified.
+		 * This operation is expensive but mmap processes have to pay
+		 * a price themselves. */
+		unmap_mapping_range(conf->coc_inode->i_mapping,
+				    0, OBD_OBJECT_EOF, 0);
+
 		return 0;
 	}
 
@@ -134,18 +149,18 @@ int vvp_conf_set(const struct lu_env *env, struct cl_object *obj,
 		return 0;
 
 	if (conf->u.coc_md != NULL && conf->u.coc_md->lsm != NULL) {
-		CDEBUG(D_VFSTRACE, "layout lock change: %u -> %u\n",
-			lli->lli_layout_gen,
-			conf->u.coc_md->lsm->lsm_layout_gen);
+		CDEBUG(D_VFSTRACE, DFID ": layout version change: %u -> %u\n",
+		       PFID(&lli->lli_fid), lli->lli_layout_gen,
+		       conf->u.coc_md->lsm->lsm_layout_gen);
 
 		lli->lli_has_smd = lsm_has_objects(conf->u.coc_md->lsm);
-		lli->lli_layout_gen = conf->u.coc_md->lsm->lsm_layout_gen;
+		ll_layout_version_set(lli, conf->u.coc_md->lsm->lsm_layout_gen);
 	} else {
-		CDEBUG(D_VFSTRACE, "layout lock destroyed: %u.\n",
-			lli->lli_layout_gen);
+		CDEBUG(D_VFSTRACE, DFID ": layout nuked: %u.\n",
+		       PFID(&lli->lli_fid), lli->lli_layout_gen);
 
 		lli->lli_has_smd = false;
-		lli->lli_layout_gen = LL_LAYOUT_GEN_EMPTY;
+		ll_layout_version_set(lli, LL_LAYOUT_GEN_EMPTY);
 	}
 	return 0;
 }
-- 
1.8.5.3


  parent reply	other threads:[~2014-04-27 17:17 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-27 17:06 [PATCH 00/47] Lustre fixes and cleanups Oleg Drokin
2014-04-27 17:06 ` [PATCH 01/47] staging/lustre/ptlrpc: Fix assertion failure of null_alloc_rs() Oleg Drokin
2014-04-27 17:06 ` [PATCH 02/47] staging/lustre/ptlrpc: Remove log message about export timer update Oleg Drokin
2014-04-27 17:06 ` [PATCH 03/47] staging/lustre/gss: gssnull security flavor Oleg Drokin
2014-04-27 17:06 ` [PATCH 04/47] staging/lustre/gss: Shared key mechanism & flavors Oleg Drokin
2014-04-27 17:20   ` Greg Kroah-Hartman
2014-04-27 17:06 ` [PATCH 05/47] staging/lustre/osc: don't activate deactivated obd_import Oleg Drokin
2014-04-27 17:06 ` [PATCH 06/47] staging/lustre/lnet: Dropped messages are not accounted correctly Oleg Drokin
2014-04-27 17:06 ` [PATCH 07/47] staging/lustre/ldlm: Hold lock when clearing flag Oleg Drokin
2014-04-27 17:06 ` [PATCH 08/47] staging/lustre/clio: clear nowait flag agl lock re-enqueue Oleg Drokin
2014-04-27 17:06 ` [PATCH 09/47] staging/lustre/ptlrpc: don't try to recover no_recov connection Oleg Drokin
2014-04-27 17:06 ` [PATCH 10/47] staging/lustre/gss: fix few issues found by Klocwork Insight tool Oleg Drokin
2014-04-27 17:06 ` [PATCH 11/47] staging/lustre/ptlrpc: add rpc_cache Oleg Drokin
2014-04-29  9:46   ` Dan Carpenter
2014-04-30  3:22     ` Oleg Drokin
2014-04-27 17:06 ` [PATCH 12/47] staging/lustre: restore __GFP_WAIT flag to memalloc calls Oleg Drokin
2014-04-27 17:06 ` [PATCH 13/47] staging/lustre/gss: fix uninitialized variable Oleg Drokin
2014-04-27 17:06 ` [PATCH 14/47] staging/lustre: quiet console permission error messages Oleg Drokin
2014-04-27 17:06 ` [PATCH 15/47] staging/lustre/lov: remove unused lov llog code Oleg Drokin
2014-04-27 17:06 ` [PATCH 16/47] staging/lustre/obdclass: remove uses of lov_stripe_md Oleg Drokin
2014-04-27 17:06 ` [PATCH 17/47] staging/lustre/hsm: count NULL terminator in hai_zero/hal_size Oleg Drokin
2014-04-27 17:06 ` [PATCH 18/47] staging/lustre/hsm: HSM requests not delivered Oleg Drokin
2014-04-29  9:08   ` Dan Carpenter
2014-04-30  3:31     ` Oleg Drokin
2014-04-27 17:06 ` [PATCH 19/47] staging/lustre: fix permission problem of setfacl Oleg Drokin
2014-04-27 17:06 ` [PATCH 20/47] staging/lustre/llite: issue OST_SYNC for fsync() Oleg Drokin
2014-04-27 17:06 ` [PATCH 21/47] staging/lustre/llite: deadlock taking lli_trunc_sem during file write Oleg Drokin
2014-04-27 17:06 ` [PATCH 22/47] staging/lustre/lov: to not hold sub locks at initialization Oleg Drokin
2014-04-27 17:06 ` [PATCH 23/47] staging/lustre: Limit reply buffer size Oleg Drokin
2014-04-27 17:06 ` [PATCH 24/47] staging/lustre/llite: Avoid statahead thread start/stop deadlocks Oleg Drokin
2014-04-27 17:06 ` [PATCH 25/47] stagaing/lustre: Improve statahead debug messages Oleg Drokin
2014-04-27 17:06 ` Oleg Drokin [this message]
2014-04-27 17:06 ` [PATCH 27/47] staging/lustre: shrink lu_object_header by 8 bytes on x86_64 Oleg Drokin
2014-04-27 17:06 ` [PATCH 28/47] staging/lustre/ldlm: fix NULL pointer dereference Oleg Drokin
2014-04-27 17:06 ` [PATCH 29/47] staging/lustre/lnet: lnet: fix issues found by Klocwork Insight tool Oleg Drokin
2014-04-27 17:25   ` Greg Kroah-Hartman
2014-04-27 17:06 ` [PATCH 30/47] staging/lustre/mdc: fix issue " Oleg Drokin
2014-04-29 10:20   ` Dan Carpenter
2014-04-27 17:06 ` [PATCH 31/47] staging/lustre/libcfs: fix issues " Oleg Drokin
2014-04-27 17:06 ` [PATCH 32/47] staging/lustre/lnet: NI shutdown may loop forever Oleg Drokin
2014-04-27 17:06 ` [PATCH 33/47] staging/lustre: remove lustre/include/ioctl.h Oleg Drokin
2014-04-27 17:06 ` [PATCH 34/47] staging/lustre/libcfs: add CPU table functions for uniprocessor Oleg Drokin
2014-04-29 10:35   ` Dan Carpenter
2014-04-27 17:06 ` [PATCH 35/47] staging/lustre: replace semaphores with mutexes Oleg Drokin
2014-04-27 17:07 ` [PATCH 36/47] staging/lustre/clio: replace semaphore with mutex Oleg Drokin
2014-04-27 17:07 ` [PATCH 37/47] staging/lustre/llite: Do not rate limit dirty page discard warning Oleg Drokin
2014-04-27 17:07 ` [PATCH 38/47] staging/lustre/lloop: avoid panic during blockdev_info Oleg Drokin
2014-04-27 17:07 ` [PATCH 39/47] staging/lustre/clio: Solve a race in cl_lock_put Oleg Drokin
2014-04-27 17:07 ` [PATCH 40/47] staging/lustre/mdc: use cl_max_mds_md to pack getattr RPC Oleg Drokin
2014-04-27 17:07 ` [PATCH 41/47] staging/lustre/llite: remove dead code Oleg Drokin
2014-04-29 11:02   ` Dan Carpenter
2014-04-29 19:16     ` Hammond, John
2014-04-29 20:17       ` Dan Carpenter
2014-04-30  3:21     ` Oleg Drokin
2014-04-30  8:01       ` Dan Carpenter
2014-04-29 11:12   ` Richard Weinberger
2014-04-27 17:07 ` [PATCH 42/47] staging/lustre: remove assertion of spin_is_locked() Oleg Drokin
2014-04-27 17:07 ` [PATCH 43/47] staging/lustre/osc: Update inode timestamp for lockless IO as well Oleg Drokin
2014-04-27 17:07 ` [PATCH 44/47] staging/lustre: Always clamp cdls_delay between min and max Oleg Drokin
2014-04-27 17:07 ` [PATCH 45/47] staging/lustre: pass fsync() range through RPC/IO stack Oleg Drokin
2014-04-27 17:07 ` [PATCH 46/47] staging/lustre: Fix unsafe userspace access in many proc files Oleg Drokin
2014-04-27 17:30   ` Greg Kroah-Hartman
2014-04-27 17:07 ` [PATCH 47/47] staging/lustre/llite: prevent buffer overflow in fiemap Oleg Drokin
2014-04-27 17:33 ` [PATCH 00/47] Lustre fixes and cleanups Greg Kroah-Hartman
2014-04-27 18:28   ` Oleg Drokin

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=1398618431-29757-27-git-send-email-green@linuxhacker.ru \
    --to=green@linuxhacker.ru \
    --cc=devel@driverdev.osuosl.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jinshan.xiong@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oleg.drokin@intel.com \
    /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;
as well as URLs for NNTP newsgroup(s).