[34-longterm 044/247] ALSA: hrtimer: handle delayed timer interrupts

From: Paul Gortmaker
Date: Thu Jun 23 2011 - 13:29:45 EST

From: Clemens Ladisch <clemens@xxxxxxxxxx>

This is a commit scheduled for the next v2.6.34 longterm release.
If you see a problem with using this for longterm, please comment.

commit b1d4f7f4bdcf9915c41ff8cfc4425c84dabb1fde upstream.

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@xxxxxxxxxx>
Reported-and-tested-by: Arthur Marsh <arthur.marsh@xxxxxxxxxxxxxxxx>
Signed-off-by: Takashi Iwai <tiwai@xxxxxxx>
Signed-off-by: Paul Gortmaker <paul.gortmaker@xxxxxxxxxxxxx>
sound/core/hrtimer.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c
index 7730575..07efa29 100644
--- a/sound/core/hrtimer.c
+++ b/sound/core/hrtimer.c
@@ -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))

- 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))

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/