|
@@ -163,6 +163,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
|
|
|
int count, res;
|
|
|
unsigned char buf[32], *pbuf;
|
|
|
unsigned long flags;
|
|
|
+ bool check_resched = !in_atomic();
|
|
|
|
|
|
if (up) {
|
|
|
vmidi->trigger = 1;
|
|
@@ -200,6 +201,15 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
|
|
|
vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
|
|
|
}
|
|
|
}
|
|
|
+ if (!check_resched)
|
|
|
+ continue;
|
|
|
+ /* do temporary unlock & cond_resched() for avoiding
|
|
|
+ * CPU soft lockup, which may happen via a write from
|
|
|
+ * a huge rawmidi buffer
|
|
|
+ */
|
|
|
+ spin_unlock_irqrestore(&substream->runtime->lock, flags);
|
|
|
+ cond_resched();
|
|
|
+ spin_lock_irqsave(&substream->runtime->lock, flags);
|
|
|
}
|
|
|
out:
|
|
|
spin_unlock_irqrestore(&substream->runtime->lock, flags);
|