[alsa-devel] [PATCH] RME HDSPM MADI lock fix
Takashi Iwai
tiwai at suse.de
Mon Jun 6 11:05:13 CEST 2011
At Sun, 05 Jun 2011 11:57:57 +0200,
Jörn Nettingsmeier wrote:
>
> hi *!
>
> while we were trying to debug the midi-related xruns in the current
> driver, i came across what looks like an unrelated locking bug to me:
>
> static int snd_hdspm_midi_input_read (struct hdspm_midi *hmidi)
> ...
> spin_lock_irqsave (&hmidi->lock, flags); <---------------
> n_pending = snd_hdspm_midi_input_available (hmidi->hdspm,
> hmidi->id);
> if (n_pending > 0) {
> if (hmidi->input) {
> if (n_pending > (int)sizeof (buf))
> n_pending = sizeof (buf);
> for (i = 0; i < n_pending; ++i)
> buf[i] = snd_hdspm_midi_read_byte
> (hmidi->hdspm,
>
> hmidi->id);
> if (n_pending)
> snd_rawmidi_receive (hmidi->input, buf,
> n_pending);
> } else {
> /* flush the MIDI input FIFO */
> while (n_pending--)
> snd_hdspm_midi_read_byte (hmidi->hdspm,
> hmidi->id);
> }
> }
> hmidi->pending = 0;
>
> hmidi->hdspm->control_register |= hmidi->ie;<------- !!!
> hdspm_write(hmidi->hdspm, HDSPM_controlRegister,
> hmidi->hdspm->control_register);
>
> spin_unlock_irqrestore (&hmidi->lock, flags);<---------
> return snd_hdspm_midi_output_write (hmidi);
> }
>
>
> if i understand this whole business correctly, we should be holding the
> hdspm lock here, not the hmidi one.
>
> please review the attached patch and apply if you think it's ok.
Well, it's a wrong lock for snd_hdspm_midi_input_available().
So you'll need to lock twice, either once unlock and lock another or
nested. Re-locking would be less messy in this case, I suppose.
thanks,
Takashi
>
>
> best,
>
>
> jörn
>
>
>
> --
> Jörn Nettingsmeier
> Lortzingstr. 11, 45128 Essen, Tel. +49 177 7937487
>
> Meister für Veranstaltungstechnik (Bühne/Studio)
> Tonmeister (VDT)
>
> http://stackingdwarves.net
> [2 hdspm-lockfix.diff <text/x-patch (7bit)>]
> --- sound/pci/rme9652/hdspm.c~ 2011-06-01 21:30:24.000000000 +0200
> +++ sound/pci/rme9652/hdspm.c 2011-06-01 22:04:08.184946711 +0200
> @@ -1619,7 +1619,7 @@
> int n_pending;
> int i;
>
> - spin_lock_irqsave (&hmidi->lock, flags);
> + spin_lock_irqsave (&hmidi->hdspm->lock, flags);
> n_pending = snd_hdspm_midi_input_available (hmidi->hdspm, hmidi->id);
> if (n_pending > 0) {
> if (hmidi->input) {
> @@ -1644,7 +1644,7 @@
> hdspm_write(hmidi->hdspm, HDSPM_controlRegister,
> hmidi->hdspm->control_register);
>
> - spin_unlock_irqrestore (&hmidi->lock, flags);
> + spin_unlock_irqrestore (&hmidi->hdspm->lock, flags);
> return snd_hdspm_midi_output_write (hmidi);
> }
>
More information about the Alsa-devel
mailing list