aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pipe.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-28 12:43:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-28 13:40:47 -0400
commita11e1d432b51f63ba698d044441284a661f01144 (patch)
tree9f3c5a10bf0d7f9a342d5fb39c0c35ea14170124 /fs/pipe.c
parentf57494321cbf5b1e7769b6135407d2995a369e28 (diff)
Revert changes to convert to ->poll_mask() and aio IOCB_CMD_POLL
The poll() changes were not well thought out, and completely unexplained. They also caused a huge performance regression, because "->poll()" was no longer a trivial file operation that just called down to the underlying file operations, but instead did at least two indirect calls. Indirect calls are sadly slow now with the Spectre mitigation, but the performance problem could at least be largely mitigated by changing the "->get_poll_head()" operation to just have a per-file-descriptor pointer to the poll head instead. That gets rid of one of the new indirections. But that doesn't fix the new complexity that is completely unwarranted for the regular case. The (undocumented) reason for the poll() changes was some alleged AIO poll race fixing, but we don't make the common case slower and more complex for some uncommon special case, so this all really needs way more explanations and most likely a fundamental redesign. [ This revert is a revert of about 30 different commits, not reverted individually because that would just be unnecessarily messy - Linus ] Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Christoph Hellwig <hch@lst.de> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/pipe.c')
-rw-r--r--fs/pipe.c22
1 files changed, 9 insertions, 13 deletions
diff --git a/fs/pipe.c b/fs/pipe.c
index bb0840e234f3..39d6f431da83 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -509,22 +509,19 @@ static long pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
509 } 509 }
510} 510}
511 511
512static struct wait_queue_head *
513pipe_get_poll_head(struct file *filp, __poll_t events)
514{
515 struct pipe_inode_info *pipe = filp->private_data;
516
517 return &pipe->wait;
518}
519
520/* No kernel lock held - fine */ 512/* No kernel lock held - fine */
521static __poll_t pipe_poll_mask(struct file *filp, __poll_t events) 513static __poll_t
514pipe_poll(struct file *filp, poll_table *wait)
522{ 515{
516 __poll_t mask;
523 struct pipe_inode_info *pipe = filp->private_data; 517 struct pipe_inode_info *pipe = filp->private_data;
524 int nrbufs = pipe->nrbufs; 518 int nrbufs;
525 __poll_t mask = 0; 519
520 poll_wait(filp, &pipe->wait, wait);
526 521
527 /* Reading only -- no need for acquiring the semaphore. */ 522 /* Reading only -- no need for acquiring the semaphore. */
523 nrbufs = pipe->nrbufs;
524 mask = 0;
528 if (filp->f_mode & FMODE_READ) { 525 if (filp->f_mode & FMODE_READ) {
529 mask = (nrbufs > 0) ? EPOLLIN | EPOLLRDNORM : 0; 526 mask = (nrbufs > 0) ? EPOLLIN | EPOLLRDNORM : 0;
530 if (!pipe->writers && filp->f_version != pipe->w_counter) 527 if (!pipe->writers && filp->f_version != pipe->w_counter)
@@ -1023,8 +1020,7 @@ const struct file_operations pipefifo_fops = {
1023 .llseek = no_llseek, 1020 .llseek = no_llseek,
1024 .read_iter = pipe_read, 1021 .read_iter = pipe_read,
1025 .write_iter = pipe_write, 1022 .write_iter = pipe_write,
1026 .get_poll_head = pipe_get_poll_head, 1023 .poll = pipe_poll,
1027 .poll_mask = pipe_poll_mask,
1028 .unlocked_ioctl = pipe_ioctl, 1024 .unlocked_ioctl = pipe_ioctl,
1029 .release = pipe_release, 1025 .release = pipe_release,
1030 .fasync = pipe_fasync, 1026 .fasync = pipe_fasync,