OSDN Git Service

staging: greybus: Avoid abusing controls_rwsem
authorTakashi Iwai <tiwai@suse.de>
Tue, 18 Jul 2023 14:13:00 +0000 (16:13 +0200)
committerTakashi Iwai <tiwai@suse.de>
Thu, 20 Jul 2023 08:02:59 +0000 (10:02 +0200)
The controls_rwsem of snd_card object is rather an internal lock, and
not really meant to be used by others for its data protection.

This patch addresses it by replacing the controls_rwsem usages with
the own (new) mutex.

Note that the up_write() and down_write() calls around
gbaudio_remove_component_controls() are simply dropped without
replacement.  These temporary up/down were a workaround since
gbaudio_remove_component_controls() itself took the rwsem.  Now it was
also gone, we can clean up the workaround, too.

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Vaibhav Agarwal <vaibhav.sr@gmail.com>
Cc: Mark Greer <mgreer@animalcreek.com>
Cc: Johan Hovold <johan@kernel.org>
Cc: Alex Elder <elder@kernel.org>
Cc: greybus-dev@lists.linaro.org
Link: https://lore.kernel.org/r/20230718141304.1032-8-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
drivers/staging/greybus/audio_codec.c
drivers/staging/greybus/audio_codec.h

index 72ace74..2f05e76 100644 (file)
@@ -807,7 +807,6 @@ int gbaudio_register_module(struct gbaudio_module_info *module)
 {
        int ret;
        struct snd_soc_component *comp;
-       struct snd_card *card;
        struct gbaudio_jack *jack = NULL;
 
        if (!gbcodec) {
@@ -816,21 +815,20 @@ int gbaudio_register_module(struct gbaudio_module_info *module)
        }
 
        comp = gbcodec->component;
-       card = comp->card->snd_card;
 
-       down_write(&card->controls_rwsem);
+       mutex_lock(&gbcodec->register_mutex);
 
        if (module->num_dais) {
                dev_err(gbcodec->dev,
                        "%d:DAIs not supported via gbcodec driver\n",
                        module->num_dais);
-               up_write(&card->controls_rwsem);
+               mutex_unlock(&gbcodec->register_mutex);
                return -EINVAL;
        }
 
        ret = gbaudio_init_jack(module, comp->card);
        if (ret) {
-               up_write(&card->controls_rwsem);
+               mutex_unlock(&gbcodec->register_mutex);
                return ret;
        }
 
@@ -867,7 +865,7 @@ int gbaudio_register_module(struct gbaudio_module_info *module)
                ret = snd_soc_dapm_new_widgets(comp->card);
        dev_dbg(comp->dev, "Registered %s module\n", module->name);
 
-       up_write(&card->controls_rwsem);
+       mutex_unlock(&gbcodec->register_mutex);
        return ret;
 }
 EXPORT_SYMBOL(gbaudio_register_module);
@@ -935,13 +933,12 @@ static void gbaudio_codec_cleanup(struct gbaudio_module_info *module)
 void gbaudio_unregister_module(struct gbaudio_module_info *module)
 {
        struct snd_soc_component *comp = gbcodec->component;
-       struct snd_card *card = comp->card->snd_card;
        struct gbaudio_jack *jack, *n;
        int mask;
 
        dev_dbg(comp->dev, "Unregister %s module\n", module->name);
 
-       down_write(&card->controls_rwsem);
+       mutex_lock(&gbcodec->register_mutex);
        mutex_lock(&gbcodec->lock);
        gbaudio_codec_cleanup(module);
        list_del(&module->list);
@@ -978,10 +975,8 @@ void gbaudio_unregister_module(struct gbaudio_module_info *module)
                dev_dbg(comp->dev, "Removing %d controls\n",
                        module->num_controls);
                /* release control semaphore */
-               up_write(&card->controls_rwsem);
                gbaudio_remove_component_controls(comp, module->controls,
                                                  module->num_controls);
-               down_write(&card->controls_rwsem);
        }
        if (module->dapm_widgets) {
                dev_dbg(comp->dev, "Removing %d widgets\n",
@@ -992,7 +987,7 @@ void gbaudio_unregister_module(struct gbaudio_module_info *module)
 
        dev_dbg(comp->dev, "Unregistered %s module\n", module->name);
 
-       up_write(&card->controls_rwsem);
+       mutex_unlock(&gbcodec->register_mutex);
 }
 EXPORT_SYMBOL(gbaudio_unregister_module);
 
@@ -1012,6 +1007,7 @@ static int gbcodec_probe(struct snd_soc_component *comp)
        info->dev = comp->dev;
        INIT_LIST_HEAD(&info->module_list);
        mutex_init(&info->lock);
+       mutex_init(&info->register_mutex);
        INIT_LIST_HEAD(&info->dai_list);
 
        /* init dai_list used to maintain runtime stream info */
index ce15e80..f3f7a7e 100644 (file)
@@ -71,6 +71,7 @@ struct gbaudio_codec_info {
        /* to maintain runtime stream params for each DAI */
        struct list_head dai_list;
        struct mutex lock;
+       struct mutex register_mutex;
 };
 
 struct gbaudio_widget {