• Takashi Iwai's avatar
    ALSA: hrtimer: Handle start/stop more properly · d2c5cf88
    Takashi Iwai authored
    This patch tries to address the still remaining issues in ALSA hrtimer
    driver:
    - Spurious use-after-free was detected in hrtimer callback
    - Incorrect rescheduling due to delayed start
    - WARN_ON() is triggered in hrtimer_forward() invoked in hrtimer
      callback
    
    The first issue happens only when the new timer is scheduled even
    while hrtimer is being closed.  It's related with the second and third
    items; since ALSA timer core invokes hw.start callback during hrtimer
    interrupt, this may result in the explicit call of hrtimer_start().
    
    Also, the similar problem is seen for the stop; ALSA timer core
    invokes hw.stop callback even in the hrtimer handler, too.  Since we
    must not call the synced hrtimer_cancel() in such a context, it's just
    a hrtimer_try_to_cancel() call that doesn't properly work.
    
    Another culprit of the second and third items is the call of
    hrtimer_forward_now() before snd_timer_interrupt().  The timer->stick
    value may change during snd_timer_interrupt() call, but this
    possibility is ignored completely.
    
    For covering these subtle and messy issues, the following changes have
    been done in this patch:
    - A new flag, in_callback, is introduced in the private data to
      indicate that the hrtimer handler is being processed.
    - Both start and stop callbacks skip when called from (during)
      in_callback flag.
    - The hrtimer handler returns properly HRTIMER_RESTART and NORESTART
      depending on the running state now.
    - The hrtimer handler reprograms the expiry properly after
      snd_timer_interrupt() call, instead of before.
    - The close callback clears running flag and sets in_callback flag
      to block any further start/stop calls.
    Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
    d2c5cf88
Name
Last commit
Last update
Documentation Loading commit data...
arch Loading commit data...
block Loading commit data...
certs Loading commit data...
crypto Loading commit data...
drivers Loading commit data...
firmware Loading commit data...
fs Loading commit data...
include Loading commit data...
init Loading commit data...
ipc Loading commit data...
kernel Loading commit data...
lib Loading commit data...
mm Loading commit data...
net Loading commit data...
samples Loading commit data...
scripts Loading commit data...
security Loading commit data...
sound Loading commit data...
tools Loading commit data...
usr Loading commit data...
virt Loading commit data...
.get_maintainer.ignore Loading commit data...
.gitignore Loading commit data...
.mailmap Loading commit data...
COPYING Loading commit data...
CREDITS Loading commit data...
Kbuild Loading commit data...
Kconfig Loading commit data...
MAINTAINERS Loading commit data...
Makefile Loading commit data...
README Loading commit data...
REPORTING-BUGS Loading commit data...