summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2017-10-25 10:00:43 +0200
committerTakashi Iwai <tiwai@suse.de>2017-10-25 10:00:43 +0200
commit20e5f8bfb153bdd43b5be194658f8ad814470a5d (patch)
tree7989623430877bfdbb32e446b8f7ce64c0de3555
parent4f928246f0e8f9bda88f41131ec447a1b8193dbc (diff)
downloadlinux-20e5f8bfb153bdd43b5be194658f8ad814470a5d.tar.bz2
ALSA: sb: Minor optimization / fix of timer usage in sb8_midi.c
Currently the SB8 MIDI code sets up the timer object at each time before scheduling it at trigger callback, but basically this is superfluous once after set up. Also, the code misses the del_timer_sync() call that may leave a race condition for use-after-free. This patch addresses these issues, moving timer_setup() to snd_sb8dsp_midi(), and adding the del_timer_sync() call at snd_sb8dsp_midi_output_trigger() to make sure. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/isa/sb/sb8_midi.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/sound/isa/sb/sb8_midi.c b/sound/isa/sb/sb8_midi.c
index 05ba2c6b1a8c..4affdcb78f72 100644
--- a/sound/isa/sb/sb8_midi.c
+++ b/sound/isa/sb/sb8_midi.c
@@ -138,6 +138,7 @@ static int snd_sb8dsp_midi_output_close(struct snd_rawmidi_substream *substream)
struct snd_sb *chip;
chip = substream->rmidi->private_data;
+ del_timer_sync(&chip->midi_timer);
spin_lock_irqsave(&chip->open_lock, flags);
chip->open &= ~(SB_OPEN_MIDI_OUTPUT | SB_OPEN_MIDI_OUTPUT_TRIGGER);
chip->midi_substream_output = NULL;
@@ -230,8 +231,6 @@ static void snd_sb8dsp_midi_output_trigger(struct snd_rawmidi_substream *substre
spin_lock_irqsave(&chip->open_lock, flags);
if (up) {
if (!(chip->open & SB_OPEN_MIDI_OUTPUT_TRIGGER)) {
- timer_setup(&chip->midi_timer,
- snd_sb8dsp_midi_output_timer, 0);
mod_timer(&chip->midi_timer, 1 + jiffies);
chip->open |= SB_OPEN_MIDI_OUTPUT_TRIGGER;
}
@@ -274,6 +273,7 @@ int snd_sb8dsp_midi(struct snd_sb *chip, int device)
if (chip->hardware >= SB_HW_20)
rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;
rmidi->private_data = chip;
+ timer_setup(&chip->midi_timer, snd_sb8dsp_midi_output_timer, 0);
chip->rmidi = rmidi;
return 0;
}