On 2015/05/09 17:10, Brad Smith wrote:
> On Sun, May 03, 2015 at 12:16:21PM +0200, Mark Kettenis wrote:
> > > Date: Sun, 3 May 2015 02:38:12 -0700
> > > From: Bryan Linton <[email protected]>
> > >
> > > The key difference is the following two lines. The first wedged,
> > > the second unwedged:
> > > em0 2048 2 2 256 2
> > > em0 2048 4 2 256 4
> > >
> > > It seems like the em0 line always shows the latter line, so I'm hoping
> > > this indicates something useful.
> >
> > I believe em(4) needs at least 4 descriptors on its rx ring. If you
> > fall below that limit (which can happen if the CPU is busy), the card
> > stops receiving packets. I believe em(4) is supposed to get an
> > interrupt for dropped packets and will attempt to refill the ring if
> > it receives such an interrupt. It seems that mechanism isn't working
> > for your card. Perhaps the usual workaround of using a timeout should
> > be added to the driver.
>
> Good hint, rev 1.280 broke the chips not capable of jumbo frames. Correcting
> the low watermark for the affected chips resolves the issue Christian and
> Bryan were experiencing.
If all em(4) need 4 descriptors, would it make more sense to just enforce
lwm >= 4? Both from a self-documentation point of view, and to avoid a
potential trap if some nic was discovered to support <2k baby jumbos
i.e. give the same result for the if_hardmtu/MCLBYTES sum.
.
>
> Index: if_em.c
> ===================================================================
> RCS file: /home/cvs/src/sys/dev/pci/if_em.c,v
> retrieving revision 1.295
> diff -u -p -u -p -r1.295 if_em.c
> --- if_em.c 11 Feb 2015 23:21:47 -0000 1.295
> +++ if_em.c 3 May 2015 11:17:49 -0000
> @@ -2597,6 +2597,7 @@ int
> em_setup_receive_structures(struct em_softc *sc)
> {
> struct ifnet *ifp = &sc->interface_data.ac_if;
> + u_int lwm;
>
> memset(sc->rx_desc_base, 0,
> sizeof(struct em_rx_desc) * sc->num_rx_desc);
> @@ -2608,8 +2609,12 @@ em_setup_receive_structures(struct em_so
> sc->next_rx_desc_to_check = 0;
> sc->last_rx_desc_filled = sc->num_rx_desc - 1;
>
> - if_rxr_init(&sc->rx_ring, 2 * ((ifp->if_hardmtu / MCLBYTES) + 1),
> - sc->num_rx_desc);
> + if (sc->hw.max_frame_size == ETHER_MAX_LEN)
> + lwm = 4;
> + else
> + lwm = 2 * ((ifp->if_hardmtu / MCLBYTES) + 1);
> +
> + if_rxr_init(&sc->rx_ring, lwm, sc->num_rx_desc);
>
> if (em_rxfill(sc) == 0) {
> printf("%s: unable to fill any rx descriptors\n",
>
> --
> This message has been scanned for viruses and
> dangerous content by MailScanner, and is
> believed to be clean.
>