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