This happened shortly after unplugging a cardbus ral(4)
card without bringing it down first.

vm_fault(0xd0af91a0, 0xd41f2000, 0, 1) -> e
kernel: page fault trap, code=0
Stopped at      rt_missmsg+0x79:        movzwl  0x58(%ebx),%eax
ddb{0}> trace
rt_missmsg(5, f5c7de14,802,d41f2030,0) at rt_missmsg+0x79
in_losing(d97ef4b4,1900,0,0,d0dba5e0) at in_losing+0x83
tcp_timer_rexmt(d97eb00c,f5cdef0,d03b50dd,f5c7dee4,d41b8460) at 
tcp_timer_rexmt+0x2ab
softclock(0,203286,0,0,d020205e) at softclock+0x225
softintr_dispatch(0) at softintr_dispatch+0x5a
Xsoftclock() at Xsoftclock+0x17
--- interrupt ---
cpu_idle_mwait_cycle(d03c354a,d0b1f060,d0bda5e0,d0bda5e0,f5c7df90) at 
cpu_idle_mwait_cycle+0x58
cpu_idle_cycle(d0bda5e0)
Bad frame pointer: 0xd0ca3e58
ddb{0}>

It looks like in_losing() is being called with a NULL ifp here
(3rd parameter). so it seems this interrupt was scheduled for
the ral interface and ran after it was detached.

This is a similar problem to the one fixed in r1.127 of this file.

The diff below fixes the case where the ifp is NULL, but I've
seen it happen also with a non-NULL ifp. Similar trace, expect
in_losing looks like this:

  in_losing(d97f61ec,1900,f5f276d8,d03ce1a5,d0ab2f28) at in_losing+0x8a

So perhaps the real problem is a missing timeout_del()?
I'm not sure where that could be added to fix this.

Index: in_pcb.c
===================================================================
RCS file: /cvs/src/sys/netinet/in_pcb.c,v
retrieving revision 1.145
diff -u -p -r1.145 in_pcb.c
--- in_pcb.c    23 Oct 2013 19:57:49 -0000      1.145
+++ in_pcb.c    30 Nov 2013 16:07:17 -0000
@@ -610,16 +610,19 @@ in_losing(struct inpcb *inp)
 
        if ((rt = inp->inp_route.ro_rt)) {
                inp->inp_route.ro_rt = 0;
-               bzero((caddr_t)&info, sizeof(info));
-               info.rti_flags = rt->rt_flags;
-               info.rti_info[RTAX_DST] = &inp->inp_route.ro_dst;
-               info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
-               info.rti_info[RTAX_NETMASK] = rt_mask(rt);
-               rt_missmsg(RTM_LOSING, &info, rt->rt_flags, rt->rt_ifp, 0,
-                   inp->inp_rtableid);
-               if (rt->rt_flags & RTF_DYNAMIC)
-                       (void)rtrequest1(RTM_DELETE, &info, rt->rt_priority,
-                               (struct rtentry **)0, inp->inp_rtableid);
+               if (rt->rt_ifp) {
+                       bzero((caddr_t)&info, sizeof(info));
+                       info.rti_flags = rt->rt_flags;
+                       info.rti_info[RTAX_DST] = &inp->inp_route.ro_dst;
+                       info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
+                       info.rti_info[RTAX_NETMASK] = rt_mask(rt);
+                       rt_missmsg(RTM_LOSING, &info, rt->rt_flags, rt->rt_ifp,
+                           0, inp->inp_rtableid);
+                       if (rt->rt_flags & RTF_DYNAMIC)
+                               (void)rtrequest1(RTM_DELETE, &info,
+                                   rt->rt_priority, (struct rtentry **)0,
+                                   inp->inp_rtableid);
+               }
                /*
                 * A new route can be allocated
                 * the next time output is attempted.

Reply via email to