git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] index-pack: avoid excessive re-reading of pack directory

From
Jeff King <peff@peff.net>
Date
Jun 9, 2015, 17:24 UTC
Message-ID
<20150609172436.GA32034@peff.net>
In-Reply-To
<20150605122921.GA7586@peff.net>
On Fri, Jun 05, 2015 at 08:29:21AM -0400, Jeff King wrote:
Show 21 quoted lines
> On Fri, Jun 05, 2015 at 08:18:17AM -0400, Jeff King wrote:
> 
> >   1. Devise some torture to tests to see whether my patch series is in
> >      fact racy on Linux.
> >
> >   2. Assuming it is, scrap it and make a has_sha1_file_quick() which
> >      might sometimes return a false negative (if somebody else is
> >      repacking). Use that in index-pack (and possibly other places, but
> >      we can start with index-pack).
> > 
> > If we skip step 1 out of pessimism (which I think is a reasonable thing
> > to do), then step 2 should not be all that much work. I'm going to be
> > offline for a few days, though, so I won't get to it until next week at
> > the earliest. If you (or someone else) wants to take a stab at it,
> > please feel free.
> 
> Actually, it really is a tiny bit of work. I knocked this out in less
> than 10 minutes. It passes the test suite, but it's entirely possible
> that I did something boneheaded that does not fix your problem. ;)
> 
> Please test and confirm that it makes things better on your system.

I tested this on my system, and confirmed that for a "git clone --no-local --bare git.git":

  1. It cuts the number of openat/getdents/close syscalls by several
     orders of magnitude.
  2. The overall time drops from ~11.4s to ~10.5s. I suppose if I timed
     only the `index-pack` process, it would be even higher (as a
     percentage improvement).
So I expect it should fix the problem on your NFS system.

Here's the patch again. Same as before, but I'm cc-ing Junio, as I think it is good to apply.

-- >8 --
Subject: index-pack: avoid excessive re-reading of pack directory

Since 45e8a74 (has_sha1_file: re-check pack directory before giving up, 2013-08-30), we spend extra effort for has_sha1_file to give the right answer when somebody else is repacking. Usually this effort does not matter, because after finding that the object does not exist, the next step is usually to die().

However, some code paths make a large number of has_sha1_file checks which are _not_ expected to return 1. The collision test in index-pack.c is such a case. On a local system, this can cause a performance slowdown of around 5%. But on a system with high-latency system calls (like NFS), it can be much worse.

This patch introduces a "quick" flag to has_sha1_file which callers can use when they would prefer high performance at the cost of false negatives during repacks. There may be other code paths that can use this, but the index-pack one is the most obviously critical, so we'll start with switching that one.

Signed-off-by: Jeff King <peff@peff.net>
---
 builtin/index-pack.c |  2 +-
 cache.h              | 11 ++++++++++-
 sha1_file.c          |  4 +++-
 3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 7ea2020..0761dfd 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -784,7 +784,7 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
 	assert(data || obj_entry);
 
 	read_lock();
-	collision_test_needed = has_sha1_file(sha1);
+	collision_test_needed = has_sha1_file_with_flags(sha1, HAS_SHA1_QUICK);
 	read_unlock();
 
 	if (collision_test_needed && !data) {
diff --git a/cache.h b/cache.h
index 571c98f..98edc2c 100644
--- a/cache.h
+++ b/cache.h
@@ -943,8 +943,17 @@ extern int has_sha1_pack(const unsigned char *sha1);
  * Return true iff we have an object named sha1, whether local or in
  * an alternate object database, and whether packed or loose.  This
  * function does not respect replace references.
+ *
+ * If the QUICK flag is set, do not re-check the pack directory
+ * when we cannot find the object (this means we may give a false
+ * negative answer if another process is simultaneously repacking).
  */
-extern int has_sha1_file(const unsigned char *sha1);
+#define HAS_SHA1_QUICK 0x1
+extern int has_sha1_file_with_flags(const unsigned char *sha1, int flags);
+static inline int has_sha1_file(const unsigned char *sha1)
+{
+	return has_sha1_file_with_flags(sha1, 0);
+}
 
 /*
  * Return true iff an alternate object database has a loose object
diff --git a/sha1_file.c b/sha1_file.c
index 7e38148..dc8746b 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -3161,7 +3161,7 @@ int has_sha1_pack(const unsigned char *sha1)
 	return find_pack_entry(sha1, &e);
 }
 
-int has_sha1_file(const unsigned char *sha1)
+int has_sha1_file_with_flags(const unsigned char *sha1, int flags)
 {
 	struct pack_entry e;
 
@@ -3169,6 +3169,8 @@ int has_sha1_file(const unsigned char *sha1)
 		return 1;
 	if (has_loose_object(sha1))
 		return 1;
+	if (flags & HAS_SHA1_QUICK)
+		return 0;
 	reprepare_packed_git();
 	return find_pack_entry(sha1, &e);
 }
-- 
2.4.2.752.geeb594a
Previous: Jeff KingNext: Jeff King
Message 25 of 32 in “Troubleshoot clone issue to NFS.”
  1. steve.norman@thomsonreuters.comMay 21, 2015
  2. Christian CouderMay 21, 2015
  3. Duy NguyenMay 21, 2015
  4. Duy NguyenMay 21, 2015
  5. steve.norman@thomsonreuters.comMay 21, 2015
  6. Duy NguyenMay 22, 2015
  7. Jeff KingMay 22, 2015
  8. steve.norman@thomsonreuters.comMay 22, 2015
  9. Duy NguyenMay 22, 2015
  10. Junio C HamanoMay 22, 2015
  11. steve.norman@thomsonreuters.comMay 22, 2015
  12. 0/3 using stat() to avoid re-scanning pack dirJeff King, May 22, 2015
  13. 1/3 stat_validity: handle non-regular filesJeff King, May 22, 2015
  14. Michael HaggertyMay 23, 2015
  15. Jeff KingMay 24, 2015
  16. 2/3 cache.h: move stat_validity definition upJeff King, May 22, 2015
  17. 3/3 prepare_packed_git: use stat_validity to avoid re-reading packsJeff King, May 22, 2015
  18. Duy NguyenMay 23, 2015
  19. Duy NguyenMay 23, 2015
  20. Jeff KingMay 24, 2015
  21. Duy NguyenMay 24, 2015
  22. steve.norman@thomsonreuters.comJun 5, 2015
  23. Jeff KingJun 5, 2015
  24. index-pack: avoid excessive re-reading of pack directoryJeff King, Jun 5, 2015
  25. Jeff KingJun 9, 2015
  26. Jeff KingJun 9, 2015
  27. Shawn PearceJun 10, 2015
  28. Jeff KingJun 10, 2015
  29. Duy NguyenJun 10, 2015
  30. Shawn PearceJun 10, 2015
  31. steve.norman@thomsonreuters.comJun 5, 2015
  32. Jeff KingJun 16, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.