dm-devel.redhat.com archive mirror
 help / color / mirror / Atom feed
* [dm-devel] [PATCH] dm writecache: fix inaccurate reads/writes stats
@ 2022-07-06  9:31 Yu Kuai
  2022-07-11 20:29 ` Mikulas Patocka
  0 siblings, 1 reply; 6+ messages in thread
From: Yu Kuai @ 2022-07-06  9:31 UTC (permalink / raw)
  To: agk, snitzer, dm-devel, mpatocka; +Cc: yukuai3, yi.zhang, linux-kernel, yukuai1

From: Yu Kuai <yukuai3@huawei.com>

Test procedures:

1) format a dm writecache device with 4k blocksize.
2) flush cache.
3) cache 1G data through write.
4) clear stats.
5) read 2G data with bs=1m.
6) read stats.

Expected result:
cache hit ratio is 50%.

Test result:
stats: 0, 1011345, 749201, 0, 263168, 262144, 0, 0, 0, 0, 0, 0, 0, 0
ratio is 99% (262144/263168)

The way that reads is accounted is different between cache hit and cache
miss:

1) If cache hit, reads will be accounted for each entry, which means reads
and read_hits will both increase 256 for each io in the above test.

2) If cache miss, reads will only account once, which means reads will only
increase 1 for each io in the above test.

The case that writes_around has the same problem, fix it by adding
appropriate reads/writes in writecache_map_remap_origin().

Fixes: e3a35d03407c ("dm writecache: add event counters")
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
---
 drivers/md/dm-writecache.c | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c
index d74c5a7a0ab4..c2c6c3a023dd 100644
--- a/drivers/md/dm-writecache.c
+++ b/drivers/md/dm-writecache.c
@@ -1329,16 +1329,29 @@ enum wc_map_op {
 	WC_MAP_ERROR,
 };
 
-static enum wc_map_op writecache_map_remap_origin(struct dm_writecache *wc, struct bio *bio,
-						  struct wc_entry *e)
+static enum wc_map_op writecache_map_remap_origin(struct dm_writecache *wc,
+						  struct bio *bio,
+						  struct wc_entry *e, bool read)
 {
+	sector_t next_boundary;
+	unsigned long long miss_count;
+
 	if (e) {
-		sector_t next_boundary =
+		next_boundary =
 			read_original_sector(wc, e) - bio->bi_iter.bi_sector;
 		if (next_boundary < bio->bi_iter.bi_size >> SECTOR_SHIFT)
 			dm_accept_partial_bio(bio, next_boundary);
+	} else {
+		next_boundary = bio->bi_iter.bi_size;
 	}
 
+	miss_count = (round_up(next_boundary, wc->block_size) >>
+			wc->block_size_bits) - 1;
+	if (read)
+		wc->stats.reads += miss_count;
+	else
+		wc->stats.writes += miss_count;
+
 	return WC_MAP_REMAP_ORIGIN;
 }
 
@@ -1366,7 +1379,7 @@ static enum wc_map_op writecache_map_read(struct dm_writecache *wc, struct bio *
 			map_op = WC_MAP_REMAP;
 		}
 	} else {
-		map_op = writecache_map_remap_origin(wc, bio, e);
+		map_op = writecache_map_remap_origin(wc, bio, e, true);
 	}
 
 	return map_op;
@@ -1458,7 +1471,8 @@ static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio
 direct_write:
 				wc->stats.writes_around++;
 				e = writecache_find_entry(wc, bio->bi_iter.bi_sector, WFE_RETURN_FOLLOWING);
-				return writecache_map_remap_origin(wc, bio, e);
+				return writecache_map_remap_origin(wc, bio, e,
+								   false);
 			}
 			wc->stats.writes_blocked_on_freelist++;
 			writecache_wait_on_freelist(wc);
-- 
2.31.1

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [dm-devel] [PATCH] dm writecache: fix inaccurate reads/writes stats
  2022-07-06  9:31 [dm-devel] [PATCH] dm writecache: fix inaccurate reads/writes stats Yu Kuai
@ 2022-07-11 20:29 ` Mikulas Patocka
  2022-07-11 20:30   ` [dm-devel] [PATCH 1/4] dm-writecache: make writecache_map_remap_origin return void Mikulas Patocka
                     ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Mikulas Patocka @ 2022-07-11 20:29 UTC (permalink / raw)
  To: Yu Kuai, Mike Snitzer; +Cc: yukuai3, dm-devel, linux-kernel, agk, yi.zhang



On Wed, 6 Jul 2022, Yu Kuai wrote:

> From: Yu Kuai <yukuai3@huawei.com>
> 
> Test procedures:
> 
> 1) format a dm writecache device with 4k blocksize.
> 2) flush cache.
> 3) cache 1G data through write.
> 4) clear stats.
> 5) read 2G data with bs=1m.
> 6) read stats.
> 
> Expected result:
> cache hit ratio is 50%.
> 
> Test result:
> stats: 0, 1011345, 749201, 0, 263168, 262144, 0, 0, 0, 0, 0, 0, 0, 0
> ratio is 99% (262144/263168)

Hi

Here I'm providing patches that change the dm-writecache counting from 
requests to blocks.

Mike, you can queue them for the next merge window.

Mikulas
--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [dm-devel] [PATCH 1/4] dm-writecache: make writecache_map_remap_origin return void
  2022-07-11 20:29 ` Mikulas Patocka
