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
This commit is contained in:
christos 2018-01-21 20:36:49 +00:00
parent 04a3ff8338
commit ef140c5bfd
4 changed files with 28 additions and 14 deletions

View File

@ -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) */

View File

@ -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 <sys/cdefs.h>
__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.

View File

@ -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 <sys/cdefs.h>
__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) {

View File

@ -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 <sys/cdefs.h>
__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();