On Tue, Jul 26, 2011 at 08:34:11AM +0800, Andiry Xu wrote: > In xhci_urb_enqueue(), allocate a block of memory for all the TDs instead > of allocating memory for each of them separately. This reduces the number > of kzalloc calling when an isochronous usb is submitted. Hi Andiry, I've actually been finding a lot of memory leaks and race conditions in the isochronous transfer queueing. I have a box that consistently hard-hangs with a certain setup of HS webcams and audio devices when xHCI driver debugging is enabled. I'd like to root out those problems before we do any optimizations. I'm at a conference this week, so I won't be able to finish that bug fix until end of next week. Then we can look and see if this patch is useful. Makes sense? Sarah Sharp > Signed-off-by: Andiry Xu <andiry.xu@xxxxxxx> > --- > drivers/usb/host/xhci-mem.c | 14 +++----------- > drivers/usb/host/xhci.c | 15 +++++++++------ > 2 files changed, 12 insertions(+), 17 deletions(-) > > diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c > index 1370db8..275d393 100644 > --- a/drivers/usb/host/xhci-mem.c > +++ b/drivers/usb/host/xhci-mem.c > @@ -1465,18 +1465,10 @@ struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, > > void xhci_urb_free_priv(struct xhci_hcd *xhci, struct urb_priv *urb_priv) > { > - int last; > - > - if (!urb_priv) > - return; > - > - last = urb_priv->length - 1; > - if (last >= 0) { > - int i; > - for (i = 0; i <= last; i++) > - kfree(urb_priv->td[i]); > + if (urb_priv) { > + kfree(urb_priv->td[0]); > + kfree(urb_priv); > } > - kfree(urb_priv); > } > > void xhci_free_command(struct xhci_hcd *xhci, > diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c > index d0a6540..95c6d91 100644 > --- a/drivers/usb/host/xhci.c > +++ b/drivers/usb/host/xhci.c > @@ -1029,6 +1029,7 @@ static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id, > int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) > { > struct xhci_hcd *xhci = hcd_to_xhci(hcd); > + struct xhci_td *buffer; > unsigned long flags; > int ret = 0; > unsigned int slot_id, ep_index; > @@ -1059,13 +1060,15 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) > if (!urb_priv) > return -ENOMEM; > > + buffer = kzalloc(size * sizeof(struct xhci_td), mem_flags); > + if (!buffer) { > + kfree(urb_priv); > + return -ENOMEM; > + } > + > for (i = 0; i < size; i++) { > - urb_priv->td[i] = kzalloc(sizeof(struct xhci_td), mem_flags); > - if (!urb_priv->td[i]) { > - urb_priv->length = i; > - xhci_urb_free_priv(xhci, urb_priv); > - return -ENOMEM; > - } > + urb_priv->td[i] = buffer; > + buffer++; > } > > urb_priv->length = size; > -- > 1.7.1 > > -- 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