Skip site navigation (1)Skip section navigation (2)
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>