panic: mutex inp not owned at
/usr/src/sys/netinet/tcp_output.c:140
Robert Watson
rwatson at FreeBSD.org
Thu Aug 5 06:45:00 PDT 2004
On Thu, 5 Aug 2004, Jun Kuriyama wrote:
>
> This is "2004-08-05 00:35:00 UTC"'s kernel. (Just before rwatson's
> bpf commit)
>
>
> panic: mutex inp not owned at /usr/src/sys/netinet/tcp_output.c:140
Could you try the attached patch? This modifies the IPv6 code to match
the IPv4 code in passing in the "inpcbinfo" reference for a protocol,
rather than just its inpcb list. This allows in6_pcbnotify() to lock the
structure before walking it. It also acquires the per-pcb locks before
notifying each pcb of an event.
Sorry about the panic!
Index: in6_pcb.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet6/in6_pcb.c,v
retrieving revision 1.57
diff -u -r1.57 in6_pcb.c
--- in6_pcb.c 28 Jul 2004 13:03:07 -0000 1.57
+++ in6_pcb.c 5 Aug 2004 13:42:44 -0000
@@ -610,8 +610,8 @@
* Must be called at splnet.
*/
void
-in6_pcbnotify(head, dst, fport_arg, src, lport_arg, cmd, cmdarg, notify)
- struct inpcbhead *head;
+in6_pcbnotify(pcbinfo, dst, fport_arg, src, lport_arg, cmd, cmdarg, notify)
+ struct inpcbinfo *pcbinfo;
struct sockaddr *dst;
const struct sockaddr *src;
u_int fport_arg, lport_arg;
@@ -619,6 +619,7 @@
void *cmdarg;
struct inpcb *(*notify) __P((struct inpcb *, int));
{
+ struct inpcbhead *head;
struct inpcb *inp, *ninp;
struct sockaddr_in6 sa6_src, *sa6_dst;
u_short fport = fport_arg, lport = lport_arg;
@@ -656,11 +657,16 @@
}
errno = inet6ctlerrmap[cmd];
s = splnet();
+ head = pcbinfo->listhead;
+ INP_INFO_WLOCK(pcbinfo);
for (inp = LIST_FIRST(head); inp != NULL; inp = ninp) {
+ INP_LOCK(inp);
ninp = LIST_NEXT(inp, inp_list);
- if ((inp->inp_vflag & INP_IPV6) == 0)
+ if ((inp->inp_vflag & INP_IPV6) == 0) {
+ INP_UNLOCK(inp);
continue;
+ }
/*
* If the error designates a new path MTU for a destination
@@ -698,13 +704,17 @@
(!IN6_IS_ADDR_UNSPECIFIED(&sa6_src.sin6_addr) &&
!IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr,
&sa6_src.sin6_addr)) ||
- (fport && inp->inp_fport != fport))
+ (fport && inp->inp_fport != fport)) {
+ INP_UNLOCK(inp);
continue;
+ }
do_notify:
if (notify)
(*notify)(inp, errno);
+ INP_UNLOCK(inp);
}
+ INP_INFO_WUNLOCK(pcbinfo);
splx(s);
}
Index: in6_pcb.h
===================================================================
RCS file: /home/ncvs/src/sys/netinet6/in6_pcb.h,v
retrieving revision 1.14
diff -u -r1.14 in6_pcb.h
--- in6_pcb.h 7 Apr 2004 20:46:15 -0000 1.14
+++ in6_pcb.h 5 Aug 2004 13:37:55 -0000
@@ -85,7 +85,7 @@
in6_pcblookup_hash __P((struct inpcbinfo *,
struct in6_addr *, u_int, struct in6_addr *,
u_int, int, struct ifnet *));
-void in6_pcbnotify __P((struct inpcbhead *, struct sockaddr *,
+void in6_pcbnotify __P((struct inpcbinfo *, struct sockaddr *,
u_int, const struct sockaddr *, u_int, int, void *,
struct inpcb *(*)(struct inpcb *, int)));
struct inpcb *
Index: raw_ip6.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet6/raw_ip6.c,v
retrieving revision 1.43
diff -u -r1.43 raw_ip6.c
--- raw_ip6.c 27 Jul 2004 23:45:19 -0000 1.43
+++ raw_ip6.c 5 Aug 2004 13:40:50 -0000
@@ -298,7 +298,8 @@
sa6_src = &sa6_any;
}
- (void) in6_pcbnotify(&ripcb, sa, 0, (const struct sockaddr *)sa6_src,
+ (void) in6_pcbnotify(&ripcbinfo, sa, 0,
+ (const struct sockaddr *)sa6_src,
0, cmd, cmdarg, notify);
}
Index: udp6_usrreq.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet6/udp6_usrreq.c,v
retrieving revision 1.50
diff -u -r1.50 udp6_usrreq.c
--- udp6_usrreq.c 27 Jul 2004 23:45:19 -0000 1.50
+++ udp6_usrreq.c 5 Aug 2004 13:41:22 -0000
@@ -444,11 +444,11 @@
bzero(&uh, sizeof(uh));
m_copydata(m, off, sizeof(*uhp), (caddr_t)&uh);
- (void) in6_pcbnotify(&udb, sa, uh.uh_dport,
+ (void) in6_pcbnotify(&udbinfo, sa, uh.uh_dport,
(struct sockaddr *)ip6cp->ip6c_src,
uh.uh_sport, cmd, cmdarg, notify);
} else
- (void) in6_pcbnotify(&udb, sa, 0,
+ (void) in6_pcbnotify(&udbinfo, sa, 0,
(const struct sockaddr *)sa6_src,
0, cmd, cmdarg, notify);
}
More information about the freebsd-current
mailing list