ALSA: hrtimer: handle delayed timer interrupts
If a timer interrupt was delayed too much, hrtimer_forward_now() will forward the timer expiry more than once. When this happens, the additional number of elapsed ALSA timer ticks must be passed to snd_timer_interrupt() to prevent the ALSA timer from falling behind. This mostly fixes MIDI slowdown problems on highly-loaded systems with badly behaved interrupt handlers. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Reported-and-tested-by: Arthur Marsh <arthur.marsh@internode.on.net> Cc: <stable@kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
a6c47a85b8
commit
b1d4f7f4bd
1 changed files with 3 additions and 2 deletions
|
@ -45,12 +45,13 @@ static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
|
|||
{
|
||||
struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt);
|
||||
struct snd_timer *t = stime->timer;
|
||||
unsigned long oruns;
|
||||
|
||||
if (!atomic_read(&stime->running))
|
||||
return HRTIMER_NORESTART;
|
||||
|
||||
hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution));
|
||||
snd_timer_interrupt(stime->timer, t->sticks);
|
||||
oruns = hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution));
|
||||
snd_timer_interrupt(stime->timer, t->sticks * oruns);
|
||||
|
||||
if (!atomic_read(&stime->running))
|
||||
return HRTIMER_NORESTART;
|
||||
|
|
Loading…
Reference in a new issue