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 */ }