[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v1 14/18] backup/pcache: pick up parts of the cache
From: |
Pavel Butsykin |
Subject: |
[Qemu-devel] [PATCH v1 14/18] backup/pcache: pick up parts of the cache |
Date: |
Tue, 15 Nov 2016 09:37:11 +0300 |
Provided that the request size is less than the readahead size, a partial cache
hit can occur in the following three cases:
1. The request covers the bottom part of the node
2. The request covers the upper part of the node
3. The request is between two nodes and partially covers both of them
The function pickup_parts_of_cache() covers all three cases and for the
uncached part of the request it creates a new request.
Signed-off-by: Pavel Butsykin <address@hidden>
---
block/pcache.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 55 insertions(+), 2 deletions(-)
diff --git a/block/pcache.c b/block/pcache.c
index 55d1061..40fa3f3 100644
--- a/block/pcache.c
+++ b/block/pcache.c
@@ -100,6 +100,11 @@ typedef struct PCacheAIOCBRead {
uint64_t offset;
uint64_t bytes;
QEMUIOVector *qiov;
+ struct {
+ QEMUIOVector qiov;
+ uint64_t offset;
+ uint64_t bytes;
+ } part;
int ref;
int ret;
} PCacheAIOCBRead;
@@ -189,6 +194,10 @@ static void pcache_aio_read_cb(void *opaque, int ret)
{
PCacheAIOCBRead *acb = opaque;
+ if (acb->part.qiov.niov != 0) {
+ qemu_iovec_destroy(&acb->part.qiov);
+ }
+
aio_read_complete(acb, ret);
}
@@ -421,6 +430,44 @@ static void pcache_readahead_request(PCacheAIOCBRead *acb)
qemu_coroutine_enter(co);
}
+static void set_part_req(PCacheAIOCBRead *acb, uint64_t offset, uint64_t bytes)
+{
+ acb->part.offset = offset;
+ acb->part.bytes = bytes;
+
+ assert(acb->part.qiov.niov == 0);
+
+ qemu_iovec_init(&acb->part.qiov, acb->qiov->niov);
+ qemu_iovec_concat(&acb->part.qiov, acb->qiov, offset - acb->offset, bytes);
+}
+
+static void pickup_parts_of_cache(PCacheAIOCBRead *acb, PCacheNode *node,
+ uint64_t offset, uint64_t bytes)
+{
+ BDRVPCacheState *s = acb->bs->opaque;
+ uint64_t end_offs = offset + bytes;
+
+ do {
+ if (offset < node->common.offset) {
+ set_part_req(acb, offset, node->common.offset - offset);
+ }
+
+ pcache_aio_read(acb, node);
+
+ offset = node->common.offset + node->common.bytes;
+ if (end_offs <= offset) {
+ break;
+ }
+
+ bytes = end_offs - offset;
+ node = rbcache_search(s->cache, offset, bytes);
+ if (node == NULL) {
+ set_part_req(acb, offset, bytes);
+ break;
+ }
+ } while (true);
+}
+
enum {
CACHE_MISS,
CACHE_HIT,
@@ -444,7 +491,9 @@ static int pcache_lookup_data(PCacheAIOCBRead *acb)
return CACHE_HIT;
}
- return PARTIAL_CACHE_HIT;
+ pickup_parts_of_cache(acb, node, acb->offset, acb->bytes);
+
+ return acb->part.qiov.niov == 0 ? CACHE_HIT : PARTIAL_CACHE_HIT;
}
static coroutine_fn int pcache_co_preadv(BlockDriverState *bs, uint64_t offset,
@@ -471,9 +520,13 @@ static coroutine_fn int pcache_co_preadv(BlockDriverState
*bs, uint64_t offset,
update_req_stats(s->req_stats, offset, bytes);
status = pcache_lookup_data(&acb);
- if (status == CACHE_MISS || status == PARTIAL_CACHE_HIT) {
+ if (status == CACHE_MISS) {
bdrv_aio_preadv(bs->file, offset, qiov, bytes,
pcache_aio_read_cb, &acb);
+ } else if (status == PARTIAL_CACHE_HIT) {
+ assert(acb.part.qiov.niov != 0);
+ bdrv_aio_preadv(bs->file, acb.part.offset, &acb.part.qiov,
+ acb.part.bytes, pcache_aio_read_cb, &acb);
}
pcache_readahead_request(&acb);
--
2.10.1
- [Qemu-devel] [PATCH v1 07/18] block/pcache: skip large aio read, (continued)
- [Qemu-devel] [PATCH v1 07/18] block/pcache: skip large aio read, Pavel Butsykin, 2016/11/15
- [Qemu-devel] [PATCH v1 04/18] util/rbcache: range-based cache core, Pavel Butsykin, 2016/11/15
- [Qemu-devel] [PATCH v1 13/18] block/pcache: inflight readahead request waiting for aio read, Pavel Butsykin, 2016/11/15
- [Qemu-devel] [PATCH v1 10/18] block/pcache: skip readahead for unallocated clusters, Pavel Butsykin, 2016/11/15
- [Qemu-devel] [PATCH v1 05/18] tests/test-rbcache: add test cases, Pavel Butsykin, 2016/11/15
- [Qemu-devel] [PATCH v1 14/18] backup/pcache: pick up parts of the cache,
Pavel Butsykin <=
- [Qemu-devel] [PATCH v1 08/18] block/pcache: updating statistics for overlapping requests, Pavel Butsykin, 2016/11/15
- [Qemu-devel] [PATCH v1 12/18] block/pcache: add reading data from the cache, Pavel Butsykin, 2016/11/15
- [Qemu-devel] [PATCH v1 03/18] util/rbtree: add rbtree from linux kernel, Pavel Butsykin, 2016/11/15
- [Qemu-devel] [PATCH v1 02/18] block/pcache: empty pcache driver filter, Pavel Butsykin, 2016/11/15
[Qemu-devel] [PATCH v1 06/18] block/pcache: statistics collection read requests, Pavel Butsykin, 2016/11/15
[Qemu-devel] [PATCH v1 11/18] block/pcache: cache invalidation on AIO write requests, Pavel Butsykin, 2016/11/15
[Qemu-devel] [PATCH v1 15/18] block/pcache: drop used pcache nodes, Pavel Butsykin, 2016/11/15