On 10/02/17(Fri) 15:21, Alexander Bluhm wrote:
> [..]
> The 42 looks like an evil hack.
It is. I couldn't come to a better solution without refactoring the
pr_usrreq interface. I think that we still need to do it if we want
to unlock the syscalls. But I'd argue that having something that work
and allow people working on the forwarding path to make progress is
good, even if it is a hack. That said I'm open to better solutions.
Here's an updated diff that should fix all your previous comments and
those of millert@. I also change the SOCKET_LOCK() macros into real
functions to stop polluting <sys/systm.h>. It also find it easier to
follow the lock ordering between sockerbuffer and NET_LOCK().
Comments, oks?
Index: kern/sys_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/sys_socket.c,v
retrieving revision 1.28
diff -u -p -r1.28 sys_socket.c
--- kern/sys_socket.c 31 Jan 2017 12:16:20 -0000 1.28
+++ kern/sys_socket.c 13 Feb 2017 09:28:51 -0000
@@ -127,10 +127,10 @@ soo_ioctl(struct file *fp, u_long cmd, c
}
if (IOCGROUP(cmd) == 'r')
return (EOPNOTSUPP);
- NET_LOCK(s);
+ s = solock(so);
error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
(struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)NULL, p));
- NET_UNLOCK(s);
+ sounlock(s);
return (error);
}
@@ -187,10 +187,10 @@ soo_stat(struct file *fp, struct stat *u
ub->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
ub->st_uid = so->so_euid;
ub->st_gid = so->so_egid;
- NET_LOCK(s);
+ s = solock(so);
(void) ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
(struct mbuf *)ub, NULL, NULL, p));
- NET_UNLOCK(s);
+ sounlock(s);
return (0);
}
Index: kern/uipc_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.176
diff -u -p -r1.176 uipc_socket.c
--- kern/uipc_socket.c 1 Feb 2017 20:59:47 -0000 1.176
+++ kern/uipc_socket.c 13 Feb 2017 09:29:45 -0000
@@ -135,16 +135,16 @@ socreate(int dom, struct socket **aso, i
so->so_egid = p->p_ucred->cr_gid;
so->so_cpid = p->p_p->ps_pid;
so->so_proto = prp;
- NET_LOCK(s);
+ s = solock(so);
error = (*prp->pr_usrreq)(so, PRU_ATTACH, NULL,
(struct mbuf *)(long)proto, NULL, p);
if (error) {
so->so_state |= SS_NOFDREF;
sofree(so);
- NET_UNLOCK(s);
+ sounlock(s);
return (error);
}
- NET_UNLOCK(s);
+ sounlock(s);
*aso = so;
return (0);
}
@@ -154,9 +154,9 @@ sobind(struct socket *so, struct mbuf *n
{
int s, error;
- NET_LOCK(s);
+ s = solock(so);
error = (*so->so_proto->pr_usrreq)(so, PRU_BIND, NULL, nam, NULL, p);
- NET_UNLOCK(s);
+ sounlock(s);
return (error);
}
@@ -171,11 +171,11 @@ solisten(struct socket *so, int backlog)
if (isspliced(so) || issplicedback(so))
return (EOPNOTSUPP);
#endif /* SOCKET_SPLICE */
- NET_LOCK(s);
+ s = solock(so);
error = (*so->so_proto->pr_usrreq)(so, PRU_LISTEN, NULL, NULL, NULL,
curproc);
if (error) {
- NET_UNLOCK(s);
+ sounlock(s);
return (error);
}
if (TAILQ_FIRST(&so->so_q) == NULL)
@@ -185,14 +185,14 @@ solisten(struct socket *so, int backlog)
if (backlog < sominconn)
backlog = sominconn;
so->so_qlimit = backlog;
- NET_UNLOCK(s);
+ sounlock(s);
return (0);
}
void
sofree(struct socket *so)
{
- NET_ASSERT_LOCKED();
+ soassertlocked(so);
if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)
return;
@@ -232,7 +232,7 @@ soclose(struct socket *so)
struct socket *so2;
int s, error = 0;
- NET_LOCK(s);
+ s = solock(so);
if (so->so_options & SO_ACCEPTCONN) {
while ((so2 = TAILQ_FIRST(&so->so_q0)) != NULL) {
(void) soqremque(so2, 0);
@@ -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 = sosleep(so, &so->so_timeo,
PSOCK | PCATCH, "netcls",
so->so_linger * hz);
if (error)
@@ -276,14 +276,14 @@ discard:
panic("soclose NOFDREF: so %p, so_type %d", so, so->so_type);
so->so_state |= SS_NOFDREF;
sofree(so);
- NET_UNLOCK(s);
+ sounlock(s);
return (error);
}
int
soabort(struct socket *so)
{
- NET_ASSERT_LOCKED();
+ soassertlocked(so);
return (*so->so_proto->pr_usrreq)(so, PRU_ABORT, NULL, NULL, NULL,
curproc);
@@ -294,7 +294,7 @@ soaccept(struct socket *so, struct mbuf
{
int error = 0;
- NET_ASSERT_LOCKED();
+ soassertlocked(so);
if ((so->so_state & SS_NOFDREF) == 0)
panic("soaccept !NOFDREF: so %p, so_type %d", so, so->so_type);
@@ -315,7 +315,7 @@ soconnect(struct socket *so, struct mbuf
if (so->so_options & SO_ACCEPTCONN)
return (EOPNOTSUPP);
- NET_LOCK(s);
+ s = solock(so);
/*
* If protocol is connection-based, can only connect once.
* Otherwise, if connected, try to disconnect first.
@@ -329,7 +329,7 @@ soconnect(struct socket *so, struct mbuf
else
error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT,
NULL, nam, NULL, curproc);
- NET_UNLOCK(s);
+ sounlock(s);
return (error);
}
@@ -338,10 +338,10 @@ soconnect2(struct socket *so1, struct so
{
int s, error;
- NET_LOCK(s);
+ s = solock(so1);
error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2, NULL,
(struct mbuf *)so2, NULL, curproc);
- NET_UNLOCK(s);
+ sounlock(s);
return (error);
}
@@ -350,7 +350,7 @@ sodisconnect(struct socket *so)
{
int error;
- NET_ASSERT_LOCKED();
+ soassertlocked(so);
if ((so->so_state & SS_ISCONNECTED) == 0)
return (ENOTCONN);
@@ -418,14 +418,14 @@ sosend(struct socket *so, struct mbuf *a
(sizeof(struct fdpass) / sizeof(int)));
}
-#define snderr(errno) { error = errno; NET_UNLOCK(s); goto release; }
+#define snderr(errno) { error = errno; sounlock(s); goto release; }
restart:
if ((error = sblock(&so->so_snd, SBLOCKWAIT(flags), NULL)) != 0)
goto out;
so->so_state |= SS_ISSENDING;
do {
- NET_LOCK(s);
+ s = solock(so);
if (so->so_state & SS_CANTSENDMORE)
snderr(EPIPE);
if (so->so_error) {
@@ -453,14 +453,14 @@ restart:
if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT))
snderr(EWOULDBLOCK);
sbunlock(&so->so_snd);
- error = sbwait(&so->so_snd);
+ error = sbwait(so, &so->so_snd);
so->so_state &= ~SS_ISSENDING;
- NET_UNLOCK(s);
+ sounlock(s);
if (error)
goto out;
goto restart;
}
- NET_UNLOCK(s);
+ sounlock(s);
space -= clen;
do {
if (uio == NULL) {
@@ -480,13 +480,13 @@ restart:
if (flags & MSG_EOR)
top->m_flags |= M_EOR;
}
- NET_LOCK(s);
+ s = solock(so);
if (resid == 0)
so->so_state &= ~SS_ISSENDING;
error = (*so->so_proto->pr_usrreq)(so,
(flags & MSG_OOB) ? PRU_SENDOOB : PRU_SEND,
top, addr, control, curproc);
- NET_UNLOCK(s);
+ sounlock(s);
clen = 0;
control = NULL;
top = NULL;
@@ -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 release
- * the NET_LOCK() while doing the actual copy to user space.
+ * the solock() 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.
*
@@ -649,10 +649,10 @@ soreceive(struct socket *so, struct mbuf
flags |= MSG_DONTWAIT;
if (flags & MSG_OOB) {
m = m_get(M_WAIT, MT_DATA);
- NET_LOCK(s);
+ s = solock(so);
error = (*pr->pr_usrreq)(so, PRU_RCVOOB, m,
(struct mbuf *)(long)(flags & MSG_PEEK), NULL, curproc);
- NET_UNLOCK(s);
+ sounlock(s);
if (error)
goto bad;
do {
@@ -670,7 +670,7 @@ bad:
restart:
if ((error = sblock(&so->so_rcv, SBLOCKWAIT(flags), NULL)) != 0)
return (error);
- NET_LOCK(s);
+ s = solock(so);
m = so->so_rcv.sb_mb;
#ifdef SOCKET_SPLICE
@@ -734,8 +734,8 @@ restart:
SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 1");
SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 1");
sbunlock(&so->so_rcv);
- error = sbwait(&so->so_rcv);
- NET_UNLOCK(s);
+ error = sbwait(so, &so->so_rcv);
+ sounlock(s);
if (error)
return (error);
goto restart;
@@ -801,11 +801,9 @@ dontblock:
if (pr->pr_domain->dom_externalize &&
mtod(cm, struct cmsghdr *)->cmsg_type ==
SCM_RIGHTS) {
- NET_UNLOCK(s);
error =
(*pr->pr_domain->dom_externalize)
(cm, controllen, flags);
- NET_LOCK(s);
}
*controlp = cm;
} else {
@@ -873,9 +871,9 @@ dontblock:
SBLASTRECORDCHK(&so->so_rcv, "soreceive uiomove");
SBLASTMBUFCHK(&so->so_rcv, "soreceive uiomove");
resid = uio->uio_resid;
- NET_UNLOCK(s);
+ sounlock(s);
uio_error = uiomove(mtod(m, caddr_t) + moff, len, uio);
- NET_LOCK(s);
+ s = solock(so);
if (uio_error)
uio->uio_resid = resid - len;
} else
@@ -954,10 +952,10 @@ dontblock:
break;
SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 2");
SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 2");
- error = sbwait(&so->so_rcv);
+ error = sbwait(so, &so->so_rcv);
if (error) {
sbunlock(&so->so_rcv);
- NET_UNLOCK(s);
+ sounlock(s);
return (0);
}
if ((m = so->so_rcv.sb_mb) != NULL)
@@ -993,7 +991,7 @@ dontblock:
if (orig_resid == uio->uio_resid && orig_resid &&
(flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
sbunlock(&so->so_rcv);
- NET_UNLOCK(s);
+ sounlock(s);
goto restart;
}
@@ -1004,7 +1002,7 @@ dontblock:
*flagsp |= flags;
release:
sbunlock(&so->so_rcv);
- NET_UNLOCK(s);
+ sounlock(s);
return (error);
}
@@ -1014,7 +1012,7 @@ soshutdown(struct socket *so, int how)
struct protosw *pr = so->so_proto;
int s, error = 0;
- NET_LOCK(s);
+ s = solock(so);
switch (how) {
case SHUT_RD:
case SHUT_RDWR:
@@ -1030,7 +1028,7 @@ soshutdown(struct socket *so, int how)
error = EINVAL;
break;
}
- NET_UNLOCK(s);
+ sounlock(s);
return (error);
}
@@ -1043,7 +1041,8 @@ sorflush(struct socket *so)
struct sockbuf asb;
sb->sb_flags |= SB_NOINTR;
- (void) sblock(sb, M_WAITOK, &netlock);
+ sblock(sb, M_WAITOK,
+ (pr->pr_domain->dom_family != PF_LOCAL) ? &netlock : NULL);
socantrcvmore(so);
sbunlock(sb);
asb = *sb;
@@ -1094,10 +1093,10 @@ sosplice(struct socket *so, int fd, off_
if ((error = sblock(&so->so_rcv,
(so->so_state & SS_NBIO) ? M_NOWAIT : M_WAITOK, NULL)) != 0)
return (error);
- NET_LOCK(s);
+ s = solock(so);
if (so->so_sp->ssp_socket)
sounsplice(so, so->so_sp->ssp_socket, 1);
- NET_UNLOCK(s);
+ sounlock(s);
sbunlock(&so->so_rcv);
return (0);
}
@@ -1126,7 +1125,7 @@ sosplice(struct socket *so, int fd, off_
FRELE(fp, curproc);
return (error);
}
- NET_LOCK(s);
+ s = solock(so);
if (so->so_sp->ssp_socket || sosp->so_sp->ssp_soback) {
error = EBUSY;
@@ -1167,7 +1166,7 @@ sosplice(struct socket *so, int fd, off_
}
release:
- NET_UNLOCK(s);
+ sounlock(s);
sbunlock(&sosp->so_snd);
sbunlock(&so->so_rcv);
FRELE(fp, curproc);
@@ -1177,7 +1176,7 @@ sosplice(struct socket *so, int fd, off_
void
sounsplice(struct socket *so, struct socket *sosp, int wakeup)
{
- NET_ASSERT_LOCKED();
+ soassertlocked(so);
task_del(sosplice_taskq, &so->so_splicetask);
timeout_del(&so->so_idleto);
@@ -1194,12 +1193,12 @@ soidle(void *arg)
struct socket *so = arg;
int s;
- NET_LOCK(s);
+ s = solock(so);
if (so->so_rcv.sb_flagsintr & SB_SPLICE) {
so->so_error = ETIMEDOUT;
sounsplice(so, so->so_sp->ssp_socket, 1);
}
- NET_UNLOCK(s);
+ sounlock(s);
}
void
@@ -1208,7 +1207,7 @@ sotask(void *arg)
struct socket *so = arg;
int s;
- NET_LOCK(s);
+ s = solock(so);
if (so->so_rcv.sb_flagsintr & SB_SPLICE) {
/*
* We may not sleep here as sofree() and unsplice() may be
@@ -1217,7 +1216,7 @@ sotask(void *arg)
*/
somove(so, M_DONTWAIT);
}
- NET_UNLOCK(s);
+ sounlock(s);
/* Avoid user land starvation. */
yield();
@@ -1239,7 +1238,7 @@ somove(struct socket *so, int wait)
int error = 0, maxreached = 0;
short state;
- NET_ASSERT_LOCKED();
+ soassertlocked(so);
nextpkt:
if (so->so_error) {
@@ -1509,7 +1508,7 @@ somove(struct socket *so, int wait)
void
sorwakeup(struct socket *so)
{
- NET_ASSERT_LOCKED();
+ soassertlocked(so);
#ifdef SOCKET_SPLICE
if (so->so_rcv.sb_flagsintr & SB_SPLICE) {
@@ -1541,7 +1540,7 @@ sorwakeup(struct socket *so)
void
sowwakeup(struct socket *so)
{
- NET_ASSERT_LOCKED();
+ soassertlocked(so);
#ifdef SOCKET_SPLICE
if (so->so_snd.sb_flagsintr & SB_SPLICE)
@@ -1558,10 +1557,10 @@ sosetopt(struct socket *so, int level, i
if (level != SOL_SOCKET) {
if (so->so_proto && so->so_proto->pr_ctloutput) {
- NET_LOCK(s);
+ s = solock(so);
error = (*so->so_proto->pr_ctloutput)(PRCO_SETOPT, so,
level, optname, m0);
- NET_UNLOCK(s);
+ sounlock(s);
return (error);
}
error = ENOPROTOOPT;
@@ -1705,10 +1704,10 @@ sosetopt(struct socket *so, int level, i
struct domain *dom = so->so_proto->pr_domain;
level = dom->dom_protosw->pr_protocol;
- NET_LOCK(s);
+ s = solock(so);
error = (*so->so_proto->pr_ctloutput)
(PRCO_SETOPT, so, level, optname, m0);
- NET_UNLOCK(s);
+ sounlock(s);
return (error);
}
error = ENOPROTOOPT;
@@ -1737,10 +1736,10 @@ sosetopt(struct socket *so, int level, i
break;
}
if (error == 0 && so->so_proto && so->so_proto->pr_ctloutput) {
- NET_LOCK(s);
+ s = solock(so);
(*so->so_proto->pr_ctloutput)(PRCO_SETOPT, so,
level, optname, m0);
- NET_UNLOCK(s);
+ sounlock(s);
m = NULL; /* freed by protocol */
}
}
@@ -1761,10 +1760,10 @@ sogetopt(struct socket *so, int level, i
m = m_get(M_WAIT, MT_SOOPTS);
m->m_len = 0;
- NET_LOCK(s);
+ s = solock(so);
error = (*so->so_proto->pr_ctloutput)(PRCO_GETOPT, so,
level, optname, m);
- NET_UNLOCK(s);
+ sounlock(s);
if (error) {
m_free(m);
return (error);
@@ -1849,10 +1848,10 @@ sogetopt(struct socket *so, int level, i
struct domain *dom = so->so_proto->pr_domain;
level = dom->dom_protosw->pr_protocol;
- NET_LOCK(s);
+ s = solock(so);
error = (*so->so_proto->pr_ctloutput)
(PRCO_GETOPT, so, level, optname, m);
- NET_UNLOCK(s);
+ sounlock(s);
if (error) {
(void)m_free(m);
return (error);
Index: kern/uipc_socket2.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket2.c,v
retrieving revision 1.71
diff -u -p -r1.71 uipc_socket2.c
--- kern/uipc_socket2.c 25 Jan 2017 06:15:50 -0000 1.71
+++ kern/uipc_socket2.c 13 Feb 2017 09:29:25 -0000
@@ -38,6 +38,7 @@
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
+#include <sys/domain.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/signalvar.h>
@@ -147,7 +148,7 @@ sonewconn(struct socket *head, int conns
struct socket *so;
int soqueue = connstatus ? 1 : 0;
- NET_ASSERT_LOCKED();
+ soassertlocked(head);
if (mclpools[0].pr_nout > mclpools[0].pr_hardlimit * 95 / 100)
return (NULL);
@@ -267,16 +268,52 @@ socantrcvmore(struct socket *so)
sorwakeup(so);
}
+int
+solock(struct socket *so)
+{
+ int s;
+
+ if (so->so_proto->pr_domain->dom_family != PF_LOCAL)
+ NET_LOCK(s);
+ else
+ s = -42;
+
+ return (s);
+}
+
+void
+sounlock(int s)
+{
+ if (s != -42)
+ NET_UNLOCK(s);
+}
+
+void
+soassertlocked(struct socket *so)
+{
+ if (so->so_proto->pr_domain->dom_family != PF_LOCAL)
+ NET_ASSERT_LOCKED();
+}
+
+int
+sosleep(struct socket *so, void *ident, int prio, const char *wmesg, int timo)
+{
+ if (so->so_proto->pr_domain->dom_family != PF_LOCAL)
+ return rwsleep(ident, &netlock, prio, wmesg, timo);
+ else
+ return tsleep(ident, prio, wmesg, timo);
+}
+
/*
* Wait for data to arrive at/drain from a socket buffer.
*/
int
-sbwait(struct sockbuf *sb)
+sbwait(struct socket *so, struct sockbuf *sb)
{
- NET_ASSERT_LOCKED();
+ soassertlocked(so);
sb->sb_flagsintr |= SB_WAIT;
- return (rwsleep(&sb->sb_cc, &netlock,
+ return (sosleep(so, &sb->sb_cc,
(sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, "netio",
sb->sb_timeo));
}
@@ -338,7 +375,7 @@ sbunlock(struct sockbuf *sb)
void
sowakeup(struct socket *so, struct sockbuf *sb)
{
- NET_ASSERT_LOCKED();
+ soassertlocked(so);
selwakeup(&sb->sb_sel);
sb->sb_flagsintr &= ~SB_SEL;
Index: kern/uipc_syscalls.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.149
diff -u -p -r1.149 uipc_syscalls.c
--- kern/uipc_syscalls.c 11 Feb 2017 19:51:06 -0000 1.149
+++ kern/uipc_syscalls.c 13 Feb 2017 09:30:07 -0000
@@ -285,9 +285,9 @@ doaccept(struct proc *p, int sock, struc
}
nam = m_get(M_WAIT, MT_SONAME);
-
- NET_LOCK(s);
+
head = headfp->f_data;
+ s = solock(head);
if (isdnssocket(head) || (head->so_options & SO_ACCEPTCONN) == 0) {
error = EINVAL;
goto out;
@@ -304,8 +304,8 @@ doaccept(struct proc *p, int sock, struc
head->so_error = ECONNABORTED;
break;
}
- error = rwsleep(&head->so_timeo, &netlock, PSOCK | PCATCH,
- "netcon", 0);
+ error = sosleep(head, &head->so_timeo, PSOCK | PCATCH, "netcon",
+ 0);
if (error)
goto out;
}
@@ -342,7 +342,7 @@ doaccept(struct proc *p, int sock, struc
*retval = tmpfd;
}
out:
- NET_UNLOCK(s);
+ sounlock(s);
m_freem(nam);
if (error) {
fdplock(fdp);
@@ -406,9 +406,9 @@ sys_connect(struct proc *p, void *v, reg
m_freem(nam);
return (EINPROGRESS);
}
- NET_LOCK(s);
+ s = solock(so);
while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
- error = rwsleep(&so->so_timeo, &netlock, PSOCK | PCATCH,
+ error = sosleep(so, &so->so_timeo, PSOCK | PCATCH,
"netcon2", 0);
if (error) {
if (error == EINTR || error == ERESTART)
@@ -420,7 +420,7 @@ sys_connect(struct proc *p, void *v, reg
error = so->so_error;
so->so_error = 0;
}
- NET_UNLOCK(s);
+ sounlock(s);
bad:
if (!interrupted)
so->so_state &= ~SS_ISCONNECTING;
@@ -1044,9 +1044,9 @@ sys_getsockname(struct proc *p, void *v,
if (error)
goto bad;
m = m_getclr(M_WAIT, MT_SONAME);
- NET_LOCK(s);
+ s = solock(so);
error = (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0, p);
- NET_UNLOCK(s);
+ sounlock(s);
if (error)
goto bad;
error = copyaddrout(p, m, SCARG(uap, asa), len, SCARG(uap, alen));
@@ -1087,9 +1087,9 @@ sys_getpeername(struct proc *p, void *v,
if (error)
goto bad;
m = m_getclr(M_WAIT, MT_SONAME);
- NET_LOCK(s);
+ s = solock(so);
error = (*so->so_proto->pr_usrreq)(so, PRU_PEERADDR, 0, m, 0, p);
- NET_UNLOCK(s);
+ sounlock(s);
if (error)
goto bad;
error = copyaddrout(p, m, SCARG(uap, asa), len, SCARG(uap, alen));
Index: kern/uipc_usrreq.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.115
diff -u -p -r1.115 uipc_usrreq.c
--- kern/uipc_usrreq.c 9 Feb 2017 11:18:55 -0000 1.115
+++ kern/uipc_usrreq.c 13 Feb 2017 09:27:32 -0000
@@ -121,6 +121,9 @@ uipc_usrreq(struct socket *so, int req,
error = EINVAL;
goto release;
}
+
+ NET_ASSERT_UNLOCKED();
+
switch (req) {
case PRU_ATTACH:
@@ -132,17 +135,11 @@ uipc_usrreq(struct socket *so, int req,
break;
case PRU_DETACH:
- /* XXXSMP breaks atomicity */
- rw_exit_write(&netlock);
unp_detach(unp);
- rw_enter_write(&netlock);
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:
@@ -151,10 +148,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:
@@ -222,10 +216,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 {
@@ -398,8 +389,6 @@ unp_detach(struct unpcb *unp)
{
struct vnode *vp;
- NET_ASSERT_UNLOCKED();
-
LIST_REMOVE(unp, unp_link);
if (unp->unp_vnode) {
unp->unp_vnode->v_socket = NULL;
@@ -411,10 +400,7 @@ unp_detach(struct unpcb *unp)
unp_disconnect(unp);
while (!SLIST_EMPTY(&unp->unp_refs))
unp_drop(SLIST_FIRST(&unp->unp_refs), ECONNRESET);
- /* XXXSMP The assert is wrong */
- rw_enter_write(&netlock);
soisdisconnected(unp->unp_socket);
- rw_exit_write(&netlock);
unp->unp_socket->so_pcb = NULL;
m_freem(unp->unp_addr);
free(unp, M_PCB, sizeof *unp);
@@ -505,9 +491,7 @@ unp_connect(struct socket *so, struct mb
struct socket *so2, *so3;
struct unpcb *unp, *unp2, *unp3;
struct nameidata nd;
- int error, s;
-
- NET_ASSERT_UNLOCKED();
+ int error;
if (soun->sun_family != AF_UNIX)
return (EAFNOSUPPORT);
@@ -539,12 +523,11 @@ unp_connect(struct socket *so, struct mb
error = EPROTOTYPE;
goto bad;
}
- NET_LOCK(s);
if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
if ((so2->so_options & SO_ACCEPTCONN) == 0 ||
(so3 = sonewconn(so2, 0)) == 0) {
error = ECONNREFUSED;
- goto unlock;
+ goto bad;
}
unp = sotounpcb(so);
unp2 = sotounpcb(so2);
@@ -563,8 +546,6 @@ unp_connect(struct socket *so, struct mb
}
}
error = unp_connect2(so, so2);
-unlock:
- NET_UNLOCK(s);
bad:
vput(vp);
return (error);
Index: sys/socketvar.h
===================================================================
RCS file: /cvs/src/sys/sys/socketvar.h,v
retrieving revision 1.67
diff -u -p -r1.67 socketvar.h
--- sys/socketvar.h 19 Dec 2016 08:36:50 -0000 1.67
+++ sys/socketvar.h 13 Feb 2017 09:29:09 -0000
@@ -278,7 +278,7 @@ void sbrelease(struct sockbuf *sb);
int sbcheckreserve(u_long cnt, u_long defcnt);
int sbchecklowmem(void);
int sbreserve(struct sockbuf *sb, u_long cc);
-int sbwait(struct sockbuf *sb);
+int sbwait(struct socket *, struct sockbuf *sb);
int sb_lock(struct sockbuf *sb);
void soinit(void);
int soabort(struct socket *so);
@@ -317,6 +317,11 @@ void sowakeup(struct socket *so, struct
void sorwakeup(struct socket *);
void sowwakeup(struct socket *);
int sockargs(struct mbuf **, const void *, size_t, int);
+
+int sosleep(struct socket *, void *, int, const char *, int);
+int solock(struct socket *);
+void sounlock(int);
+void soassertlocked(struct socket *);
int sendit(struct proc *, int, struct msghdr *, int, register_t *);
int recvit(struct proc *, int, struct msghdr *, caddr_t,
Index: sys/systm.h
===================================================================
RCS file: /cvs/src/sys/sys/systm.h,v
retrieving revision 1.123
diff -u -p -r1.123 systm.h
--- sys/systm.h 25 Jan 2017 06:15:50 -0000 1.123
+++ sys/systm.h 13 Feb 2017 09:14:22 -0000
@@ -301,7 +301,7 @@ do {
\
s = splsoftnet(); \
} while (0)
-#define NET_UNLOCK(s) \
+#define NET_UNLOCK(s)
\
do { \
splx(s); \
rw_exit_write(&netlock); \