summaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-era-target.c
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2021-04-13 11:03:45 +0100
committerMike Snitzer <snitzer@redhat.com>2021-06-04 12:07:22 -0400
commitbe500ed721a6ec8d49bf0814c277ce7162acee0e (patch)
treeb61c5518a38b187dd2ffd4a830ca64105e41fe2c /drivers/md/dm-era-target.c
parent5faafc77f7de69147d1e818026b9a0cbf036a7b2 (diff)
downloadlinux-be500ed721a6ec8d49bf0814c277ce7162acee0e.tar.bz2
dm space maps: improve performance with inc/dec on ranges of blocks
When we break sharing on btree nodes we typically need to increment the reference counts to every value held in the node. This can cause a lot of repeated calls to the space maps. Fix this by changing the interface to the space map inc/dec methods to take ranges of adjacent blocks to be operated on. For installations that are using a lot of snapshots this will reduce cpu overhead of fundamental operations such as provisioning a new block, or deleting a snapshot, by as much as 10 times. Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/dm-era-target.c')
-rw-r--r--drivers/md/dm-era-target.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/drivers/md/dm-era-target.c b/drivers/md/dm-era-target.c
index d9ac7372108c..3b748393fca5 100644
--- a/drivers/md/dm-era-target.c
+++ b/drivers/md/dm-era-target.c
@@ -363,28 +363,32 @@ static void ws_unpack(const struct writeset_disk *disk, struct writeset_metadata
core->root = le64_to_cpu(disk->root);
}
-static void ws_inc(void *context, const void *value)
+static void ws_inc(void *context, const void *value, unsigned count)
{
struct era_metadata *md = context;
struct writeset_disk ws_d;
dm_block_t b;
+ unsigned i;
- memcpy(&ws_d, value, sizeof(ws_d));
- b = le64_to_cpu(ws_d.root);
-
- dm_tm_inc(md->tm, b);
+ for (i = 0; i < count; i++) {
+ memcpy(&ws_d, value + (i * sizeof(ws_d)), sizeof(ws_d));
+ b = le64_to_cpu(ws_d.root);
+ dm_tm_inc(md->tm, b);
+ }
}
-static void ws_dec(void *context, const void *value)
+static void ws_dec(void *context, const void *value, unsigned count)
{
struct era_metadata *md = context;
struct writeset_disk ws_d;
dm_block_t b;
+ unsigned i;
- memcpy(&ws_d, value, sizeof(ws_d));
- b = le64_to_cpu(ws_d.root);
-
- dm_bitset_del(&md->bitset_info, b);
+ for (i = 0; i < count; i++) {
+ memcpy(&ws_d, value + (i * sizeof(ws_d)), sizeof(ws_d));
+ b = le64_to_cpu(ws_d.root);
+ dm_bitset_del(&md->bitset_info, b);
+ }
}
static int ws_eq(void *context, const void *value1, const void *value2)