On 29/12/16(Thu) 11:44, Martin Pieuchot wrote:
> On 29/12/16(Thu) 10:32, Dimitris Papastamos wrote:
> > Hi everyone,
> >
> > I am experiencing a kernel freeze with -current. The last kernel I
> > built that still had the issue was from the 27th of December. The
> > freeze takes hours to happen but usually occurs with browsing
> > activity. I try to manually break into ddb but that did not work.
> > The machine is stuck in X so I can't see what's printed on the console
> > buffer.
>
> Thanks for the report, this confirms what other people reported. I sent
> a diff to revert part of the NET_LOCK() work, that should be the cause
> for the freeze you're experiencing.
Here's the diff.
Index: kern/uipc_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.170
diff -u -p -r1.170 uipc_socket.c
--- kern/uipc_socket.c 20 Dec 2016 21:15:36 -0000 1.170
+++ kern/uipc_socket.c 29 Dec 2016 08:09:20 -0000
@@ -256,7 +256,7 @@ soclose(struct socket *so)
(so->so_state & SS_NBIO))
goto drop;
while (so->so_state & SS_ISCONNECTED) {
- error = rwsleep(&so->so_timeo, &netlock,
+ error = tsleep(&so->so_timeo,
PSOCK | PCATCH, "netcls",
so->so_linger * hz);
if (error)
@@ -615,7 +615,7 @@ sbsync(struct sockbuf *sb, struct mbuf *
* followed by an optional mbuf or mbufs containing ancillary data,
* and then zero or more mbufs of data.
* In order to avoid blocking network for the entire time here, we splx()
- * and release ``netlock'' while doing the actual copy to user space.
+ * and release NET_LOCK() while doing the actual copy to user space.
* Although the sockbuf is locked, new data may still be appended,
* and thus we must maintain consistency of the sockbuf during that time.
*
@@ -1039,7 +1039,7 @@ sorflush(struct socket *so)
struct sockbuf asb;
sb->sb_flags |= SB_NOINTR;
- (void) sblock(sb, M_WAITOK, &netlock);
+ (void) sblock(sb, M_WAITOK, NULL);
socantrcvmore(so);
sbunlock(sb);
asb = *sb;
@@ -1528,10 +1528,7 @@ sorwakeup(struct socket *so)
#endif
sowakeup(so, &so->so_rcv);
if (so->so_upcall) {
- /* XXXSMP breaks atomicity */
- rw_exit_write(&netlock);
(*(so->so_upcall))(so, so->so_upcallarg, M_DONTWAIT);
- rw_enter_write(&netlock);
}
}
Index: kern/uipc_socket2.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket2.c,v
retrieving revision 1.69
diff -u -p -r1.69 uipc_socket2.c
--- kern/uipc_socket2.c 19 Dec 2016 08:36:49 -0000 1.69
+++ kern/uipc_socket2.c 29 Dec 2016 08:08:42 -0000
@@ -276,7 +276,7 @@ sbwait(struct sockbuf *sb)
NET_ASSERT_LOCKED();
sb->sb_flagsintr |= SB_WAIT;
- return (rwsleep(&sb->sb_cc, &netlock,
+ return (tsleep(&sb->sb_cc,
(sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, "netio",
sb->sb_timeo));
}
Index: kern/uipc_syscalls.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.143
diff -u -p -r1.143 uipc_syscalls.c
--- kern/uipc_syscalls.c 19 Dec 2016 08:36:49 -0000 1.143
+++ kern/uipc_syscalls.c 29 Dec 2016 08:09:37 -0000
@@ -296,7 +296,7 @@ redo:
head->so_error = ECONNABORTED;
break;
}
- error = rwsleep(&head->so_timeo, &netlock, PSOCK | PCATCH,
+ error = tsleep(&head->so_timeo, PSOCK | PCATCH,
"netcon", 0);
if (error) {
goto bad;
@@ -436,7 +436,7 @@ sys_connect(struct proc *p, void *v, reg
}
NET_LOCK(s);
while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
- error = rwsleep(&so->so_timeo, &netlock, PSOCK | PCATCH,
+ error = tsleep(&so->so_timeo, PSOCK | PCATCH,
"netcon2", 0);
if (error) {
if (error == EINTR || error == ERESTART)
Index: kern/uipc_usrreq.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.108
diff -u -p -r1.108 uipc_usrreq.c
--- kern/uipc_usrreq.c 29 Dec 2016 07:35:09 -0000 1.108
+++ kern/uipc_usrreq.c 29 Dec 2016 08:10:04 -0000
@@ -131,10 +131,7 @@ uipc_usrreq(struct socket *so, int req,
break;
case PRU_BIND:
- /* XXXSMP breaks atomicity */
- rw_exit_write(&netlock);
error = unp_bind(unp, nam, p);
- rw_enter_write(&netlock);
break;
case PRU_LISTEN:
@@ -143,10 +140,7 @@ uipc_usrreq(struct socket *so, int req,
break;
case PRU_CONNECT:
- /* XXXSMP breaks atomicity */
- rw_exit_write(&netlock);
error = unp_connect(so, nam, p);
- rw_enter_write(&netlock);
break;
case PRU_CONNECT2:
@@ -214,10 +208,7 @@ uipc_usrreq(struct socket *so, int req,
error = EISCONN;
break;
}
- /* XXXSMP breaks atomicity */
- rw_exit_write(&netlock);
error = unp_connect(so, nam, p);
- rw_enter_write(&netlock);
if (error)
break;
} else {
@@ -493,8 +484,6 @@ unp_connect(struct socket *so, struct mb
struct unpcb *unp, *unp2, *unp3;
struct nameidata nd;
int error, s;
-
- rw_assert_unlocked(&netlock);
if (soun->sun_family != AF_UNIX)
return (EAFNOSUPPORT);
Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.468
diff -u -p -r1.468 if.c
--- net/if.c 21 Dec 2016 10:22:14 -0000 1.468
+++ net/if.c 29 Dec 2016 08:10:48 -0000
@@ -229,12 +229,6 @@ struct taskq *softnettq;
struct task if_input_task_locked = TASK_INITIALIZER(if_netisr, NULL);
-
-/*
- * Serialize socket operations to ensure no new sleeping points
- * are introduced in IP output paths.
- */
-struct rwlock netlock = RWLOCK_INITIALIZER("netlock");
/*
* Network interface utility routines.
*/
@@ -1072,10 +1066,7 @@ if_clone_create(const char *name, int rd
if (ifunit(name) != NULL)
return (EEXIST);
- /* XXXSMP breaks atomicity */
- rw_exit_write(&netlock);
ret = (*ifc->ifc_create)(ifc, unit);
- rw_enter_write(&netlock);
if (ret != 0 || (ifp = ifunit(name)) == NULL)
return (ret);
@@ -1117,10 +1108,7 @@ if_clone_destroy(const char *name)
splx(s);
}
- /* XXXSMP breaks atomicity */
- rw_exit_write(&netlock);
ret = (*ifc->ifc_destroy)(ifp);
- rw_enter_write(&netlock);
return (ret);
}
Index: net/if_pflow.c
===================================================================
RCS file: /cvs/src/sys/net/if_pflow.c,v
retrieving revision 1.64
diff -u -p -r1.64 if_pflow.c
--- net/if_pflow.c 21 Dec 2016 12:28:49 -0000 1.64
+++ net/if_pflow.c 29 Dec 2016 08:10:32 -0000
@@ -375,8 +375,6 @@ pflowioctl(struct ifnet *ifp, u_long cmd
}
}
- /* XXXSMP breaks atomicity */
- rw_exit_write(&netlock);
s = splnet();
pflow_flush(sc);
@@ -400,7 +398,6 @@ pflowioctl(struct ifnet *ifp, u_long cmd
sizeof(struct sockaddr_in),
M_DEVBUF, M_NOWAIT)) == NULL) {
splx(s);
- rw_enter_write(&netlock);
return (ENOMEM);
}
memcpy(sc->sc_flowdst, &pflowr.flowdst,
@@ -413,7 +410,6 @@ pflowioctl(struct ifnet *ifp, u_long cmd
sizeof(struct sockaddr_in6),
M_DEVBUF, M_NOWAIT)) == NULL) {
splx(s);
- rw_enter_write(&netlock);
return (ENOMEM);
}
memcpy(sc->sc_flowdst, &pflowr.flowdst,
@@ -453,7 +449,6 @@ pflowioctl(struct ifnet *ifp, u_long cmd
sizeof(struct sockaddr_in),
M_DEVBUF, M_NOWAIT)) == NULL) {
splx(s);
- rw_enter_write(&netlock);
return (ENOMEM);
}
memcpy(sc->sc_flowsrc, &pflowr.flowsrc,
@@ -466,7 +461,6 @@ pflowioctl(struct ifnet *ifp, u_long cmd
sizeof(struct sockaddr_in6),
M_DEVBUF, M_NOWAIT)) == NULL) {
splx(s);
- rw_enter_write(&netlock);
return (ENOMEM);
}
memcpy(sc->sc_flowsrc, &pflowr.flowsrc,
@@ -490,7 +484,6 @@ pflowioctl(struct ifnet *ifp, u_long cmd
&so, SOCK_DGRAM, 0);
if (error) {
splx(s);
- rw_enter_write(&netlock);
return (error);
}
if (pflowvalidsockaddr(sc->sc_flowsrc, 1)) {
@@ -505,7 +498,6 @@ pflowioctl(struct ifnet *ifp, u_long cmd
if (error) {
soclose(so);
splx(s);
- rw_enter_write(&netlock);
return (error);
}
}
@@ -538,7 +530,6 @@ pflowioctl(struct ifnet *ifp, u_long cmd
} else
ifp->if_flags &= ~IFF_RUNNING;
- rw_enter_write(&netlock);
break;
default:
Index: sys/systm.h
===================================================================
RCS file: /cvs/src/sys/sys/systm.h,v
retrieving revision 1.120
diff -u -p -r1.120 systm.h
--- sys/systm.h 19 Dec 2016 08:36:50 -0000 1.120
+++ sys/systm.h 29 Dec 2016 08:11:06 -0000
@@ -291,26 +291,18 @@ int uiomove(void *, size_t, struct uio *
#if defined(_KERNEL)
-#include <sys/rwlock.h>
-
-extern struct rwlock netlock;
-
#define NET_LOCK(s)
\
do { \
- rw_enter_write(&netlock); \
s = splsoftnet(); \
} while (0)
-#define NET_UNLOCK(s) \
+#define NET_UNLOCK(s)
\
do { \
splx(s); \
- rw_exit_write(&netlock); \
} while (0)
#define NET_ASSERT_LOCKED()
\
do { \
- if (rw_status(&netlock) != RW_WRITE) \
- splassert_fail(RW_WRITE, rw_status(&netlock), __func__);\
splsoftassert(IPL_SOFTNET); \
} while (0)