[alsa-devel] (no subject)

Philippe Carriere philippe-f.carriere at wanadoo.fr
Thu Jan 29 09:35:53 CET 2009


Hi Karsten,

I successfully tested your new version of the patch and sent a
"tested:by" to linux-usb at vger.kernel.org today (see attached).
Hope it will speed up the process.

Regards,

Phil.

Le mardi 27 janvier 2009 à 01:16 +0100, Karsten Wiese a écrit :
> Am Dienstag, 14. Oktober 2008 schrieb Philippe Carriere:
> > Might this patch (the original one, without features yet implemented in
> > 2.6.26, and an extremely slight modification to fit it) I use on Fedora
> > kernel (the patch also applies as it stands to vanilla) save works and
> > time ?
> 
> I resent the patch to linux-usb at vger.kernel.org today.
> Maybe it helps, if you post a "tested-by:" there.
> 
> Regards,
> Karsten
> 
> pièce jointe message de courriel (forwarded message), "Karsten Wiese
> <fzu at wemgehoertderstaat.de>: [RESEND][PATCH] USB: Prevent EHCI ITDs
> reusage while frame is active"
> > -------- Message transféré --------
> > De: Karsten Wiese <fzu at wemgehoertderstaat.de>
> > À: David Brownell <david-b at pacbell.net>
> > Cc: linux-usb at vger.kernel.org
> > Sujet: [RESEND][PATCH] USB: Prevent EHCI ITDs reusage while frame is
> > active
> > Date: Mon, 26 Jan 2009 14:32:51 +0100
> > 
> > pièce jointe document texte brut (forwarded message)
> > Hi,
> > 
> > this is a refresh to let patch fit ontop 2.6.29-rc2.
> > Changes from previous version:
> > - use variable clock_frame instead of hw_frame
> > - Patch Description exactified
> > snd_usb_us122l (in kernel since .28) needs it, if device is attached to
> > ehci.
> > 
> > thanks,
> > Karsten
> > 
> > 
> > 
> > ----------------------------------------------------------------------
> > From: Karsten Wiese <fzu at wemgehoertderstaat.de>
> > Date: Wed, 13 Feb 2008 22:22:09 +0100
> > Subject: [PATCH] USB: Prevent EHCI ITDs reusage while frame is active
> > 
> > ITDs can be detached from urbs, before the frame elapses. Now those ITDs are
> > immediately recycled.
> > If the ITD is reused before the frame elapses, the ITD becomes invalid
> > regarding the not yet elapsed frame.
> > Patch takes care of those ITDs by moving them into a new ehci member list
> > cached_itd_list. ITDs resting in cached_itd_list are moved back into their
> > stream's free_list once scan_periodic() detects that the active frame has
> > elapsed.
> > 
> > Signed-off-by: Karsten Wiese <fzu at wemgehoertderstaat.de>
> > 
> > ---
> >  drivers/usb/host/ehci-hcd.c   |    2 +
> >  drivers/usb/host/ehci-mem.c   |    1 +
> >  drivers/usb/host/ehci-sched.c |   54 ++++++++++++++++++++++++++++++++++------
> >  drivers/usb/host/ehci.h       |    5 ++++
> >  4 files changed, 54 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
> > index 4725d15..e551bb3 100644
> > --- a/drivers/usb/host/ehci-hcd.c
> > +++ b/drivers/usb/host/ehci-hcd.c
> > @@ -485,6 +485,7 @@ static int ehci_init(struct usb_hcd *hcd)
> >  	 * periodic_size can shrink by USBCMD update if hcc_params allows.
> >  	 */
> >  	ehci->periodic_size = DEFAULT_I_TDPS;
> > +	INIT_LIST_HEAD(&ehci->cached_itd_list);
> >  	if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0)
> >  		return retval;
> >  
> > @@ -497,6 +498,7 @@ static int ehci_init(struct usb_hcd *hcd)
> >  
> >  	ehci->reclaim = NULL;
> >  	ehci->next_uframe = -1;
> > +	ehci->clock_frame = -1;
> >  
> >  	/*
> >  	 * dedicate a qh for the async ring head, since we couldn't unlink
> > diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
> > index 0431397..10d5291 100644
> > --- a/drivers/usb/host/ehci-mem.c
> > +++ b/drivers/usb/host/ehci-mem.c
> > @@ -128,6 +128,7 @@ static inline void qh_put (struct ehci_qh *qh)
> >  
> >  static void ehci_mem_cleanup (struct ehci_hcd *ehci)
> >  {
> > +	free_cached_itd_list(ehci);
> >  	if (ehci->async)
> >  		qh_put (ehci->async);
> >  	ehci->async = NULL;
> > diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
> > index a081ee6..c1f7d5f 100644
> > --- a/drivers/usb/host/ehci-sched.c
> > +++ b/drivers/usb/host/ehci-sched.c
> > @@ -1004,7 +1004,8 @@ iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream)
> >  
> >  		is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0;
> >  		stream->bEndpointAddress &= 0x0f;
> > -		stream->ep->hcpriv = NULL;
> > +		if (stream->ep)
> > +			stream->ep->hcpriv = NULL;
> >  
> >  		if (stream->rescheduled) {
> >  			ehci_info (ehci, "ep%d%s-iso rescheduled "
> > @@ -1653,14 +1654,26 @@ itd_complete (
> >  			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
> >  	}
> >  	iso_stream_put (ehci, stream);
> > -	/* OK to recycle this ITD now that its completion callback ran. */
> > +
> >  done:
> >  	usb_put_urb(urb);
> >  	itd->urb = NULL;
> > -	itd->stream = NULL;
> > -	list_move(&itd->itd_list, &stream->free_list);
> > -	iso_stream_put(ehci, stream);
> > -
> > +	if (ehci->clock_frame != itd->frame || itd->index[7] != -1) {
> > +		/* OK to recycle this ITD now. */
> > +		itd->stream = NULL;
> > +		list_move(&itd->itd_list, &stream->free_list);
> > +		iso_stream_put(ehci, stream);
> > +	} else {
> > +		/* HW might still start transactions based on this ITD.
> > +		   If its content changed that is. Move it to a safe place. */
> > +		list_move(&itd->itd_list, &ehci->cached_itd_list);
> > +		if (stream->refcount == 2) {
> > +			/* If iso_stream_put() would be called here, stream
> > +			   would be freed. Prevent stream's reusage instead. */
> > +			stream->ep->hcpriv = NULL;
> > +			stream->ep = NULL;
> > +		}
> > +	}
> >  	return retval;
> >  }
> >  
> > @@ -2101,6 +2114,20 @@ done:
> >  
> >  /*-------------------------------------------------------------------------*/
> >  
> > +static void free_cached_itd_list(struct ehci_hcd *ehci)
> > +{
> > +	struct ehci_itd *itd, *n;
> > +
> > +	list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) {
> > +		struct ehci_iso_stream	*stream = itd->stream;
> > +		itd->stream = NULL;
> > +		list_move(&itd->itd_list, &stream->free_list);
> > +		iso_stream_put(ehci, stream);
> > +	}
> > +}
> > +
> > +/*-------------------------------------------------------------------------*/
> > +
> >  static void
> >  scan_periodic (struct ehci_hcd *ehci)
> >  {
> > @@ -2115,10 +2142,17 @@ scan_periodic (struct ehci_hcd *ehci)
> >  	 * Touches as few pages as possible:  cache-friendly.
> >  	 */
> >  	now_uframe = ehci->next_uframe;
> > -	if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state))
> > +	if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {
> >  		clock = ehci_readl(ehci, &ehci->regs->frame_index);
> > -	else
> > +		clock_frame = (clock >> 3) % ehci->periodic_size;
> > +	} else  {
> >  		clock = now_uframe + mod - 1;
> > +		clock_frame = -1;
> > +	}
> > +	if (ehci->clock_frame != clock_frame) {
> > +		free_cached_itd_list(ehci);
> > +		ehci->clock_frame = clock_frame;
> > +	}
> >  	clock %= mod;
> >  	clock_frame = clock >> 3;
> >  
> > @@ -2277,6 +2311,10 @@ restart:
> >  			/* rescan the rest of this frame, then ... */
> >  			clock = now;
> >  			clock_frame = clock >> 3;
> > +			if (ehci->clock_frame != clock_frame) {
> > +				free_cached_itd_list(ehci);
> > +				ehci->clock_frame = clock_frame;
> > +			}
> >  		} else {
> >  			now_uframe++;
> >  			now_uframe %= mod;
> > diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
> > index fb7054c..5262fb7 100644
> > --- a/drivers/usb/host/ehci.h
> > +++ b/drivers/usb/host/ehci.h
> > @@ -86,6 +86,9 @@ struct ehci_hcd {			/* one per controller */
> >  	union ehci_shadow	*pshadow;	/* mirror hw periodic table */
> >  	int			next_uframe;	/* scan periodic, start here */
> >  	unsigned		periodic_sched;	/* periodic activity count */
> > +	struct list_head	cached_itd_list; /* list of itds completed
> > +						    while frame hadn't yet elapsed */
> > +	unsigned		clock_frame;
> >  
> >  	/* per root hub port */
> >  	unsigned long		reset_done [EHCI_MAX_ROOT_PORTS];
> > @@ -220,6 +223,8 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
> >  	}
> >  }
> >  
> > +static void free_cached_itd_list(struct ehci_hcd *ehci);
> > +
> >  /*-------------------------------------------------------------------------*/
> >  
> >  #include <linux/usb/ehci_def.h>

-- 
Philippe Carriere <philippe-f.carriere at wanadoo.fr>
-------------- next part --------------



More information about the Alsa-devel mailing list