Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 17 Sep 2019 15:24:30 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Peter Jeremy <peter@rulingia.com>
Cc:        Masachika ISHIZUKA <ish@amail.plala.or.jp>, freebsd-current@freebsd.org, Rick Macklem <rmacklem@uoguelph.ca>
Subject:   Re: panic: sleeping thread on r352386
Message-ID:  <20190917122430.GZ2559@kib.kiev.ua>
In-Reply-To: <20190917101826.GJ97181@server.rulingia.com>
References:  <20190916.205532.1314832713594158104.ish@amail.plala.or.jp> <16601631.sFgvYJuXru@direwolf.local.> <20190917.144251.30337396601444833.ish@amail.plala.or.jp> <20190917080658.GW2559@kib.kiev.ua> <20190917101826.GJ97181@server.rulingia.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Sep 17, 2019 at 08:18:26PM +1000, Peter Jeremy wrote:
> On 2019-Sep-17 11:06:58 +0300, Konstantin Belousov <kostikbel@gmail.com> wrote:
> >Try the following change, which more accurately tries to avoid
> >vnode_pager_setsize().  The real cause requires much more extensive
> >changes.
> >
> >diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c
> >index 63ea4736707..16dc7745c77 100644
> >--- a/sys/fs/nfsclient/nfs_clport.c
> >+++ b/sys/fs/nfsclient/nfs_clport.c
> ...
> 
> With that patch, I'm back to "Sleeping thread (...) owns a non-sleepable
> lock" panics.

Try this.

diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c
index 63ea4736707..a23b4ba4efa 100644
--- a/sys/fs/nfsclient/nfs_clport.c
+++ b/sys/fs/nfsclient/nfs_clport.c
@@ -414,12 +414,12 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvattr *nap, void *nvaper,
 	struct nfsnode *np;
 	struct nfsmount *nmp;
 	struct timespec mtime_save;
+	vm_object_t object;
 	u_quad_t nsize;
-	int setnsize, error, force_fid_err;
+	int error, force_fid_err;
+	bool setnsize;
 
 	error = 0;
-	setnsize = 0;
-	nsize = 0;
 
 	/*
 	 * If v_type == VNON it is a new node, so fill in the v_type,
@@ -511,8 +511,7 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvattr *nap, void *nvaper,
 				 * zero np->n_attrstamp to indicate that
 				 * the attributes are stale.
 				 */
-				nsize = vap->va_size = np->n_size;
-				setnsize = 1;
+				vap->va_size = np->n_size;
 				np->n_attrstamp = 0;
 				KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
 			} else if (np->n_flag & NMODIFIED) {
@@ -526,22 +525,9 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvattr *nap, void *nvaper,
 					np->n_size = vap->va_size;
 					np->n_flag |= NSIZECHANGED;
 				}
-				nsize = np->n_size;
-				setnsize = 1;
-			} else if (vap->va_size < np->n_size) {
-				/*
-				 * When shrinking the size, the call to
-				 * vnode_pager_setsize() cannot be done
-				 * with the mutex held, so delay it until
-				 * after the mtx_unlock call.
-				 */
-				nsize = np->n_size = vap->va_size;
-				np->n_flag |= NSIZECHANGED;
-				setnsize = 1;
 			} else {
-				nsize = np->n_size = vap->va_size;
+				np->n_size = vap->va_size;
 				np->n_flag |= NSIZECHANGED;
-				setnsize = 1;
 			}
 		} else {
 			np->n_size = vap->va_size;
@@ -579,6 +565,23 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvattr *nap, void *nvaper,
 	if (np->n_attrstamp != 0)
 		KDTRACE_NFS_ATTRCACHE_LOAD_DONE(vp, vap, error);
 #endif
+	nsize = vap->va_size;
+	object = vp->v_object;
+	setnsize = false;
+	if (object != NULL) {
+		if (OFF_TO_IDX(nsize + PAGE_MASK) < object->size) {
+			/*
+			 * When shrinking the size, the call to
+			 * vnode_pager_setsize() cannot be done with
+			 * the mutex held, because we might need to
+			 * wait for a busy page.  Delay it until after
+			 * the node is unlocked.
+			 */
+			setnsize = true;
+		} else {
+			vnode_pager_setsize(vp, nsize);
+		}
+	}
 	NFSUNLOCKNODE(np);
 	if (setnsize)
 		vnode_pager_setsize(vp, nsize);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20190917122430.GZ2559>