Git development
 help / color / mirror / Atom feed
From: Justin Tobler <jltobler@gmail.com>
To: Karthik Nayak <karthik.188@gmail.com>
Cc: git@vger.kernel.org, Jeff King <peff@peff.net>
Subject: Re: [PATCH 3/3] reftable/stack: avoid reloading the stack when already locked
Date: Wed, 19 Aug 2026 11:49:47 -0500	[thread overview]
Message-ID: <aoXcvhFbUJruALIe@denethor> (raw)
In-Reply-To: <20260819-740-optimize-reloading-the-reftable-stack-v1-3-6bf5305d4e43@gmail.com>

On 26/08/19 03:19PM, Karthik Nayak wrote:
> When making modifications to the reftable stack, the stack obtains a
> lock to the list file and removes the lock after the commit phase. Since
> most operations reload the stack to ensure we have the latest state, any
> branched operation during the locked phase could trigger a state reload.
> 
> To prevent data loss due to concurrent writes, state reload is necessary
> right after obtaining the lock. But any reloads after that are just a
> no-op. Now that the struct has access to the lock file status, simply
> skip reloading if the lock is present.

Makes sense.

> Benchmarking with a fixed, non-symbolic target OID shows a modest but
> consistent ~1-2% improvement in clock time for `update-ref` across ref
> counts ranging from 2,000 to 100,000.
> 
> We can see better improvements in the number of syscall counts. On
> master, the number of calls to `newfstatat()` grows linearly with the
> number of refs created. With this patch, the number is now a constant:
> 
>   refcount   master   patch
>   --------   ------   ------
>   1,000      1,059       55
>   5,000      5,059       55
>   10,000     10,059      55
>   20,000     20,059      55
> 
> Reported-by: Jeff King <peff@peff.net>
> Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
> ---
>  reftable/stack.c | 17 ++++++++++++-----
>  1 file changed, 12 insertions(+), 5 deletions(-)
> 
> diff --git a/reftable/stack.c b/reftable/stack.c
> index e449af9c03..433a611ed1 100644
> --- a/reftable/stack.c
> +++ b/reftable/stack.c
> @@ -553,14 +553,21 @@ int reftable_new_stack(struct reftable_stack **dest, const char *dir,
>  
>  /*
>   * Check whether the given stack is up-to-date with what we have in memory.
> + * If skip_if_locked is set skip stack reloading if the stack is currently
> + * locked. Stack reloading must _not_ be skipped right after obtaining the
> + * lock, to check for concurrent updates which may have happened.
> + *
>   * Returns 0 if so, 1 if the stack is out-of-date or a negative error code
>   * otherwise.
>   */
> -static int stack_uptodate(struct reftable_stack *st)
> +static int stack_uptodate(struct reftable_stack *st, int skip_if_locked)
>  {
>  	char **names = NULL;
>  	int err;
>  
> +	if (skip_if_locked && st->list_lock.fd != -1)
> +		return 0;
> +
>  	/*
>  	 * When we have cached stat information available then we use it to
>  	 * verify whether the file has been rewritten.
> @@ -623,7 +630,7 @@ static int stack_uptodate(struct reftable_stack *st)
>  
>  int reftable_stack_reload(struct reftable_stack *st)
>  {
> -	int err = stack_uptodate(st);
> +	int err = stack_uptodate(st, 1);

Ok, this appears to be the only call site where is actually want to skip
if there is a lock present. Could we instead just not invoke
`stack_uptodate()` in such cases? That way we don't have to change its
function signature and can leave all other existing call sites alone.

-Justin

      reply	other threads:[~2026-08-19 16:49 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-19 13:19 [PATCH 0/3] reftable/stack: avoid reloading the stack when locked Karthik Nayak
2026-08-19 13:19 ` [PATCH 1/3] reftable/stack: remove `REFTABLE_STACK_NEW_ADDITION_RELOAD` Karthik Nayak
2026-08-19 16:28   ` Justin Tobler
2026-08-19 13:19 ` [PATCH 2/3] reftable/stack: move list lock to `struct reftable_stack` Karthik Nayak
2026-08-19 16:39   ` Justin Tobler
2026-08-19 17:17   ` Junio C Hamano
2026-08-19 13:19 ` [PATCH 3/3] reftable/stack: avoid reloading the stack when already locked Karthik Nayak
2026-08-19 16:49   ` Justin Tobler [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=aoXcvhFbUJruALIe@denethor \
    --to=jltobler@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=karthik.188@gmail.com \
    --cc=peff@peff.net \
    /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