diff options
author | Takashi Iwai <tiwai@suse.de> | 2005-11-18 12:52:14 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-01-03 06:29:08 -0500 |
commit | b32425ac93370e1ba5556110e662f896b2e143b3 (patch) | |
tree | c5837ee90c16d2aa358e399f2ad79ca4eb770e94 | |
parent | 2eb061f41cf74f829bfe90a9c79c765172be9f0b (diff) |
[ALSA] Fix possible races in timer callbacks
Fix possible races in timer callbacks.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/core/timer.c | 5 | ||||
-rw-r--r-- | sound/drivers/dummy.c | 10 | ||||
-rw-r--r-- | sound/drivers/mpu401/mpu401_uart.c | 5 | ||||
-rw-r--r-- | sound/drivers/opl3/opl3_midi.c | 5 | ||||
-rw-r--r-- | sound/pci/korg1212/korg1212.c | 5 | ||||
-rw-r--r-- | sound/synth/emux/emux_synth.c | 5 |
6 files changed, 20 insertions, 15 deletions
diff --git a/sound/core/timer.c b/sound/core/timer.c index 74637cef6d2c..6aad411dd7b8 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c | |||
@@ -662,12 +662,13 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left) | |||
662 | struct snd_timer_instance *ti, *ts; | 662 | struct snd_timer_instance *ti, *ts; |
663 | unsigned long resolution, ticks; | 663 | unsigned long resolution, ticks; |
664 | struct list_head *p, *q, *n, *ack_list_head; | 664 | struct list_head *p, *q, *n, *ack_list_head; |
665 | unsigned long flags; | ||
665 | int use_tasklet = 0; | 666 | int use_tasklet = 0; |
666 | 667 | ||
667 | if (timer == NULL) | 668 | if (timer == NULL) |
668 | return; | 669 | return; |
669 | 670 | ||
670 | spin_lock(&timer->lock); | 671 | spin_lock_irqsave(&timer->lock, flags); |
671 | 672 | ||
672 | /* remember the current resolution */ | 673 | /* remember the current resolution */ |
673 | if (timer->hw.c_resolution) | 674 | if (timer->hw.c_resolution) |
@@ -752,7 +753,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left) | |||
752 | 753 | ||
753 | /* do we have any slow callbacks? */ | 754 | /* do we have any slow callbacks? */ |
754 | use_tasklet = !list_empty(&timer->sack_list_head); | 755 | use_tasklet = !list_empty(&timer->sack_list_head); |
755 | spin_unlock(&timer->lock); | 756 | spin_unlock_irqrestore(&timer->lock, flags); |
756 | 757 | ||
757 | if (use_tasklet) | 758 | if (use_tasklet) |
758 | tasklet_hi_schedule(&timer->task_queue); | 759 | tasklet_hi_schedule(&timer->task_queue); |
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index a276f7c80360..186117571745 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c | |||
@@ -231,8 +231,9 @@ static int snd_card_dummy_pcm_prepare(struct snd_pcm_substream *substream) | |||
231 | static void snd_card_dummy_pcm_timer_function(unsigned long data) | 231 | static void snd_card_dummy_pcm_timer_function(unsigned long data) |
232 | { | 232 | { |
233 | struct snd_dummy_pcm *dpcm = (struct snd_dummy_pcm *)data; | 233 | struct snd_dummy_pcm *dpcm = (struct snd_dummy_pcm *)data; |
234 | unsigned long flags; | ||
234 | 235 | ||
235 | spin_lock(&dpcm->lock); | 236 | spin_lock_irqsave(&dpcm->lock, flags); |
236 | dpcm->timer.expires = 1 + jiffies; | 237 | dpcm->timer.expires = 1 + jiffies; |
237 | add_timer(&dpcm->timer); | 238 | add_timer(&dpcm->timer); |
238 | dpcm->pcm_irq_pos += dpcm->pcm_jiffie; | 239 | dpcm->pcm_irq_pos += dpcm->pcm_jiffie; |
@@ -240,11 +241,10 @@ static void snd_card_dummy_pcm_timer_function(unsigned long data) | |||
240 | dpcm->pcm_buf_pos %= dpcm->pcm_size; | 241 | dpcm->pcm_buf_pos %= dpcm->pcm_size; |
241 | if (dpcm->pcm_irq_pos >= dpcm->pcm_count) { | 242 | if (dpcm->pcm_irq_pos >= dpcm->pcm_count) { |
242 | dpcm->pcm_irq_pos %= dpcm->pcm_count; | 243 | dpcm->pcm_irq_pos %= dpcm->pcm_count; |
243 | spin_unlock(&dpcm->lock); | 244 | spin_unlock_irqrestore(&dpcm->lock, flags); |
244 | snd_pcm_period_elapsed(dpcm->substream); | 245 | snd_pcm_period_elapsed(dpcm->substream); |
245 | spin_lock(&dpcm->lock); | 246 | } else |
246 | } | 247 | spin_unlock_irqrestore(&dpcm->lock, flags); |
247 | spin_unlock(&dpcm->lock); | ||
248 | } | 248 | } |
249 | 249 | ||
250 | static snd_pcm_uframes_t snd_card_dummy_pcm_pointer(struct snd_pcm_substream *substream) | 250 | static snd_pcm_uframes_t snd_card_dummy_pcm_pointer(struct snd_pcm_substream *substream) |
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c index ee67b522d259..8687ae3c66b8 100644 --- a/sound/drivers/mpu401/mpu401_uart.c +++ b/sound/drivers/mpu401/mpu401_uart.c | |||
@@ -133,12 +133,13 @@ irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *reg | |||
133 | static void snd_mpu401_uart_timer(unsigned long data) | 133 | static void snd_mpu401_uart_timer(unsigned long data) |
134 | { | 134 | { |
135 | struct snd_mpu401 *mpu = (struct snd_mpu401 *)data; | 135 | struct snd_mpu401 *mpu = (struct snd_mpu401 *)data; |
136 | unsigned long flags; | ||
136 | 137 | ||
137 | spin_lock(&mpu->timer_lock); | 138 | spin_lock_irqsave(&mpu->timer_lock, flags); |
138 | /*mpu->mode |= MPU401_MODE_TIMER;*/ | 139 | /*mpu->mode |= MPU401_MODE_TIMER;*/ |
139 | mpu->timer.expires = 1 + jiffies; | 140 | mpu->timer.expires = 1 + jiffies; |
140 | add_timer(&mpu->timer); | 141 | add_timer(&mpu->timer); |
141 | spin_unlock(&mpu->timer_lock); | 142 | spin_unlock_irqrestore(&mpu->timer_lock, flags); |
142 | if (mpu->rmidi) | 143 | if (mpu->rmidi) |
143 | _snd_mpu401_uart_interrupt(mpu); | 144 | _snd_mpu401_uart_interrupt(mpu); |
144 | } | 145 | } |
diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c index 48c480e050ce..1b6f227af370 100644 --- a/sound/drivers/opl3/opl3_midi.c +++ b/sound/drivers/opl3/opl3_midi.c | |||
@@ -238,10 +238,11 @@ void snd_opl3_timer_func(unsigned long data) | |||
238 | { | 238 | { |
239 | 239 | ||
240 | struct snd_opl3 *opl3 = (struct snd_opl3 *)data; | 240 | struct snd_opl3 *opl3 = (struct snd_opl3 *)data; |
241 | unsigned long flags; | ||
241 | int again = 0; | 242 | int again = 0; |
242 | int i; | 243 | int i; |
243 | 244 | ||
244 | spin_lock(&opl3->sys_timer_lock); | 245 | spin_lock_irqsave(&opl3->sys_timer_lock, flags); |
245 | for (i = 0; i < opl3->max_voices; i++) { | 246 | for (i = 0; i < opl3->max_voices; i++) { |
246 | struct snd_opl3_voice *vp = &opl3->voices[i]; | 247 | struct snd_opl3_voice *vp = &opl3->voices[i]; |
247 | if (vp->state > 0 && vp->note_off_check) { | 248 | if (vp->state > 0 && vp->note_off_check) { |
@@ -257,7 +258,7 @@ void snd_opl3_timer_func(unsigned long data) | |||
257 | } else { | 258 | } else { |
258 | opl3->sys_timer_status = 0; | 259 | opl3->sys_timer_status = 0; |
259 | } | 260 | } |
260 | spin_unlock(&opl3->sys_timer_lock); | 261 | spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); |
261 | } | 262 | } |
262 | 263 | ||
263 | /* | 264 | /* |
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index a8a6a5c41a7f..4eddb512c12f 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c | |||
@@ -609,8 +609,9 @@ static void snd_korg1212_SendStopAndWait(struct snd_korg1212 *korg1212) | |||
609 | static void snd_korg1212_timer_func(unsigned long data) | 609 | static void snd_korg1212_timer_func(unsigned long data) |
610 | { | 610 | { |
611 | struct snd_korg1212 *korg1212 = (struct snd_korg1212 *) data; | 611 | struct snd_korg1212 *korg1212 = (struct snd_korg1212 *) data; |
612 | unsigned long flags; | ||
612 | 613 | ||
613 | spin_lock(&korg1212->lock); | 614 | spin_lock_irqsave(&korg1212->lock, flags); |
614 | if (korg1212->sharedBufferPtr->cardCommand == 0) { | 615 | if (korg1212->sharedBufferPtr->cardCommand == 0) { |
615 | /* ack'ed */ | 616 | /* ack'ed */ |
616 | korg1212->stop_pending_cnt = 0; | 617 | korg1212->stop_pending_cnt = 0; |
@@ -632,7 +633,7 @@ static void snd_korg1212_timer_func(unsigned long data) | |||
632 | stateName[korg1212->cardState]); | 633 | stateName[korg1212->cardState]); |
633 | } | 634 | } |
634 | } | 635 | } |
635 | spin_unlock(&korg1212->lock); | 636 | spin_unlock_irqrestore(&korg1212->lock, flags); |
636 | } | 637 | } |
637 | 638 | ||
638 | static int snd_korg1212_TurnOnIdleMonitor(struct snd_korg1212 *korg1212) | 639 | static int snd_korg1212_TurnOnIdleMonitor(struct snd_korg1212 *korg1212) |
diff --git a/sound/synth/emux/emux_synth.c b/sound/synth/emux/emux_synth.c index c387a83a655e..24705d15ebd8 100644 --- a/sound/synth/emux/emux_synth.c +++ b/sound/synth/emux/emux_synth.c | |||
@@ -205,9 +205,10 @@ void snd_emux_timer_callback(unsigned long data) | |||
205 | { | 205 | { |
206 | struct snd_emux *emu = (struct snd_emux *) data; | 206 | struct snd_emux *emu = (struct snd_emux *) data; |
207 | struct snd_emux_voice *vp; | 207 | struct snd_emux_voice *vp; |
208 | unsigned long flags; | ||
208 | int ch, do_again = 0; | 209 | int ch, do_again = 0; |
209 | 210 | ||
210 | spin_lock(&emu->voice_lock); | 211 | spin_lock_irqsave(&emu->voice_lock, flags); |
211 | for (ch = 0; ch < emu->max_voices; ch++) { | 212 | for (ch = 0; ch < emu->max_voices; ch++) { |
212 | vp = &emu->voices[ch]; | 213 | vp = &emu->voices[ch]; |
213 | if (vp->state == SNDRV_EMUX_ST_PENDING) { | 214 | if (vp->state == SNDRV_EMUX_ST_PENDING) { |
@@ -225,7 +226,7 @@ void snd_emux_timer_callback(unsigned long data) | |||
225 | emu->timer_active = 1; | 226 | emu->timer_active = 1; |
226 | } else | 227 | } else |
227 | emu->timer_active = 0; | 228 | emu->timer_active = 0; |
228 | spin_unlock(&emu->voice_lock); | 229 | spin_unlock_irqrestore(&emu->voice_lock, flags); |
229 | } | 230 | } |
230 | 231 | ||
231 | /* | 232 | /* |