@ 2022-07-11 20:30   ` Mikulas Patocka
  2022-07-11 20:30   ` [dm-devel] [PATCH 2/4] dm-writecache: count the number of blocks read, not the number of read bios Mikulas Patocka
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Mikulas Patocka @ 2022-07-11 20:30 UTC (permalink / raw)
  To: Yu Kuai, Mike Snitzer; +Cc: yukuai3, dm-devel, linux-kernel, agk, yi.zhang

The functions writecache_map_remap_origin and writecache_bio_copy_ssd
return only a single value, thus we can make them return void.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>

Index: linux-2.6/drivers/md/dm-writecache.c
===================================================================
--- linux-2.6.orig/drivers/md/dm-writecache.c
+++ linux-2.6/drivers/md/dm-writecache.c
@@ -1329,8 +1329,8 @@ enum wc_map_op {
 	WC_MAP_ERROR,
 };
 
-static enum wc_map_op writecache_map_remap_origin(struct dm_writecache *wc, struct bio *bio,
-						  struct wc_entry *e)
+static void writecache_map_remap_origin(struct dm_writecache *wc, struct bio *bio,
+					struct wc_entry *e)
 {
 	if (e) {
 		sector_t next_boundary =
@@ -1338,8 +1338,6 @@ static enum wc_map_op writecache_map_rem
 		if (next_boundary < bio->bi_iter.bi_size >> SECTOR_SHIFT)
 			dm_accept_partial_bio(bio, next_boundary);
 	}
-
-	return WC_MAP_REMAP_ORIGIN;
 }
 
 static enum wc_map_op writecache_map_read(struct dm_writecache *wc, struct bio *bio)
@@ -1366,14 +1364,15 @@ read_next_block:
 			map_op = WC_MAP_REMAP;
 		}
 	} else {
-		map_op = writecache_map_remap_origin(wc, bio, e);
+		writecache_map_remap_origin(wc, bio, e);
+		map_op = WC_MAP_REMAP_ORIGIN;
 	}
 
 	return map_op;
 }
 
-static enum wc_map_op writecache_bio_copy_ssd(struct dm_writecache *wc, struct bio *bio,
-					      struct wc_entry *e, bool search_used)
+static void writecache_bio_copy_ssd(struct dm_writecache *wc, struct bio *bio,
+				    struct wc_entry *e, bool search_used)
 {
 	unsigned bio_size = wc->block_size;
 	sector_t start_cache_sec = cache_sector(wc, e);
@@ -1419,8 +1418,6 @@ static enum wc_map_op writecache_bio_cop
 	} else {
 		writecache_schedule_autocommit(wc);
 	}
