From: Patrick Steinhardt Date: Tue, 03 Mar 2026 15:00:15 GMT Subject: [PATCH v2 00/10] upload-pack: reduce lock contention when writing packfile data Message-ID: <20260303-pks-upload-pack-write-contention-v2-0-7321830f08fe@pks.im> In-Reply-To: <20260227-pks-upload-pack-write-contention-v1-0-7166fe255704@pks.im> Hi, this small patch series fixes some heavy lock contention when writing data from git-upload-pack(1) into pipes. This lock contention can be observed when having hundreds of git-upload-pack(1) processes active at the same time that write data into pipes at dozens of gigabits per second. I have uploaded the flame graph that clearly shows the lock contention at [1]. Changes in v2: - Change the buffer size in git-pack-objects(1) to also reduce the number of write syscalls over there. - Introduce writev to half the number of syscalls when writing pktlines. - Use `sizeof(os->buffer)` instead of open-coding its size. - Improve keepalive logic in git-upload-pack(1) to account for buffering. - Link to v1: https://lore.kernel.org/r/20260227-pks-upload-pack-write-contention-v1-0-7166fe255704@pks.im Thanks! Patrick [1]: https://gitlab.com/gitlab-org/git/-/work_items/675 --- Patrick Steinhardt (10): upload-pack: fix debug statement when flushing packfile data upload-pack: adapt keepalives based on buffering upload-pack: reduce lock contention when writing packfile data git-compat-util: introduce `cast_size_t_to_ssize_t()` compat/posix: introduce writev(3p) wrapper wrapper: introduce writev(3p) wrappers sideband: use writev(3p) to send pktlines csum-file: introduce `hashfd_ext()` csum-file: drop `hashfd_throughput()` builtin/pack-objects: reduce lock contention when writing packfile data Makefile | 4 ++++ builtin/pack-objects.c | 23 +++++++++++++++---- compat/posix.h | 14 ++++++++++++ compat/writev.c | 29 ++++++++++++++++++++++++ config.mak.uname | 2 ++ csum-file.c | 28 +++++++---------------- csum-file.h | 16 ++++++++++++-- git-compat-util.h | 8 +++++++ meson.build | 1 + sideband.c | 14 +++++++++--- upload-pack.c | 60 ++++++++++++++++++++++++++++++++++++++++---------- wrapper.c | 41 ++++++++++++++++++++++++++++++++++ wrapper.h | 9 ++++++++ write-or-die.c | 8 +++++++ write-or-die.h | 1 + 15 files changed, 217 insertions(+), 41 deletions(-) Range-diff versus v1: 1: 368a984880 = 1: 81c00e3b52 upload-pack: fix debug statement when flushing packfile data -: ---------- > 2: 01c86a9573 upload-pack: adapt keepalives based on buffering 2: f014e8005a ! 3: 16bc5661d4 upload-pack: reduce lock contention when writing packfile data @@ Commit message write(3p) syscalls from 130,000 to 100,000. So overall this doesn't seem worth it. + Note that the issue could also be fixed by adapting the write buffer + that we use in the downstream git-pack-objects(1) command, and such a + change would have roughly the same result. But the command that + generates the packfile data may not always be git-pack-objects(1) as it + can be changed via "uploadpack.packObjectsHook", so such a fix would + only help in _some_ cases. Regardless of that, we'll also adapt the + write buffer size of git-pack-objects(1) in a subsequent commit. + Helped-by: Matt Smiley Signed-off-by: Patrick Steinhardt @@ upload-pack.c: static int relay_pack_data(int pack_objects_out, struct output_st + * Make sure that we buffer some data before sending it to the client. + * This significantly reduces the number of write(3p) syscalls. + */ -+ if (readsz && os->used < (LARGE_PACKET_DATA_MAX * 2 / 3)) ++ if (readsz && os->used < (sizeof(os->buffer) * 2 / 3)) + return readsz; + if (os->used > 1) { -: ---------- > 4: f42a8a0558 git-compat-util: introduce `cast_size_t_to_ssize_t()` -: ---------- > 5: 830c72f588 compat/posix: introduce writev(3p) wrapper -: ---------- > 6: 733ef129f1 wrapper: introduce writev(3p) wrappers -: ---------- > 7: 18f7429e14 sideband: use writev(3p) to send pktlines -: ---------- > 8: 8eb2aee74d csum-file: introduce `hashfd_ext()` -: ---------- > 9: a634506b81 csum-file: drop `hashfd_throughput()` -: ---------- > 10: ca6d52b012 builtin/pack-objects: reduce lock contention when writing packfile data --- base-commit: 7b2bccb0d58d4f24705bf985de1f4612e4cf06e5 change-id: 20260227-pks-upload-pack-write-contention-435ce01f5fe9