ehci with full speed audio device leaking sitds

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

 



Please CC me on replies, as I'm not on the list.

My system is an AR9132 mips SoC, kernel 3.6.11 with OpenWrt patches.
The audio device is a C-Media usb audio adapter, IDs 0d8c/000e. It is a
full speed device, and is connected directly to the only USB port. I'm
using only the output, but it does have a mic input as well. (There are
also various controls, e.g. mute, suggested by the USB descriptors, but
those aren't present on my device.)

The device was working fine with OpenWrt-patched kernel 3.3.8.

With the new kernel, I have the following problems:
* audio output is choppy (underruns). the usb audio driver
  intermittently prints:

  ALSA sound/usb/pcm.c:1187 delay: estimated 624, actual 288

  (I realize the message is not directly indicative of an underrun, but
  I believe the underruns and the message are correlated)

  This tends to get worse as playback progresses, and sometimes there
  are "cannot submit urb" messages with error -27, and sometimes
  playback hangs.

* audio programs almost always hang in "D" state when closing the audio
  device.

I investigated the second problem first in hopes I could eliminate the
reboot after each experiment, but in the end, both problems went away
simultaneously.

I tracked the hang to the sleep in ehci_endpoint_disable that waits for
active iso transactions to finish (indicated by stream->td_list being
empty).

My theory is that the changes in
f42890782241a60d107f23d08089a4a12b507a11 ("USB: EHCI: simplify
isochronous scanning") result in leakage of sitds when still-active
sitds in the previous frame are skipped by scan_isoc. I don't know why
this results in the underruns, but it is a low-memory embedded system,
so possibly it's just leaking enough descriptors to run out of
dma-eligible memory.

The patch below restores the behavior before commit f428 of stopping the
scan immediately once a still-active descriptor is found (and leaving
next_frame at the previous frame rather than the current frame if
appropriate). This patch resolves the problems I've been seeing, but I
don't know if it's the best fix.

I have various ftrace captures, which I can post somewhere if there's
interest. Some of them have the iso stream refcounting restored, and
clearly show that there aren't as many puts as gets. The detail of
scan_isoc behavior isn't visible in the traces, though.

(An aside: I noticed there is an rmb() before the itd status check, but
not before the sitd status check.)


--- a/drivers/usb/host/ehci-sched.c	2013-01-26 19:37:21.000000000 -0800
+++ b/drivers/usb/host/ehci-sched.c	2013-01-26 19:39:25.000000000 -0800
@@ -2296,7 +2296,7 @@
					type = Q_NEXT_TYPE(ehci,
							q.sitd->hw_next);
					q = *q_p;
-					break;
+					goto end_scan;
				}

				/* Take finished SITDs out of the schedule
@@ -2336,5 +2336,6 @@
			break;
		frame = (frame + 1) & fmask;
	}
-	ehci->next_frame = now_frame;
+end_scan:
+	ehci->next_frame = frame;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux