DragonFly bugs List (threaded) for 2007-09
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]
Re: kernel panic
I think there a ref-counting problem with the ifaddr structure. This
structure is embedded in the ifnet structure and used all over the place.
I can't find the exact cause so here's a patch which will hopefully
force a panic (with INVARIANTS turned on of course) if any attempt is
made to free the structure before it has been removed from the address
list. If we can catch it here it should become obvious where the bug
is.
-Matt
Index: net/if_var.h
===================================================================
RCS file: /cvs/src/sys/net/if_var.h,v
retrieving revision 1.39
diff -u -p -r1.39 if_var.h
--- net/if_var.h 16 Aug 2007 20:03:57 -0000 1.39
+++ net/if_var.h 3 Sep 2007 21:02:41 -0000
@@ -375,6 +375,7 @@ (struct ifaddr *, struct sockaddr *);
};
#define IFA_ROUTE RTF_UP /* route installed */
+#define IFA_XLIST RTF_XLIST /* route installed in in_ifaddrhead */
/* for compatibility with other BSDs */
#define ifa_list ifa_link
@@ -429,6 +430,7 @@ ++_ifa->ifa_refcnt;
}
#include <sys/malloc.h>
+#include <net/route.h>
MALLOC_DECLARE(M_IFADDR);
MALLOC_DECLARE(M_IFMADDR);
@@ -436,10 +438,12 @@
static __inline void
IFAFREE(struct ifaddr *_ifa)
{
- if (_ifa->ifa_refcnt <= 0)
+ if (_ifa->ifa_refcnt <= 0) {
+ KKASSERT((_ifa->ifa_flags & IFA_XLIST) == 0);
kfree(_ifa, M_IFADDR);
- else
+ } else {
_ifa->ifa_refcnt--;
+ }
}
extern struct ifnethead ifnet;
Index: net/route.h
===================================================================
RCS file: /cvs/src/sys/net/route.h,v
retrieving revision 1.21
diff -u -p -r1.21 route.h
--- net/route.h 4 Mar 2007 18:51:59 -0000 1.21
+++ net/route.h 3 Sep 2007 21:01:50 -0000
@@ -203,7 +203,8 @@ #define RTF_PINNED 0x100000 /* future us
#define RTF_LOCAL 0x200000 /* route represents a local address */
#define RTF_BROADCAST 0x400000 /* route represents a bcast address */
#define RTF_MULTICAST 0x800000 /* route represents a mcast address */
- /* 0x1000000 and up unassigned */
+#define RTF_XLIST 0x1000000 /* on auxillary list (sanity check) */
+ /* 0x2000000 and up unassigned */
/*
* Routing statistics.
Index: netinet/in.c
===================================================================
RCS file: /cvs/src/sys/netinet/in.c,v
retrieving revision 1.20
diff -u -p -r1.20 in.c
--- netinet/in.c 30 Sep 2006 22:38:21 -0000 1.20
+++ netinet/in.c 3 Sep 2007 21:00:54 -0000
@@ -274,11 +274,15 @@ bzero(ia, sizeof *ia);
/*
* Protect from ipintr() traversing address list
* while we're modifying it.
+ *
+ * IFA_XLIST applies to the in_ifaddrhead list,
+ * set it when the ifa has been added.
*/
crit_enter();
TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_link);
ifa = &ia->ia_ifa;
+ ifa->ifa_flags |= IFA_XLIST;
TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link);
ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr;
@@ -444,10 +448,14 @@
/*
* Protect from ipintr() traversing address list while we're modifying
* it.
+ *
+ * IFA_XLIST applies to the in_ifaddrhead list, clear it when the ifa
+ * has been removed.
*/
lwkt_serialize_enter(ifp->if_serializer);
TAILQ_REMOVE(&ifp->if_addrhead, &ia->ia_ifa, ifa_link);
TAILQ_REMOVE(&in_ifaddrhead, ia, ia_link);
+ ia->ia_ifa.ifa_flags &= ~IFA_XLIST;
LIST_REMOVE(ia, ia_hash);
IFAFREE(&ia->ia_ifa);
lwkt_serialize_exit(ifp->if_serializer);
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]