• Ioan-Adrian Ratiu's avatar
    ALSA: usb-audio: Fix irq/process data synchronization · bb1cacd8
    Ioan-Adrian Ratiu authored
    commit 1d0f9530 upstream.
    
    Commit 16200948 ("ALSA: usb-audio: Fix race at stopping the stream") was
    incomplete causing another more severe kernel panic, so it got reverted.
    This fixes both the original problem and its fallout kernel race/crash.
    
    The original fix is to move the endpoint member NULL clearing logic inside
    wait_clear_urbs() so the irq triggering the urb completion doesn't call
    retire_capture/playback_urb() after the NULL clearing and generate a panic.
    
    However this creates a new race between snd_usb_endpoint_start()'s call
    to wait_clear_urbs() and the irq urb completion handler which again calls
    retire_capture/playback_urb() leading to a new NULL dereference.
    
    We keep the EP deactivation code in snd_usb_endpoint_start() because
    removing it will break the EP reference counting (see [1] [2] for info),
    however we don't need the "can_sleep" mechanism anymore because a new
    function was introduced (snd_usb_endpoint_sync_pending_stop()) which
    synchronizes pending stops and gets called inside the pcm prepare callback.
    
    It also makes sense to remove can_sleep because it was also removed from
    deactivate_urbs() signature in [3] so we benefit from more simplification.
    
    [1] commit 015618b9 ("ALSA: snd-usb: Fix URB cancellation at stream start")
    [2] commit e9ba389c ("ALSA: usb-audio: Fix scheduling-while-atomic bug in PCM capture stream")
    [3] commit ccc1696d ("ALSA: usb-audio: simplify endpoint deactivation code")
    
    Fixes: f8114f85 ("Revert "ALSA: usb-audio: Fix race at stopping the stream"")
    Signed-off-by: default avatarIoan-Adrian Ratiu <adi@adirat.com>
    Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    bb1cacd8
endpoint.c 32.7 KB