From owner-freebsd-smp Fri Jun 23 1:46:31 2000 Delivered-To: freebsd-smp@freebsd.org Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by hub.freebsd.org (Postfix) with ESMTP id ED0A137C0EB for ; Fri, 23 Jun 2000 01:46:23 -0700 (PDT) (envelope-from bde@zeta.org.au) Received: from bde.zeta.org.au (bde.zeta.org.au [203.2.228.102]) by mailman.zeta.org.au (8.8.7/8.8.7) with ESMTP id SAA15077; Fri, 23 Jun 2000 18:45:34 +1000 Date: Fri, 23 Jun 2000 18:45:32 +1000 (EST) From: Bruce Evans X-Sender: bde@besplex.bde.org To: Matthew Dillon Cc: Jason Evans , Greg Lehey , Warner Losh , The Hermit Hacker , freebsd-smp@FreeBSD.ORG Subject: Re: SP Patchset #1 up In-Reply-To: <200006221558.IAA03062@apollo.backplane.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-smp@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org 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