History

pipe: remove 'waiting_writers' merging logic

This code is ancient, and goes back to when we only had a single page for the pipe buffers. The exact history is hidden in the mists of time (ie "before git", and in fact predates the BK repository too). At that long-ago point in time, it actually helped to try to merge big back-and-forth pipe reads and writes, and not limit pipe reads to the single pipe buffer in length just because that was all we had at a time. However, since then we've expanded the pipe buffers to multiple pages, and this logic really doesn't seem to make sense. And a lot of it is somewhat questionable (ie "hmm, the user asked for a non-blocking read, but we see that there's a writer pending, so let's wait anyway to get the extra data that the writer will have"). But more importantly, it makes the "go to sleep" logic much less obvious, and considering the wakeup issues we've had, I want to make for less of those kinds of things.

Linus Torvalds committed 6 years ago

Commit a28c8b91 parent f467a6a3 files · +9 −33Browse files

Unified · Split

3 files
  1. fs/pipe.c +5 −14
  2. fs/splice.c +4 −17
  3. include/linux/pipe_fs_i.h +0 −2
fs/pipe.c+5−14
@@ -348,18 +348,11 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to) · 347 unmodified lines
348348
349349 if (!pipe->writers)
350350 break;
351− if (!pipe->waiting_writers) {
352− /* syscall merging: Usually we must not sleep
353− * if O_NONBLOCK is set, or if we got some data.
354− * But if a writer sleeps in kernel space, then
355− * we can wait for that data without violating POSIX.
356− */
357− if (ret)
358− break;
359− if (filp->f_flags & O_NONBLOCK) {
360− ret = -EAGAIN;
361− break;
362− }
351+ if (ret)
352+ break;
353+ if (filp->f_flags & O_NONBLOCK) {
354+ ret = -EAGAIN;
355+ break;
363356 }
364357 if (signal_pending(current)) {
365358 if (!ret)
@@ -540,9 +533,7 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from) · 174 unmodified lines
540533 wake_up_interruptible_sync_poll(&pipe->wait, EPOLLIN | EPOLLRDNORM);
541534 kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
542535 }
543− pipe->waiting_writers++;
544536 pipe_wait(pipe);
545− pipe->waiting_writers--;
546537
547538 was_empty = pipe_empty(head, pipe->tail);
548539 }
fs/splice.c+4−17
@@ -559,7 +559,7 @@ static int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_des · 558 unmodified lines
559559 if (!pipe->writers)
560560 return 0;
561561
562− if (!pipe->waiting_writers && sd->num_spliced)
562+ if (sd->num_spliced)
563563 return 0;
564564
565565 if (sd->flags & SPLICE_F_NONBLOCK)
@@ -1098,9 +1098,7 @@ static int wait_for_space(struct pipe_inode_info *pipe, unsigned flags) · 532 unmodified lines
10981098 return -EAGAIN;
10991099 if (signal_pending(current))
11001100 return -ERESTARTSYS;
1101− pipe->waiting_writers++;
11021101 pipe_wait(pipe);
1103− pipe->waiting_writers--;
11041102 }
11051103 }
11061104
@@ -1482,11 +1480,9 @@ static int ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags) · 375 unmodified lines
14821480 }
14831481 if (!pipe->writers)
14841482 break;
1485− if (!pipe->waiting_writers) {
1486− if (flags & SPLICE_F_NONBLOCK) {
1487− ret = -EAGAIN;
1488− break;
1489− }
1483+ if (flags & SPLICE_F_NONBLOCK) {
1484+ ret = -EAGAIN;
1485+ break;
14901486 }
14911487 pipe_wait(pipe);
14921488 }
@@ -1527,9 +1523,7 @@ static int opipe_prep(struct pipe_inode_info *pipe, unsigned int flags) · 34 unmodified lines
15271523 ret = -ERESTARTSYS;
15281524 break;
15291525 }
1530− pipe->waiting_writers++;
15311526 pipe_wait(pipe);
1532− pipe->waiting_writers--;
15331527 }
15341528
15351529 pipe_unlock(pipe);
@@ -1751,13 +1745,6 @@ static int link_pipe(struct pipe_inode_info *ipipe, · 215 unmodified lines
17511745 i_tail++;
17521746 } while (len);
17531747
1754− /*
1755− * return EAGAIN if we have the potential of some data in the
1756− * future, otherwise just return 0
1757− */
1758− if (!ret && ipipe->waiting_writers && (flags & SPLICE_F_NONBLOCK))
1759− ret = -EAGAIN;
1760−
17611748 pipe_unlock(ipipe);
17621749 pipe_unlock(opipe);
17631750
include/linux/pipe_fs_i.h+0−2
@@ -38,7 +38,6 @@ struct pipe_buffer { · 37 unmodified lines
3838 * @readers: number of current readers of this pipe
3939 * @writers: number of current writers of this pipe
4040 * @files: number of struct file referring this pipe (protected by ->i_lock)
41− * @waiting_writers: number of writers blocked waiting for room
4241 * @r_counter: reader counter
4342 * @w_counter: writer counter
4443 * @fasync_readers: reader side fasync
@@ -56,7 +55,6 @@ struct pipe_inode_info { · 11 unmodified lines
5655 unsigned int readers;
5756 unsigned int writers;
5857 unsigned int files;
59− unsigned int waiting_writers;
6058 unsigned int r_counter;
6159 unsigned int w_counter;
6260 struct page *tmp_page;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t