Date: Fri, 23 Jun 2000 08:56:35 -0700 (PDT) From: Matthew Dillon <dillon@apollo.backplane.com> To: Bruce Evans <bde@zeta.org.au> 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: <200006231556.IAA10465@apollo.backplane.com> References: <Pine.BSF.4.21.0006231737460.1626-100000@besplex.bde.org>
next in thread | previous in thread | raw e-mail | index | archive | help
:> :> 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. A break point is a one-time deal. That'l work just fine. If the SchedMutex is already held then getting it again isn't going to hurt. If it isn't held then getting it the first time isn't going to hurt. The warning is there to avoid this situation: printf -> mtx_enter -> causes printf -> mtx_enter -> causes printf -> mtx_enter If we clear the break point prior to entering SchedMutex, then we don't have a recursion problem. :| 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. SchedMutex is never invalid. No mutex is ever 'invalid'... they are locked in an atomic cmpexg. Either SchedMutex is held when the break point occurs, or it isn't. : :| ++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 I don't see the issue here. interrupts cannot nest SchedMutex - look at the interrupt code. At the moment interrupt can nest other interrupts only insofar as the new interrupt occuring before the old interrupt has obtained the giant mutex. :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. I don't follow. The SchedMutex recursion count is saved and restored when a switch occurs. : :| } 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. If you place a debugger trap at a point where SchedMutex is held, guess which cpu the debugger takes the trap on? The one holding SchedMutex. Thus no problem... the debug trap will simply bump the recursion count of SchedMutex temporarily. :| } else { :| _mtx_enter_blocking(mtp, newv); :| } :| } :| mtp->mtx_type = type; /* set the type after obtaining */ :| } :| } : :Bruce The only thing we have to worry about insofar as debugger traps go is to be sure to clear the debug point prior to entering the SchedMutex within the debugger trap. I think this is trivial. -Matt Matthew Dillon <dillon@backplane.com> 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?200006231556.IAA10465>