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@samsung.com 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;