Re: race in usb_get_from_anchor?

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

 



On Saturday 31 July 2010 21:48:05 Greg KH wrote:
> On Sat, Jul 31, 2010 at 06:24:33PM +0200, Christian Lamparter wrote:
> > (No maintainer for usb/core?)
> 
> Yes, did you look in the MAINTAINERS file?  Or use
> scripts/get_maintainer.pl?  It should show you the proper name...

Ah, I was looking for something with USB and CORE, or /usb/core.
Anyway, doesn't matter anymore, since you've added :-)


> > First a bit of background:
> > 
> > I'm developing a driver for the AR9170 USB 802.11n Wireless device.
> > And if you are interested in this thing, the driver code + fw is available at:
> > http://www.kernel.org/pub/linux/kernel/people/chr/carl9170/carl9170-1.7.4-pre/
> > 
> > Now, back to my problem:
> > 
> > The driver uses a sophisticated 3 anchor layout:
> > 	1. rx_pool => a pool of prepared urbs, which can be
> > 		submitted to the device anytime.
> 
> Why a pool?  Is allocating new ones somehow too slow?  If so, why?

Because the device uses some sort of streaming technology.
Basically, it aggregates multiple frames/command responses and traps
into a single, large transfer (which can be as large as 32K)
(Note: the _current_ limit is at 8K, but the HW supports up to 32K)

So, the usual replacement buffers on-demand stuff is not an option.

> > 	2. rx_work => storage for received urbs, which will be
> > 		processed in the rx tasklet.
> > 
> > 	3. rx_anchor => all active rx urbs (i.e.: those which have been
> > 		submitted to the device)
> > 
> > ---
> > diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
> > index 7c05555..93f8f4c 100644
> > --- a/drivers/usb/core/urb.c
> > +++ b/drivers/usb/core/urb.c
> > @@ -137,6 +137,16 @@ void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor)
> >  }
> >  EXPORT_SYMBOL_GPL(usb_anchor_urb);
> >  
> > +static void __usb_unanchor_urb(struct urb *urb, struct usb_anchor *anchor)
> > +{
> > +	urb->anchor = NULL;
> > +
> > +	list_del(&urb->anchor_list);
> > +	usb_put_urb(urb);
> > +	if (list_empty(&anchor->urb_list))
> > +		wake_up(&anchor->wait);
> 
> You are calling wake_up with a spinlock held, is that ok?
> 
uhh, I know that you can't sleep while holding a spinlock.
But I haven't read anything about why you can't call
wake_up (or complete for that matter?) while holding a lock.

I see you point, though. Do you have an idea for an alternative
way without making a real mess of it?

Regards,
	Chr
--
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