On Fri, May 08, 2015 at 12:34 +0200, Mike Belopuhov wrote:
> > I think tsleep(9) and msleep(9) need to release and re-acquire the
> > kernel lock in the "cold || panicstr" case.
> 
> Well, it's not hard to do really, but...
> 
> > We might need this for
> > handling interrupts during autoconf as soon as we start distributing
> > interrupts over CPUs.
> >
> 
> ...cold might mean that interrupts are not ready yet.  So then we might
> need another flag for shutdown?

This is what I have come up with.  Chunks were taken directly from
mi_switch and it seems to do the job just fine.  Right now I'm not
using any additional flags and it seems to work here.  I'll resume
testing on Monday, but it looks fairly complete.  Any comments?

diff --git sys/kern/kern_synch.c sys/kern/kern_synch.c
index 03308b4..4089adf 100644
--- sys/kern/kern_synch.c
+++ sys/kern/kern_synch.c
@@ -103,10 +103,13 @@ extern int safepri;
 int
 tsleep(const volatile void *ident, int priority, const char *wmesg, int timo)
 {
        struct sleep_state sls;
        int error, error1;
+#ifdef MULTIPROCESSOR
+       int hold_count;
+#endif
 
        KASSERT((priority & ~(PRIMASK | PCATCH)) == 0);
 
 #ifdef MULTIPROCESSOR
        KASSERT(timo || __mp_lock_held(&kernel_lock));
@@ -120,10 +123,18 @@ tsleep(const volatile void *ident, int priority, const 
char *wmesg, int timo)
                 * don't run any other procs or panic below,
                 * in case this is the idle process and already asleep.
                 */
                s = splhigh();
                splx(safepri);
+#ifdef MULTIPROCESSOR
+               if (__mp_lock_held(&kernel_lock))
+                       hold_count = __mp_release_all(&kernel_lock);
+               else
+                       hold_count = 0;
+               if (hold_count)
+                       __mp_acquire_count(&kernel_lock, hold_count);
+#endif
                splx(s);
                return (0);
        }
 
        sleep_setup(&sls, ident, priority, wmesg);
@@ -149,10 +160,13 @@ int
 msleep(const volatile void *ident, struct mutex *mtx, int priority,
     const char *wmesg, int timo)
 {
        struct sleep_state sls;
        int error, error1, spl;
+#ifdef MULTIPROCESSOR
+       int hold_count;
+#endif
 
        KASSERT((priority & ~(PRIMASK | PCATCH | PNORELOCK)) == 0);
        KASSERT(mtx != NULL);
 
        if (cold || panicstr) {
@@ -163,10 +177,18 @@ msleep(const volatile void *ident, struct mutex *mtx, int 
priority,
                 * in case this is the idle process and already asleep.
                 */
                spl = MUTEX_OLDIPL(mtx);
                MUTEX_OLDIPL(mtx) = safepri;
                mtx_leave(mtx);
+#ifdef MULTIPROCESSOR
+               if (__mp_lock_held(&kernel_lock))
+                       hold_count = __mp_release_all(&kernel_lock);
+               else
+                       hold_count = 0;
+               if (hold_count)
+                       __mp_acquire_count(&kernel_lock, hold_count);
+#endif
                if ((priority & PNORELOCK) == 0) {
                        mtx_enter(mtx);
                        MUTEX_OLDIPL(mtx) = spl;
                } else
                        splx(spl);
diff --git sys/kern/vfs_subr.c sys/kern/vfs_subr.c
index a26fbe2..a373789 100644
--- sys/kern/vfs_subr.c
+++ sys/kern/vfs_subr.c
@@ -1664,10 +1664,13 @@ int
 vfs_syncwait(int verbose)
 {
        struct buf *bp;
        int iter, nbusy, dcount, s;
        struct proc *p;
+#ifdef MULTIPROCESSOR
+       int hold_count;
+#endif
 
        p = curproc? curproc : &proc0;
        sys_sync(p, (void *)0, (register_t *)0);
 
        /* Wait for sync to finish. */
@@ -1698,11 +1701,21 @@ vfs_syncwait(int verbose)
                }
                if (nbusy == 0)
                        break;
                if (verbose)
                        printf("%d ", nbusy);
+#ifdef MULTIPROCESSOR
+               if (__mp_lock_held(&kernel_lock))
+                       hold_count = __mp_release_all(&kernel_lock);
+               else
+                       hold_count = 0;
+#endif
                DELAY(40000 * iter);
+#ifdef MULTIPROCESSOR
+               if (hold_count)
+                       __mp_acquire_count(&kernel_lock, hold_count);
+#endif
        }
 
        return nbusy;
 }
 

Reply via email to