On Mon, Sep 26, 2016 at 01:24:54PM -0400, David Hill wrote: > On Mon, Sep 26, 2016 at 01:55:01PM +0100, Stuart Henderson wrote: > > Seen about a dozen times on a box doing ospfd + ospf6d (for internal > > routes), bgpd (for default route) + isakmpd, shortly after startup > > after updating: > > > > splassert: sorwakeup: want 5 have 4 > > Starting stack trace... > > splassert_check() at splassert_check+0x78 > > sorwakeup() at sorwakeup+0x27 > > timeout_run() at timeout_run+0x48 > > softclock() at softclock+0x14c > > softintr_dispatch() at softintr_dispatch+0x8b > > Xsoftclock() at Xsoftclock+0x1f > > --- interrupt --- > > end of kernel > > end trace frame: 0x51, count: 251 > > 0x8: > > End of stack trace. > > > > Perhaps this?
rt_senddesync() is a very good candidate to cause this stack trace. I would prefer to put the splsoftnet() also around sbappendaddr(). The goal is to protect all socket buffer functions with a lock. ok? bluhm Index: net/rtsock.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/net/rtsock.c,v retrieving revision 1.205 diff -u -p -r1.205 rtsock.c --- net/rtsock.c 17 Sep 2016 07:35:05 -0000 1.205 +++ net/rtsock.c 26 Sep 2016 18:18:33 -0000 @@ -302,28 +302,34 @@ rt_senddesync(void *data) struct rawcb *rp; struct routecb *rop; struct mbuf *desync_mbuf; + int s; rp = (struct rawcb *)data; rop = (struct routecb *)rp; /* If we are in a DESYNC state, try to send a RTM_DESYNC packet */ - if ((rop->flags & ROUTECB_FLAG_DESYNC) != 0) { - /* - * If we fail to alloc memory or if sbappendaddr() - * fails, re-add timeout and try again. - */ - desync_mbuf = rt_msg1(RTM_DESYNC, NULL); - if ((desync_mbuf != NULL) && - (sbappendaddr(&rp->rcb_socket->so_rcv, &route_src, - desync_mbuf, (struct mbuf *)NULL) != 0)) { + if ((rop->flags & ROUTECB_FLAG_DESYNC) == 0) + return; + + /* + * If we fail to alloc memory or if sbappendaddr() + * fails, re-add timeout and try again. + */ + desync_mbuf = rt_msg1(RTM_DESYNC, NULL); + if (desync_mbuf != NULL) { + s = splsoftnet(); + if (sbappendaddr(&rp->rcb_socket->so_rcv, &route_src, + desync_mbuf, NULL) != 0) { rop->flags &= ~ROUTECB_FLAG_DESYNC; sorwakeup(rp->rcb_socket); - } else { - m_freem(desync_mbuf); - /* Re-add timeout to try sending msg again */ - timeout_add(&rop->timeout, ROUTE_DESYNC_RESEND_TIMEOUT); + splx(s); + return; } + splx(s); + m_freem(desync_mbuf); } + /* Re-add timeout to try sending msg again */ + timeout_add(&rop->timeout, ROUTE_DESYNC_RESEND_TIMEOUT); } void