NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/57322: hdafg(4) hotplug switch detection races with suspend/resume and detach



>Number:         57322
>Category:       kern
>Synopsis:       hdafg(4) hotplug switch detection races with suspend/resume and detach
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Apr 04 11:15:01 +0000 2023
>Originator:     Taylor R Campbell
>Release:        current, 10, 9, 8, ...
>Organization:
The NetBSD Founda<acpi0: entering state S3
>Environment:
on target to develop a fever of 1.5C or more
>Description:
hdafg_detach and hdafg_suspend use callout_halt to prevent any further calls to hdafg_hp_switch_handler from running, and to wait for any pending calls to complete.

However, if hdafg_hp_switch_handler is already running concurrently, it will automatically reschedule itself.  callout_halt does not prevent this.

If this happens, suspend/resume or detach might fail or crash.
>How-To-Repeat:
- code inspection
- probably suspend/resume on machine with hdaudio
>Fix:
1. Create a new lock, say sc_jack_lock, and flag, say sc_jack_detect.
2. Teach hdafg_suspend and hdafg_detach to set sc_jack_detect = true under sc_jack_lock before calling callout_halt.
3. Teach hdafg_hp_switch_handler to reschedule itself only conditionally on sc_jack_detect, under the lock.

/* hdafg_suspend/detach */
mutex_enter(&sc->sc_jack_lock);
sc->sc_jack_detect = false;
mutex_exit(&sc->sc_jack_lock);
callout_halt(&sc->sc_jack_callout, NULL);

/* hdafg_hp_switch_handler */
muteX_enter(&sc->sc_jack_lock);
if (sc->sc_jack_detect) {
        callout_schedule(&sc->sc_jack_callout, ...);
mutex_exit(&sc->sc_jack_lock);

(Maybe hdafg_hp_switch_handler should also run in thread context instead of softint context, with a kpause loop and a similar sc_jack_detect variable to suspend it.)



Home | Main Index | Thread Index | Old Index