[PATCH] ALSA: rawmidi: Work around false-positive mutex lockdep warning
Takashi Iwai <[email protected]> Thu, 6 Aug 2026 12:13:51 +0200
| Newsgroups | org.kernel.vger.linux-sound,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
When opening a legacy rawmidi device for a UMP, it may re-open an existing rawmidi device for appending to a substream, leading to a lockdep warning due to rmidi->open_mutex taken twice -- but the rawmidi devices are completely individual, hence it's a false-positive. For avoiding the warning, modify the helper to open a rawmidi instance with a proper locking subclass from the UMP legacy open. Unfortunately, there is no good way to achieve it with guard(), so reverted to the manual mutex calls again. Reported-by: [email protected] Closes: https://lore.kernel.org/[email protected] Signed-off-by: Takashi Iwai <[email protected]> --- include/sound/rawmidi.h | 14 ++++++++++++-- sound/core/rawmidi.c | 12 +++++++----- sound/core/ump.c | 9 +++++---- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h index 6916f7133597..88a6159364d0 100644 --- a/include/sound/rawmidi.h +++ b/include/sound/rawmidi.h @@ -176,8 +176,9 @@ int snd_rawmidi_proceed(struct snd_rawmidi_substream *substream); /* main midi functions */ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info); -int snd_rawmidi_kernel_open(struct snd_rawmidi *rmidi, int subdevice, - int mode, struct snd_rawmidi_file *rfile); +int snd_rawmidi_kernel_open_nested(struct snd_rawmidi *rmidi, int subdevice, + int mode, struct snd_rawmidi_file *rfile, + int depth); int snd_rawmidi_kernel_release(struct snd_rawmidi_file *rfile); int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream, struct snd_rawmidi_params *params); @@ -191,6 +192,15 @@ long snd_rawmidi_kernel_read(struct snd_rawmidi_substream *substream, long snd_rawmidi_kernel_write(struct snd_rawmidi_substream *substream, const unsigned char *buf, long count); +/* non-nested version */ +static inline int snd_rawmidi_kernel_open(struct snd_rawmidi *rmidi, + int subdevice, + int mode, + struct snd_rawmidi_file *rfile) +{ + return snd_rawmidi_kernel_open_nested(rmidi, subdevice, mode, rfile, 0); +} + /* set up the tied devices */ static inline void snd_rawmidi_tie_devices(struct snd_rawmidi *r1, struct snd_rawmidi *r2) diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 1d55da2dcb01..bf504e27f73e 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -408,9 +408,10 @@ static int rawmidi_open_priv(struct snd_rawmidi *rmidi, int subdevice, int mode, return 0; } -/* called from sound/core/seq/seq_midi.c */ -int snd_rawmidi_kernel_open(struct snd_rawmidi *rmidi, int subdevice, - int mode, struct snd_rawmidi_file *rfile) +/* called from sound/core/seq/seq_midi.c and sound/core/ump.c */ +int snd_rawmidi_kernel_open_nested(struct snd_rawmidi *rmidi, int subdevice, + int mode, struct snd_rawmidi_file *rfile, + int depth) { int err; @@ -419,13 +420,14 @@ int snd_rawmidi_kernel_open(struct snd_rawmidi *rmidi, int subdevice, if (!try_module_get(rmidi->card->module)) return -ENXIO; - guard(mutex)(&rmidi->open_mutex); + mutex_lock_nested(&rmidi->open_mutex, depth); err = rawmidi_open_priv(rmidi, subdevice, mode, rfile); if (err < 0) module_put(rmidi->card->module); + mutex_unlock(&rmidi->open_mutex); return err; } -EXPORT_SYMBOL(snd_rawmidi_kernel_open); +EXPORT_SYMBOL(snd_rawmidi_kernel_open_nested); static int snd_rawmidi_open(struct inode *inode, struct file *file) { diff --git a/sound/core/ump.c b/sound/core/ump.c index 632c13baf21e..82ad155c56e6 100644 --- a/sound/core/ump.c +++ b/sound/core/ump.c @@ -1157,10 +1157,11 @@ static int snd_ump_legacy_open(struct snd_rawmidi_substream *substream) return -ENODEV; if (dir == SNDRV_RAWMIDI_STREAM_OUTPUT) { if (!ump->legacy_out_opens) { - err = snd_rawmidi_kernel_open(&ump->core, 0, - SNDRV_RAWMIDI_LFLG_OUTPUT | - SNDRV_RAWMIDI_LFLG_APPEND, - &ump->legacy_out_rfile); + err = snd_rawmidi_kernel_open_nested(&ump->core, 0, + SNDRV_RAWMIDI_LFLG_OUTPUT | + SNDRV_RAWMIDI_LFLG_APPEND, + &ump->legacy_out_rfile, + SINGLE_DEPTH_NESTING); if (err < 0) return err; } -- 2.55.0