forked from Minki/linux
[ALSA] Fix possible races in timer callbacks
Fix possible races in timer callbacks. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
2eb061f41c
commit
b32425ac93
@ -662,12 +662,13 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
|
||||
struct snd_timer_instance *ti, *ts;
|
||||
unsigned long resolution, ticks;
|
||||
struct list_head *p, *q, *n, *ack_list_head;
|
||||
unsigned long flags;
|
||||
int use_tasklet = 0;
|
||||
|
||||
if (timer == NULL)
|
||||
return;
|
||||
|
||||
spin_lock(&timer->lock);
|
||||
spin_lock_irqsave(&timer->lock, flags);
|
||||
|
||||
/* remember the current resolution */
|
||||
if (timer->hw.c_resolution)
|
||||
@ -752,7 +753,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
|
||||
|
||||
/* do we have any slow callbacks? */
|
||||
use_tasklet = !list_empty(&timer->sack_list_head);
|
||||
spin_unlock(&timer->lock);
|
||||
spin_unlock_irqrestore(&timer->lock, flags);
|
||||
|
||||
if (use_tasklet)
|
||||
tasklet_hi_schedule(&timer->task_queue);
|
||||
|
@ -231,8 +231,9 @@ static int snd_card_dummy_pcm_prepare(struct snd_pcm_substream *substream)
|
||||
static void snd_card_dummy_pcm_timer_function(unsigned long data)
|
||||
{
|
||||
struct snd_dummy_pcm *dpcm = (struct snd_dummy_pcm *)data;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock(&dpcm->lock);
|
||||
spin_lock_irqsave(&dpcm->lock, flags);
|
||||
dpcm->timer.expires = 1 + jiffies;
|
||||
add_timer(&dpcm->timer);
|
||||
dpcm->pcm_irq_pos += dpcm->pcm_jiffie;
|
||||
@ -240,11 +241,10 @@ static void snd_card_dummy_pcm_timer_function(unsigned long data)
|
||||
dpcm->pcm_buf_pos %= dpcm->pcm_size;
|
||||
if (dpcm->pcm_irq_pos >= dpcm->pcm_count) {
|
||||
dpcm->pcm_irq_pos %= dpcm->pcm_count;
|
||||
spin_unlock(&dpcm->lock);
|
||||
spin_unlock_irqrestore(&dpcm->lock, flags);
|
||||
snd_pcm_period_elapsed(dpcm->substream);
|
||||
spin_lock(&dpcm->lock);
|
||||
}
|
||||
spin_unlock(&dpcm->lock);
|
||||
} else
|
||||
spin_unlock_irqrestore(&dpcm->lock, flags);
|
||||
}
|
||||
|
||||
static snd_pcm_uframes_t snd_card_dummy_pcm_pointer(struct snd_pcm_substream *substream)
|
||||
|
@ -133,12 +133,13 @@ irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *reg
|
||||
static void snd_mpu401_uart_timer(unsigned long data)
|
||||
{
|
||||
struct snd_mpu401 *mpu = (struct snd_mpu401 *)data;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock(&mpu->timer_lock);
|
||||
spin_lock_irqsave(&mpu->timer_lock, flags);
|
||||
/*mpu->mode |= MPU401_MODE_TIMER;*/
|
||||
mpu->timer.expires = 1 + jiffies;
|
||||
add_timer(&mpu->timer);
|
||||
spin_unlock(&mpu->timer_lock);
|
||||
spin_unlock_irqrestore(&mpu->timer_lock, flags);
|
||||
if (mpu->rmidi)
|
||||
_snd_mpu401_uart_interrupt(mpu);
|
||||
}
|
||||
|
@ -238,10 +238,11 @@ void snd_opl3_timer_func(unsigned long data)
|
||||
{
|
||||
|
||||
struct snd_opl3 *opl3 = (struct snd_opl3 *)data;
|
||||
unsigned long flags;
|
||||
int again = 0;
|
||||
int i;
|
||||
|
||||
spin_lock(&opl3->sys_timer_lock);
|
||||
spin_lock_irqsave(&opl3->sys_timer_lock, flags);
|
||||
for (i = 0; i < opl3->max_voices; i++) {
|
||||
struct snd_opl3_voice *vp = &opl3->voices[i];
|
||||
if (vp->state > 0 && vp->note_off_check) {
|
||||
@ -257,7 +258,7 @@ void snd_opl3_timer_func(unsigned long data)
|
||||
} else {
|
||||
opl3->sys_timer_status = 0;
|
||||
}
|
||||
spin_unlock(&opl3->sys_timer_lock);
|
||||
spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -609,8 +609,9 @@ static void snd_korg1212_SendStopAndWait(struct snd_korg1212 *korg1212)
|
||||
static void snd_korg1212_timer_func(unsigned long data)
|
||||
{
|
||||
struct snd_korg1212 *korg1212 = (struct snd_korg1212 *) data;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock(&korg1212->lock);
|
||||
spin_lock_irqsave(&korg1212->lock, flags);
|
||||
if (korg1212->sharedBufferPtr->cardCommand == 0) {
|
||||
/* ack'ed */
|
||||
korg1212->stop_pending_cnt = 0;
|
||||
@ -632,7 +633,7 @@ static void snd_korg1212_timer_func(unsigned long data)
|
||||
stateName[korg1212->cardState]);
|
||||
}
|
||||
}
|
||||
spin_unlock(&korg1212->lock);
|
||||
spin_unlock_irqrestore(&korg1212->lock, flags);
|
||||
}
|
||||
|
||||
static int snd_korg1212_TurnOnIdleMonitor(struct snd_korg1212 *korg1212)
|
||||
|
@ -205,9 +205,10 @@ void snd_emux_timer_callback(unsigned long data)
|
||||
{
|
||||
struct snd_emux *emu = (struct snd_emux *) data;
|
||||
struct snd_emux_voice *vp;
|
||||
unsigned long flags;
|
||||
int ch, do_again = 0;
|
||||
|
||||
spin_lock(&emu->voice_lock);
|
||||
spin_lock_irqsave(&emu->voice_lock, flags);
|
||||
for (ch = 0; ch < emu->max_voices; ch++) {
|
||||
vp = &emu->voices[ch];
|
||||
if (vp->state == SNDRV_EMUX_ST_PENDING) {
|
||||
@ -225,7 +226,7 @@ void snd_emux_timer_callback(unsigned long data)
|
||||
emu->timer_active = 1;
|
||||
} else
|
||||
emu->timer_active = 0;
|
||||
spin_unlock(&emu->voice_lock);
|
||||
spin_unlock_irqrestore(&emu->voice_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user