From 3bf371cf5dd7363c2732088f9e49d4a9813d0139 Mon Sep 17 00:00:00 2001 From: mpi Date: Sun, 10 Dec 2017 11:31:54 +0000 Subject: [PATCH] Move SB_SPLICE, SB_WAIT and SB_SEL to `sb_flags', serialized by solock(). SB_KNOTE remains the only bit set on `sb_flagsintr' as it is set/unset in contexts related to kqueue(2) where we'd like to avoid grabbing solock(). While here add some KERNEL_LOCK()/UNLOCK() dances around selwakeup() and csignal() to mark which remaining functions need to be addressed in the socket layer. ok visa@, bluhm@ --- sys/kern/sys_socket.c | 6 +++--- sys/kern/uipc_socket.c | 31 ++++++++++++++++--------------- sys/kern/uipc_socket2.c | 21 +++++++++++---------- sys/miscfs/fifofs/fifo_vnops.c | 15 +++++++++------ 4 files changed, 39 insertions(+), 34 deletions(-) diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c index 4b1b826b349..e070acce938 100644 --- a/sys/kern/sys_socket.c +++ b/sys/kern/sys_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_socket.c,v 1.34 2017/11/14 16:01:55 tb Exp $ */ +/* $OpenBSD: sys_socket.c,v 1.35 2017/12/10 11:31:54 mpi Exp $ */ /* $NetBSD: sys_socket.c,v 1.13 1995/08/12 23:59:09 mycroft Exp $ */ /* @@ -166,11 +166,11 @@ soo_poll(struct file *fp, int events, struct proc *p) if (revents == 0) { if (events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND)) { selrecord(p, &so->so_rcv.sb_sel); - so->so_rcv.sb_flagsintr |= SB_SEL; + so->so_rcv.sb_flags |= SB_SEL; } if (events & (POLLOUT | POLLWRNORM)) { selrecord(p, &so->so_snd.sb_sel); - so->so_snd.sb_flagsintr |= SB_SEL; + so->so_snd.sb_flags |= SB_SEL; } } sounlock(s); diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 99b2dc4331e..611cdb88165 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket.c,v 1.209 2017/11/23 13:45:46 mpi Exp $ */ +/* $OpenBSD: uipc_socket.c,v 1.210 2017/12/10 11:31:54 mpi Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* @@ -1054,9 +1054,9 @@ sorflush(struct socket *so) aso.so_rcv = *sb; memset(sb, 0, sizeof (*sb)); /* XXX - the memset stomps all over so_rcv */ - if (aso.so_rcv.sb_flags & SB_KNOTE) { + if (aso.so_rcv.sb_flagsintr & SB_KNOTE) { sb->sb_sel.si_note = aso.so_rcv.sb_sel.si_note; - sb->sb_flags = SB_KNOTE; + sb->sb_flagsintr = SB_KNOTE; } if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose) (*pr->pr_domain->dom_dispose)(aso.so_rcv.sb_mb); @@ -1178,8 +1178,8 @@ sosplice(struct socket *so, int fd, off_t max, struct timeval *tv) * we sleep, the socket buffers are not marked as spliced yet. */ if (somove(so, M_WAIT)) { - so->so_rcv.sb_flagsintr |= SB_SPLICE; - sosp->so_snd.sb_flagsintr |= SB_SPLICE; + so->so_rcv.sb_flags |= SB_SPLICE; + sosp->so_snd.sb_flags |= SB_SPLICE; } release: @@ -1196,8 +1196,8 @@ sounsplice(struct socket *so, struct socket *sosp, int wakeup) task_del(sosplice_taskq, &so->so_splicetask); timeout_del(&so->so_idleto); - sosp->so_snd.sb_flagsintr &= ~SB_SPLICE; - so->so_rcv.sb_flagsintr &= ~SB_SPLICE; + sosp->so_snd.sb_flags &= ~SB_SPLICE; + so->so_rcv.sb_flags &= ~SB_SPLICE; so->so_sp->ssp_socket = sosp->so_sp->ssp_soback = NULL; if (wakeup && soreadable(so)) sorwakeup(so); @@ -1210,7 +1210,7 @@ soidle(void *arg) int s; s = solock(so); - if (so->so_rcv.sb_flagsintr & SB_SPLICE) { + if (so->so_rcv.sb_flags & SB_SPLICE) { so->so_error = ETIMEDOUT; sounsplice(so, so->so_sp->ssp_socket, 1); } @@ -1224,7 +1224,7 @@ sotask(void *arg) int s; s = solock(so); - if (so->so_rcv.sb_flagsintr & SB_SPLICE) { + if (so->so_rcv.sb_flags & SB_SPLICE) { /* * We may not sleep here as sofree() and unsplice() may be * called from softnet interrupt context. This would remove @@ -1527,7 +1527,7 @@ sorwakeup(struct socket *so) soassertlocked(so); #ifdef SOCKET_SPLICE - if (so->so_rcv.sb_flagsintr & SB_SPLICE) { + if (so->so_rcv.sb_flags & SB_SPLICE) { /* * TCP has a sendbuffer that can handle multiple packets * at once. So queue the stream a bit to accumulate data. @@ -1555,7 +1555,7 @@ sowwakeup(struct socket *so) soassertlocked(so); #ifdef SOCKET_SPLICE - if (so->so_snd.sb_flagsintr & SB_SPLICE) + if (so->so_snd.sb_flags & SB_SPLICE) task_add(sosplice_taskq, &so->so_sp->ssp_soback->so_splicetask); #endif sowakeup(so, &so->so_snd); @@ -1871,9 +1871,10 @@ sogetopt(struct socket *so, int level, int optname, struct mbuf *m) void sohasoutofband(struct socket *so) { - KERNEL_ASSERT_LOCKED(); + KERNEL_LOCK(); csignal(so->so_pgid, SIGURG, so->so_siguid, so->so_sigeuid); selwakeup(&so->so_rcv.sb_sel); + KERNEL_UNLOCK(); } int @@ -1901,7 +1902,7 @@ soo_kqfilter(struct file *fp, struct knote *kn) } SLIST_INSERT_HEAD(&sb->sb_sel.si_note, kn, kn_selnext); - sb->sb_flags |= SB_KNOTE; + sb->sb_flagsintr |= SB_KNOTE; return (0); } @@ -1915,7 +1916,7 @@ filt_sordetach(struct knote *kn) SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext); if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note)) - so->so_rcv.sb_flags &= ~SB_KNOTE; + so->so_rcv.sb_flagsintr &= ~SB_KNOTE; } int @@ -1958,7 +1959,7 @@ filt_sowdetach(struct knote *kn) SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext); if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note)) - so->so_snd.sb_flags &= ~SB_KNOTE; + so->so_snd.sb_flagsintr &= ~SB_KNOTE; } int diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index 8c903859175..d1981343e8e 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket2.c,v 1.87 2017/11/23 13:42:53 mpi Exp $ */ +/* $OpenBSD: uipc_socket2.c,v 1.88 2017/12/10 11:31:54 mpi Exp $ */ /* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */ /* @@ -329,12 +329,12 @@ sosleep(struct socket *so, void *ident, int prio, const char *wmesg, int timo) int sbwait(struct socket *so, struct sockbuf *sb) { + int prio = (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH; + soassertlocked(so); - sb->sb_flagsintr |= SB_WAIT; - return (sosleep(so, &sb->sb_cc, - (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, "netio", - sb->sb_timeo)); + sb->sb_flags |= SB_WAIT; + return (sosleep(so, &sb->sb_cc, prio, "netio", sb->sb_timeo)); } int @@ -381,17 +381,18 @@ sbunlock(struct socket *so, struct sockbuf *sb) void sowakeup(struct socket *so, struct sockbuf *sb) { - KERNEL_ASSERT_LOCKED(); soassertlocked(so); - selwakeup(&sb->sb_sel); - sb->sb_flagsintr &= ~SB_SEL; - if (sb->sb_flagsintr & SB_WAIT) { - sb->sb_flagsintr &= ~SB_WAIT; + sb->sb_flags &= ~SB_SEL; + if (sb->sb_flags & SB_WAIT) { + sb->sb_flags &= ~SB_WAIT; wakeup(&sb->sb_cc); } + KERNEL_LOCK(); if (so->so_state & SS_ASYNC) csignal(so->so_pgid, SIGIO, so->so_siguid, so->so_sigeuid); + selwakeup(&sb->sb_sel); + KERNEL_UNLOCK(); } /* diff --git a/sys/miscfs/fifofs/fifo_vnops.c b/sys/miscfs/fifofs/fifo_vnops.c index 0f2077538a3..c2eb03a96c3 100644 --- a/sys/miscfs/fifofs/fifo_vnops.c +++ b/sys/miscfs/fifofs/fifo_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fifo_vnops.c,v 1.59 2017/11/04 14:13:53 mpi Exp $ */ +/* $OpenBSD: fifo_vnops.c,v 1.60 2017/12/10 11:31:54 mpi Exp $ */ /* $NetBSD: fifo_vnops.c,v 1.18 1996/03/16 23:52:42 christos Exp $ */ /* @@ -307,10 +307,12 @@ fifo_poll(void *v) struct socket *wso = ap->a_vp->v_fifoinfo->fi_writesock; int events = 0; int revents = 0; + int s; /* * FIFOs don't support out-of-band or high priority data. */ + s = solock(rso); if (ap->a_fflag & FREAD) events |= ap->a_events & (POLLIN | POLLRDNORM); if (ap->a_fflag & FWRITE) @@ -333,13 +335,14 @@ fifo_poll(void *v) events = POLLIN; if (events & (POLLIN | POLLRDNORM)) { selrecord(ap->a_p, &rso->so_rcv.sb_sel); - rso->so_rcv.sb_flagsintr |= SB_SEL; + rso->so_rcv.sb_flags |= SB_SEL; } if (events & (POLLOUT | POLLWRNORM)) { selrecord(ap->a_p, &wso->so_snd.sb_sel); - wso->so_snd.sb_flagsintr |= SB_SEL; + wso->so_snd.sb_flags |= SB_SEL; } } + sounlock(s); return (revents); } @@ -526,7 +529,7 @@ fifo_kqfilter(void *v) ap->a_kn->kn_hook = so; SLIST_INSERT_HEAD(&sb->sb_sel.si_note, ap->a_kn, kn_selnext); - sb->sb_flags |= SB_KNOTE; + sb->sb_flagsintr |= SB_KNOTE; return (0); } @@ -538,7 +541,7 @@ filt_fifordetach(struct knote *kn) SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext); if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note)) - so->so_rcv.sb_flags &= ~SB_KNOTE; + so->so_rcv.sb_flagsintr &= ~SB_KNOTE; } int @@ -570,7 +573,7 @@ filt_fifowdetach(struct knote *kn) SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext); if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note)) - so->so_snd.sb_flags &= ~SB_KNOTE; + so->so_snd.sb_flagsintr &= ~SB_KNOTE; } int -- 2.20.1