Page fault in rt_newaddrmsg on gif0 destruction
Luigi Rizzo
rizzo at icir.org
Mon Apr 19 01:36:28 PDT 2004
Ok i understand what is going on (thanks for the very detailed
report, btw) -- basically the code was trying to use
ifadd_byindex() after the information had been destroyed.
I think the attached patch (basically mving a block of code down
in if_detach) should fix the problem.
Actually I believe this particular chunk of code should be moved
even further down, possibly right before the final IF_AFDATA_UNLOCK(),
because you cannot tell, a-priori, what information on the device
the lower level routines expect to use, so zeroing the ifindex_table[]
or calling destroy_dev() too early is probably a bug.
If you can try it (in the proposed form, or moving it at the end
of if_detach) and let me khow how it works for you, i can commit
the fix.
cheers
luigi
On Sun, Apr 18, 2004 at 05:57:58PM +0200, Andreas Kohn wrote:
> Hello,
>
> since I updated kernel + world two days ago, I get a reproducible panic
> on system shutdown. It seems to happen when gif0 is destroyed.
> Is there anything I could do to help debugging this problem?
>
> Regards,
> Andreas Kohn
Index: if.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if.c,v
retrieving revision 1.189
diff -u -r1.189 if.c
--- if.c 18 Apr 2004 18:59:44 -0000 1.189
+++ if.c 19 Apr 2004 08:31:49 -0000
@ -520,17 +520,6 @@ if_detach(struct ifnet *ifp)
s = splnet();
if_down(ifp);
- /*
- * Remove address from ifindex_table[] and maybe decrement if_index.
- * Clean up all addresses.
- */
- ifaddr_byindex(ifp->if_index) = NULL;
- destroy_dev(ifdev_byindex(ifp->if_index));
- ifdev_byindex(ifp->if_index) = NULL;
-
- while (if_index > 0 && ifaddr_byindex(if_index) == NULL)
- if_index--;
-
for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa; ifa = next) {
next = TAILQ_NEXT(ifa, ifa_link);
@@ -570,6 +559,17 @@
*/
in6_ifdetach(ifp);
#endif
+ /*
+ * Remove address from ifindex_table[] and maybe decrement if_index.
+ * Clean up all addresses.
+ */
+ ifaddr_byindex(ifp->if_index) = NULL;
+ destroy_dev(ifdev_byindex(ifp->if_index));
+ ifdev_byindex(ifp->if_index) = NULL;
+
+ while (if_index > 0 && ifaddr_byindex(if_index) == NULL)
+ if_index--;
+
/* We can now free link ifaddr. */
ifa = TAILQ_FIRST(&ifp->if_addrhead);
More information about the freebsd-current
mailing list