Date: Wed, 23 Aug 2006 12:53:49 -0700 From: "David Christensen" <davidch@broadcom.com> To: "Gleb Smirnoff" <glebius@FreeBSD.org> Cc: brad@openbsd.org, oleg@FreeBSD.org, net@FreeBSD.org Subject: RE: bge(4) one packet wedge Message-ID: <09BFF2FA5EAB4A45B6655E151BBDD90301D43002@NT-IRVA-0750.brcm.ad.broadcom.com> In-Reply-To: <20060823161649.GE76666@cell.sick.ru>
next in thread | previous in thread | raw e-mail | index | archive | help
This "lost interrupt" type of problem is addressed by the use of the status_tag=20 field in the status block. (Listed as bge_rsvd0 in the bge_status_block structure).=20 Everytime the status block is updated a new tag value is written to the status block. =20 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=20 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@FreeBSD.org]=20 > Sent: Wednesday, August 23, 2006 9:17 AM > To: David Christensen > Cc: brad@openbsd.org; oleg@FreeBSD.org; net@FreeBSD.org > Subject: bge(4) one packet wedge >=20 > Colleagues, >=20 > 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. >=20 > 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! >=20 > 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. >=20 > Ok, let's look at the receive ring: >=20 > (kgdb) p $sc->bge_rx_saved_considx > $14 =3D 51 > (kgdb) p $sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx > $15 =3D 51 >=20 > Looks like there is nothing to process. >=20 > However, if I run 'ping -c 1 10.0.0.2' I will get an=20 > interrupt and read > two packets: first the old packet, and then recently sent ping. >=20 > --=20 > Totus tuus, Glebius. > GLEBIUS-RIPN GLEB-RIPE >=20 >=20
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?09BFF2FA5EAB4A45B6655E151BBDD90301D43002>