Re: [PATCH v2 0/4] fs/pipe: unify the page pools into a single per-pipe pool
From: Mateusz Guzik
Date: Tue Jul 07 2026 - 11:41:13 EST
On Tue, Jul 7, 2026 at 5:05 PM Breno Leitao <leitao@xxxxxxxxxx> wrote:
>
> TL;DR: This simplifies the pipe code, unify the page pools, reduce the
> code by 9 lines (not counting comments), and no regressions are seen in
> terms of performance.
>
This adds an additional acquire + release cycle on the mutex for every
write which preallocates, so I don't see how that's supposed to *not*
slow things down in some capacity.
I have a trivial benchmark for pipe throughput, usable with
will-it-scale (e.g., plop into tests/pipen.c):
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
#define READ 0
#define WRITE 1
char *testcase_description = "pipe read/write";
int fd[2];
void testcase_prepare(unsigned long nr_tasks)
{
if (nr_tasks < 2)
err(1, "bad worker count");
assert(pipe(fd) == 0);
}
void testcase(unsigned long long *iterations, unsigned long nr)
{
char buf[1024 * 128] __attribute__((aligned(64)));
int ret;
int size = atoi(getenv("PIPEN_SIZE"));
if (nr == 0) {
for (;;) {
ret = write(fd[WRITE], buf, size);
if (ret >= 0)
(*iterations) += ret;
else
break;
}
} else {
do {
ret = read(fd[READ], buf, size);
} while (ret >= 0);
}
err(1, "bailing ret %d");
}
Then for example: PIPEN_SIZE=32678 ./pipen_processes -t 2
This gives one writer and one reader, both on separate CPUs.
With this size of write I'm seeing a 7% drop in throughput with the
patchset when benchmarking on Sapphire Rapids.
> Summary:
> =======
>
> I've spent some time converging tmp_page[] and the on-stack
> anon_pipe_prealloc pool of pages into a single per-pipe pool, as
> discussed previously in a few places, most recently at:
>
> https://lore.kernel.org/all/ajLA_zxsYyKISkwp@xxxxxxxxxx/
>
> Problem:
> ========
>
> 1) We have two types of page caches in the pipe mechanism today
> * tmp_page[]
> * anon_pipe_prealloc
>
> 2) they operate in different ways:
> * tmp_page[] is protected by the pipe lock
> * per-pipe, persistent, 2 pages
> * anon_pipe_prealloc is an on-stack pool, not lock protected
> * burst, up to 8 pages
>
> Proposal/Design:
> ================
>
> 1) Keep the same page budget as today
> a) up to two per-pipe persistent pages
> b) burst of up to 8 pages
>
> 2) no pages are allocated unless necessary
> * Pages are _ONLY_ allocated based on the length of the write,
> minus the pages already available in the pool.
> * No page is allocated but left unused
>
> 3) keep allocation and freeing outside of the lock
> * only the assignment of pages stays lock-protected
> * Currently, tmp_page[] pages are allocated in the lock, so
> this patch will improve it (thus the performance numbers)
>
> How:
> ====
>
> 1) replace tmp_page[] with anon_pipe_prealloc in pipe_inode_info
> 2) at write (anon_pipe_write), allocate the pages outside the lock in a helper
> called anon_pipe_prefill()
> a) the assignment into the pool must be lock protected
> * anon_pipe_prefill() does it
> b) anon_pipe_prefill() can populate up to PIPE_PREALLOC_MAX pages in the
> pool
> 3) once anon_pipe_write is done, the pool is trimmed back to at most
> PIPE_PREALLOC_KEEP (2) pages by anon_pipe_trim_pool()
>
> Future:
> =======
>
> Once this lands, we could keep all allocated pages in the pool and rely
> on a shrinker to trim it under memory pressure.
>
> Signed-off-by: Breno Leitao <leitao@xxxxxxxxxx>
> ---
> Changes in v2:
> - User READ_ONCE to read prealloc.count
> - Trim the pool at the reader side
> - Link to v1: https://lore.kernel.org/r/20260626-b4-pipe-unification-v1-0-d23fa6b1ee27@xxxxxxxxxx
>
> ---
> Breno Leitao (4):
> fs/pipe: move the prealloc pool to per-pipe infrastructure
> fs/pipe: add per-pipe pool push, prefill and trim helpers
> fs/pipe: switch the read and write paths to the per-pipe pool
> fs/pipe: remove the old on-stack prealloc helpers and tmp_page[2]
>
> fs/pipe.c | 169 ++++++++++++++++++++--------------------------
> include/linux/pipe_fs_i.h | 21 +++++-
> 2 files changed, 94 insertions(+), 96 deletions(-)
> ---
> base-commit: 4e5dfb7c84012007c3c7061126491bbc92d71bf1
> change-id: 20260625-b4-pipe-unification-aba7b8525de7
>
> Best regards,
> --
> Breno Leitao <leitao@xxxxxxxxxx>
>