summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authoranton <anton@cvs.openbsd.org>2019-12-27 09:29:51 +0000
committeranton <anton@cvs.openbsd.org>2019-12-27 09:29:51 +0000
commit488b623c2fa8b7213b0e7b65c4fcfa5f8fb961e4 (patch)
treedb37164bab68fdfe05de00430a63a9a274555c06 /sys/kern
parent8030c5033a6b2a9edaafb1cda587f8adaa2dbedc (diff)
Remove the kernel lock in pipe read and write routines since everything
is serialized by the pipe_lock by now. The kernel lock is however still needed when interacting with kqueue in order to prevent a race and when potentially issuing SIGIO signals. ok visa@
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/sys_pipe.c19
1 files changed, 7 insertions, 12 deletions
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index 9553334346d..2229aee7cf7 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_pipe.c,v 1.104 2019/12/25 09:46:09 anton Exp $ */
+/* $OpenBSD: sys_pipe.c,v 1.105 2019/12/27 09:29:50 anton Exp $ */
/*
* Copyright (c) 1996 John S. Dyson
@@ -352,14 +352,20 @@ pipeselwakeup(struct pipe *cpipe)
{
rw_assert_wrlock(&pipe_lock);
+ KERNEL_LOCK();
+
+ /* Kernel lock needed in order to prevent race with kevent. */
if (cpipe->pipe_state & PIPE_SEL) {
cpipe->pipe_state &= ~PIPE_SEL;
selwakeup(&cpipe->pipe_sel);
} else
KNOTE(&cpipe->pipe_sel.si_note, NOTE_SUBMIT);
+ /* Kernel lock needed since pgsigio() calls ptsignal(). */
if (cpipe->pipe_state & PIPE_ASYNC)
pgsigio(&cpipe->pipe_sigio, SIGIO, 0);
+
+ KERNEL_UNLOCK();
}
int
@@ -369,8 +375,6 @@ pipe_read(struct file *fp, struct uio *uio, int fflags)
int error;
size_t size, nread = 0;
- KERNEL_LOCK();
-
rw_enter_write(&pipe_lock);
++rpipe->pipe_busy;
error = pipelock(rpipe);
@@ -378,7 +382,6 @@ pipe_read(struct file *fp, struct uio *uio, int fflags)
--rpipe->pipe_busy;
pipe_rundown(rpipe);
rw_exit_write(&pipe_lock);
- KERNEL_UNLOCK();
return (error);
}
@@ -462,7 +465,6 @@ unlocked_error:
pipeselwakeup(rpipe);
rw_exit_write(&pipe_lock);
- KERNEL_UNLOCK();
return (error);
}
@@ -473,8 +475,6 @@ pipe_write(struct file *fp, struct uio *uio, int fflags)
size_t orig_resid;
struct pipe *wpipe, *rpipe;
- KERNEL_LOCK();
-
rpipe = fp->f_data;
rw_enter_write(&pipe_lock);
@@ -483,7 +483,6 @@ pipe_write(struct file *fp, struct uio *uio, int fflags)
/* Detect loss of pipe read side, issue SIGPIPE if lost. */
if (wpipe == NULL) {
rw_exit_write(&pipe_lock);
- KERNEL_UNLOCK();
return (EPIPE);
}
@@ -493,7 +492,6 @@ pipe_write(struct file *fp, struct uio *uio, int fflags)
--wpipe->pipe_busy;
pipe_rundown(wpipe);
rw_exit_write(&pipe_lock);
- KERNEL_UNLOCK();
return (error);
}
@@ -660,7 +658,6 @@ unlocked_error:
pipeselwakeup(wpipe);
rw_exit_write(&pipe_lock);
- KERNEL_UNLOCK();
return (error);
}
@@ -790,9 +787,7 @@ pipe_close(struct file *fp, struct proc *p)
fp->f_ops = NULL;
fp->f_data = NULL;
- KERNEL_LOCK();
pipe_destroy(cpipe);
- KERNEL_UNLOCK();
return (0);
}