Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 Aug 2005 10:25:54 -0400
From:      John Baldwin <jhb@FreeBSD.org>
To:        freebsd-current@freebsd.org, holm@freibergnet.de, rwatson@FreeBSD.org
Subject:   Re: Panic in -current cvsupped today
Message-ID:  <200508041025.55148.jhb@FreeBSD.org>
In-Reply-To: <20050804081835.GA81613@pegasus.freiberg-net.de>
References:  <20050804081835.GA81613@pegasus.freiberg-net.de>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thursday 04 August 2005 04:18 am, Holm Tiffe wrote:
> Hi all,
>
> I've got a kernel panic with -current today:
>
> de0: <Digital 21040 Ethernet> port 0xec00-0xec7f mem 0xdffffb80-0xdffffbff
> irq 5 at device 0.9 on pci0
> de0: Cogent 21040 [10Mb/s] pass 2.3
> kernel trap 12 with interrupts disabled
>
> Fatal trap 12: page fault while in kernel mode
> faul virtual address  -0x74
> fault code  - supervisor read, page not present
> instruction pointer   -0x20:0xc050e9c9
> stack pointer  - 0x28:0xd3cac900
> frame pointer  - 0x28:0xd3cac904
> code segment   - base 0x0, limit 0xffff, type 0x1b
>                - DPL 0, pres 1, def32 1, gran 1
> processor eflags  - reume, IOPL - 0
> current process  - 188 (ifconfig)
> [thread pid 188 tid 100051 ]
> Stopped at        turnstile_setowner+0x9: movl  0x74(xedx),xeax
>
> db>
> ...
> turnstile_setowner+0x09
> turnstile_wait(c175f200,0,c174780,d3cac858) at turnstile_wait+0x24b
> _mtx_lock_sleep(c175f200,c1686480,0,c1825301,bd5) at _mtx_lock_sleep+0x8a
> _mtx_lock_flags(c175f200,0,c1825301,bd5,c1747800) at _mtx_lock_flags+0x34
> tulip_addr_filter
> tulip_reset
> tulip_attach

Well, I needed the numbers for these three lines but let me look at the code 
for a second.  Ok, I found it.  It's actually a bug in the new if_addr locking 
recently added.  The problem is that the driver is trying to use the 
IF_ADDR_LOCK() before it is initialized in ether_ifattach().  Oddly enough, 
the IF_ADDR_LOCK is destroyed in if_free() rather than if_detach(), so 
there's another bug in that if a driver does an if_free() of an ifp that has 
been allocated via if_alloc() but not attached due to a bug in attach, 
if_free() will try to destroy an uninitialized mutex.  The simple fix for 
both of these bugs is to move the initialization of the IF_ADDR_LOCK to 
if_alloc().  It also means that all the ethernet device drivers don't have to 
be touched to handle IF_ADDR_LOCK not being initialized until 
ether_ifattach().  Patch below:

Index: net/if.c
===================================================================
RCS file: /usr/cvs/src/sys/net/if.c,v
retrieving revision 1.239
diff -u -r1.239 if.c
--- if.c        2 Aug 2005 23:23:26 -0000       1.239
+++ if.c        4 Aug 2005 14:20:35 -0000
@@ -408,6 +408,7 @@
                        return (NULL);
                }
        }
+       IF_ADDR_LOCK_INIT(ifp);

        return (ifp);
 }
@@ -462,7 +463,6 @@
        TASK_INIT(&ifp->if_starttask, 0, if_start_deferred, ifp);
        TASK_INIT(&ifp->if_linktask, 0, do_link_state_change, ifp);
        IF_AFDATA_LOCK_INIT(ifp);
-       IF_ADDR_LOCK_INIT(ifp);
        ifp->if_afdata_initialized = 0;
        IFNET_WLOCK();
        TAILQ_INSERT_TAIL(&ifnet, ifp, if_link);


-- 
John Baldwin <jhb@FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve"  =  http://www.FreeBSD.org



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