Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

staging: greybus: Avoid abusing controls_rwsem

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>

+8 -11
+7 -11
drivers/staging/greybus/audio_codec.c
··· 807 807 { 808 808 int ret; 809 809 struct snd_soc_component *comp; 810 - struct snd_card *card; 811 810 struct gbaudio_jack *jack = NULL; 812 811 813 812 if (!gbcodec) { ··· 815 816 } 816 817 817 818 comp = gbcodec->component; 818 - card = comp->card->snd_card; 819 819 820 - down_write(&card->controls_rwsem); 820 + mutex_lock(&gbcodec->register_mutex); 821 821 822 822 if (module->num_dais) { 823 823 dev_err(gbcodec->dev, 824 824 "%d:DAIs not supported via gbcodec driver\n", 825 825 module->num_dais); 826 - up_write(&card->controls_rwsem); 826 + mutex_unlock(&gbcodec->register_mutex); 827 827 return -EINVAL; 828 828 } 829 829 830 830 ret = gbaudio_init_jack(module, comp->card); 831 831 if (ret) { 832 - up_write(&card->controls_rwsem); 832 + mutex_unlock(&gbcodec->register_mutex); 833 833 return ret; 834 834 } 835 835 ··· 865 867 ret = snd_soc_dapm_new_widgets(comp->card); 866 868 dev_dbg(comp->dev, "Registered %s module\n", module->name); 867 869 868 - up_write(&card->controls_rwsem); 870 + mutex_unlock(&gbcodec->register_mutex); 869 871 return ret; 870 872 } 871 873 EXPORT_SYMBOL(gbaudio_register_module); ··· 933 935 void gbaudio_unregister_module(struct gbaudio_module_info *module) 934 936 { 935 937 struct snd_soc_component *comp = gbcodec->component; 936 - struct snd_card *card = comp->card->snd_card; 937 938 struct gbaudio_jack *jack, *n; 938 939 int mask; 939 940 940 941 dev_dbg(comp->dev, "Unregister %s module\n", module->name); 941 942 942 - down_write(&card->controls_rwsem); 943 + mutex_lock(&gbcodec->register_mutex); 943 944 mutex_lock(&gbcodec->lock); 944 945 gbaudio_codec_cleanup(module); 945 946 list_del(&module->list); ··· 975 978 dev_dbg(comp->dev, "Removing %d controls\n", 976 979 module->num_controls); 977 980 /* release control semaphore */ 978 - up_write(&card->controls_rwsem); 979 981 gbaudio_remove_component_controls(comp, module->controls, 980 982 module->num_controls); 981 - down_write(&card->controls_rwsem); 982 983 } 983 984 if (module->dapm_widgets) { 984 985 dev_dbg(comp->dev, "Removing %d widgets\n", ··· 987 992 988 993 dev_dbg(comp->dev, "Unregistered %s module\n", module->name); 989 994 990 - up_write(&card->controls_rwsem); 995 + mutex_unlock(&gbcodec->register_mutex); 991 996 } 992 997 EXPORT_SYMBOL(gbaudio_unregister_module); 993 998 ··· 1007 1012 info->dev = comp->dev; 1008 1013 INIT_LIST_HEAD(&info->module_list); 1009 1014 mutex_init(&info->lock); 1015 + mutex_init(&info->register_mutex); 1010 1016 INIT_LIST_HEAD(&info->dai_list); 1011 1017 1012 1018 /* init dai_list used to maintain runtime stream info */
+1
drivers/staging/greybus/audio_codec.h
··· 71 71 /* to maintain runtime stream params for each DAI */ 72 72 struct list_head dai_list; 73 73 struct mutex lock; 74 + struct mutex register_mutex; 74 75 }; 75 76 76 77 struct gbaudio_widget {