91 lines
3.2 KiB
Diff
91 lines
3.2 KiB
Diff
From 15d235587c14dcbc9a98197921994bc6e2d505d8 Mon Sep 17 00:00:00 2001
|
|
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
Date: Tue, 1 Apr 2025 11:56:22 +0100
|
|
Subject: [PATCH] file: Reduce the size of the lock around write eviction
|
|
|
|
Previously we held window_lock during the synchronous eviction of the
|
|
oldest window. This potentially serializes all writes in the slow
|
|
write case. We don't need to hold the lock here.
|
|
|
|
(cherry picked from commit d3d2bc45bb59a30669a3d926435cf57e99feb3a2)
|
|
---
|
|
plugins/file/file.c | 52 +++++++++++++++++++++++++++------------------
|
|
1 file changed, 31 insertions(+), 21 deletions(-)
|
|
|
|
diff --git a/plugins/file/file.c b/plugins/file/file.c
|
|
index aa552037..d1e91203 100644
|
|
--- a/plugins/file/file.c
|
|
+++ b/plugins/file/file.c
|
|
@@ -121,37 +121,47 @@ static struct write_window window[NR_WINDOWS];
|
|
static int
|
|
evict_writes (int fd, uint64_t offset, size_t len)
|
|
{
|
|
- ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&window_lock);
|
|
-
|
|
- /* Tell Linux to start writing the current range out to disk
|
|
- * (asynchronously).
|
|
- */
|
|
- if (sync_file_range (fd, offset, len, SYNC_FILE_RANGE_WRITE) == -1) {
|
|
- nbdkit_error ("sync_file_range: cache=none: starting eviction: %m");
|
|
- return -1;
|
|
+ struct write_window oldest = { 0 };
|
|
+
|
|
+ {
|
|
+ ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&window_lock);
|
|
+
|
|
+ /* Save oldest window[0] for eviction below, and move all windows
|
|
+ * down one. Set the newest slot to empty.
|
|
+ */
|
|
+ oldest = window[0];
|
|
+ memmove (&window[0], &window[1], sizeof window[0] * (NR_WINDOWS-1));
|
|
+ window[NR_WINDOWS-1].len = 0;
|
|
+
|
|
+ /* Tell Linux to start writing the current range out to disk
|
|
+ * (asynchronously).
|
|
+ */
|
|
+ if (sync_file_range (fd, offset, len, SYNC_FILE_RANGE_WRITE) == -1) {
|
|
+ nbdkit_error ("sync_file_range: cache=none: starting eviction: %m");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /* Add the range to the newest end of the list of windows. */
|
|
+ window[NR_WINDOWS-1].fd = fd;
|
|
+ window[NR_WINDOWS-1].offset = offset;
|
|
+ window[NR_WINDOWS-1].len = len;
|
|
}
|
|
+ /* Release lock here. */
|
|
|
|
- /* Evict the oldest window from the page cache. */
|
|
- if (window[0].len > 0) {
|
|
- if (sync_file_range (window[0].fd, window[0].offset, window[0].len,
|
|
- SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|
|
|
+ /* Evict the oldest window from the page cache (synchronously). */
|
|
+ if (oldest.len > 0) {
|
|
+ if (sync_file_range (oldest.fd, oldest.offset, oldest.len,
|
|
+ SYNC_FILE_RANGE_WAIT_BEFORE |
|
|
+ SYNC_FILE_RANGE_WRITE |
|
|
SYNC_FILE_RANGE_WAIT_AFTER) == -1) {
|
|
nbdkit_error ("sync_file_range: cache=none: evicting oldest window: %m");
|
|
return -1;
|
|
}
|
|
- if (posix_fadvise (window[0].fd, window[0].offset, window[0].len,
|
|
+ if (posix_fadvise (oldest.fd, oldest.offset, oldest.len,
|
|
POSIX_FADV_DONTNEED) == -1)
|
|
nbdkit_debug ("posix_fadvise: POSIX_FADV_DONTNEED: (ignored): %m");
|
|
}
|
|
|
|
- /* Move the Nth window to N-1. */
|
|
- memmove (&window[0], &window[1], sizeof window[0] * (NR_WINDOWS-1));
|
|
-
|
|
- /* Add the range to the newest end of the list of windows. */
|
|
- window[NR_WINDOWS-1].fd = fd;
|
|
- window[NR_WINDOWS-1].offset = offset;
|
|
- window[NR_WINDOWS-1].len = len;
|
|
-
|
|
return 0;
|
|
}
|
|
|
|
--
|
|
2.47.1
|
|
|