Re: port of aggressive autosuspend from option to sierra

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

 



On Wed, 2009-08-19 at 05:24 -0700, Oliver Neukum wrote:
> Am Dienstag, 11. August 2009 03:51:04 schrieb Elina Pasheva:
> > If you look at the sierra_resume() function in the 'while' loop where it
> > processes the delayed queue and further down right after the 'for' loop:
> > Between  the marks "----->" (i.e. between spin_unlock_irq() and the
> > next spin_lock_irg() setting the "suspend" flag,  there is a window of
> > opportunity for a sierra_write() to be called and because the suspend
> > flag still indicates "suspended" (see ******* in sierra_write()) these
> > urbs will be kept on the delayed queue. But right after that the
> > "suspend" status is set to 0 by the resume() function so in reality the
> > urbs in the delayed queue will not be processed until the next
> > (auto)suspend condition occurs or may be lost if the port is closed.
> >
> > This window of opportunity may be used for instance, in a dual-core
> > architecture by the other CPU to call write() function, etc.
> > This condition exist for the option driver as well.
> 
> Hi,
> 
> sorry for the delay, I suffered some major hardware problems.
> The race you describe is due to incorrect locking. The locking
> needs to be changed because the flag cannot be cleared earlier
> without changing the order of writes. It seems to me that the correct
> version looks like:
> 
> 		portdata = usb_get_serial_port_data(port);
> 
> 		spin_lock_irq(&intfdata->susp_lock);
> 		while ((urb = usb_get_from_anchor(&portdata->delayed))) {
> 			usb_anchor_urb(urb, &portdata->active);	
> 			intfdata->in_flight++;
> 			spin_unlock_irq(&intfdata->susp_lock);
> 			err = usb_submit_urb(urb, GFP_NOIO);
> 			if (err < 0) {
> 				spin_lock_irq(&intfdata->susp_lock);
> 				intfdata->in_flight--;
> 				spin_unlock_irq(&intfdata->susp_lock);
> 				usb_unanchor_urb(urb);
> 				usb_scuttle_anchored_urbs(&portdata->delayed);
> 				spin_lock_irq(&intfdata->susp_lock);
> 				break;
> 			}
> 			spin_lock_irq(&intfdata->susp_lock);
> 		}
> 		intfdata->suspended = 0;
> 
> 		if (portdata->opened) {
> 			err = sierra_submit_rx_urbs(port, GFP_ATOMIC);
> 			if (err)
> 				ec++;
> 		}
> 		spin_unlock_irq(&intfdata->susp_lock);
> 
> 	Regards
> 		Oliver
> 
> 
Hi Oliver,
Thank you for your time looking into it. Your fix is correct, indeed.
We tested it and approve of it.

Please re-generate the patch with this fix.

Thanks in advance.
Regards,
Elina


--
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