[PATCH] ALSA: core: Replace mutex_lock with mutex_trylock

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Task1 waits for mutex_lock, and task2 waits for pde to be unused.(deadlock)
/*call trace*/
    task1 Call trace:
            __switch_to+0x174/0x338
            schedule+0x7c/0xe8
            schedule_preempt_disabled+0x24/0x40
            mutex_lock+0x40/0xec
            snd_info_text_entry_open+0x28/0x120
            proc_reg_open+0xe4/0x248
            do_dentry_open+0x2a4/0x4e0

    task2 Call trace:
            schedule_timeout+0x44/0x1c8
            wait_for_completion+0x18/0x24
            proc_entry_rundown+0x60/0xf0
            remove_proc_subtree+0x180/0x218
            proc_remove+0x20/0x30
            snd_info_disconnect+0x4c/0x68
            snd_info_card_disconnect+0x3c/0x58
            snd_card_disconnect+0x130/0x264
            usb_audio_disconnect+0xc0/0x24c

/*the sequence*/
    task1:
            - proc_reg_open: set the use_pde
    task2:
            - usb_audio_disconnect: usb device disconnection occurs
            - snd_info_card_disconnect: acquire the mutex_lock(&info_mutex)
            - proc_entry_rundown: wait_for_completion(unuse_pde)
    task1:
            - wait for mutex_lock in snd_info_text_entry_open

To avoid it, a mutex without wating(mutex_trylock) shoud be used in
snd_info_text_entry_open(task1).
Then, when mutex_lock acquisition fails, an error is returned, and the pde
becomes unused, and the mutex_lock held by task2 is released.


Signed-off-by: Shinhyung Kang <s47.kang@xxxxxxxxxxx>
diff --git a/sound/core/info.c b/sound/core/info.c
index 0b2f04dcb589..6cb4064b292e 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -369,7 +369,10 @@ static int snd_info_text_entry_open(struct inode
*inode, struct file *file)
        struct snd_info_private_data *data;
        int err;

-       mutex_lock(&info_mutex);
+       if (!mutex_trylock(&info_mutex)) {
+               pr_err("%s: failed to acquire the info_mutex\n", __func__);
+               return -EAGAIN;
+       }
        err = alloc_info_private(entry, &data);
        if (err < 0)
                goto unlock;






[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux