Re: Panic in -current cvsupped today

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Thu, 4 Aug 2005 10:25:54 -0400
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
_at__at_ -408,6 +408,7 _at__at_
                        return (NULL);
                }
        }
+       IF_ADDR_LOCK_INIT(ifp);

        return (ifp);
 }
_at__at_ -462,7 +463,6 _at__at_
        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_at_FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve"  =  http://www.FreeBSD.org
Received on Thu Aug 04 2005 - 12:25:24 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:40 UTC