Module Name: src
Committed By: rmind
Date: Sun Aug 3 22:55:24 UTC 2014
Modified Files:
src/sys/netinet6: in6_pcb.c
Log Message:
in6_pcbdetach: now that IGMP and multicast groups are MP-safe, we can move
the ip6_freemoptions() call outside the softnet_lock. Should fix PR/49065.
To generate a diff of this commit:
cvs rdiff -u -r1.126 -r1.127 src/sys/netinet6/in6_pcb.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/netinet6/in6_pcb.c
diff -u src/sys/netinet6/in6_pcb.c:1.126 src/sys/netinet6/in6_pcb.c:1.127
--- src/sys/netinet6/in6_pcb.c:1.126 Thu Jul 24 15:12:03 2014
+++ src/sys/netinet6/in6_pcb.c Sun Aug 3 22:55:24 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: in6_pcb.c,v 1.126 2014/07/24 15:12:03 rtr Exp $ */
+/* $NetBSD: in6_pcb.c,v 1.127 2014/08/03 22:55:24 rmind Exp $ */
/* $KAME: in6_pcb.c,v 1.84 2001/02/08 18:02:08 itojun Exp $ */
/*
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.126 2014/07/24 15:12:03 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.127 2014/08/03 22:55:24 rmind Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@@ -599,24 +599,28 @@ in6_pcbdetach(struct in6pcb *in6p)
#if defined(IPSEC)
if (ipsec_enabled)
ipsec6_delete_pcbpolicy(in6p);
-#endif /* IPSEC */
- so->so_pcb = 0;
- if (in6p->in6p_options)
+#endif
+ so->so_pcb = NULL;
+
+ s = splnet();
+ in6_pcbstate(in6p, IN6P_ATTACHED);
+ LIST_REMOVE(&in6p->in6p_head, inph_lhash);
+ TAILQ_REMOVE(&in6p->in6p_table->inpt_queue, &in6p->in6p_head,
+ inph_queue);
+ splx(s);
+
+ if (in6p->in6p_options) {
m_freem(in6p->in6p_options);
+ }
if (in6p->in6p_outputopts != NULL) {
ip6_clearpktopts(in6p->in6p_outputopts, -1);
free(in6p->in6p_outputopts, M_IP6OPT);
}
rtcache_free(&in6p->in6p_route);
+ sofree(so); /* drops the socket's lock */
+
ip6_freemoptions(in6p->in6p_moptions);
- s = splnet();
- in6_pcbstate(in6p, IN6P_ATTACHED);
- LIST_REMOVE(&in6p->in6p_head, inph_lhash);
- TAILQ_REMOVE(&in6p->in6p_table->inpt_queue, &in6p->in6p_head,
- inph_queue);
pool_put(&in6pcb_pool, in6p);
- splx(s);
- sofree(so); /* drops the socket's lock */
mutex_enter(softnet_lock); /* reacquire it */
}