[3.16.y-ckt stable] Patch "ALSA: usb-audio: Fix device_del() sysfs warnings at disconnect" has been added to staging queue

Luis Henriques luis.henriques at canonical.com
Mon Nov 24 15:00:52 UTC 2014


This is a note to let you know that I have just added a patch titled

    ALSA: usb-audio: Fix device_del() sysfs warnings at disconnect

to the linux-3.16.y-queue branch of the 3.16.y-ckt extended stable tree 
which can be found at:

 http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.16.y-queue

This patch is scheduled to be released in version 3.16.7-ckt2.

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.16.y-ckt tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Luis

------

>From 2e768e5c160c8a8c03dfc1584149c9aacf42dc19 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai at suse.de>
Date: Wed, 5 Nov 2014 15:08:49 +0100
Subject: ALSA: usb-audio: Fix device_del() sysfs warnings at disconnect

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:
  [<ffffffff814a3e38>] ? dump_stack+0x49/0x71
  [<ffffffff8103cb72>] ? warn_slowpath_common+0x82/0xb0
  [<ffffffff8103cc55>] ? warn_slowpath_fmt+0x45/0x50
  [<ffffffff813521e9>] ? device_del+0x39/0x180
  [<ffffffff81352339>] ? device_unregister+0x9/0x20
  [<ffffffff81352384>] ? device_destroy+0x34/0x40
  [<ffffffffa00ba29f>] ? snd_unregister_device+0x7f/0xd0 [snd]
  [<ffffffffa025124e>] ? snd_rawmidi_dev_disconnect+0xce/0x100 [snd_rawmidi]
  [<ffffffffa00c0192>] ? snd_device_disconnect+0x62/0x90 [snd]
  [<ffffffffa00c025c>] ? snd_device_disconnect_all+0x3c/0x60 [snd]
  [<ffffffffa00bb574>] ? snd_card_disconnect+0x124/0x1a0 [snd]
  [<ffffffffa02e54e8>] ? usb_audio_disconnect+0x88/0x1c0 [snd_usb_audio]
  [<ffffffffa015260e>] ? usb_unbind_interface+0x5e/0x1b0 [usbcore]
  [<ffffffff813553e9>] ? __device_release_driver+0x79/0xf0
  [<ffffffff81355485>] ? device_release_driver+0x25/0x40
  [<ffffffff81354e11>] ? bus_remove_device+0xf1/0x130
  [<ffffffff813522b9>] ? device_del+0x109/0x180
  [<ffffffffa01501d5>] ? usb_disable_device+0x95/0x1f0 [usbcore]
  [<ffffffffa014634f>] ? usb_disconnect+0x8f/0x190 [usbcore]
  [<ffffffffa0149179>] ? hub_thread+0x539/0x13a0 [usbcore]
  [<ffffffff810669f5>] ? sched_clock_local+0x15/0x80
  [<ffffffff81066c98>] ? sched_clock_cpu+0xb8/0xd0
  [<ffffffff81070730>] ? bit_waitqueue+0xb0/0xb0
  [<ffffffffa0148c40>] ? usb_port_resume+0x430/0x430 [usbcore]
  [<ffffffffa0148c40>] ? usb_port_resume+0x430/0x430 [usbcore]
  [<ffffffff8105973e>] ? kthread+0xce/0xf0
  [<ffffffff81059670>] ? kthread_create_on_node+0x1c0/0x1c0
  [<ffffffff814a8b7c>] ? ret_from_fork+0x7c/0xb0
  [<ffffffff81059670>] ? 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 <tgayoso at gmail.com>
Reported-and-tested-by: Chris J Arges <chris.j.arges at canonical.com>
Signed-off-by: Takashi Iwai <tiwai at suse.de>
Signed-off-by: Luis Henriques <luis.henriques at canonical.com>
---
 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 a09e5f3519e3..8df7e1d14603 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -591,18 +591,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(&register_mutex);
-	chip->num_interfaces--;
-	if (chip->num_interfaces <= 0) {
+	if (!was_shutdown) {
 		struct snd_usb_endpoint *ep;

 		snd_card_disconnect(card);
@@ -622,6 +623,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(&register_mutex);
 		snd_card_free_when_closed(card);
--
2.1.0





More information about the kernel-team mailing list