Re: Page fault in rt_newaddrmsg on gif0 destruction

From: Luigi Rizzo <rizzo_at_icir.org>
Date: Mon, 19 Apr 2004 01:36:27 -0700
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
_at_ -520,17 +520,6 _at__at_ 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);
 
_at__at_ -570,6 +559,17 _at__at_
 	 */
 	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);
Received on Sun Apr 18 2004 - 23:36:28 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:51 UTC