From: David Sterba <dsterba@suse.cz>
To: Leo Martins <loemra.dev@gmail.com>
Cc: linux-btrfs@vger.kernel.org, kernel-team@fb.com
Subject: Re: [PATCH v4 2/3] btrfs: inhibit extent buffer writeback to prevent COW amplification
Date: Wed, 4 Mar 2026 05:22:50 +0100 [thread overview]
Message-ID: <20260304042249.GI8455@twin.jikos.cz> (raw)
In-Reply-To: <9e49ee6ee946e6cabb6b691693a955dbd201055c.1772097864.git.loemra.dev@gmail.com>
On Thu, Feb 26, 2026 at 01:51:07AM -0800, Leo Martins wrote:
> +/*
> + * btrfs_inhibit_eb_writeback - Inhibit writeback on buffer during transaction.
> + * @trans: transaction handle that will own the inhibitor
> + * @eb: extent buffer to inhibit writeback on
> + *
> + * Attempts to track this extent buffer in the transaction's inhibited set.
> + * If memory allocation fails, the buffer is simply not tracked. It may
> + * be written back and need re-COW, which is the original behavior.
> + * This is acceptable since inhibiting writeback is an optimization.
> + */
Minor thing, please check how functions should be commented, with the
parameter block.
https://btrfs.readthedocs.io/en/latest/dev/Development-notes.html#comments
> +/*
> + * btrfs_uninhibit_all_eb_writeback - Uninhibit writeback on all buffers.
> + * @trans: transaction handle to clean up
> + */
Same
> @@ -102,6 +102,8 @@ struct extent_buffer {
> /* >= 0 if eb belongs to a log tree, -1 otherwise */
> s8 log_index;
> u8 folio_shift;
> + /* Inhibits WB_SYNC_NONE writeback when > 0. */
> + atomic_t writeback_inhibitors;
The extent buffer is a sensitive data structure so the layout and size
is closely watched. You increase the size to 248 bytes which is still
under 256 so it fits fine to the slabs. What is not good is the
placement after the s8/u8 members as this leaves 2 byte hole before and
4 byte hole after it
@@ -5666,15 +5669,19 @@ struct extent_buffer {
/* XXX 2 bytes hole, try to pack */
- struct callback_head callback_head __attribute__((__aligned__(8))); /* 56 16 */
- /* --- cacheline 1 boundary (64 bytes) was 8 bytes ago --- */
- struct rw_semaphore lock __attribute__((__aligned__(8))); /* 72 40 */
- struct folio * folios[16]; /* 112 128 */
+ atomic_t writeback_inhibitors __attribute__((__aligned__(4))); /* 56 4 */
- /* size: 240, cachelines: 4, members: 14 */
- /* sum members: 238, holes: 1, sum holes: 2 */
- /* forced alignments: 4, forced holes: 1, sum forced holes: 2 */
- /* last cacheline: 48 bytes */
+ /* XXX 4 bytes hole, try to pack */
+
+ /* --- cacheline 1 boundary (64 bytes) --- */
+ struct callback_head callback_head __attribute__((__aligned__(8))); /* 64 16 */
+ struct rw_semaphore lock __attribute__((__aligned__(8))); /* 80 40 */
+ struct folio * folios[16]; /* 120 128 */
+
+ /* size: 248, cachelines: 4, members: 15 */
+ /* sum members: 242, holes: 2, sum holes: 6 */
+ /* forced alignments: 5, forced holes: 2, sum forced holes: 6 */
+ /* last cacheline: 56 bytes */
} __attribute__((__aligned__(8)));
We can't get rid of the holes unfortunately but at least placing it after
mirror_num the hole becomes contiguous:
@@ -5664,14 +5664,11 @@ struct extent_buffer {
spinlock_t refs_lock __attribute__((__aligned__(4))); /* 40 4 */
refcount_t refs __attribute__((__aligned__(4))); /* 44 4 */
int read_mirror; /* 48 4 */
- s8 log_index; /* 52 1 */
- u8 folio_shift; /* 53 1 */
+ atomic_t writeback_inhibitors __attribute__((__aligned__(4))); /* 52 4 */
+ s8 log_index; /* 56 1 */
+ u8 folio_shift; /* 57 1 */
- /* XXX 2 bytes hole, try to pack */
-
- atomic_t writeback_inhibitors __attribute__((__aligned__(4))); /* 56 4 */
-
- /* XXX 4 bytes hole, try to pack */
+ /* XXX 6 bytes hole, try to pack */
/* --- cacheline 1 boundary (64 bytes) --- */
struct callback_head callback_head __attribute__((__aligned__(8))); /* 64 16 */
@@ -5679,8 +5676,8 @@ struct extent_buffer {
struct folio * folios[16]; /* 120 128 */
/* size: 248, cachelines: 4, members: 15 */
- /* sum members: 242, holes: 2, sum holes: 6 */
- /* forced alignments: 5, forced holes: 2, sum forced holes: 6 */
+ /* sum members: 242, holes: 1, sum holes: 6 */
+ /* forced alignments: 5, forced holes: 1, sum forced holes: 6 */
/* last cacheline: 56 bytes */
} __attribute__((__aligned__(8)));
The placement to first cacheline cannot be avoided but the access pattern seems
consistent with the other members like refs or lock so this should be OK.
next prev parent reply other threads:[~2026-03-04 4:22 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-26 9:51 [PATCH v4 0/3] btrfs: fix COW amplification under memory pressure Leo Martins
2026-02-26 9:51 ` [PATCH v4 1/3] btrfs: skip COW for written extent buffers allocated in current transaction Leo Martins
2026-03-04 6:31 ` Qu Wenruo
2026-03-05 20:11 ` Boris Burkov
2026-02-26 9:51 ` [PATCH v4 2/3] btrfs: inhibit extent buffer writeback to prevent COW amplification Leo Martins
2026-02-26 15:23 ` Filipe Manana
2026-02-26 15:27 ` Sun YangKai
2026-03-04 4:22 ` David Sterba [this message]
2026-02-26 9:51 ` [PATCH v4 3/3] btrfs: add tracepoint for search slot restart tracking Leo Martins
2026-03-02 23:12 ` [PATCH v4 0/3] btrfs: fix COW amplification under memory pressure Boris Burkov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260304042249.GI8455@twin.jikos.cz \
--to=dsterba@suse.cz \
--cc=kernel-team@fb.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=loemra.dev@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox