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;

Reply via email to