Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Jan 2006 09:06:09 -0500
From:      John Baldwin <jhb@freebsd.org>
To:        Scott Long <scottl@samsco.org>
Cc:        cvs-src@freebsd.org, src-committers@freebsd.org, Scott Long <scottl@freebsd.org>, cvs-all@freebsd.org
Subject:   Re: cvs commit: src/sys/kern subr_taskqueue.c
Message-ID:  <200601110906.12293.jhb@freebsd.org>
In-Reply-To: <43C50E9B.5050508@samsco.org>
References:  <200601110037.k0B0bDv4009424@repoman.freebsd.org> <200601110847.08614.jhb@freebsd.org> <43C50E9B.5050508@samsco.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wednesday 11 January 2006 08:56 am, Scott Long wrote:
> John Baldwin wrote:
> > On Tuesday 10 January 2006 07:37 pm, Scott Long wrote:
> >>scottl      2006-01-11 00:37:13 UTC
> >>
> >>  FreeBSD src repository
> >>
> >>  Modified files:
> >>    sys/kern             subr_taskqueue.c
> >>  Log:
> >>  The interlock in taskqueue_terminate() is completely wrong for
> >> taskqueues that use spinlocks.  Remove it for now.
> >
> > Eh?  It's waiting for the wakeup that comes from kthread_exit() after t=
he
> > thread has exited which is locked via the proc lock.  Sleeping on the
> > taskqueue itself doesn't buy you anything.  (In fact, it might sleep
> > forever.)   The simplest solution might be to acquire the proc lock a l=
ot
> > earlier before the taskqueue lock in this function so that you don't ha=
ve
> > to acquire it while holding the taskqueue lock since that is what gives
> > you problems.
>
> With the code the way it was, kthread_exit() in taskqueue_thread_loop
> can wind up blocking on the proc lock while the lock is still held in
> taskqueue_terminate.  I don't know why this is actually a problem, but
> turning on WITNESS to investigate revealed the immediate problem of
> trying to grab the proc lock with a spinlock already held.  The
> interlock is really just a protection against drivers that don't
> adequately quiesce themselves, so I removed it for now until we can
> figure out something better.

The interlock to make sure the thread has terminated before the function=20
returns.  This would be important if the taskqueue routine for this thread=
=20
was in a kernel module that was being unloaded to avoid having a kernel pag=
e=20
fault.  The solution for the LOR you saw is probably to just lock the proc=
=20
lock earlier.  taskqueue_terminate() is not really a critical path operatio=
n=20
(if it is that's a bug) so holding the proc lock a bit longer there won't=20
kill.  As it is, there isn't a matching wakeup to ever resume the sleeper i=
n=20
taskqueue_terminate(), so the calling thread will block indefinitely (unles=
s=20
it is using a timeout).

=2D-=20
John Baldwin <jhb@FreeBSD.org> =A0<>< =A0http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve" =A0=3D =A0http://www.FreeBSD.org



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200601110906.12293.jhb>