Re: [PATCH 2/2] upload-pack: reduce lock contention when writing packfile data
- From
Patrick Steinhardt <ps@pks.im>
- Date
- Mar 2, 2026, 12:12 UTC
- Message-ID
- <aaV-l_NyWpkKDDp6@pks.im>
- In-Reply-To
- <20260227193758.GA2931515@coredump.intra.peff.net>
On Fri, Feb 27, 2026 at 02:37:58PM -0500, Jeff King wrote:
Show 17 quoted lines
> On Fri, Feb 27, 2026 at 12:23:01PM +0100, Patrick Steinhardt wrote: > > > Extend our use of the buffering infrastructure so that we soak up bytes > > until the buffer is filled up at least 2/3rds of its capacity. The > > change is relatively simple to implement as we already know to flush the > > buffer in `create_pack_file()` after git-pack-objects(1) has finished. > > We are relaying write() calls from pack-objects here, which is writing > to us in 8kb chunks (due to csum-file.c buffering). So most of our > writes will be 8k. > > Rather than buffering in upload-pack, would it not be simpler to just > increase the write size from pack-objects? Then we do not have to worry > about disrupting upload-pack's keepalive timeouts. And as a bonus, if > you are worried about the system-wide number of calls, you will likewise > be reducing the number of read() and write() calls over the pipe between > pack-objects and upload-pack.
We can do that. But we also have to keep in mind that downstream in the pipe may be a process that's not even git-pack-objects(1) in the first place because of "uploadpack.packObjectsHook". So maybe we should have a look at doing both.
Show 11 quoted lines
> > Now git-upload-pack(1) already has the infrastructure in place to buffer > > some of the data it reads from git-pack-objects(1) before actually > > sending it out. We only use this infrastructure in very limited ways > > though, so we generally end up matching one read(3p) call with one > > write(3p) call. Even worse, when the sideband is enabled we end up > > matching one read with _two_ writes: one for the pkt-line length, and > > one for the packfile data. > > Using writev() would be an easy-ish fix here, modulo portability > concerns (though of course it is easy to implement a fallback writev() > in terms of write()). Doing this:
Right, I was also wondering about whether we might want to use writev(), but I didn't have the time yet to have a deeper look. I'll have a look at whether I can integrate your change in a platform-compatible way.
Show 5 quoted lines
> Out of curiosity, how did you end up measuring? I first tried with > strace (without "-f") on the upload-pack process, but strace slowed it > enough that it ended up collecting multiple of pack-object's 8k write() > calls in a single read() call. ;) The "perf stat" above seemed to work > OK, though of course it's counting child processes, too.
I used strace for this. I didn't really dig into it too deep as I was rather busy handling the havoc that this issue caused :)
I'll send a v2 soonish, thanks!
Patrick