-
-	return WC_MAP_REMAP;
 }
 
 static enum wc_map_op writecache_map_write(struct dm_writecache *wc, struct bio *bio)
@@ -1458,7 +1455,8 @@ static enum wc_map_op writecache_map_wri
 direct_write:
 				wc->stats.writes_around++;
 				e = writecache_find_entry(wc, bio->bi_iter.bi_sector, WFE_RETURN_FOLLOWING);
-				return writecache_map_remap_origin(wc, bio, e);
+				writecache_map_remap_origin(wc, bio, e);
+				return WC_MAP_REMAP_ORIGIN;
 			}
 			wc->stats.writes_blocked_on_freelist++;
 			writecache_wait_on_freelist(wc);
@@ -1469,10 +1467,12 @@ direct_write:
 		wc->uncommitted_blocks++;
 		wc->stats.writes_allocate++;
 bio_copy:
-		if (WC_MODE_PMEM(wc))
+		if (WC_MODE_PMEM(wc)) {
 			bio_copy_block(wc, bio, memory_data(wc, e));
-		else
-			return writecache_bio_copy_ssd(wc, bio, e, search_used);
+		} else {
+			writecache_bio_copy_ssd(wc, bio, e, search_used);
+			return WC_MAP_REMAP;
+		}
 	} while (bio->bi_iter.bi_size);
 
 	if (unlikely(bio->bi_opf & REQ_FUA || wc->uncommitted_blocks >= wc->autocommit_blocks))

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [dm-devel] [PATCH 2/4] dm-writecache: count the number of blocks read, not the number of read bios
  2022-07-11 20:29 ` Mikulas Patocka
  2022-07-11 20:30   ` [dm-devel] [PATCH 1/4] dm-writecache: make writecache_map_remap_origin return void Mikulas Patocka
@ 2022-07-11 20:30   ` Mikulas Patocka
  2022-07-11 20:31   ` [dm-devel] [PATCH 3/4] dm-writecache: count the number of blocks written, not the number of write bios Mikulas Patocka
  2022-07-11 20:31   ` [dm-devel] [PATCH 4/4] dm-writecache: count the number of blocks discarded, not the number of discard bios Mikulas Patocka
  3 siblings, 0 replies; 6+ messages in thread
From: Mikulas Patocka @ 2022-07-11 20:30 UTC (permalink / raw)
  To: Yu Kuai, Mike Snitzer; +Cc: yukuai3, dm-devel, linux-kernel, agk, yi.zhang

Change dm-writecache, so that it counts the number of blocks read instead
of the number of read bios. Bios can be split and requeued using the
dm_accept_partial_bio function, so counting of bios provided inaccurate
results.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Reported-by: Yu Kuai <yukuai1@huaweicloud.com>

Index: linux-2.6/drivers/md/dm-writecache.c
===================================================================
--- linux-2.6.orig/drivers/md/dm-writecache.c
+++ linux-2.6/drivers/md/dm-writecache.c
@@ -1365,6 +1365,7 @@ read_next_block:
 		}
 	} else {
 		writecache_map_remap_origin(wc, bio, e);
+		wc->stats.reads += (bio->bi_iter.bi_size - wc->block_size) >> wc->block_size_bits;
 		map_op = WC_MAP_REMAP_ORIGIN;
 	}
 
Index: linux-2.6/Documentation/admin-guide/device-mapper/writecache.rst
===================================================================
--- linux-2.6.orig/Documentation/admin-guide/device-mapper/writecache.rst
+++ linux-2.6/Documentation/admin-guide/device-mapper/writecache.rst
@@ -78,8 +78,8 @@ Status:
 2. the number of blocks
 3. the number of free blocks
 4. the number of blocks under writeback
-5. the number of read requests
-6. the number of read requests that hit the cache
+5. the number of read blocks
+6. the number of read blocks that hit the cache
 7. the number of write requests
 8. the number of write requests that hit uncommitted block
 9. the number of write requests that hit committed block

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [dm-devel] [PATCH 3/4] dm-writecache: count the number of blocks written, not the number of write bios
  2022-07-11 20:29 ` Mikulas Patocka
  2022-07-11 20:30   ` [dm-devel] [PATCH 1/4] dm-writecache: make writecache_map_remap_origin return void Mikulas Patocka
  2022-07-11 20:30   ` [dm-devel] [PATCH 2/4] dm-writecache: count the number of blocks read, not the number of read bios Mikulas Patocka
