From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934507AbbA1EYw (ORCPT ); Tue, 27 Jan 2015 23:24:52 -0500 Received: from mail.kernel.org ([198.145.29.136]:40834 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934469AbbA1EYs (ORCPT ); Tue, 27 Jan 2015 23:24:48 -0500 From: lizf@kernel.org To: stable@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Takashi Iwai , Zefan Li Subject: [PATCH 3.4 136/177] ALSA: usb-audio: Fix device_del() sysfs warnings at disconnect Date: Wed, 28 Jan 2015 12:09:54 +0800 Message-Id: <1422418236-12852-227-git-send-email-lizf@kernel.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1422418050-12581-1-git-send-email-lizf@kernel.org> References: <1422418050-12581-1-git-send-email-lizf@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Takashi Iwai 3.4.106-rc1 review patch. If anyone has any objections, please let me know. ------------------ commit 0725dda207e95ff25f1aa01432250323e0ec49d6 upstream. Some USB-audio devices show weird sysfs warnings at disconnecting the devices, e.g. usb 1-3: USB disconnect, device number 3 ------------[ cut here ]------------ WARNING: CPU: 0 PID: 973 at fs/sysfs/group.c:216 device_del+0x39/0x180() sysfs group ffffffff8183df40 not found for kobject 'midiC1D0' Call Trace: [] ? dump_stack+0x49/0x71 [] ? warn_slowpath_common+0x82/0xb0 [] ? warn_slowpath_fmt+0x45/0x50 [] ? device_del+0x39/0x180 [] ? device_unregister+0x9/0x20 [] ? device_destroy+0x34/0x40 [] ? snd_unregister_device+0x7f/0xd0 [snd] [] ? snd_rawmidi_dev_disconnect+0xce/0x100 [snd_rawmidi] [] ? snd_device_disconnect+0x62/0x90 [snd] [] ? snd_device_disconnect_all+0x3c/0x60 [snd] [] ? snd_card_disconnect+0x124/0x1a0 [snd] [] ? usb_audio_disconnect+0x88/0x1c0 [snd_usb_audio] [] ? usb_unbind_interface+0x5e/0x1b0 [usbcore] [] ? __device_release_driver+0x79/0xf0 [] ? device_release_driver+0x25/0x40 [] ? bus_remove_device+0xf1/0x130 [] ? device_del+0x109/0x180 [] ? usb_disable_device+0x95/0x1f0 [usbcore] [] ? usb_disconnect+0x8f/0x190 [usbcore] [] ? hub_thread+0x539/0x13a0 [usbcore] [] ? sched_clock_local+0x15/0x80 [] ? sched_clock_cpu+0xb8/0xd0 [] ? bit_waitqueue+0xb0/0xb0 [] ? usb_port_resume+0x430/0x430 [usbcore] [] ? usb_port_resume+0x430/0x430 [usbcore] [] ? kthread+0xce/0xf0 [] ? kthread_create_on_node+0x1c0/0x1c0 [] ? ret_from_fork+0x7c/0xb0 [] ? kthread_create_on_node+0x1c0/0x1c0 ---[ end trace 40b1928d1136b91e ]--- This comes from the fact that usb-audio driver may receive the disconnect callback multiple times, per each usb interface. When a device has both audio and midi interfaces, it gets called twice, and currently the driver tries to release resources at the last call. At this point, the first parent interface has been already deleted, thus deleting a child of the first parent hits such a warning. For fixing this problem, we need to call snd_card_disconnect() and cancel pending operations at the very first disconnect while the release of the whole objects waits until the last disconnect call. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=80931 Reported-and-tested-by: Tomas Gayoso Reported-and-tested-by: Chris J Arges Signed-off-by: Takashi Iwai [lizf: Backported to 3.4: adjust context] Signed-off-by: Zefan Li --- sound/usb/card.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sound/usb/card.c b/sound/usb/card.c index 658ea11..43fca52 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -568,18 +568,19 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, { struct snd_card *card; struct list_head *p; + bool was_shutdown; if (chip == (void *)-1L) return; card = chip->card; down_write(&chip->shutdown_rwsem); + was_shutdown = chip->shutdown; chip->shutdown = 1; up_write(&chip->shutdown_rwsem); mutex_lock(®ister_mutex); - chip->num_interfaces--; - if (chip->num_interfaces <= 0) { + if (!was_shutdown) { snd_card_disconnect(card); /* release the pcm resources */ list_for_each(p, &chip->pcm_list) { @@ -593,6 +594,10 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, list_for_each(p, &chip->mixer_list) { snd_usb_mixer_disconnect(p); } + } + + chip->num_interfaces--; + if (chip->num_interfaces <= 0) { usb_chip[chip->index] = NULL; mutex_unlock(®ister_mutex); snd_card_free_when_closed(card); -- 1.9.1