From: Jonathan Derrick <jonathan.derrick@linux.dev>
To: Song Liu <song@kernel.org>
Cc: <linux-raid@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
jonathan.derrick@solidigm.com, jonathanx.sk.derrick@intel.com,
Jonathan Derrick <jonathan.derrick@linux.dev>
Subject: [PATCH 2/2] md/bitmap: Add chunk-count-based bitmap flushing
Date: Thu, 6 Oct 2022 16:08:40 -0600 [thread overview]
Message-ID: <20221006220840.275-4-jonathan.derrick@linux.dev> (raw)
In-Reply-To: <20221006220840.275-1-jonathan.derrick@linux.dev>
In addition to the timer, allow the bitmap flushing to be controlled by a
counter that tracks the number of dirty chunks and flushes when it exceeds a
user-defined chunk-count threshold.
This introduces a new field to the bitmap superblock and version 6.
Signed-off-by: Jonathan Derrick <jonathan.derrick@linux.dev>
---
drivers/md/md-bitmap.c | 37 ++++++++++++++++++++++++++++++++++---
drivers/md/md-bitmap.h | 5 ++++-
drivers/md/md.h | 1 +
3 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
index 451259b38d25..fa6b3c71c314 100644
--- a/drivers/md/md-bitmap.c
+++ b/drivers/md/md-bitmap.c
@@ -499,6 +499,7 @@ void md_bitmap_print_sb(struct bitmap *bitmap)
pr_debug(" state: %08x\n", le32_to_cpu(sb->state));
pr_debug(" chunksize: %d B\n", le32_to_cpu(sb->chunksize));
pr_debug(" daemon sleep: %ds\n", le32_to_cpu(sb->daemon_sleep));
+ pr_debug(" flush chunks: %d\n", le32_to_cpu(sb->daemon_flush_chunks));
pr_debug(" sync size: %llu KB\n",
(unsigned long long)le64_to_cpu(sb->sync_size)/2);
pr_debug("max write behind: %d\n", le32_to_cpu(sb->write_behind));
@@ -581,6 +582,7 @@ static int md_bitmap_read_sb(struct bitmap *bitmap)
bitmap_super_t *sb;
unsigned long chunksize, daemon_sleep, write_behind;
unsigned long long events;
+ unsigned int daemon_flush_chunks;
int nodes = 0;
unsigned long sectors_reserved = 0;
int err = -EINVAL;
@@ -644,7 +646,7 @@ static int md_bitmap_read_sb(struct bitmap *bitmap)
if (sb->magic != cpu_to_le32(BITMAP_MAGIC))
reason = "bad magic";
else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO ||
- le32_to_cpu(sb->version) > BITMAP_MAJOR_CLUSTERED)
+ le32_to_cpu(sb->version) > BITMAP_MAJOR_CHUNKFLUSH)
reason = "unrecognized superblock version";
else if (chunksize < 512)
reason = "bitmap chunksize too small";
@@ -660,6 +662,9 @@ static int md_bitmap_read_sb(struct bitmap *bitmap)
goto out;
}
+ if (sb->version == cpu_to_le32(BITMAP_MAJOR_CHUNKFLUSH))
+ daemon_flush_chunks = le32_to_cpu(sb->daemon_flush_chunks);
+
/*
* Setup nodes/clustername only if bitmap version is
* cluster-compatible
@@ -720,6 +725,7 @@ static int md_bitmap_read_sb(struct bitmap *bitmap)
bitmap->events_cleared = bitmap->mddev->events;
bitmap->mddev->bitmap_info.chunksize = chunksize;
bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep;
+ bitmap->mddev->bitmap_info.daemon_flush_chunks = daemon_flush_chunks;
bitmap->mddev->bitmap_info.max_write_behind = write_behind;
bitmap->mddev->bitmap_info.nodes = nodes;
if (bitmap->mddev->bitmap_info.space == 0 ||
@@ -1218,6 +1224,31 @@ static bitmap_counter_t *md_bitmap_get_counter(struct bitmap_counts *bitmap,
sector_t offset, sector_t *blocks,
int create);
+static bool md_daemon_should_sleep(struct mddev *mddev)
+{
+ struct bitmap *bitmap = mddev->bitmap;
+ struct bitmap_page *bp;
+ unsigned long k, pages;
+ unsigned int count = 0;
+
+ if (time_after(jiffies, bitmap->daemon_lastrun
+ + mddev->bitmap_info.daemon_sleep))
+ return false;
+
+ if (mddev->bitmap_info.daemon_flush_chunks) {
+ bp = bitmap->counts.bp;
+ pages = bitmap->counts.pages;
+ for (k = 0; k < pages; k++)
+ if (bp[k].map && !bp[k].hijacked)
+ count += bp[k].count;
+
+ if (count >= mddev->bitmap_info.daemon_flush_chunks)
+ return false;
+ }
+
+ return true;
+}
+
/*
* bitmap daemon -- periodically wakes up to clean bits and flush pages
* out to disk
@@ -1240,8 +1271,8 @@ void md_bitmap_daemon_work(struct mddev *mddev)
mutex_unlock(&mddev->bitmap_info.mutex);
return;
}
- if (time_before(jiffies, bitmap->daemon_lastrun
- + mddev->bitmap_info.daemon_sleep))
+
+ if (md_daemon_should_sleep(mddev))
goto done;
md_bitmap_unplug(bitmap);
diff --git a/drivers/md/md-bitmap.h b/drivers/md/md-bitmap.h
index cfd7395de8fd..e0aeedbdde17 100644
--- a/drivers/md/md-bitmap.h
+++ b/drivers/md/md-bitmap.h
@@ -11,10 +11,12 @@
/* version 4 insists the bitmap is in little-endian order
* with version 3, it is host-endian which is non-portable
* Version 5 is currently set only for clustered devices
++ * Version 6 supports the flush-chunks threshold
*/
#define BITMAP_MAJOR_HI 4
#define BITMAP_MAJOR_CLUSTERED 5
#define BITMAP_MAJOR_HOSTENDIAN 3
+#define BITMAP_MAJOR_CHUNKFLUSH 6
/*
* in-memory bitmap:
@@ -135,7 +137,8 @@ typedef struct bitmap_super_s {
* reserved for the bitmap. */
__le32 nodes; /* 68 the maximum number of nodes in cluster. */
__u8 cluster_name[64]; /* 72 cluster name to which this md belongs */
- __u8 pad[256 - 136]; /* set to zero */
+ __le32 daemon_flush_chunks; /* 136 dirty chunks between flushes */
+ __u8 pad[256 - 140]; /* set to zero */
} bitmap_super_t;
/* notes:
diff --git a/drivers/md/md.h b/drivers/md/md.h
index b4e2d8b87b61..d25574e46283 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -497,6 +497,7 @@ struct mddev {
struct mutex mutex;
unsigned long chunksize;
unsigned long daemon_sleep; /* how many jiffies between updates? */
+ unsigned int daemon_flush_chunks; /* how many dirty chunks between updates */
unsigned long max_write_behind; /* write-behind mode */
int external;
int nodes; /* Maximum number of nodes in the cluster */
--
2.31.1
next prev parent reply other threads:[~2022-10-06 22:11 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-06 22:08 [PATCH 0/2] Bitmap percentage flushing Jonathan Derrick
2022-10-06 22:08 ` [RFC PATCH] mdadm: Add parameter for bitmap chunk threshold Jonathan Derrick
2022-10-12 7:17 ` Mariusz Tkaczyk
2022-10-06 22:08 ` [PATCH 1/2] md/bitmap: Move unplug to daemon thread Jonathan Derrick
2022-10-10 4:32 ` [md/bitmap] 935dbb156b: mdadm-selftests.05r1-bitmapfile.fail kernel test robot
2022-10-10 4:32 ` kernel test robot
2022-10-17 22:58 ` Jonathan Derrick
2022-10-17 22:58 ` Jonathan Derrick
2022-10-06 22:08 ` Jonathan Derrick [this message]
2022-10-07 17:50 ` [PATCH 2/2] md/bitmap: Add chunk-count-based bitmap flushing Song Liu
2022-10-07 18:58 ` Jonathan Derrick
2022-10-10 18:18 ` Song Liu
2022-10-13 22:19 ` Jonathan Derrick
2022-10-13 22:56 ` Song Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221006220840.275-4-jonathan.derrick@linux.dev \
--to=jonathan.derrick@linux.dev \
--cc=jonathan.derrick@solidigm.com \
--cc=jonathanx.sk.derrick@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-raid@vger.kernel.org \
--cc=song@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.