From ef140c5bfd3e70ccc6030c86b8586d823be5ef2f Mon Sep 17 00:00:00 2001 From: christos Date: Sun, 21 Jan 2018 20:36:49 +0000 Subject: [PATCH] PR/40491: From Tobias Ulmer in tech-kern@: 1. Protect the nfs request queue with its own mutex 2. make the nfs_receive queue check for signals so that intr mounts can be interrupted. XXX: pullup-8 --- sys/nfs/nfs.h | 3 ++- sys/nfs/nfs_clntsocket.c | 18 +++++++++++++----- sys/nfs/nfs_socket.c | 15 +++++++++------ sys/nfs/nfs_subs.c | 6 ++++-- 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/sys/nfs/nfs.h b/sys/nfs/nfs.h index efc2a6efbe7a..c31626458236 100644 --- a/sys/nfs/nfs.h +++ b/sys/nfs/nfs.h @@ -1,4 +1,4 @@ -/* $NetBSD: nfs.h,v 1.75 2015/04/20 13:12:24 riastradh Exp $ */ +/* $NetBSD: nfs.h,v 1.76 2018/01/21 20:36:49 christos Exp $ */ /* * Copyright (c) 1989, 1993, 1995 * The Regents of the University of California. All rights reserved. @@ -341,6 +341,7 @@ struct nfsreq { * Queue head for nfsreq's */ extern TAILQ_HEAD(nfsreqhead, nfsreq) nfs_reqq; +extern kmutex_t nfs_reqq_lock; /* Flag values for r_flags */ #define R_TIMING 0x01 /* timing request (in mntp) */ diff --git a/sys/nfs/nfs_clntsocket.c b/sys/nfs/nfs_clntsocket.c index a16b92653045..e59e45639f78 100644 --- a/sys/nfs/nfs_clntsocket.c +++ b/sys/nfs/nfs_clntsocket.c @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_clntsocket.c,v 1.5 2016/06/17 14:28:29 christos Exp $ */ +/* $NetBSD: nfs_clntsocket.c,v 1.6 2018/01/21 20:36:49 christos Exp $ */ /* * Copyright (c) 1989, 1991, 1993, 1995 @@ -39,7 +39,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nfs_clntsocket.c,v 1.5 2016/06/17 14:28:29 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nfs_clntsocket.c,v 1.6 2018/01/21 20:36:49 christos Exp $"); #ifdef _KERNEL_OPT #include "opt_nfs.h" @@ -294,9 +294,11 @@ errout: rcvflg = 0; error = (*so->so_receive)(so, getnam, &auio, mp, NULL, &rcvflg); - if (error == EWOULDBLOCK && - (rep->r_flags & R_SOFTTERM)) - return (EINTR); + if (error == EWOULDBLOCK) { + int intr = nfs_sigintr(rep->r_nmp, rep, l); + if (intr) + error = intr; + } } while (error == EWOULDBLOCK); len -= auio.uio_resid; if (!error && *mp == NULL) @@ -403,6 +405,7 @@ nfsmout: * Iff no match, just drop the datagram */ s = splsoftnet(); + mutex_enter(&nfs_reqq_lock); TAILQ_FOREACH(rep, &nfs_reqq, r_chain) { if (rep->r_mrep != NULL || rxid != rep->r_xid) continue; @@ -468,6 +471,7 @@ nfsmout: nmp->nm_timeouts = 0; break; } + mutex_exit(&nfs_reqq_lock); splx(s); nfs_rcvunlock(nmp); /* @@ -653,7 +657,9 @@ tryagain: * to put it LAST so timer finds oldest requests first. */ s = splsoftnet(); + mutex_enter(&nfs_reqq_lock); TAILQ_INSERT_TAIL(&nfs_reqq, rep, r_chain); + mutex_exit(&nfs_reqq_lock); nfs_timer_start(); /* @@ -695,7 +701,9 @@ tryagain: * RPC done, unlink the request. */ s = splsoftnet(); + mutex_enter(&nfs_reqq_lock); TAILQ_REMOVE(&nfs_reqq, rep, r_chain); + mutex_exit(&nfs_reqq_lock); /* * Decrement the outstanding request count. diff --git a/sys/nfs/nfs_socket.c b/sys/nfs/nfs_socket.c index 7214ad5b0df5..20f4dd45db38 100644 --- a/sys/nfs/nfs_socket.c +++ b/sys/nfs/nfs_socket.c @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_socket.c,v 1.198 2016/06/17 14:28:29 christos Exp $ */ +/* $NetBSD: nfs_socket.c,v 1.199 2018/01/21 20:36:49 christos Exp $ */ /* * Copyright (c) 1989, 1991, 1993, 1995 @@ -39,7 +39,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nfs_socket.c,v 1.198 2016/06/17 14:28:29 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nfs_socket.c,v 1.199 2018/01/21 20:36:49 christos Exp $"); #ifdef _KERNEL_OPT #include "opt_nfs.h" @@ -166,6 +166,7 @@ int nfsrtton = 0; struct nfsrtt nfsrtt; static const int nfs_backoff[8] = { 2, 4, 8, 16, 32, 64, 128, 256, }; struct nfsreqhead nfs_reqq; +kmutex_t nfs_reqq_lock; static callout_t nfs_timer_ch; static struct evcnt nfs_timer_ev; static struct evcnt nfs_timer_start_ev; @@ -385,6 +386,7 @@ nfs_reconnect(struct nfsreq *rep) * on old socket. */ s = splsoftnet(); + mutex_enter(&nfs_reqq_lock); TAILQ_FOREACH(rp, &nfs_reqq, r_chain) { if (rp->r_nmp == nmp) { if ((rp->r_flags & R_MUSTRESEND) == 0) @@ -392,6 +394,7 @@ nfs_reconnect(struct nfsreq *rep) rp->r_rexmit = 0; } } + mutex_exit(&nfs_reqq_lock); splx(s); return (0); } @@ -759,7 +762,7 @@ nfs_timer(void *arg) nfs_timer_ev.ev_count++; - mutex_enter(softnet_lock); /* XXX PR 40491 */ + mutex_enter(&nfs_reqq_lock); TAILQ_FOREACH(rep, &nfs_reqq, r_chain) { more = true; nmp = rep->r_nmp; @@ -813,7 +816,7 @@ nfs_timer(void *arg) * Resend it * Set r_rtt to -1 in case we fail to send it now. */ - /* solock(so); XXX PR 40491 */ + solock(so); rep->r_rtt = -1; if (sbspace(&so->so_snd) >= rep->r_mreq->m_pkthdr.len && ((nmp->nm_flag & NFSMNT_DUMBTIMR) || @@ -858,9 +861,9 @@ nfs_timer(void *arg) rep->r_rtt = 0; } } - /* sounlock(so); XXX PR 40491 */ + sounlock(so); } - mutex_exit(softnet_lock); /* XXX PR 40491 */ + mutex_exit(&nfs_reqq_lock); mutex_enter(&nfs_timer_lock); if (nfs_timer_srvvec != NULL) { diff --git a/sys/nfs/nfs_subs.c b/sys/nfs/nfs_subs.c index ae27af521a5b..7e25d11a0b69 100644 --- a/sys/nfs/nfs_subs.c +++ b/sys/nfs/nfs_subs.c @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_subs.c,v 1.229 2017/04/01 19:35:57 riastradh Exp $ */ +/* $NetBSD: nfs_subs.c,v 1.230 2018/01/21 20:36:49 christos Exp $ */ /* * Copyright (c) 1989, 1993 @@ -70,7 +70,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.229 2017/04/01 19:35:57 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.230 2018/01/21 20:36:49 christos Exp $"); #ifdef _KERNEL_OPT #include "opt_nfs.h" @@ -1495,6 +1495,7 @@ nfs_init0(void) * Initialize reply list and start timer */ TAILQ_INIT(&nfs_reqq); + mutex_init(&nfs_reqq_lock, MUTEX_DEFAULT, IPL_NONE); nfs_timer_init(); MOWNER_ATTACH(&nfs_mowner); @@ -1534,6 +1535,7 @@ nfs_fini(void) if (--nfs_refcount == 0) { MOWNER_DETACH(&nfs_mowner); nfs_timer_fini(); + mutex_destroy(&nfs_reqq_lock); nfsdreq_fini(); } nfs_v();