summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/uipc_socket.c51
-rw-r--r--sys/kern/uipc_socket2.c22
2 files changed, 30 insertions, 43 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 0066d6f1923..7aa6aa595a4 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_socket.c,v 1.191 2017/07/03 08:29:24 mpi Exp $ */
+/* $OpenBSD: uipc_socket.c,v 1.192 2017/07/04 12:58:32 mpi Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
/*
@@ -418,14 +418,14 @@ sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top,
(sizeof(struct fdpass) / sizeof(int)));
}
-#define snderr(errno) { error = errno; sounlock(s); goto release; }
+#define snderr(errno) { error = errno; goto release; }
+ s = solock(so);
restart:
- if ((error = sblock(&so->so_snd, SBLOCKWAIT(flags), NULL)) != 0)
+ if ((error = sblock(so, &so->so_snd, SBLOCKWAIT(flags))) != 0)
goto out;
so->so_state |= SS_ISSENDING;
do {
- s = solock(so);
if (so->so_state & SS_CANTSENDMORE)
snderr(EPIPE);
if (so->so_error) {
@@ -455,12 +455,10 @@ restart:
sbunlock(&so->so_snd);
error = sbwait(so, &so->so_snd);
so->so_state &= ~SS_ISSENDING;
- sounlock(s);
if (error)
goto out;
goto restart;
}
- sounlock(s);
space -= clen;
do {
if (uio == NULL) {
@@ -471,8 +469,9 @@ restart:
if (flags & MSG_EOR)
top->m_flags |= M_EOR;
} else {
- error = m_getuio(&top, atomic,
- space, uio);
+ sounlock(s);
+ error = m_getuio(&top, atomic, space, uio);
+ s = solock(so);
if (error)
goto release;
space -= top->m_pkthdr.len;
@@ -480,7 +479,6 @@ restart:
if (flags & MSG_EOR)
top->m_flags |= M_EOR;
}
- s = solock(so);
if (resid == 0)
so->so_state &= ~SS_ISSENDING;
if (top && so->so_options & SO_ZEROIZE)
@@ -488,7 +486,6 @@ restart:
error = (*so->so_proto->pr_usrreq)(so,
(flags & MSG_OOB) ? PRU_SENDOOB : PRU_SEND,
top, addr, control, curproc);
- sounlock(s);
clen = 0;
control = NULL;
top = NULL;
@@ -501,6 +498,7 @@ release:
so->so_state &= ~SS_ISSENDING;
sbunlock(&so->so_snd);
out:
+ sounlock(s);
m_freem(top);
m_freem(control);
return (error);
@@ -670,9 +668,11 @@ bad:
*mp = NULL;
restart:
- if ((error = sblock(&so->so_rcv, SBLOCKWAIT(flags), NULL)) != 0)
- return (error);
s = solock(so);
+ if ((error = sblock(so, &so->so_rcv, SBLOCKWAIT(flags))) != 0) {
+ sounlock(s);
+ return (error);
+ }
m = so->so_rcv.sb_mb;
#ifdef SOCKET_SPLICE
@@ -1040,13 +1040,10 @@ sorflush(struct socket *so)
{
struct sockbuf *sb = &so->so_rcv;
struct protosw *pr = so->so_proto;
- sa_family_t af = pr->pr_domain->dom_family;
struct socket aso;
sb->sb_flags |= SB_NOINTR;
- sblock(sb, M_WAITOK,
- (af != PF_LOCAL && af != PF_ROUTE && af != PF_KEY) ?
- &netlock : NULL);
+ sblock(so, sb, M_WAITOK);
socantrcvmore(so);
sbunlock(sb);
aso.so_proto = pr;
@@ -1094,15 +1091,17 @@ sosplice(struct socket *so, int fd, off_t max, struct timeval *tv)
/* If no fd is given, unsplice by removing existing link. */
if (fd < 0) {
+ s = solock(so);
/* Lock receive buffer. */
- if ((error = sblock(&so->so_rcv,
- (so->so_state & SS_NBIO) ? M_NOWAIT : M_WAITOK, NULL)) != 0)
+ if ((error = sblock(so, &so->so_rcv,
+ (so->so_state & SS_NBIO) ? M_NOWAIT : M_WAITOK)) != 0) {
+ sounlock(s);
return (error);
- s = solock(so);
+ }
if (so->so_sp->ssp_socket)
sounsplice(so, so->so_sp->ssp_socket, 1);
- sounlock(s);
sbunlock(&so->so_rcv);
+ sounlock(s);
return (0);
}
@@ -1119,18 +1118,20 @@ sosplice(struct socket *so, int fd, off_t max, struct timeval *tv)
if (sosp->so_sp == NULL)
sosp->so_sp = pool_get(&sosplice_pool, PR_WAITOK | PR_ZERO);
+ s = solock(so);
/* Lock both receive and send buffer. */
- if ((error = sblock(&so->so_rcv,
- (so->so_state & SS_NBIO) ? M_NOWAIT : M_WAITOK, NULL)) != 0) {
+ if ((error = sblock(so, &so->so_rcv,
+ (so->so_state & SS_NBIO) ? M_NOWAIT : M_WAITOK)) != 0) {
+ sounlock(s);
FRELE(fp, curproc);
return (error);
}
- if ((error = sblock(&sosp->so_snd, M_WAITOK, NULL)) != 0) {
+ if ((error = sblock(so, &sosp->so_snd, M_WAITOK)) != 0) {
sbunlock(&so->so_rcv);
+ sounlock(s);
FRELE(fp, curproc);
return (error);
}
- s = solock(so);
if (so->so_sp->ssp_socket || sosp->so_sp->ssp_soback) {
error = EBUSY;
@@ -1171,9 +1172,9 @@ sosplice(struct socket *so, int fd, off_t max, struct timeval *tv)
}
release:
- sounlock(s);
sbunlock(&sosp->so_snd);
sbunlock(&so->so_rcv);
+ sounlock(s);
FRELE(fp, curproc);
return (error);
}
diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c
index 15f1a7fd50f..27e47adf8ed 100644
--- a/sys/kern/uipc_socket2.c
+++ b/sys/kern/uipc_socket2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_socket2.c,v 1.82 2017/07/04 12:52:48 mpi Exp $ */
+/* $OpenBSD: uipc_socket2.c,v 1.83 2017/07/04 12:58:32 mpi Exp $ */
/* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */
/*
@@ -54,8 +54,6 @@ u_long sb_max = SB_MAX; /* patchable */
extern struct pool mclpools[];
extern struct pool mbpool;
-int sbsleep(struct sockbuf *, struct rwlock *);
-
/*
* Procedures to manipulate state flags of socket
* and do appropriate wakeups. Normal sequence from the
@@ -340,24 +338,12 @@ sbwait(struct socket *so, struct sockbuf *sb)
}
int
-sbsleep(struct sockbuf *sb, struct rwlock *lock)
+sblock(struct socket *so, struct sockbuf *sb, int wait)
{
int error, prio = (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH;
- if (lock != NULL)
- error = rwsleep(&sb->sb_flags, lock, prio, "netlck", 0);
- else
- error = tsleep(&sb->sb_flags, prio, "netlck", 0);
-
- return (error);
-}
-
-int
-sblock(struct sockbuf *sb, int wait, struct rwlock *lock)
-{
- int error;
-
KERNEL_ASSERT_LOCKED();
+ soassertlocked(so);
if ((sb->sb_flags & SB_LOCK) == 0) {
sb->sb_flags |= SB_LOCK;
@@ -368,7 +354,7 @@ sblock(struct sockbuf *sb, int wait, struct rwlock *lock)
while (sb->sb_flags & SB_LOCK) {
sb->sb_flags |= SB_WANT;
- error = sbsleep(sb, lock);
+ error = sosleep(so, &sb->sb_flags, prio, "netlck", 0);
if (error)
return (error);
}