tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
possible fix for: PR# 39420 - stopped processes can hold locks
The following patch adds an optional sigset to the list of signals
that we are not allowed to catch when waiting with PCATCH, and a
flag 'PNOSTOP' that uses this feature. This is so that NFS
interruptible mounts don't get stuck when people suspend their
processes while the NFS client code is holding locks. This is a
stopgap measure and is written in a way to minimize diffs.
Opinions?
christos
Index: kern/kern_condvar.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_condvar.c,v
retrieving revision 1.26
diff -u -u -r1.26 kern_condvar.c
--- kern/kern_condvar.c 19 Dec 2008 07:57:28 -0000 1.26
+++ kern/kern_condvar.c 17 Aug 2009 15:03:01 -0000
@@ -228,7 +228,7 @@
* call is restartable, or EINTR otherwise.
*/
int
-cv_wait_sig(kcondvar_t *cv, kmutex_t *mtx)
+cv_wait_sig1(kcondvar_t *cv, kmutex_t *mtx, const sigset_t *set)
{
lwp_t *l = curlwp;
int error;
@@ -236,7 +236,7 @@
KASSERT(mutex_owned(mtx));
cv_enter(cv, mtx, l);
- error = sleepq_block(0, true);
+ error = sleepq_block1(0, true, set);
return cv_exit(cv, mtx, l, error);
}
@@ -270,7 +270,7 @@
* call is restartable, or EINTR otherwise.
*/
int
-cv_timedwait_sig(kcondvar_t *cv, kmutex_t *mtx, int timo)
+cv_timedwait_sig1(kcondvar_t *cv, kmutex_t *mtx, int timo, const sigset_t *set)
{
lwp_t *l = curlwp;
int error;
@@ -278,7 +278,7 @@
KASSERT(mutex_owned(mtx));
cv_enter(cv, mtx, l);
- error = sleepq_block(timo, true);
+ error = sleepq_block1(timo, true, set);
return cv_exit(cv, mtx, l, error);
}
Index: kern/kern_sig.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_sig.c,v
retrieving revision 1.298
diff -u -u -r1.298 kern_sig.c
--- kern/kern_sig.c 24 May 2009 21:41:26 -0000 1.298
+++ kern/kern_sig.c 17 Aug 2009 15:03:02 -0000
@@ -640,7 +640,7 @@
* set.
*/
int
-sigispending(struct lwp *l, int signo)
+sigispending1(struct lwp *l, int signo, const sigset_t *set)
{
struct proc *p = l->l_proc;
sigset_t tset;
@@ -652,6 +652,9 @@
sigminusset(&p->p_sigctx.ps_sigignore, &tset);
sigminusset(&l->l_sigmask, &tset);
+ if (set)
+ sigminusset(set, &tset);
+
if (signo == 0) {
if (firstsig(&tset) != 0)
return EINTR;
Index: kern/kern_sleepq.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_sleepq.c,v
retrieving revision 1.36
diff -u -u -r1.36 kern_sleepq.c
--- kern/kern_sleepq.c 21 Mar 2009 13:11:14 -0000 1.36
+++ kern/kern_sleepq.c 17 Aug 2009 15:03:02 -0000
@@ -230,7 +230,7 @@
* example if the LWP's containing process is exiting.
*/
int
-sleepq_block(int timo, bool catch)
+sleepq_block1(int timo, bool catch, const sigset_t *set)
{
int error = 0, sig;
struct proc *p;
@@ -250,7 +250,8 @@
l->l_flag &= ~LW_CANCELLED;
error = EINTR;
early = true;
- } else if ((l->l_flag & LW_PENDSIG) != 0 && sigispending(l, 0))
+ } else if ((l->l_flag & LW_PENDSIG) != 0 && sigispending1(l, 0,
+ set))
early = true;
}
Index: kern/vfs_bio.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_bio.c,v
retrieving revision 1.218
diff -u -u -r1.218 vfs_bio.c
--- kern/vfs_bio.c 11 Mar 2009 05:55:22 -0000 1.218
+++ kern/vfs_bio.c 17 Aug 2009 15:03:04 -0000
@@ -1359,8 +1359,9 @@
if (!from_bufq || curlwp != uvm.pagedaemon_lwp) {
/* wait for a free buffer of any kind */
if ((slpflag & PCATCH) != 0)
- (void)cv_timedwait_sig(&needbuffer_cv,
- &bufcache_lock, slptimeo);
+ (void)cv_timedwait_sig1(&needbuffer_cv,
+ &bufcache_lock, slptimeo,
+ (slpflag & PNOSTOP) ? &stopsigmask : NULL);
else
(void)cv_timedwait(&needbuffer_cv,
&bufcache_lock, slptimeo);
Index: nfs/nfs_bio.c
===================================================================
RCS file: /cvsroot/src/sys/nfs/nfs_bio.c,v
retrieving revision 1.183
diff -u -u -r1.183 nfs_bio.c
--- nfs/nfs_bio.c 14 Mar 2009 14:46:11 -0000 1.183
+++ nfs/nfs_bio.c 17 Aug 2009 15:03:05 -0000
@@ -592,7 +592,7 @@
struct nfsmount *nmp = VFSTONFS(vp->v_mount);
if (nmp->nm_flag & NFSMNT_INT) {
- bp = getblk(vp, bn, size, PCATCH, 0);
+ bp = getblk(vp, bn, size, PCATCH|PNOSTOP, 0);
while (bp == NULL) {
if (nfs_sigintr(nmp, NULL, l))
return (NULL);
Index: rump/librump/rumpkern/emul.c
===================================================================
RCS file: /cvsroot/src/sys/rump/librump/rumpkern/emul.c,v
retrieving revision 1.91
diff -u -u -r1.91 emul.c
--- rump/librump/rumpkern/emul.c 20 Jul 2009 17:12:43 -0000 1.91
+++ rump/librump/rumpkern/emul.c 17 Aug 2009 15:03:05 -0000
@@ -53,6 +53,7 @@
#include <sys/module.h>
#include <sys/tty.h>
#include <sys/reboot.h>
+#include <sys/signal.h>
#include <dev/cons.h>
@@ -505,7 +506,7 @@
}
int
-sigispending(struct lwp *l, int signo)
+sigispending1(struct lwp *l, int signo, const sigset_t *ss)
{
return 0;
Index: rump/librump/rumpkern/locks.c
===================================================================
RCS file: /cvsroot/src/sys/rump/librump/rumpkern/locks.c,v
retrieving revision 1.27
diff -u -u -r1.27 locks.c
--- rump/librump/rumpkern/locks.c 7 Feb 2009 01:50:29 -0000 1.27
+++ rump/librump/rumpkern/locks.c 17 Aug 2009 15:03:06 -0000
@@ -239,7 +239,7 @@
}
int
-cv_wait_sig(kcondvar_t *cv, kmutex_t *mtx)
+cv_wait_sig1(kcondvar_t *cv, kmutex_t *mtx, const sigset_t *ss)
{
rumpuser_cv_wait(RUMPCV(cv), RUMPMTX(mtx));
@@ -266,7 +266,7 @@
}
int
-cv_timedwait_sig(kcondvar_t *cv, kmutex_t *mtx, int ticks)
+cv_timedwait_sig1(kcondvar_t *cv, kmutex_t *mtx, int ticks, const sigset_t *ss)
{
return cv_timedwait(cv, mtx, ticks);
Index: rump/librump/rumpkern/sleepq.c
===================================================================
RCS file: /cvsroot/src/sys/rump/librump/rumpkern/sleepq.c,v
retrieving revision 1.2
diff -u -u -r1.2 sleepq.c
--- rump/librump/rumpkern/sleepq.c 18 Dec 2008 00:24:12 -0000 1.2
+++ rump/librump/rumpkern/sleepq.c 17 Aug 2009 15:03:06 -0000
@@ -34,6 +34,7 @@
#include <sys/queue.h>
#include <sys/sleepq.h>
#include <sys/syncobj.h>
+#include <sys/signal.h>
/*
* Flimsy and minimalistic sleepq implementation. This is implemented
@@ -44,6 +45,7 @@
syncobj_t sleep_syncobj;
static kcondvar_t sq_cv;
static kmutex_t sq_mtx;
+sigset_t stopsigmask;
void
sleepq_init(sleepq_t *sq)
@@ -69,7 +71,7 @@
}
int
-sleepq_block(int timo, bool hatch)
+sleepq_block1(int timo, bool hatch, const sigset_t *ss)
{
struct lwp *l = curlwp;
Index: sys/condvar.h
===================================================================
RCS file: /cvsroot/src/sys/sys/condvar.h,v
retrieving revision 1.11
diff -u -u -r1.11 condvar.h
--- sys/condvar.h 19 Dec 2008 07:57:28 -0000 1.11
+++ sys/condvar.h 17 Aug 2009 15:03:06 -0000
@@ -33,6 +33,7 @@
#define _SYS_CONDVAR_H_
#include <sys/mutex.h>
+#include <sys/signal.h>
typedef struct kcondvar {
void *cv_opaque[3];
@@ -44,9 +45,12 @@
void cv_destroy(kcondvar_t *);
void cv_wait(kcondvar_t *, kmutex_t *);
-int cv_wait_sig(kcondvar_t *, kmutex_t *);
+int cv_wait_sig1(kcondvar_t *, kmutex_t *, const sigset_t *);
+#define cv_wait_sig(_cv, _km) cv_wait_sig1((_cv), (_km), NULL)
int cv_timedwait(kcondvar_t *, kmutex_t *, int);
-int cv_timedwait_sig(kcondvar_t *, kmutex_t *, int);
+int cv_timedwait_sig1(kcondvar_t *, kmutex_t *, int, const sigset_t *);
+#define cv_timedwait_sig(_cv, _km, _t) \
+ cv_timedwait_sig1((_cv), (_km), (_t), NULL)
void cv_signal(kcondvar_t *);
void cv_broadcast(kcondvar_t *);
Index: sys/param.h
===================================================================
RCS file: /cvsroot/src/sys/sys/param.h,v
retrieving revision 1.350
diff -u -u -r1.350 param.h
--- sys/param.h 29 Jun 2009 05:47:35 -0000 1.350
+++ sys/param.h 17 Aug 2009 15:03:06 -0000
@@ -63,7 +63,7 @@
* 2.99.9 (299000900)
*/
-#define __NetBSD_Version__ 599001500 /* NetBSD 5.99.15 */
+#define __NetBSD_Version__ 599001600 /* NetBSD 5.99.16 */
#define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \
(m) * 1000000) + (p) * 100) <= __NetBSD_Version__)
@@ -239,6 +239,8 @@
#define PCATCH 0x100 /* OR'd with pri for tsleep to check
signals */
#define PNORELOCK 0x200 /* OR'd with pri for tsleep to not
relock */
+#define PNOSTOP 0x400 /* OR'd with pri for tsleep to not
check stop
+ * signals */
/*
* New priority levels.
Index: sys/signalvar.h
===================================================================
RCS file: /cvsroot/src/sys/sys/signalvar.h,v
retrieving revision 1.75
diff -u -u -r1.75 signalvar.h
--- sys/signalvar.h 11 Jan 2009 02:45:55 -0000 1.75
+++ sys/signalvar.h 17 Aug 2009 15:03:06 -0000
@@ -183,7 +183,8 @@
register_t *, copyout_t, copyin_t, copyout_t);
void signotify(struct lwp *);
-int sigispending(struct lwp *, int);
+int sigispending1(struct lwp *, int, const sigset_t *);
+#define sigispending(_lw, _si) sigispending1((_lw), (_si), NULL)
/*
* Machine-dependent functions:
Index: sys/sleepq.h
===================================================================
RCS file: /cvsroot/src/sys/sys/sleepq.h,v
retrieving revision 1.16
diff -u -u -r1.16 sleepq.h
--- sys/sleepq.h 21 Mar 2009 13:11:14 -0000 1.16
+++ sys/sleepq.h 17 Aug 2009 15:03:07 -0000
@@ -38,6 +38,7 @@
#include <sys/queue.h>
#include <sys/sched.h>
#include <sys/syncobj.h>
+#include <sys/signal.h>
/*
* Generic sleep queues.
@@ -68,7 +69,8 @@
int sleepq_abort(kmutex_t *, int);
void sleepq_changepri(lwp_t *, pri_t);
void sleepq_lendpri(lwp_t *, pri_t);
-int sleepq_block(int, bool);
+int sleepq_block1(int, bool, const sigset_t *);
+#define sleepq_block(_t, _c) sleepq_block1((_t), (_c), NULL)
void sleepq_insert(sleepq_t *, lwp_t *, syncobj_t *);
void sleeptab_init(sleeptab_t *);
Home |
Main Index |
Thread Index |
Old Index