lkml.org 
[lkml]   [2016]   [Jul]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.6 177/203] ALSA: pcm: Free chmap at PCM free callback, too
    Date
    4.6-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Takashi Iwai <tiwai@suse.de>

    commit a8ff48cb70835f48de5703052760312019afea55 upstream.

    The chmap ctls assigned to PCM streams are freed in the PCM disconnect
    callback. However, since the disconnect callback isn't called when
    the card gets freed before registering, the chmap ctls may still be
    left assigned. They are eventually freed together with other ctls,
    but it may cause an Oops at pcm_chmap_ctl_private_free(), as the
    function refers to the assigned PCM stream, while the PCM objects have
    been already freed beforehand.

    The fix is to free the chmap ctls also at PCM free callback, not only
    at PCM disconnect.

    Reported-by: Laxminath Kasam <b_lkasam@codeaurora.org>
    Signed-off-by: Takashi Iwai <tiwai@suse.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    sound/core/pcm.c | 14 ++++++++++----
    1 file changed, 10 insertions(+), 4 deletions(-)

    --- a/sound/core/pcm.c
    +++ b/sound/core/pcm.c
    @@ -849,6 +849,14 @@ int snd_pcm_new_internal(struct snd_card
    }
    EXPORT_SYMBOL(snd_pcm_new_internal);

    +static void free_chmap(struct snd_pcm_str *pstr)
    +{
    + if (pstr->chmap_kctl) {
    + snd_ctl_remove(pstr->pcm->card, pstr->chmap_kctl);
    + pstr->chmap_kctl = NULL;
    + }
    +}
    +
    static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
    {
    struct snd_pcm_substream *substream, *substream_next;
    @@ -871,6 +879,7 @@ static void snd_pcm_free_stream(struct s
    kfree(setup);
    }
    #endif
    + free_chmap(pstr);
    if (pstr->substream_count)
    put_device(&pstr->dev);
    }
    @@ -1135,10 +1144,7 @@ static int snd_pcm_dev_disconnect(struct
    for (cidx = 0; cidx < 2; cidx++) {
    if (!pcm->internal)
    snd_unregister_device(&pcm->streams[cidx].dev);
    - if (pcm->streams[cidx].chmap_kctl) {
    - snd_ctl_remove(pcm->card, pcm->streams[cidx].chmap_kctl);
    - pcm->streams[cidx].chmap_kctl = NULL;
    - }
    + free_chmap(&pcm->streams[cidx]);
    }
    mutex_unlock(&pcm->open_mutex);
    mutex_unlock(&register_mutex);

    \
     
     \ /
      Last update: 2016-07-26 00:41    [W:4.085 / U:0.700 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site