[lvm-devel] master - bcache: nr_ios_pending wasn't being incremented

Joe Thornber thornber at sourceware.org
Wed May 16 09:14:47 UTC 2018


Gitweb:        https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=df2acbbb97dbda000053afd40d2e4a707e226b52
Commit:        df2acbbb97dbda000053afd40d2e4a707e226b52
Parent:        413488edc6dd077e79517e44a8d3b9a51c5138e5
Author:        Joe Thornber <ejt at redhat.com>
AuthorDate:    Wed May 16 10:09:17 2018 +0100
Committer:     Joe Thornber <ejt at redhat.com>
CommitterDate: Wed May 16 10:09:17 2018 +0100

bcache: nr_ios_pending wasn't being incremented

... but it was being decremented on completion.  Which meant
it wrapped, and no prefetches were ever issued after the
first completion.
---
 lib/device/bcache.c  |    1 +
 test/unit/bcache_t.c |   45 ++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 45 insertions(+), 1 deletions(-)

diff --git a/lib/device/bcache.c b/lib/device/bcache.c
index 9085d87..652441f 100644
--- a/lib/device/bcache.c
+++ b/lib/device/bcache.c
@@ -667,6 +667,7 @@ static void _issue_low_level(struct block *b, enum dir d)
 
 	b->io_dir = d;
 	_set_flags(b, BF_IO_PENDING);
+	cache->nr_io_pending++;
 
 	dm_list_move(&cache->io_pending, &b->list);
 
diff --git a/test/unit/bcache_t.c b/test/unit/bcache_t.c
index e1c0e85..803a088 100644
--- a/test/unit/bcache_t.c
+++ b/test/unit/bcache_t.c
@@ -504,7 +504,7 @@ static void test_prefetch_issues_a_read(void *context)
 		_expect_read(me, fd, i);
 		bcache_prefetch(cache, fd, i);
 	}
-
+	_no_outstanding_expectations(me);
 
 	for (i = 0; i < nr_cache_blocks; i++) {
 		_expect(me, E_WAIT);
@@ -810,6 +810,47 @@ static void test_invalidate_held_block(void *context)
 	bcache_put(b);
 }
 
+//----------------------------------------------------------------
+// Chasing a bug reported by dct
+
+static void _cycle(struct fixture *f, unsigned nr_cache_blocks)
+{
+	struct mock_engine *me = f->me;
+	struct bcache *cache = f->cache;
+
+	unsigned i;
+	struct block *b;
+
+	for (i = 0; i < nr_cache_blocks; i++) {
+		// prefetch should not wait
+		_expect_read(me, i, 0);
+		bcache_prefetch(cache, i, 0);
+	}
+
+	// This double checks the reads occur in response to the prefetch
+	_no_outstanding_expectations(me);
+
+	for (i = 0; i < nr_cache_blocks; i++) {
+		_expect(me, E_WAIT);
+		T_ASSERT(bcache_get(cache, i, 0, 0, &b));
+		bcache_put(b);
+	}
+
+	_no_outstanding_expectations(me);
+}
+
+static void test_concurrent_reads_after_invalidate(void *context)
+{
+	struct fixture *f = context;
+	unsigned i, nr_cache_blocks = 16;
+
+	_cycle(f, nr_cache_blocks);
+	fprintf(stderr, "cycle 1 complete\n");
+	for (i = 0; i < nr_cache_blocks; i++)
+        	bcache_invalidate_fd(f->cache, i);
+        _cycle(f, nr_cache_blocks);
+	fprintf(stderr, "cycle 2 complete\n");
+}
 
 /*----------------------------------------------------------------
  * Top level
@@ -859,6 +900,8 @@ static struct test_suite *_small_tests(void)
 	T("invalidate-read-error", "invalidate a block that errored", test_invalidate_after_read_error);
 	T("invalidate-write-error", "invalidate a block that errored", test_invalidate_after_write_error);
 	T("invalidate-fails-in-held", "invalidating a held block fails", test_invalidate_held_block);
+	T("concurrent-reads-after-invalidate", "prefetch should still issue concurrent reads after invalidate",
+          test_concurrent_reads_after_invalidate);
 
 	return ts;
 }




More information about the lvm-devel mailing list