All of lore.kernel.org
 help / color / mirror / Atom feed
From: Leo Martins <loemra.dev@gmail.com>
To: Filipe Manana <fdmanana@kernel.org>
Cc: linux-btrfs@vger.kernel.org, kernel-team@fb.com
Subject: Re: [PATCH v2 3/3] btrfs: add tracepoint for COW amplification tracking
Date: Tue, 17 Feb 2026 14:06:35 -0800	[thread overview]
Message-ID: <20260217220637.820818-1-loemra.dev@gmail.com> (raw)
In-Reply-To: <CAL3q7H5X2JmkDX7qXxbmaHQCCtFt8f4niqhiKxERfPZyL2Cwcg@mail.gmail.com>

On Mon, 16 Feb 2026 12:40:04 +0000 Filipe Manana <fdmanana@kernel.org> wrote:

> On Fri, Feb 13, 2026 at 8:37 PM Leo Martins <loemra.dev@gmail.com> wrote:
> >
> > Add a btrfs_search_slot_stats tracepoint to btrfs_search_slot() for
> > measuring COW amplification.
> >
> > The tracepoint fires when a search with at least one COW completes,
> > recording the root, total cow_count, restart_count, and return value.
> > cow_count and restart_count per search_slot call are useful metrics
> > for tracking COW amplification.
> >
> > Signed-off-by: Leo Martins <loemra.dev@gmail.com>
> > ---
> >  fs/btrfs/ctree.c             | 15 +++++++++++++--
> >  include/trace/events/btrfs.h | 26 ++++++++++++++++++++++++++
> >  2 files changed, 39 insertions(+), 2 deletions(-)
> >
> > diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
> > index 55187ba59cc0..1971d7bb5f60 100644
> > --- a/fs/btrfs/ctree.c
> > +++ b/fs/btrfs/ctree.c
> > @@ -2069,6 +2069,8 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
> >         u8 lowest_level = 0;
> >         int min_write_lock_level;
> >         int prev_cmp;
> > +       int cow_count = 0;
> > +       int restart_count = 0;
> >
> >         if (!root)
> >                 return -EINVAL;
> > @@ -2157,6 +2159,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
> >                             p->nodes[level + 1])) {
> >                                 write_lock_level = level + 1;
> >                                 btrfs_release_path(p);
> > +                               restart_count++;
> >                                 goto again;
> >                         }
> >
> > @@ -2172,6 +2175,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
> >                                 ret = ret2;
> >                                 goto done;
> >                         }
> > +                       cow_count++;
> >                 }
> >  cow_done:
> >                 p->nodes[level] = b;
> > @@ -2219,8 +2223,10 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
> >                 p->slots[level] = slot;
> >                 ret2 = setup_nodes_for_search(trans, root, p, b, level, ins_len,
> >                                               &write_lock_level);
> > -               if (ret2 == -EAGAIN)
> > +               if (ret2 == -EAGAIN) {
> > +                       restart_count++;
> >                         goto again;
> > +               }
> >                 if (ret2) {
> >                         ret = ret2;
> >                         goto done;
> > @@ -2236,6 +2242,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
> >                 if (slot == 0 && ins_len && write_lock_level < level + 1) {
> >                         write_lock_level = level + 1;
> >                         btrfs_release_path(p);
> > +                       restart_count++;
> >                         goto again;
> >                 }
> >
> > @@ -2249,8 +2256,10 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
> >                 }
> >
> >                 ret2 = read_block_for_search(root, p, &b, slot, key);
> > -               if (ret2 == -EAGAIN && !p->nowait)
> > +               if (ret2 == -EAGAIN && !p->nowait) {
> > +                       restart_count++;
> >                         goto again;
> > +               }
> >                 if (ret2) {
> >                         ret = ret2;
> >                         goto done;
> > @@ -2281,6 +2290,8 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root,
> >         }
> >         ret = 1;
> >  done:
> > +       if (cow_count > 0)
> > +               trace_btrfs_search_slot_stats(root, cow_count, restart_count, ret);
> 
> So I find this way too specific, plus even if trace points are
> disabled we have the overhead of the counters (and inside critical
> sections).
> 
> We already have a tracepoint for COW, trace_btrfs_cow_block(), and we
> could have one just for the retry thing, maybe naming it like
> trace_btrfs_search_slot_restart() or something.
> So we could use those two tracepoints to measure things (bpftrace
> scripts could easily report a count of each trace point and such),
> instead of this highly specialized tracepoint that adds some overhead
> when tracepoints are disabled.

Good point, added a per-restart-site trace_btrfs_search_slot_restart()
tracepoint in v3.

Thanks,
Leo

> 
> Thanks.
> 
> 
> >         if (ret < 0 && !p->skip_release_on_error)
> >                 btrfs_release_path(p);
> >
> > diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h
> > index 125bdc166bfe..b8934938a087 100644
> > --- a/include/trace/events/btrfs.h
> > +++ b/include/trace/events/btrfs.h
> > @@ -1110,6 +1110,32 @@ TRACE_EVENT(btrfs_cow_block,
> >                   __entry->cow_level)
> >  );
> >
> > +TRACE_EVENT(btrfs_search_slot_stats,
> > +
> > +       TP_PROTO(const struct btrfs_root *root,
> > +                int cow_count, int restart_count, int ret),
> > +
> > +       TP_ARGS(root, cow_count, restart_count, ret),
> > +
> > +       TP_STRUCT__entry_btrfs(
> > +               __field(        u64,    root_objectid           )
> > +               __field(        int,    cow_count               )
> > +               __field(        int,    restart_count           )
> > +               __field(        int,    ret                     )
> > +       ),
> > +
> > +       TP_fast_assign_btrfs(root->fs_info,
> > +               __entry->root_objectid  = btrfs_root_id(root);
> > +               __entry->cow_count      = cow_count;
> > +               __entry->restart_count  = restart_count;
> > +               __entry->ret            = ret;
> > +       ),
> > +
> > +       TP_printk_btrfs("root=%llu(%s) cow_count=%d restarts=%d ret=%d",
> > +                 show_root_type(__entry->root_objectid),
> > +                 __entry->cow_count, __entry->restart_count, __entry->ret)
> > +);
> > +
> >  TRACE_EVENT(btrfs_space_reservation,
> >
> >         TP_PROTO(const struct btrfs_fs_info *fs_info, const char *type, u64 val,
> > --
> > 2.47.3
> >
> >

      reply	other threads:[~2026-02-17 22:06 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-13 20:30 [PATCH v2 0/3] btrfs: fix COW amplification under memory pressure Leo Martins
2026-02-13 20:30 ` [PATCH v2 1/3] btrfs: skip COW for written extent buffers allocated in current transaction Leo Martins
2026-02-14  1:25   ` Sun YangKai
2026-02-17 22:04     ` Leo Martins
2026-02-16 12:18   ` Filipe Manana
2026-02-17 21:48     ` Leo Martins
2026-02-13 20:30 ` [PATCH v2 2/3] btrfs: inhibit extent buffer writeback to prevent COW amplification Leo Martins
2026-02-16 12:33   ` Filipe Manana
2026-02-13 20:30 ` [PATCH v2 3/3] btrfs: add tracepoint for COW amplification tracking Leo Martins
2026-02-16 12:40   ` Filipe Manana
2026-02-17 22:06     ` Leo Martins [this message]

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=20260217220637.820818-1-loemra.dev@gmail.com \
    --to=loemra.dev@gmail.com \
    --cc=fdmanana@kernel.org \
    --cc=kernel-team@fb.com \
    --cc=linux-btrfs@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.