public inbox for linux-btrfs@vger.kernel.org
 help / color / mirror / Atom feed
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.

  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