Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Nov 2014 01:38:31 -0800
From:      Adrian Chadd <adrian@freebsd.org>
To:        Alfred Perlstein <alfred@freebsd.org>
Cc:        "freebsd-arch@freebsd.org" <freebsd-arch@freebsd.org>
Subject:   Re: Questions about locking; turnstiles and sleeping threads
Message-ID:  <CAJ-VmonbrB3s5SsABo1Kotfz1Dn3cpvbnRMu4J9ikPmyS_aTgQ@mail.gmail.com>
In-Reply-To: <5464764E.9080308@freebsd.org>
References:  <CAJ-VmomrauhCMoF_dZfMWWhZp0EgwfE9RmxL5Pc37PhLSzZ6Qg@mail.gmail.com> <20141112212613.21037929@kan> <CAJ-Vmok-8znyycyOBS_ZQU275zFy%2BzuZ2C-jt4N3DnuEVS=PWg@mail.gmail.com> <CAJ-Vmo=R4ayAn-d986TC3CzZ4y23jnDW=uTyo4O=x4Ae1wB60A@mail.gmail.com> <CAJ-Vmok40-W%2B%2BdUJPcfO74%2BuudCgbs3tR5nwrR-aNuCy=5o0HQ@mail.gmail.com> <546472DA.3080006@freebsd.org> <CAJ-VmomQdNDWqdC7o-nuGfypDDgDsJX9ouhx%2Br7ckZptgzQ10Q@mail.gmail.com> <5464764E.9080308@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
It looks like the initial firings are because the check I put in
didn't check to see if it's MPSAFE.

eg:

ip6_input -> tcp6_input -> tcp_input -> tcp_do_segment ->
tcp_timer_active -> callout_stop_safe; called with tcpinp held.
closefp() -> closef() -> fdrop -> soclose() -> sofree() ->
tcp_usr_detach() -> tcp_discardcb() -> callout_stop_safe() with the
tcpinp and tcp locks held.
ioctl -> sys_ioctl-> devfs_ioctl_f -> acpi_ackSleepState ->
callout_stop_safe; with ACPI global lock held;
suspend path -> hdaa_suspend -> callout_stop_safe() with HDA driver mutex held

So we can't just put the simple witness check from _sleep() in
_callout_stop_safe(), it looks like it's mis-firing on MPSAFE callouts
(which the tcp timers all are) and that won't go via the sleepq.
It looks like the acpi callout is also mpsafe, as well as the HDA jack callout.

However, I did pick up this:

detach path -> usbd_transfer_drain() -> usbd_transfer_stop() ->
ehci_device_intr_close() -> usbd_transfer_done() ->
callout_stop_safe() with USB HUB mutex held

The usbd_transfer_done() callout is initialised with a mutex, but the
witness code should've detected it wasn't callout->c_lock and thus
warned.



-adrian

On 13 November 2014 01:13, Alfred Perlstein <alfred@freebsd.org> wrote:
>
> On 11/13/14, 1:09 AM, Adrian Chadd wrote:
>>
>> On 13 November 2014 00:59, Alfred Perlstein <alfred@freebsd.org> wrote:
>>>
>>> On 11/12/14, 11:25 PM, Adrian Chadd wrote:
>>>>
>>>> On 12 November 2014 19:48, Adrian Chadd <adrian@freebsd.org> wrote:
>>>>>
>>>>> kan pointed out that we should likely do a WITNESS_WARN() in the
>>>>> relevant spots in the callout code so we catch these before it
>>>>> happens.
>>>>>
>>>>> I'll see what we can add to -HEAD to be pro-active about it.
>>>>
>>>> Amusingly, I tried adding it and it made my laptop turn to soup very
>>>> quickly - among other things, the TCP timer callouts are all setup
>>>> with non sleep locks held.
>>>>
>>> Howso?  You only have to worry about callout_drain(), most other callout
>>> functions should be safe-ish....
>>
>> yeah, except for all the places where they drain the timer once
>> something happens so it doesn't fire.
>>
>> :)
>
>
> What is the backtrace...?
>
>



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