git: c50c5a47a9d5 - main - snd_hda: Drain callout in hdac_detach()

From: Christos Margiolis <christos_at_FreeBSD.org>
Date: Fri, 02 May 2025 10:38:53 UTC
The branch main has been updated by christos:

URL: https://cgit.FreeBSD.org/src/commit/?id=c50c5a47a9d515a7dbf584c10c7f66e56b29b305

commit c50c5a47a9d515a7dbf584c10c7f66e56b29b305
Author:     Christos Margiolis <christos@FreeBSD.org>
AuthorDate: 2025-05-02 10:38:41 +0000
Commit:     Christos Margiolis <christos@FreeBSD.org>
CommitDate: 2025-05-02 10:38:41 +0000

    snd_hda: Drain callout in hdac_detach()
    
    Because we do not drain the hdac callout during detach, hot-unloading
    can result in a panic if the callback fires after we have freed the
    resources it uses.
    
    pcm0: detached
    pcm1: detached
    hdaa0: detached
    hdacc0: detached
    Kernel page fault with the following non-sleepable locks held:
    exclusive sleep mutex hdac0 (HDA driver mutex) r = 0 (0xfffffe000212c820) locked @ /mnt/src/sys/dev/sound/pci/hda/hdac.c:400
    
    [...]
    
    db_trace_self_wrapper() at db_trace_self_wrapper+0xa5/frame 0xfffffe0046b04490
    kdb_backtrace() at kdb_backtrace+0xc6/frame 0xfffffe0046b045f0
    vpanic() at vpanic+0x226/frame 0xfffffe0046b04790
    panic() at panic+0xb5/frame 0xfffffe0046b04850
    trap_fatal() at trap_fatal+0x65b/frame 0xfffffe0046b04950
    trap_pfault() at trap_pfault+0x12b/frame 0xfffffe0046b04a70
    trap() at trap+0x54c/frame 0xfffffe0046b04c50
    calltrap() at calltrap+0x8/frame 0xfffffe0046b04c50
    --- trap 0xc, rip = 0xffffffff8412e7ec, rsp = 0xfffffe0046b04d20, rbp = 0xfffffe0046b04d40 ---
    hdacc_stream_intr() at hdacc_stream_intr+0x3c/frame 0xfffffe0046b04d40
    hdac_intr_handler() at hdac_intr_handler+0x15c/frame 0xfffffe0046b04d90
    ithread_loop() at ithread_loop+0x387/frame 0xfffffe0046b04ef0
    fork_exit() at fork_exit+0xa3/frame 0xfffffe0046b04f30
    fork_trampoline() at fork_trampoline+0xe/frame 0xfffffe0046b04f30
    --- trap 0xc, rip = 0x829cc531a, rsp = 0x82b8b7a88, rbp = 0x82b8b7aa0 ---
    KDB: enter: panic
    [ thread pid 12 tid 100211 ]
    Stopped at      kdb_enter+0x34: movq    $0,0x1f09af1(%rip)
    db>
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 day
    Reviewed by:    kib, adrian
    Differential Revision:  https://reviews.freebsd.org/D50087
---
 sys/dev/sound/pci/hda/hdac.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index a4242d2d1609..602f5df93648 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -1748,8 +1748,10 @@ hdac_detach(device_t dev)
 		return (error);
 
 	hdac_lock(sc);
+	callout_stop(&sc->poll_callout);
 	hdac_reset(sc, false);
 	hdac_unlock(sc);
+	callout_drain(&sc->poll_callout);
 	taskqueue_drain(taskqueue_thread, &sc->unsolq_task);
 	hdac_irq_free(sc);