@ 2022-07-11 20:31   ` Mikulas Patocka
  2022-07-11 20:31   ` [dm-devel] [PATCH 4/4] dm-writecache: count the number of blocks discarded, not the number of discard bios Mikulas Patocka
  3 siblings, 0 replies; 6+ messages in thread
From: Mikulas Patocka @ 2022-07-11 20:31 UTC (permalink / raw)
  To: Yu Kuai, Mike Snitzer; +Cc: yukuai3, dm-devel, linux-kernel, agk, yi.zhang

Change dm-writecache, so that it counts the number of blocks written
instead of the number of write bios. Bios can be split and requeued using
the dm_accept_partial_bio function, so counting of bios provided
inaccurate results.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Reported-by: Yu Kuai <yukuai1@huaweicloud.com>

Index: linux-2.6/drivers/md/dm-writecache.c
===================================================================
--- linux-2.6.orig/drivers/md/dm-writecache.c
+++ linux-2.6/drivers/md/dm-writecache.c
@@ -1413,6 +1413,9 @@ static void writecache_bio_copy_ssd(stru
 	bio->bi_iter.bi_sector = start_cache_sec;
 	dm_accept_partial_bio(bio, bio_size >> SECTOR_SHIFT);
 
+	wc->stats.writes += bio->bi_iter.bi_size >> wc->block_size_bits;
+	wc->stats.writes_allocate += (bio->bi_iter.bi_size - wc->block_size) >> wc->block_size_bits;
+
 	if (unlikely(wc->uncommitted_blocks >= wc->autocommit_blocks)) {
 		wc->uncommitted_blocks = 0;
 		queue_work(wc->writeback_wq, &wc->flush_work);
@@ -1428,9 +1431,10 @@ static enum wc_map_op writecache_map_wri
 	do {
 		bool found_entry = false;
 		bool search_used = false;
-		wc->stats.writes++;
-		if (writecache_has_error(wc))
+		if (writecache_has_error(wc)) {
+			wc->stats.writes += bio->bi_iter.bi_size >> wc->block_size_bits;
 			return WC_MAP_ERROR;
+		}
 		e = writecache_find_entry(wc, bio->bi_iter.bi_sector, 0);
 		if (e) {
 			if (!writecache_entry_is_committed(wc, e)) {
@@ -1454,9 +1458,10 @@ static enum wc_map_op writecache_map_wri
 		if (unlikely(!e)) {
 			if (!WC_MODE_PMEM(wc) && !found_entry) {
 direct_write:
-				wc->stats.writes_around++;
 				e = writecache_find_entry(wc, bio->bi_iter.bi_sector, WFE_RETURN_FOLLOWING);
 				writecache_map_remap_origin(wc, bio, e);
+				wc->stats.writes_around += bio->bi_iter.bi_size >> wc->block_size_bits;
+				wc->stats.writes += bio->bi_iter.bi_size >> wc->block_size_bits;
 				return WC_MAP_REMAP_ORIGIN;
 			}
 			wc->stats.writes_blocked_on_freelist++;
@@ -1470,6 +1475,7 @@ direct_write:
 bio_copy:
 		if (WC_MODE_PMEM(wc)) {
 			bio_copy_block(wc, bio, memory_data(wc, e));
+			wc->stats.writes++;
 		} else {
 			writecache_bio_copy_ssd(wc, bio, e, search_used);
 			return WC_MAP_REMAP;
Index: linux-2.6/Documentation/admin-guide/device-mapper/writecache.rst
===================================================================
--- linux-2.6.orig/Documentation/admin-guide/device-mapper/writecache.rst
+++ linux-2.6/Documentation/admin-guide/device-mapper/writecache.rst
@@ -80,11 +80,11 @@ Status:
 4. the number of blocks under writeback
 5. the number of read blocks
 6. the number of read blocks that hit the cache
-7. the number of write requests
-8. the number of write requests that hit uncommitted block
-9. the number of write requests that hit committed block
-10. the number of write requests that bypass the cache
-11. the number of write requests that are allocated in the cache
+7. the number of write blocks
+8. the number of write blocks that hit uncommitted block
+9. the number of write blocks that hit committed block
+10. the number of write blocks that bypass the cache
+11. the number of write blocks that are allocated in the cache
 12. the number of write requests that are blocked on the freelist
 13. the number of flush requests
 14. the number of discard requests

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [dm-devel] [PATCH 4/4] dm-writecache: count the number of blocks discarded, not the number of discard bios
  2022-07-11 20:29 ` Mikulas Patocka
                     ` (2 preceding siblings ...)
  2022-07-11 20:31   ` [dm-devel] [PATCH 3/4] dm-writecache: count the number of blocks written, not the number of write bios Mikulas Patocka
@ 2022-07-11 20:31   ` Mikulas Patocka
  3 siblings, 0 replies; 6+ messages in thread
From: Mikulas Patocka @ 2022-07-11 20:31 UTC (permalink / raw)
  To: Yu Kuai, Mike Snitzer; +Cc: yukuai3, dm-devel, linux-kernel, agk, yi.zhang

Change dm-writecache, so that it counts the number of blocks discarded
instead of the number of discard bios. Make it consistent with the read
and write statistics counters that were changed to count the number of
blocks instead of bios.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>

Index: linux-2.6/drivers/md/dm-writecache.c
===================================================================
--- linux-2.6.orig/drivers/md/dm-writecache.c
+++ linux-2.6/drivers/md/dm-writecache.c
@@ -1514,7 +1514,7 @@ static enum wc_map_op writecache_map_flu
 
 static enum wc_map_op writecache_map_discard(struct dm_writecache *wc, struct bio *bio)
 {
-	wc->stats.discards++;
+	wc->stats.discards += bio->bi_iter.bi_size >> wc->block_size_bits;
 
 	if (writecache_has_error(wc))
 		return WC_MAP_ERROR;
Index: linux-2.6/Documentation/admin-guide/device-mapper/writecache.rst
===================================================================
--- linux-2.6.orig/Documentation/admin-guide/device-mapper/writecache.rst
+++ linux-2.6/Documentation/admin-guide/device-mapper/writecache.rst
@@ -87,7 +87,7 @@ Status:
 11. the number of write blocks that are allocated in the cache
 12. the number of write requests that are blocked on the freelist
 13. the number of flush requests
-14. the number of discard requests
+14. the number of discarded blocks
 
 Messages:
 	flush

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-07-11 20:32 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-06  9:31 [dm-devel] [PATCH] dm writecache: fix inaccurate reads/writes stats Yu Kuai
2022-07-11 20:29 ` Mikulas Patocka
2022-07-11 20:30   ` [dm-devel] [PATCH 1/4] dm-writecache: make writecache_map_remap_origin return void Mikulas Patocka
2022-07-11 20:30   ` [dm-devel] [PATCH 2/4] dm-writecache: count the number of blocks read, not the number of read bios Mikulas Patocka
2022-07-11 20:31   ` [dm-devel] [PATCH 3/4] dm-writecache: count the number of blocks written, not the number of write bios Mikulas Patocka
2022-07-11 20:31   ` [dm-devel] [PATCH 4/4] dm-writecache: count the number of blocks discarded, not the number of discard bios Mikulas Patocka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).