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