bge(4) one packet wedge

David Christensen davidch at broadcom.com
Wed Aug 23 19:54:08 UTC 2006


This "lost interrupt" type of problem is addressed by the use of the
status_tag 
field in the status block.  (Listed as bge_rsvd0 in the bge_status_block
structure). 
Everytime the status block is updated a new tag value is written to the
status block.  
When the ISR starts the driver should record the status_tag value.  At
the end
of the ISR, the driver should compare the current status_tag value is
the status
block with the value recorded on entry to the ISR.  If the values are
the same
then no additional status block updates have occurred so there shouldn't
be
any packets hanging around.  If the values are different then additional
packets
or completions are waiting around so the ISR should loop around again.
At the 
end of the ISR the driver will write the status_tag value it last
handled to a
mailbox register, letting the hardware know the last status block update
handled.
If necessary the hardware will generate a new interrupt and start the
process over
again.

This entire process should be included in the Linux driver, I don't see
it being
used in the bge driver (bge_intr()).

Dave


> -----Original Message-----
> From: Gleb Smirnoff [mailto:glebius at FreeBSD.org] 
> Sent: Wednesday, August 23, 2006 9:17 AM
> To: David Christensen
> Cc: brad at openbsd.org; oleg at FreeBSD.org; net at FreeBSD.org
> Subject: bge(4) one packet wedge
> 
>   Colleagues,
> 
>   I've faced a problem in bge(4) when a single packet is in the RX
> ring, but it isn't noticed by the driver. A reception of a packet
> triggers interrupt and both packets are processed - an old one
> and the new one.
> 
>   To reproduce the problem you need to run netperf (from ports
> collection): netserver on another host (10.0.0.1) and netperf on
> the host, where tested bge(4) is installed - 10.0.0.2. No traffic
> except netperf's should flow through this NIC, or the problem won't
> be reproduced!
> 
>   So, I run netperf client and simultaneously tcpdump on the
> another host. After few seconds there is a wedge. The last packet
> seen on 10.0.0.1 is the packet sent by 10.0.0.1 to 10.0.0.2. However
> it isn't seen on 10.0.0.2.
> 
> Ok, let's look at the receive ring:
> 
> (kgdb) p $sc->bge_rx_saved_considx
> $14 = 51
> (kgdb) p $sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx
> $15 = 51
> 
> Looks like there is nothing to process.
> 
> However, if I run 'ping -c 1 10.0.0.2' I will get an 
> interrupt and read
> two packets: first the old packet, and then recently sent ping.
> 
> -- 
> Totus tuus, Glebius.
> GLEBIUS-RIPN GLEB-RIPE
> 
> 



More information about the freebsd-net mailing list