ALSA: control: Take lock in snd_ctl_find_id() and snd_ctl_find_numid()
authorTakashi Iwai <tiwai@suse.de>
Tue, 18 Jul 2023 14:13:03 +0000 (16:13 +0200)
committerTakashi Iwai <tiwai@suse.de>
Thu, 20 Jul 2023 08:03:00 +0000 (10:03 +0200)
Now all needed callers have been replaced with *_locked() versions,
let's turn on the locking in snd_ctl_find_id() and
snd_ctl_find_numid().

This patch also adds the lockdep assertions for debugging, too.

Link: https://lore.kernel.org/r/20230718141304.1032-11-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/core/control.c

index 30741293708d910d783d6d8782d2eea7e7a4fc87..e13e9d6b3b890d9e0bb54626ddf6e4fe0e9dcb87 100644 (file)
@@ -836,6 +836,7 @@ snd_ctl_find_numid_locked(struct snd_card *card, unsigned int numid)
 {
        if (snd_BUG_ON(!card || !numid))
                return NULL;
+       lockdep_assert_held(&card->controls_rwsem);
 #ifdef CONFIG_SND_CTL_FAST_LOOKUP
        return xa_load(&card->ctl_numids, numid);
 #else
@@ -852,11 +853,18 @@ EXPORT_SYMBOL(snd_ctl_find_numid_locked);
  * Finds the control instance with the given number-id from the card.
  *
  * Return: The pointer of the instance if found, or %NULL if not.
+ *
+ * Note that this function takes card->controls_rwsem lock internally.
  */
 struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card,
                                        unsigned int numid)
 {
-       return snd_ctl_find_numid_locked(card, numid);
+       struct snd_kcontrol *kctl;
+
+       down_read(&card->controls_rwsem);
+       kctl = snd_ctl_find_numid_locked(card, numid);
+       up_read(&card->controls_rwsem);
+       return kctl;
 }
 EXPORT_SYMBOL(snd_ctl_find_numid);
 
@@ -879,6 +887,7 @@ struct snd_kcontrol *snd_ctl_find_id_locked(struct snd_card *card,
 
        if (snd_BUG_ON(!card || !id))
                return NULL;
+       lockdep_assert_held(&card->controls_rwsem);
        if (id->numid != 0)
                return snd_ctl_find_numid_locked(card, id->numid);
 #ifdef CONFIG_SND_CTL_FAST_LOOKUP
@@ -905,11 +914,18 @@ EXPORT_SYMBOL(snd_ctl_find_id_locked);
  * Finds the control instance with the given id from the card.
  *
  * Return: The pointer of the instance if found, or %NULL if not.
+ *
+ * Note that this function takes card->controls_rwsem lock internally.
  */
 struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card,
                                     const struct snd_ctl_elem_id *id)
 {
-       return snd_ctl_find_id_locked(card, id);
+       struct snd_kcontrol *kctl;
+
+       down_read(&card->controls_rwsem);
+       kctl = snd_ctl_find_id_locked(card, id);
+       up_read(&card->controls_rwsem);
+       return kctl;
 }
 EXPORT_SYMBOL(snd_ctl_find_id);