Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 21 Sep 2011 20:26:46 -0700
From:      Craig Leres <leres@ee.lbl.gov>
To:        freebsd-stable@freebsd.org
Cc:        John Baldwin <jhb@freebsd.org>
Subject:   Re: Panic during kernel booting on HP Proliant DL180G6 and latest STABLE
Message-ID:  <4E7AAAF6.7050004@ee.lbl.gov>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------070803060606090506000303
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

I have a lot of supermicro motherboards and the newest ones have igb
chipsets; they've been quite a headache with respect to FreeBSD 8. I'm
running 8.2-RELEASE but have upgraded parts of my kernel to 8-RELENG (as
of a few months ago). Some of them work ok while others panic on bootup.
Upgrading to newer versions of the intel igb code fixes some but breaks
others. It's been frustrating.

While working on this today, I saw two different kernel panics:

    Could not setup receive structures
    m_getzone: m_getjcl: invalid cluster type

I tried John Baldwin's patch but got the "invalid cluster type" panic so
I backed it out.

Later I figured out that either turning off hw.igb.enable_msix
(loader.conf) or raising kern.ipc.nmbclusters to 131072 (sysctl.conf)
and setting hw.igb.num_queues to 4 (loader.conf) would avoid the
"receive structures" panic but either way I was seeing the "invalid
cluster type" panic.

Looking m_getjcl(), I suspected the passed size to be 0; some debugging
confirmed this. Looks like a race here where a receive interrupt comes
in before adapter->rx_mbuf_sz has been initialized.

Attached is the hack I added to avoid the panic when booting. The idea
is to pretend m_getjcl() failed to allocate a cluster rather than to go
down in flames.

                Craig

--------------070803060606090506000303
Content-Type: text/plain;
 name="patch-if_igb.c.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="patch-if_igb.c.txt"

Index: if_igb.c
===================================================================
--- if_igb.c	(revision 31)
+++ if_igb.c	(working copy)
@@ -3695,6 +3695,11 @@
 		    htole64(hseg[0].ds_addr);
 no_split:
 		if (rxbuf->m_pack == NULL) {
+			if (adapter->rx_mbuf_sz == 0) {
+				printf("igb_refresh_mbufs: "
+				     "avoid m_getjcl() panic\n");
+				goto update;
+			}
 			mp = m_getjcl(M_DONTWAIT, MT_DATA,
 			    M_PKTHDR, adapter->rx_mbuf_sz);
 			if (mp == NULL)
@@ -3912,6 +3917,12 @@
 
 skip_head:
 		/* Now the payload cluster */
+		if (adapter->rx_mbuf_sz == 0) {
+			printf("igb_setup_receive_ring: "
+			    "avoid m_getjcl() panic\n");
+			error = ENOBUFS;
+			goto fail;
+		}
 		rxbuf->m_pack = m_getjcl(M_DONTWAIT, MT_DATA,
 		    M_PKTHDR, adapter->rx_mbuf_sz);
 		if (rxbuf->m_pack == NULL) {

--------------070803060606090506000303--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4E7AAAF6.7050004>