ALSA: sb: Minor optimization / fix of timer usage in sb8_midi.c
authorTakashi Iwai <tiwai@suse.de>
Wed, 25 Oct 2017 08:00:43 +0000 (10:00 +0200)
committerTakashi Iwai <tiwai@suse.de>
Wed, 25 Oct 2017 08:00:43 +0000 (10:00 +0200)
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>
sound/isa/sb/sb8_midi.c

index 05ba2c6b1a8cba5aa9b3b111947fce88ef7f95fc..4affdcb78f7242ca9ae575fdc7c296ab73c3f4b6 100644 (file)
@@ -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;
 }