usb-ohci leaks PCI pool memory. I discovered that on a machine with two
pc-card interfaces, both of which have an OHCI on them. (Behind the OHCI
is a three-port serial interface which thinks it's a GSM phone. ;-)
"cardctl eject 0" says:
Sep 10 15:48:23 clu kernel: usb.c: USB disconnect on device 06:00.0-0 address 1
Sep 10 15:48:23 clu kernel: usb.c: USB disconnect on device 06:00.0-1 address 2
Sep 10 15:48:23 clu kernel: usbserial.c: Generic converter now disconnected from
ttyUSB3
Sep 10 15:48:23 clu kernel: usbserial.c: Generic converter now disconnected from
ttyUSB4
Sep 10 15:48:23 clu kernel: usbserial.c: Generic converter now disconnected from
ttyUSB5
Sep 10 15:48:23 clu kernel: usb-ohci.c: free device 2 timeout
Sep 10 15:48:24 clu kernel: usb-ohci.c: USB HC TakeOver failed!
Sep 10 15:48:24 clu kernel: usb.c: USB bus 2 deregistered
Sep 10 15:48:24 clu kernel: pci_pool_destroy 06:00.0/ohci_td, c037f000 busy
Sep 10 15:48:24 clu kernel: pci_pool_destroy 06:00.0/ohci_dev, c0381000 busy
Sep 10 15:48:24 clu kernel: cs: cb_free(bus 6)
Sep 10 15:48:25 clu kernel: usb.c: USB disconnect on device 02:00.0-0 address 1
Sep 10 15:48:25 clu kernel: usb.c: USB disconnect on device 02:00.0-1 address 2
Sep 10 15:48:25 clu kernel: usbserial.c: Generic converter now disconnected from
ttyUSB0
Sep 10 15:48:25 clu kernel: usbserial.c: Generic converter now disconnected from
ttyUSB1
Sep 10 15:48:25 clu kernel: usbserial.c: Generic converter now disconnected from
ttyUSB2
Sep 10 15:48:25 clu kernel: usb.c: USB bus 1 deregistered
This of course prevents usb-ohci from reattaching to the card when it's
inserted next time.
After applying the attached patch, I saw this upon "cardctl insert 0":
Sep 10 15:55:29 clu kernel: usb-ohci.c: USB OHCI at membase 0xe046d000, IRQ 9
Sep 10 15:55:29 clu kernel: usb-ohci.c: usb-02:00.0, PCI device 1045:c861
Sep 10 15:55:29 clu kernel: usb.c: new USB bus registered, assigned bus number 1
Sep 10 15:55:29 clu kernel: hub.c: USB hub found
Sep 10 15:55:29 clu kernel: hub.c: 2 ports detected
Sep 10 15:55:30 clu kernel: hub.c: new USB device 02:00.0-1, assigned address 2
Sep 10 15:55:30 clu kernel: td_alloc- xc0005000
Sep 10 15:55:30 clu kernel: td_alloc+0 c0005040
Sep 10 15:55:30 clu kernel: td_alloc+1 c0005080
Sep 10 15:55:30 clu kernel: td_free+0 xc0005000
Sep 10 15:55:30 clu kernel: td_free+1 xc0005040
Sep 10 15:55:30 clu kernel: td_alloc+0 c0005000
Sep 10 15:55:30 clu kernel: td_alloc+1 c0005040
Sep 10 15:55:30 clu kernel: td_alloc+2 c00050c0
Sep 10 15:55:30 clu kernel: td_free+0 xc0005080
Sep 10 15:55:30 clu kernel: td_free+1 xc0005000
Sep 10 15:55:30 clu kernel: td_free+2 xc0005040
Sep 10 15:55:30 clu kernel: td_alloc+0 c0005000
Sep 10 15:55:30 clu kernel: td_alloc+1 c0005040
Sep 10 15:55:30 clu kernel: td_alloc+2 c0005080
Sep 10 15:55:30 clu kernel: td_free+0 xc00050c0
Sep 10 15:55:30 clu kernel: td_free+1 xc0005000
Sep 10 15:55:30 clu kernel: td_free+2 xc0005040
Sep 10 15:55:30 clu kernel: td_alloc+0 c0005000
Sep 10 15:55:30 clu kernel: td_alloc+1 c0005040
Sep 10 15:55:30 clu kernel: td_alloc+2 c00050c0
Sep 10 15:55:30 clu kernel: td_free+0 xc0005080
Sep 10 15:55:30 clu kernel: td_free+1 xc0005000
Sep 10 15:55:30 clu kernel: td_free+2 xc0005040
Sep 10 15:55:30 clu kernel: td_alloc+0 c0005000
Sep 10 15:55:30 clu kernel: td_alloc+1 c0005040
Sep 10 15:55:30 clu kernel: td_alloc+2 c0005080
Sep 10 15:55:30 clu kernel: td_free+0 xc00050c0
Sep 10 15:55:30 clu kernel: td_free+1 xc0005000
Sep 10 15:55:30 clu kernel: td_free+2 xc0005040
Sep 10 15:55:30 clu kernel: td_alloc+0 c0005000
Sep 10 15:55:30 clu kernel: td_alloc+1 c0005040
Sep 10 15:55:30 clu kernel: td_free+0 xc0005080
Sep 10 15:55:30 clu kernel: td_free+1 xc0005000
Sep 10 15:55:30 clu kernel: usbserial.c: Generic converter detected
Sep 10 15:55:30 clu kernel: usbserial.c: Generic converter now attached to ttyUSB0 (or
usb/tts/0 for devfs)
Sep 10 15:55:30 clu kernel: usbserial.c: Generic converter detected
Sep 10 15:55:30 clu kernel: usbserial.c: Generic converter now attached to ttyUSB1 (or
usb/tts/1 for devfs)
Sep 10 15:55:30 clu kernel: usbserial.c: Generic converter detected
Sep 10 15:55:30 clu kernel: usbserial.c: Generic converter now attached to ttyUSB2 (or
usb/tts/2 for devfs)
[The messages after ejecting are unchanged.]
... which tells me that something forgets to free that "td" someplace.
I didn't instrument for ohci_dev yet; that's probably next.
Help is appreciated. (As usual in these cases, the customer is on a
deadline.)
--
Matthias Urlichs | {M:U} IT Design @ m-u-it.de | [EMAIL PROTECTED]
--- /daten/src/kernel/remote/2.4/drivers/usb/host/usb-ohci.c 2004-07-22 15:19:12
+0200
+++ usb-ohci.c 2004-09-10 16:01:52 +0200
@@ -219,6 +219,7 @@
for (i = 0; i <= last; i++) {
td = urb_priv->td [i];
+printk(KERN_DEBUG "td_free+%d x%p\n",i,td);
if (td)
td_free (hc, td);
}
@@ -685,6 +686,7 @@
/* allocate the TDs (updating hash chains) */
for (i = 0; i < size; i++) {
urb_priv->td[i] = td_alloc (ohci, SLAB_ATOMIC);
+printk(KERN_DEBUG "td_alloc+%d %p\n",i,urb_priv->td[i]);
if (!urb_priv->td[i]) {
urb_priv->length = i;
urb_free_priv (ohci, urb_priv);
@@ -1272,9 +1274,11 @@
ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); /* skip ed */
/* dummy td; end of td list for ed */
td = td_alloc (ohci, SLAB_ATOMIC);
+printk(KERN_DEBUG "td_alloc- x%p\n",td);
/* hash the ed for later reverse mapping */
if (!td || !hash_add_ed (ohci, (ed_t *)ed)) {
/* out of memory */
+printk(KERN_DEBUG "td_OOM x%p\n",td);
if (td)
td_free(ohci, td);
return NULL;
@@ -1659,6 +1663,7 @@
if (ed->state & ED_DEL) { /* set by sohci_free_dev */
struct ohci_device * dev = usb_to_ohci (ohci->dev[edINFO &
0x7F]);
+printk(KERN_DEBUG "td_free- %p\n", tdTailP);
td_free (ohci, tdTailP); /* free dummy td */
ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP);
ed->state = ED_NEW;