diff options
author | Takashi Iwai <tiwai@suse.de> | 2016-04-24 22:52:18 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2016-04-26 09:34:40 +0200 |
commit | d2c5cf88d5282de258f4eb6ab40040b80a075cd8 (patch) | |
tree | f21c1cf7e4da494db9a36c3dab1c65aed1c4e9fb /Documentation/gdb-kernel-debugging.txt | |
parent | 8d84c1973b69621bcb89d5d8a69699e8347a3d90 (diff) | |
download | op-kernel-dev-d2c5cf88d5282de258f4eb6ab40040b80a075cd8.zip op-kernel-dev-d2c5cf88d5282de258f4eb6ab40040b80a075cd8.tar.gz |
ALSA: hrtimer: Handle start/stop more properly
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: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'Documentation/gdb-kernel-debugging.txt')
0 files changed, 0 insertions, 0 deletions