Date: Fri, 23 Jun 2000 18:45:32 +1000 (EST) From: Bruce Evans <bde@zeta.org.au> To: Matthew Dillon <dillon@apollo.backplane.com> Cc: Jason Evans <jasone@canonware.com>, Greg Lehey <grog@lemis.com>, Warner Losh <imp@village.org>, The Hermit Hacker <scrappy@hub.org>, freebsd-smp@FreeBSD.ORG Subject: Re: SP Patchset #1 up Message-ID: <Pine.BSF.4.21.0006231737460.1626-100000@besplex.bde.org> In-Reply-To: <200006221558.IAA03062@apollo.backplane.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 22 Jun 2000, Matthew Dillon wrote: > :You now have deadlock when the low level console i/o routines are > :reentered for ddb i/o, since task switching is either impossible or > :undesireable while ddb is active (it's essentially impossible if ddb > :was entered via a breakpoint in the middle of task switching code). > : > :When task switching is possible to avoid deadlock on console i/o > :resources, it may still be undesirable. A printf from a high priority > :interrupt task shouldn't have to wait for a printf from a low priority > :task to complete. > > I don't follow. Why do I have a deadlock? This is SchedMutex I'm > talking about here, not GiantMutex. mtx_enter_sched_quick() is mtx_enter(&SchedMutex, MTX_SPIN). | /* | * mtx_enter() | * ... | * WARNING: DO NOT PUT KERNEL PRINTFS IN THE SPIN CODE!, you may | * create a recursion. | */ This warning gives another reason why ddb can't call locking functions. Putting a breakpoint at a locking functions or wandering into a locking function while single stepping will cause console i/o. | static __inline void | mtx_enter(struct mtx *mtp, int type) | { | u_int32_t newv; | | newv = (u_int32_t)curproc | MTF_HELD; | if ((mtp->mtx_lock & ~MTF_CONTESTED) == newv) { Here is another reason why ddb can't call locking functions. curproc may be in the middle of being switched when a debugger trap occurs, so ddb can't call anything that depends on it being valid. SchedMutex may be invalid for the same reason. | ++mtp->mtx_recurse; /* bump recursion */ I'm not sure if this code is reached. If it is, then we don't have deadlock but we have the same bugs as for spltty() -- recursion is not prevented recursion although some console i/o routines don't support it. Many levels of recursion are possible: printf in process context --> interrupt ... printf in interrupt context --> higher priority interrupt ... printf in interrupt context ... even higher priority interrupts --> debugger trap ... debugger printf --> fatal trap for bug in printf ... bogus printfs (should longjmp) --> double fault for bug in fatal trap handler ... final printfs If switching from a high priority interrupt task to a low priority one is allowed, then the first few levels don't need to be supported. | } else { | if (atomic_cmpexg_int(&mtp->mtx_lock, 0, newv) != 0) { | if (type & MTX_SPIN) { | _mtx_enter_spin(mtp, newv); If this code is reached, then it should spin for ever, since other tasks should not run, even if there is another CPU for it to run on. | } else { | _mtx_enter_blocking(mtp, newv); | } | } | mtp->mtx_type = type; /* set the type after obtaining */ | } | } Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-smp" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0006231737460.1626-100000>