|
|
Log in / Subscribe / Register

fs/pipe: unify the page pools into a single per-pipe pool

From:  Breno Leitao <leitao-AT-debian.org>
To:  Alexander Viro <viro-AT-zeniv.linux.org.uk>, Christian Brauner <brauner-AT-kernel.org>, oleg-AT-redhat.com, mjguzik-AT-gmail.com, josh-AT-joshtriplett.org, Jan Kara <jack-AT-suse.cz>, jlayton-AT-kernel.org
Subject:  [PATCH v2 0/4] fs/pipe: unify the page pools into a single per-pipe pool
Date:  Tue, 07 Jul 2026 08:04:57 -0700
Message-ID:  <20260707-b4-pipe-unification-v2-0-eb52bddeeefd@debian.org>
Cc:  axboe-AT-kernel.dk, shakeel.butt-AT-linux.dev, linux-fsdevel-AT-vger.kernel.org, linux-kernel-AT-vger.kernel.org, Breno Leitao <leitao-AT-debian.org>, kernel-team-AT-meta.com
Archive-link:  Article

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.

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@redhat.com/

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@debian.org>
---
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...

---
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@debian.org>




Copyright © 2026, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds