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



Reply via email to