Subject: [PATCH] trace2: add stats for fsync operations

From: "Neeraj K. Singh via GitGitGadget" <[email-masked]>
Date: Wed, 30 Mar 2022 05:06:40 +0000

From: Neeraj Singh <[email-masked]>

Add some global trace2 statistics for the number of fsyncs performed
during the lifetime of a Git process.

These stats are printed as part of trace2_cmd_exit_fl, which is
presumably where we might want to print any other cross-cutting
statistics.

Signed-off-by: Neeraj Singh <[email-masked]>
---
    trace2: add stats for fsync operations
    
    Add some global trace2 statistics for the number of fsyncs performed
    during the lifetime of a Git process.
    
    These stats are printed as part of trace2_cmd_exit_fl, which is
    presumably where we might want to print any other cross-cutting
    statistics.
    
    Signed-off-by: Neeraj Singh [email-masked]

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1192%2Fneerajsi-msft%2Fns%2Ftrace2-fsync-stats-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1192/neerajsi-msft/ns/trace2-fsync-stats-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1192

 git-compat-util.h       |  5 +++++
 t/t0211/scrub_perf.perl |  4 ++++
 trace2.c                |  1 +
 wrapper.c               | 12 ++++++++++++
 4 files changed, 22 insertions(+)

diff --git a/git-compat-util.h b/git-compat-util.h
index 0892e209a2f..4d444dca274 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -1281,6 +1281,11 @@ enum fsync_action {
  */
 int git_fsync(int fd, enum fsync_action action);
 
+/*
+ * Writes out trace statistics for fsync using the trace2 API.
+ */
+void trace_git_fsync_stats(void);
+
 /*
  * Preserves errno, prints a message, but gives no warning for ENOENT.
  * Returns 0 on success, which includes trying to unlink an object that does
diff --git a/t/t0211/scrub_perf.perl b/t/t0211/scrub_perf.perl
index d164b750ff7..299999f0f89 100644
--- a/t/t0211/scrub_perf.perl
+++ b/t/t0211/scrub_perf.perl
@@ -59,6 +59,10 @@ while (<>) {
 	    # and highly variable.  Just omit them.
 	    goto SKIP_LINE;
 	}
+	if ($tokens[$col_category] =~ m/fsync/) {
+	    # fsync events aren't interesting for the test
+	    goto SKIP_LINE;
+	}
     }
 
     # t_abs and t_rel are either blank or a float.  Replace the float
diff --git a/trace2.c b/trace2.c
index 179caa72cfe..e01cf77f1a8 100644
--- a/trace2.c
+++ b/trace2.c
@@ -214,6 +214,7 @@ int trace2_cmd_exit_fl(const char *file, int line, int code)
 	if (!trace2_enabled)
 		return code;
 
+	trace_git_fsync_stats();
 	trace2_collect_process_info(TRACE2_PROCESS_INFO_EXIT);
 
 	tr2main_exit_code = code;
diff --git a/wrapper.c b/wrapper.c
index 354d784c034..f512994690b 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -4,6 +4,9 @@
 #include "cache.h"
 #include "config.h"
 
+static intmax_t count_fsync_writeout_only;
+static intmax_t count_fsync_hardware_flush;
+
 #ifdef HAVE_RTLGENRANDOM
 /* This is required to get access to RtlGenRandom. */
 #define SystemFunction036 NTAPI SystemFunction036
@@ -564,6 +567,7 @@ int git_fsync(int fd, enum fsync_action action)
 {
 	switch (action) {
 	case FSYNC_WRITEOUT_ONLY:
+		count_fsync_writeout_only += 1;
 
 #ifdef __APPLE__
 		/*
@@ -595,6 +599,8 @@ int git_fsync(int fd, enum fsync_action action)
 		return -1;
 
 	case FSYNC_HARDWARE_FLUSH:
+		count_fsync_hardware_flush += 1;
+
 		/*
 		 * On macOS, a special fcntl is required to really flush the
 		 * caches within the storage controller. As of this writing,
@@ -610,6 +616,12 @@ int git_fsync(int fd, enum fsync_action action)
 	}
 }
 
+void trace_git_fsync_stats(void)
+{
+	trace2_data_intmax("fsync", the_repository, "fsync/writeout-only", count_fsync_writeout_only);
+	trace2_data_intmax("fsync", the_repository, "fsync/hardware-flush", count_fsync_hardware_flush);
+}
+
 static int warn_if_unremovable(const char *op, const char *file, int rc)
 {
 	int err;

base-commit: c54b8eb302ffb72f31e73a26044c8a864e2cb307
-- 
gitgitgadget