[alsa-devel] [PATCH] ASoC: dapm: fix module unload/reload failed issue by reset kcontrol's widget list
Lars-Peter Clausen
lars at metafoo.de
Tue Jul 28 22:40:57 CEST 2015
On 07/28/2015 04:34 PM, Jie, Yang wrote:
>> -----Original Message-----
>> From: Takashi Iwai [mailto:tiwai at suse.de]
>> Sent: Tuesday, July 28, 2015 5:07 PM
>> To: Jie, Yang
>> Cc: broonie at kernel.org; alsa-devel at alsa-project.org; Girdwood, Liam R
>> Subject: Re: [PATCH] ASoC: dapm: fix module unload/reload failed issue by
>> reset kcontrol's widget list
>>
>> On Tue, 28 Jul 2015 11:03:39 +0200,
>> Jie Yang wrote:
>>>
>>> We need reset the related kcontrol's widget list during the freeing of
>>> a widget, otherwise, the widget list may be outdated and reference to
>>> it may introduce errors(they usually occurs during driver modules
>>> unloading/reloading).
>>>
>>> Here adding a func dapm_update_kcontrols_of_freeing_widget and call it
>>> at dapm_update_kcontrols_of_freeing_widget, to fix those issues.
>>>
>>> Signed-off-by: Jie Yang <yang.jie at intel.com>
>>> ---
>>> sound/soc/soc-dapm.c | 31 +++++++++++++++++++++++++++++++
>>> 1 file changed, 31 insertions(+)
>>>
>>> diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index
>>> aa327c9..1ad8144 100644
>>> --- a/sound/soc/soc-dapm.c
>>> +++ b/sound/soc/soc-dapm.c
>>> @@ -2305,6 +2305,35 @@ static void dapm_free_path(struct
>> snd_soc_dapm_path *path)
>>> kfree(path);
>>> }
>>>
>>> +/* update all dapm kcontrols that related to a widget which being
>>> +freed*/ static void dapm_update_kcontrols_of_freeing_widget(struct
>>> +snd_soc_dapm_widget * w) {
>>> + struct dapm_kcontrol_data *data = NULL;
>>> + int i, j, n;
>>> +
>>> + if (w && w->kcontrols) {
>>> + for (i = 0; i < w->num_kcontrols; i++) {
>>> + if (w->kcontrols[i] == NULL)
>>> + continue;
>>> + data = snd_kcontrol_chip(w->kcontrols[i]);
>>> + if (data == NULL)
>>> + continue;
>>> + for (j = 0, n = 0; j < data->wlist->num_widgets; j++) {
>>> + if (data->wlist->widgets[j] == w) {
>>> + data->wlist->widgets[j] = NULL;
>>> + n++;
>>> + }
>>> + }
>>> +
>>> + if (n) {
>>> + data->wlist->num_widgets -= n;
>>
>> This looks buggy. You didn't rearrange widgets[] but just put a hole, yet
>> decreasing the number.
>
> You are right, but since krealloc() cannot shrink the allocated size, maybe we should
> free those related kcontrols here?
>
>>
>> BTW, how does the reference occur while unloading? Or better to say:
>> isn't it the module refcount adjusted while accessing the resources?
>
>
> soc_cleanup_card_resources
> snd_soc_dapm_free
> dapm_free_widgets
> snd_card_free
> //removing kcontrols, calling private dapm_kcontrol_free()
> kfree(data->widget->name);//the widget here may be
> //already freed! So the reference here
> //may cause error.
Hi,
that free was wrong no matter what, since the widget itself frees the name.
So even if widget is valid this would result in a double free.
The issue was fixed in this commit:
http://git.kernel.org/cgit/linux/kernel/git/broonie/sound.git/commit?h=for-next&id=e18077b6e5dfe26e9fbbdc1fd1085a1701c24bea
- Lars
More information about the Alsa-devel
mailing list