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 <b...@shoshoni.info>
> > 
> > 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.


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.

Reply via email to