On 20/12/16(Tue) 14:50, Alexander Bluhm wrote:
> Hi,
> 
> This crash happened during regress/sys/net/pflow on my regression test
> machine:
> 
> panic: rw_enter: netlock locking against myself
> Stopped at      Debugger+0x7:   leave
>    TID    PID    UID     PRFLAGS     PFLAGS  CPU  COMMAND
> *291613  71462      0         0x2          0    1  ifconfig
>  96946  67690      0     0x14000      0x200    0  zerothread
> Debugger(d09facbd,f57a49e8,d09d242c,f57a49e8,0) at Debugger+0x7
> panic(d09d242c,d09dc32f,f57a4a2c,d0504491,d0b7b1ec) at panic+0x71
> rw_enter(d0b56f38,1,f57a4a7c,d03be305,d0b55fe4) at rw_enter+0x1b4
> rw_enter_write(d0b56f38,2,2,10,0) at rw_enter_write+0x3c
> socreate(2,f57a4ce8,2,0,f57a4c04) at socreate+0x8f
> pflowioctl(d3e18800,802069fd,f57a4e74,0,d3e18800) at pflowioctl+0x5f3
> in_ioctl(802069fd,f57a4e74,d3e18800,1,d3e18800) at in_ioctl+0xf9
> ifioctl(d8bfce80,802069fd,f57a4e74,d8883b60,d87a9604) at ifioctl+0x168
> soo_ioctl(d884dbec,802069fd,f57a4e74,d8883b60,0) at soo_ioctl+0x21c
> sys_ioctl(d8883b60,f57a4f5c,f57a4f7c,0,f57a4fa8) at sys_ioctl+0x19f
> syscall() at syscall+0x250
> --- syscall (number -2110258080) ---
> 0x6:
> 
> NET_LOCK() is taken in soo_ioctl()
>         NET_LOCK(s);
>         error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 
>             (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)NULL, p));
>         NET_UNLOCK(s);
> and in socreate().

I don't have a solution for the moment and I want to be sure we know all
recursions before trying to write a fix.  So here's a diff that mark the
recursions with a XXXSMP like in the NFS case.

It is safe since we're still running everything under KERNEL_LOCK().

ok?

Index: net/if_pflow.c
===================================================================
RCS file: /cvs/src/sys/net/if_pflow.c,v
retrieving revision 1.62
diff -u -p -r1.62 if_pflow.c
--- net/if_pflow.c      4 Oct 2016 13:54:32 -0000       1.62
+++ net/if_pflow.c      20 Dec 2016 14:23:32 -0000
@@ -267,7 +267,10 @@ pflow_clone_destroy(struct ifnet *ifp)
        pflow_flush(sc);
        m_freem(sc->send_nam);
        if (sc->so != NULL) {
+               /* XXXSMP breaks atomicity */
+               rw_exit_write(&netlock);
                error = soclose(sc->so);
+               rw_enter_write(&netlock);
                sc->so = NULL;
        }
        if (sc->sc_flowdst != NULL)
@@ -375,6 +378,8 @@ pflowioctl(struct ifnet *ifp, u_long cmd
                        }
                }
 
+               /* XXXSMP breaks atomicity */
+               rw_exit_write(&netlock);
                s = splnet();
                pflow_flush(sc);
 
@@ -530,6 +535,7 @@ pflowioctl(struct ifnet *ifp, u_long cmd
                } else
                        ifp->if_flags &= ~IFF_RUNNING;
 
+               rw_enter_write(&netlock);
                break;
 
        default:

Reply via email to