mirror of https://gitee.com/openkylin/linux.git
pipe: Advance tail pointer inside of wait spinlock in pipe_read()
Advance the pipe ring tail pointer inside of wait spinlock in pipe_read() so that the pipe can be written into with kernel notifications from contexts where pipe->mutex cannot be taken. Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
parent
6718b6f855
commit
b667b86734
|
@ -325,9 +325,14 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
|
||||||
|
|
||||||
if (!buf->len) {
|
if (!buf->len) {
|
||||||
pipe_buf_release(pipe, buf);
|
pipe_buf_release(pipe, buf);
|
||||||
|
spin_lock_irq(&pipe->wait.lock);
|
||||||
tail++;
|
tail++;
|
||||||
pipe->tail = tail;
|
pipe->tail = tail;
|
||||||
do_wakeup = 1;
|
do_wakeup = 0;
|
||||||
|
wake_up_interruptible_sync_poll_locked(
|
||||||
|
&pipe->wait, EPOLLOUT | EPOLLWRNORM);
|
||||||
|
spin_unlock_irq(&pipe->wait.lock);
|
||||||
|
kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
|
||||||
}
|
}
|
||||||
total_len -= chars;
|
total_len -= chars;
|
||||||
if (!total_len)
|
if (!total_len)
|
||||||
|
@ -359,6 +364,7 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
|
||||||
if (do_wakeup) {
|
if (do_wakeup) {
|
||||||
wake_up_interruptible_sync_poll(&pipe->wait, EPOLLOUT | EPOLLWRNORM);
|
wake_up_interruptible_sync_poll(&pipe->wait, EPOLLOUT | EPOLLWRNORM);
|
||||||
kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
|
kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
|
||||||
|
do_wakeup = 0;
|
||||||
}
|
}
|
||||||
pipe_wait(pipe);
|
pipe_wait(pipe);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue