Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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.

Cc: David Howells <dhowells@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

+9 -33
+5 -14
fs/pipe.c
··· 348 348 349 349 if (!pipe->writers) 350 350 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; 363 356 } 364 357 if (signal_pending(current)) { 365 358 if (!ret) ··· 533 540 wake_up_interruptible_sync_poll(&pipe->wait, EPOLLIN | EPOLLRDNORM); 534 541 kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); 535 542 } 536 - pipe->waiting_writers++; 537 543 pipe_wait(pipe); 538 - pipe->waiting_writers--; 539 544 540 545 was_empty = pipe_empty(head, pipe->tail); 541 546 }
+4 -17
fs/splice.c
··· 559 559 if (!pipe->writers) 560 560 return 0; 561 561 562 - if (!pipe->waiting_writers && sd->num_spliced) 562 + if (sd->num_spliced) 563 563 return 0; 564 564 565 565 if (sd->flags & SPLICE_F_NONBLOCK) ··· 1098 1098 return -EAGAIN; 1099 1099 if (signal_pending(current)) 1100 1100 return -ERESTARTSYS; 1101 - pipe->waiting_writers++; 1102 1101 pipe_wait(pipe); 1103 - pipe->waiting_writers--; 1104 1102 } 1105 1103 } 1106 1104 ··· 1480 1482 } 1481 1483 if (!pipe->writers) 1482 1484 break; 1483 - if (!pipe->waiting_writers) { 1484 - if (flags & SPLICE_F_NONBLOCK) { 1485 - ret = -EAGAIN; 1486 - break; 1487 - } 1485 + if (flags & SPLICE_F_NONBLOCK) { 1486 + ret = -EAGAIN; 1487 + break; 1488 1488 } 1489 1489 pipe_wait(pipe); 1490 1490 } ··· 1523 1527 ret = -ERESTARTSYS; 1524 1528 break; 1525 1529 } 1526 - pipe->waiting_writers++; 1527 1530 pipe_wait(pipe); 1528 - pipe->waiting_writers--; 1529 1531 } 1530 1532 1531 1533 pipe_unlock(pipe); ··· 1744 1750 opipe->head = o_head; 1745 1751 i_tail++; 1746 1752 } while (len); 1747 - 1748 - /* 1749 - * return EAGAIN if we have the potential of some data in the 1750 - * future, otherwise just return 0 1751 - */ 1752 - if (!ret && ipipe->waiting_writers && (flags & SPLICE_F_NONBLOCK)) 1753 - ret = -EAGAIN; 1754 1753 1755 1754 pipe_unlock(ipipe); 1756 1755 pipe_unlock(opipe);
-2
include/linux/pipe_fs_i.h
··· 38 38 * @readers: number of current readers of this pipe 39 39 * @writers: number of current writers of this pipe 40 40 * @files: number of struct file referring this pipe (protected by ->i_lock) 41 - * @waiting_writers: number of writers blocked waiting for room 42 41 * @r_counter: reader counter 43 42 * @w_counter: writer counter 44 43 * @fasync_readers: reader side fasync ··· 55 56 unsigned int readers; 56 57 unsigned int writers; 57 58 unsigned int files; 58 - unsigned int waiting_writers; 59 59 unsigned int r_counter; 60 60 unsigned int w_counter; 61 61 struct page *tmp_page;