kern/118093: [firewire] firewire bus reset hogs CPU, causing data to be lost

Sean Bruno sean.bruno at dsl-only.net
Mon Jan 5 22:30:12 PST 2009


The following reply was made to PR kern/118093; it has been noted by GNATS.

From: Sean Bruno <sean.bruno at dsl-only.net>
To: Dieter <freebsd at sopwith.solgatos.com>
Cc: bug-followup at FreeBSD.org, freebsd-firewire at FreeBSD.org
Subject: Re: kern/118093: [firewire] firewire bus reset hogs CPU, causing
 data to be lost
Date: Mon, 05 Jan 2009 22:20:03 -0800

 On Mon, 2009-01-05 at 17:52 +0000, Dieter wrote:
 > In message <1231181797.21260.8.camel at localhost.localdomain>, Sean Bruno writes:
 > 
 > > @@ -1388,6 +1387,7 @@
 > >  	struct fw_device *fwdev;
 > >  
 > >  	s = splfw();
 > > +	FW_GLOCK(fc);
 > >  	fc->status = FWBUSEXPLORE;
 > >  
 > >  	/* Invalidate all devices, just after bus reset. */
 > > @@ -1396,6 +1396,7 @@
 > >  			fwdev->status = FWDEVINVAL;
 > >  			fwdev->rcnt = 0;
 > >  		}
 > > +	FW_GUNLOCK(fc);
 > >  	splx(s);
 > >  
 > >  	wakeup((void *)fc);
 > 
 > If the (null these days) spl calls have been replaced with FW_GLOCK/FW_GUNLOCK
 > calls, can the spl calls be removed now?
 > 
 They most definitely can be removed.  However, they are a roadmap to
 where locks SHOULD be.  I'm using them as guideposts through the code to
 see if I can figure out what's missing.
 
 > > @@ -1922,6 +1924,8 @@
 > >  	u_int i;
 > >  	struct firewire_comm *fc = (struct firewire_comm *)sc;
 > >  
 > > +	FW_GLOCK(fc);
 > > +	FW_GUNLOCK(fc);
 > >  	if (stat & OHCI_INT_DMA_IR) {
 > >  		irstat = atomic_readandclear_int(&sc->irstat);
 > >  		for(i = 0; i < fc->nisodma ; i++){
 > 
 > This needs to be reviewed by someone who understands what is protected by
 > getting a lock and then immediately releasing it.  I have no clue.
 > 
 Indeed, it's gross.  I only sent this patch over as a "test" of sorts to
 validate that the issue I'm looking into(locking in the firewire driver)
 is actually something related to what you reported in this issue.
 
 > > @@ -1969,8 +1973,8 @@
 > >  			OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCTIMER);
 > >  #endif
 > >  			OWRITE(sc, FWOHCI_INTMASKCLR,  OHCI_INT_CYC_LOST);
 > > -			device_printf(fc->dev, "too many cycle lost, "
 > > -			 "no cycle master presents?\n");
 > > +			device_printf(fc->dev, "%s: too many cycle lost, "
 > > +			 "no cycle master presents?\n", __func__);
 > >  		}
 > 
 > Should this be "too many cycles lost, " and  "no cycle master present?\n"
 > 
 Who knows.  I haven't reviewed this specific chunk of code to understand
 what it really means as per the FW specs.
 > >  	uint32_t fun;
 > >  
 > > +	FW_GLOCK(fc);
 > >  	device_printf(fc->dev, "Initiate bus reset\n");
 > >  	sc = (struct fwohci_softc *)fc;
 > >  
 > > @@ -2487,6 +2495,7 @@
 > >  	fun |= FW_PHY_ISBR | FW_PHY_RHB;
 > >  	fun = fwphy_wrdata(sc, FW_PHY_ISBR_REG, fun);
 > >  #endif
 > > +	FW_GUNLOCK(fc);
 > >  }
 > 
 > Does the lock need to protect the printf?
 
 These are gross, overpowered, way to heavy handed locks that I'm playing
 with.  I need to prevent pre-emption of certain events while they are in
 progress.  One of these events is the firewire's assertion of "bus
 reset" on the firewire device.  I see the h/w interrupt firing before
 this code can actually complete, causing the driver to be confused on
 occasion.
 
 
 Thanks for surveying this code with me, it helps to see what other
 people's eyes can pick up.  I hope to have this in working order
 soon-ish.
 
 Sean
 


More information about the freebsd-bugs mailing list