From owner-freebsd-smp Fri Nov 17 18:59:30 2000 Delivered-To: freebsd-smp@freebsd.org Received: from io.yi.org (h24-69-199-88.gv.shawcable.net [24.69.199.88]) by hub.freebsd.org (Postfix) with ESMTP id B9EBC37B479; Fri, 17 Nov 2000 18:59:12 -0800 (PST) Received: from io.yi.org (localhost.gvcl1.bc.wave.home.com [127.0.0.1]) by io.yi.org (Postfix) with ESMTP id 158D4BA7A; Fri, 17 Nov 2000 18:59:12 -0800 (PST) X-Mailer: exmh version 2.1.1 10/15/1999 To: John Baldwin Cc: smp@FreeBSD.ORG Subject: Re: cvs commit: src/sys/kern kern_timeout.c In-Reply-To: Message from John Baldwin of "Fri, 17 Nov 2000 16:47:30 PST." Mime-Version: 1.0 Content-Type: multipart/mixed ; boundary="==_Exmh_18918598640" Date: Fri, 17 Nov 2000 18:59:12 -0800 From: Jake Burkholder Message-Id: <20001118025912.158D4BA7A@io.yi.org> Sender: owner-freebsd-smp@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org This is a multipart MIME message. --==_Exmh_18918598640 Content-Type: text/plain; charset=us-ascii > > On 18-Nov-00 John Baldwin wrote: > > > > On 18-Nov-00 John Baldwin wrote: > >> jhb 2000/11/17 16:21:01 PST > >> > >> Modified files: > >> sys/kern kern_timeout.c > >> Log: > >> Release sched_lock very briefly to give interrupts a chance to fire if we > >> are in softclock() for a long time. The old code already did an > >> splx()/slphigh() pair here, I just missed adding in the equivalent mutex > >> operations on sched_lock earlier. > > > > Before this I could get processes to hang (the box was still up, but one > > process was stuck, tying up its pty) though the box was still fine (I could > > login and do stuff) if I ran a buildworld -j X where X > 1. With this I > > built > > a kernel with -j 8 and am currently chugging through a -j 64 world. > > Grrrr. Spoke too soon. :( It took longer, but I have one hung process (though > the rest of the buildworld is still chugging along). I notice the problem > because I have one sh process that has been a zombie for a way too long. It's > parent is a make doing a make cleandir, and the parent is in SSLEEP on > "pipewr". I notice that when the kernel tsleep()'s with "pipewr", it does a > tsleep() with PCATCH, so I am betting that there it is still related to the > CURSIG() stuff in msleep(). Since this doesn't happen very often, I'm guessing > that this comes about when a process is switched out because it blocked on > Giant. Hmm. Do you know if its a timed sleep? If so, its possible that you're missing a timeout because hardclock and softclock are racing. If its not a timeout, and the wakeup happens while we're blocked on Giant, it should be OK because wakeup will set p_wchan to 0 even if the process is in state SMTX and we'll goto resume when the process gets unblocked. Anyway, here's the callout_lock patch I mentioned, it might help. It will conflict with the above commit because I don't have it locally yet, but its small. Before this gets committed I'd like to move the callout initialization to its own sysinit in kern_timeout.c, so we can initialize the lock there instead of in all the machdep.c's. I think the APM_FIXUP_CALLTODO thing has rotted, its based on the old delta queue timeout implementation. Jake > > -- > > John Baldwin -- http://www.FreeBSD.org/~jhb/ > PGP Key: http://www.baldwin.cx/~john/pgpkey.asc > "Power Users Use the Power to Serve!" - http://www.FreeBSD.org/ > > > To Unsubscribe: send mail to majordomo@FreeBSD.org > with "unsubscribe freebsd-smp" in the body of the message --==_Exmh_18918598640 Content-Type: text/plain ; name="timo2.diff"; charset=us-ascii Content-Description: timo2.diff Content-Disposition: attachment; filename="timo2.diff" Index: sys/callout.h =================================================================== RCS file: /home/ncvs/src/sys/sys/callout.h,v retrieving revision 1.17 diff -u -r1.17 callout.h --- sys/callout.h 2000/05/26 02:06:53 1.17 +++ sys/callout.h 2000/11/18 02:00:18 @@ -61,6 +61,7 @@ #define CALLOUT_LOCAL_ALLOC 0x0001 /* was allocated from callfree */ #define CALLOUT_ACTIVE 0x0002 /* callout is currently active */ #define CALLOUT_PENDING 0x0004 /* callout is waiting for timeout */ +#define CALLOUT_MPSAFE 0x0008 /* callout handler is mp safe */ struct callout_handle { struct callout *callout; @@ -72,6 +73,7 @@ extern int ncallout; extern struct callout_tailq *callwheel; extern int callwheelsize, callwheelbits, callwheelmask, softticks; +extern struct mtx callout_lock; #define callout_active(c) ((c)->c_flags & CALLOUT_ACTIVE) #define callout_deactivate(c) ((c)->c_flags &= ~CALLOUT_ACTIVE) Index: kern/kern_clock.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_clock.c,v retrieving revision 1.115 diff -u -r1.115 kern_clock.c --- kern/kern_clock.c 2000/10/25 05:19:38 1.115 +++ kern/kern_clock.c 2000/11/18 02:05:45 @@ -154,6 +154,7 @@ register struct clockframe *frame; { register struct proc *p; + int need_softclock = 0; p = curproc; if (p != idleproc) { @@ -187,16 +188,25 @@ statclock(frame); tc_windup(); - ticks++; /* * Process callouts at a very low cpu priority, so we don't keep the * relatively high clock interrupt priority any longer than necessary. */ + mtx_enter(&callout_lock, MTX_SPIN); + ticks++; if (TAILQ_FIRST(&callwheel[ticks & callwheelmask]) != NULL) { - sched_swi(softclock_ih, SWI_NOSWITCH); + need_softclock = 1; } else if (softticks + 1 == ticks) ++softticks; + mtx_exit(&callout_lock, MTX_SPIN); + + /* + * sched_swi acquires sched_lock, so we don't want to call it with + * callout_lock held; incorrect locking order. + */ + if (need_softclock) + sched_swi(softclock_ih, SWI_NOSWITCH); } /* Index: kern/kern_intr.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_intr.c,v retrieving revision 1.31 diff -u -r1.31 kern_intr.c --- kern/kern_intr.c 2000/11/15 22:05:23 1.31 +++ kern/kern_intr.c 2000/11/18 02:06:07 @@ -258,7 +258,7 @@ { net_ih = sinthand_add("net", NULL, swi_net, NULL, SWI_NET, 0); softclock_ih = - sinthand_add("clock", &clk_ithd, softclock, NULL, SWI_CLOCK, 0); + sinthand_add("clock", &clk_ithd, softclock, NULL, SWI_CLOCK, INTR_MPSAFE); vm_ih = sinthand_add("vm", NULL, swi_vm, NULL, SWI_VM, 0); } Index: kern/kern_mutex.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_mutex.c,v retrieving revision 1.17 diff -u -r1.17 kern_mutex.c --- kern/kern_mutex.c 2000/11/17 18:09:14 1.17 +++ kern/kern_mutex.c 2000/11/18 02:09:55 @@ -703,6 +703,7 @@ #ifdef __i386__ "clk", #endif + "callout", /* * leaf locks */ Index: kern/kern_timeout.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_timeout.c,v retrieving revision 1.61 diff -u -r1.61 kern_timeout.c --- kern/kern_timeout.c 2000/11/16 21:20:52 1.61 +++ kern/kern_timeout.c 2000/11/18 02:18:10 @@ -56,6 +56,7 @@ int callwheelsize, callwheelbits, callwheelmask; struct callout_tailq *callwheel; int softticks; /* Like ticks, but for softclock(). */ +MUTEX_DECLARE(, callout_lock); static struct callout *nextsoftcheck; /* Next callout to be checked. */ @@ -90,7 +91,7 @@ steps = 0; s = splhigh(); - mtx_enter(&sched_lock, MTX_SPIN); + mtx_enter(&callout_lock, MTX_SPIN); while (softticks != ticks) { softticks++; /* @@ -107,8 +108,10 @@ if (steps >= MAX_SOFTCLOCK_STEPS) { nextsoftcheck = c; /* Give interrupts a chance. */ + mtx_exit(&callout_lock, MTX_SPIN); splx(s); s = splhigh(); + mtx_enter(&callout_lock, MTX_SPIN); c = nextsoftcheck; steps = 0; } @@ -129,18 +132,22 @@ c->c_flags = (c->c_flags & ~CALLOUT_PENDING); } - mtx_exit(&sched_lock, MTX_SPIN); + mtx_exit(&callout_lock, MTX_SPIN); + if (!(c->c_flags & CALLOUT_MPSAFE)) + mtx_enter(&Giant, MTX_DEF); splx(s); c_func(c_arg); s = splhigh(); - mtx_enter(&sched_lock, MTX_SPIN); + if (!(c->c_flags & CALLOUT_MPSAFE)) + mtx_exit(&Giant, MTX_DEF); + mtx_enter(&callout_lock, MTX_SPIN); steps = 0; c = nextsoftcheck; } } } nextsoftcheck = NULL; - mtx_exit(&sched_lock, MTX_SPIN); + mtx_exit(&callout_lock, MTX_SPIN); splx(s); } @@ -171,7 +178,7 @@ struct callout_handle handle; s = splhigh(); - mtx_enter(&sched_lock, MTX_SPIN); + mtx_enter(&callout_lock, MTX_SPIN); /* Fill in the next free callout structure. */ new = SLIST_FIRST(&callfree); @@ -183,7 +190,7 @@ callout_reset(new, to_ticks, ftn, arg); handle.callout = new; - mtx_exit(&sched_lock, MTX_SPIN); + mtx_exit(&callout_lock, MTX_SPIN); splx(s); return (handle); } @@ -205,10 +212,10 @@ return; s = splhigh(); - mtx_enter(&sched_lock, MTX_SPIN); + mtx_enter(&callout_lock, MTX_SPIN); if (handle.callout->c_func == ftn && handle.callout->c_arg == arg) callout_stop(handle.callout); - mtx_exit(&sched_lock, MTX_SPIN); + mtx_exit(&callout_lock, MTX_SPIN); splx(s); } @@ -242,7 +249,7 @@ int s; s = splhigh(); - mtx_enter(&sched_lock, MTX_SPIN); + mtx_enter(&callout_lock, MTX_SPIN); if (c->c_flags & CALLOUT_PENDING) callout_stop(c); @@ -260,7 +267,7 @@ c->c_time = ticks + to_ticks; TAILQ_INSERT_TAIL(&callwheel[c->c_time & callwheelmask], c, c_links.tqe); - mtx_exit(&sched_lock, MTX_SPIN); + mtx_exit(&callout_lock, MTX_SPIN); splx(s); } @@ -271,13 +278,13 @@ int s; s = splhigh(); - mtx_enter(&sched_lock, MTX_SPIN); + mtx_enter(&callout_lock, MTX_SPIN); /* * Don't attempt to delete a callout that's not on the queue. */ if (!(c->c_flags & CALLOUT_PENDING)) { c->c_flags &= ~CALLOUT_ACTIVE; - mtx_exit(&sched_lock, MTX_SPIN); + mtx_exit(&callout_lock, MTX_SPIN); splx(s); return; } @@ -292,7 +299,7 @@ if (c->c_flags & CALLOUT_LOCAL_ALLOC) { SLIST_INSERT_HEAD(&callfree, c, c_links.sle); } - mtx_exit(&sched_lock, MTX_SPIN); + mtx_exit(&callout_lock, MTX_SPIN); splx(s); } @@ -354,7 +361,7 @@ /* don't collide with softclock() */ s = splhigh(); - mtx_enter(&sched_lock, MTX_SPIN); + mtx_enter(&callout_lock, MTX_SPIN); for (p = calltodo.c_next; p != NULL; p = p->c_next) { p->c_time -= delta_ticks; @@ -365,7 +372,7 @@ /* take back the ticks the timer didn't use (p->c_time <= 0) */ delta_ticks = -p->c_time; } - mtx_exit(&sched_lock, MTX_SPIN); + mtx_exit(&callout_lock, MTX_SPIN); splx(s); return; Index: i386/i386/machdep.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/machdep.c,v retrieving revision 1.420 diff -u -r1.420 machdep.c --- i386/i386/machdep.c 2000/10/27 11:45:23 1.420 +++ i386/i386/machdep.c 2000/11/18 01:59:51 @@ -409,6 +409,8 @@ TAILQ_INIT(&callwheel[i]); } + mtx_init(&callout_lock, "callout", MTX_SPIN | MTX_COLD); + #if defined(USERCONFIG) userconfig(); cninit(); /* the preferred console may have changed */ --==_Exmh_18918598640-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-smp" in the body of the message