From patchwork Mon Aug 29 17:10:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Butsykin X-Patchwork-Id: 9304569 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 32FFC601C0 for ; Mon, 29 Aug 2016 21:56:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1287328615 for ; Mon, 29 Aug 2016 21:56:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 034BC2876C; Mon, 29 Aug 2016 21:56:33 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAD_ENC_HEADER,BAYES_00, DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E2FCF28615 for ; Mon, 29 Aug 2016 21:56:31 +0000 (UTC) Received: from localhost ([::1]:45948 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1beUXf-0006jo-3Q for patchwork-qemu-devel@patchwork.kernel.org; Mon, 29 Aug 2016 17:56:31 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46262) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1beUOR-0007Bw-7h for qemu-devel@nongnu.org; Mon, 29 Aug 2016 17:47:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1beUOP-0002vP-Pw for qemu-devel@nongnu.org; Mon, 29 Aug 2016 17:46:59 -0400 Received: from mail-eopbgr10139.outbound.protection.outlook.com ([40.107.1.139]:61843 helo=EUR02-HE1-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1beUOJ-0002uY-CE; Mon, 29 Aug 2016 17:46:51 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=5iX+6KY7hRfrAJ0AXq4dEZXVidWh9d2XFHfIMO7Ba0M=; b=YMJuBWjUJTGVCuBj6fkKsYOMfhr9nRbY3Y+NDePYvh0PgB+zVZXae9ERSt4w08K3Hp0V8EU4bqafOaIQMzpC3Qpk2/N+cNdx5Sl1WrIKS7k4eWzGMmF+xUi6/QK+H3Sa0gK3ocFBvv+Q/W7fPXWzM1pC2L6WygTY5lG0qXIujWc= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=pbutsykin@virtuozzo.com; Received: from pavelb-Z68P-DS3.sw.ru (195.214.232.10) by AM5PR0802MB2547.eurprd08.prod.outlook.com (10.175.45.23) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.587.13; Mon, 29 Aug 2016 17:11:28 +0000 From: Pavel Butsykin To: , Date: Mon, 29 Aug 2016 20:10:16 +0300 Message-ID: <20160829171021.4902-18-pbutsykin@virtuozzo.com> X-Mailer: git-send-email 2.8.3 In-Reply-To: <20160829171021.4902-1-pbutsykin@virtuozzo.com> References: <20160829171021.4902-1-pbutsykin@virtuozzo.com> MIME-Version: 1.0 X-Originating-IP: [195.214.232.10] X-ClientProxiedBy: AM5PR0901CA0011.eurprd09.prod.outlook.com (10.164.186.149) To AM5PR0802MB2547.eurprd08.prod.outlook.com (10.175.45.23) X-MS-Office365-Filtering-Correlation-Id: e364ef5e-7ac4-4725-c888-08d3d02f846a X-Microsoft-Exchange-Diagnostics: 1; AM5PR0802MB2547; 2:EACLmNDQPFzWa+ZOuy+IOkZS5D5xwstKmzL89zxhK1JVLb8+2fWQQTcbUydxYkdCeE+ZMH/WlMIc3UmpF9Y35umJu+e5W6tCAHOP+KJaMF+y8u8tKB9HWgRZ8UKH1gXYlkSMwSPWdhAokRkiYgTh7EDiisX0HubulhDRjrZaKnkg00EP02+2uQRQxSuvlNvT; 3:OW+WjUZvHozL4WmghqQv0di6XIA2lk0CIeqs53J4Vdn25ZWWTr3Q+kYI1n0mlndCDd4KK5iN9iPys781JcRBki7jq+M3niv5LUGWmDswjtmMZvcqv2647g0Jj4ot/RvR; 25:oAluwaXW2GtDH9tcFoY9whFYqZ+5tnRg7n9dVQdCJzzEn3liyGCNfK28d0n3ubhT/UvOXC16Ah4mt/pMMgarlJML0oWkp+VhDkkSbkMhq7F+EiPWTBAgX72lIQzH4Tjy0iFGs8MfgSqZ0az9j3JAmTZFna1xTud7ZG2qvhSI340YwPkYaNurQorg1fV8krrktVmU+WPUpWFqwE+YZebYiPPMbe2xhnOgNWCMheI+k7sAHr8xyEfUmGJUVXMgxxelo10hFds7yHlmoj2LOMv2EmildSHDGshDFFEDmDqOUuZ0sm4ahzJi49zoXg1z4YBHpwdU94qo6+h6VgbBhQ3jZJUlIlTVt0eMUb1O6Dx+0LcbuOW2Y8tWDffm1uws2cCoiDhgk26Smm8cjI56/s+BtdfOxyXfmlpVe4tH1ZdHbmw= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:AM5PR0802MB2547; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0802MB2547; 31:BXz+F8fyHleO7odqNz9pprm9jFTUkOrqbzEcHCCIhPXl8P2Bp/UquZl2rrgBYHDV0NVWGEW/KL2I/+Eghsh3wsNRk0mmvKga9tc9VwmLz9DMNjsR5LxJ1V4rWe3c2K+V8SoblUVFAXMmMkBDTqXMZ+mN54lAvV9lHMeDIKVo8qV5OiuOlOBVKn2FGrdKos/5/pXYcsr8L3GLgXRk7GV+trasSuBNSIdtUin63ffzvG4=; 4:bHgWlidrxXVu6pNsYxgU5yWn1DO86xbHRdW2AZk6SXR1UHIibctQvYwMKtydKo593Kbup9ROQ3crQGQH6E5+bR3EnNAX0IYIKVzyZ+J9UY7KI6pPb9HWQ7KmrjTOPdzoYPa2Z/BnYSsnqqE7xe4Zfn241DoZBqS6o4wgslm+oh41bKsud38sWfsymRPUrM7zcVLRxkALUWbtUQnY28CVh4cqC8NjD9BKYNgVRL4yGW14iR2OhNn1diYCjl4GaoWmWvpqrnkY5P4xSalkm3iRCFxcMylZk1n+9JT6LaqHjmfAS8HIJfSmDhg2ePSzmJ58WVFQ4lohrYP5tcIY5w4FAYp/9x+ZMBp0uxLob/fX26yumuHDEGWfx4p3zqL0yl1NoQLDX6CUugo3LB+eQApadHmviL2AU5QlmgWW6TRnS9A= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040176)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(6042046)(6043046); SRVR:AM5PR0802MB2547; BCL:0; PCL:0; RULEID:; SRVR:AM5PR0802MB2547; X-Forefront-PRVS: 0049B3F387 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(4630300001)(6009001)(7916002)(199003)(189002)(3846002)(305945005)(77096005)(86362001)(1076002)(53416004)(92566002)(68736007)(42186005)(97736004)(5001770100001)(47776003)(105586002)(2906002)(6116002)(189998001)(50986999)(4326007)(48376002)(586003)(2950100001)(5003940100001)(50466002)(66066001)(19580405001)(19580395003)(76176999)(69596002)(5660300001)(229853001)(101416001)(36756003)(7736002)(8676002)(106356001)(50226002)(7846002)(81156014)(33646002)(81166006)(21314002)(217873001); DIR:OUT; SFP:1102; SCL:1; SRVR:AM5PR0802MB2547; H:pavelb-Z68P-DS3.sw.ru; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: virtuozzo.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM5PR0802MB2547; 23:X/a+2swI+LWvt1cb0yH9+GiT3lS9wuiN1dV8q7T?= =?us-ascii?Q?mMLsjgsT2p+XvZMTmB86KNeVvJrjlqMzTqzOtn6m7ebN1Uv+jSOweEsU9Scv?= =?us-ascii?Q?3QZSYgzv81nvaMIGoh8BRBU20vDHdoJ94ZIh1OCbVQHXWw8B2cSfGAeR9BQ4?= =?us-ascii?Q?b3Y+Iby/p+UUjpMmMtUXADXB3nVXy2tFB1QypWBraGg80ejiX1/HxNabbmVf?= =?us-ascii?Q?rB5k5udXtYEWG6HBG6MZ9YTYyqguppX/MP8FmagulwOGnQQmj8zNEc/yDhvm?= =?us-ascii?Q?LEZ4okZyd4b1ZFhwpgzFBzZRwtKpdi11In1SzV409gOsMr2XVK12lQfBDquW?= =?us-ascii?Q?PL6ynIMzd0xQARepODr7cv3RsmddkUhcm3Khh2gFnLHHI1GtNrf6HZry0efi?= =?us-ascii?Q?R4KV4t/QvUQL72FWsyx+m8cypJIwu1wbtM1GKM9oiwkqSnZqcHLEFgqg5SYA?= =?us-ascii?Q?H6M30+Cv7flojdnrTVSyUJOX4xnJfpHNT66jrZuWUsjkDt6LXZzIw4ckMwzk?= =?us-ascii?Q?fa9CdgXkCjRCK54blE4kXcIgV7T4+BwewugOO8SlaxQkFoNlLLfIfAymfmaO?= =?us-ascii?Q?ptU9YsYwYImRNagPo+Lr79WHoxkrLiNMPtkTG5UpR+SeG+fcV3OsJGTHzVqe?= =?us-ascii?Q?9mV7TpbOTu4OxRGYmZ4s5/74KBgsJHoN70MpCw2bQssjrfBEmu7X0XI9MC9C?= =?us-ascii?Q?wV+wvZNYV7eugv7p6g/59u0qRABWwNj8NLX2rwvdNjbmNuvfF4Vf4OVKhkTK?= =?us-ascii?Q?0pYpQHQ7GhJS2Ge8jm74GjmQSr7ih7aN3aVNdxmlWuN3JcCfPnlqGExHgH1m?= =?us-ascii?Q?Leillr4YnAV4ALr7BQNys8FmegKhWVieLXI8p+6dCRT3SrdIAc0A9M3/tNPa?= =?us-ascii?Q?6UQlfj04HABVTmWEU50Gdj7aWn2Vzxg/XaspRhSzLZ9+YCDkynG+sMM45auY?= =?us-ascii?Q?moTZKqkj3aknRzsFiPLUzCUkNoY8x6K9n+Hw+y+Q2VeRFteRyr28diR9UnqB?= =?us-ascii?Q?jaPZ8zHlUR3Yh4qCqFNnwKLTMF8O0xec3lVyOaexJ594MU8wFDyLKL6vWgDY?= =?us-ascii?Q?5eYiJScXysymhsKFAsPwK2c8e9CrjQb8KW8cLP4Iaz83IO56QlJw1yr+Ro2/?= =?us-ascii?Q?meZxgM3STnBWM6x2lN52evTdZbnLSGo6YefFjq8F1ZnCn8rDi//ZS1w3n8Cb?= =?us-ascii?Q?D1JwcGchZ7Q0bTxs=3D?= X-Microsoft-Exchange-Diagnostics: 1; AM5PR0802MB2547; 6:T+WbcYG9PqW6/nC8tYTPs386FqbW2+ZR66KA6+ep/sEnTQRcx9vFXvqOplRVtCemE9j5aQiwbY+cISSdFJngZVTVcbwBnEdd3BKP0/vu0yw0im3lQwgdq9KOGLGCIVCdX96NHWNZlOL3QB1IgWBUO70XgoqjLZ72nOK7xjLfGQVH7PV7udJAGwd2ileigtwFPaAmOkWZf2rnLYliMQFhtH8IAG4IwZ+SxKid5AQ3bAKfP81+IYRm+hRWqGChkAJXOakEIO0RHMG/GXvti3pMYprbulHZY597L8/0pmu5EIzzRsXcshsLE47NZXiWFm2Q; 5:UsCU6udWOfTl0zmoY0P9IcsH4Lg31qQUYwynyCbRMXtqKLS0yOiqZRPpqwpu3r/gVox1Pgj9HaBC1tedIcJRCDWAxJbqg8/OddnkZP7QdTvTqWmil25F2Hpg1vh2xvsIBZ0JfRq1C7g9rph1+I8Qdg==; 24:qt9U19c1ND84yxn1wdz0RM2GHGUzdPh3YNM2iyQzRIJEYih6YhyWRUBwiCMpuftSZtWaLYNktZGGvMxGRvYvWW46wwjk7jtJKIdHiykC4/c=; 7:6Q3gTx2X/rxWVew6tvy/OM50ZdD0Ty6w/gnOd58sDOKCeJnk2WG235re0mcy0xUjJUw3uuM9srM+ILtndicrImJnVvzD69ROQJeCQJzvopJ7dHhF5GB9k1/3QqDccYWgBRZhD78E2OgcX9W96lsbDwb6+SPjrwlO5CGOydtbMnHq4vXVnbYlUTxuyKsiEUsm//pBkLzMZjUH0EnrUzfecAiNTEfdmFb0iiHdqogARPRY7JX8E0gmUbn3TZWoM7gu SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM5PR0802MB2547; 20:pU3xSD++pDmns83KUbc8IT9f/MSZa4B6yPu2vXJcMfLfGe2/F9FdcbiwZENHzOu2TSkfJYhiwLsKQCfN0/TyEmsUSO8/O2i2X/hy/veMIRu6rfsdPT/KOQVL1eD3+6HWTb1Yl1aI4dZMaGBBJmoXna6yM9do+wtGoS6uEiy+lss= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Aug 2016 17:11:28.7598 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0802MB2547 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 40.107.1.139 Subject: [Qemu-devel] [PATCH RFC v2 17/22] block/pcache: skip readahead for non-sequential requests X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, famz@redhat.com, mreitz@redhat.com, stefanha@redhat.com, den@openvz.org, jsnow@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP When randomly reading data will be a lot of readahead, resulting in a loss of productivity. In order to avoid added checking the requests line before making the readahead. It also makes no sense to cache new requests, because a cache hit on this data is very unlikely. Signed-off-by: Pavel Butsykin --- block/pcache.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 138 insertions(+), 3 deletions(-) diff --git a/block/pcache.c b/block/pcache.c index ae7ac8d..7a317fc 100644 --- a/block/pcache.c +++ b/block/pcache.c @@ -73,6 +73,10 @@ typedef struct PCNode { CoMutex lock; } PCNode; +typedef struct LRNode { + BlockNode cm; +} LRNode; + typedef struct ReqStor { struct { struct RbRoot root; @@ -91,10 +95,12 @@ typedef struct BDRVPCacheState { BlockDriverState **bs; ReqStor pcache; + ReqStor lreq; struct { uint32_t cache_size; uint32_t readahead_size; + uint32_t lreq_pool_size; } cfg; #ifdef PCACHE_DEBUG @@ -166,6 +172,7 @@ static QemuOptsList runtime_opts = { #define MB_BITS 20 #define PCACHE_DEFAULT_CACHE_SIZE (4 << MB_BITS) #define PCACHE_DEFAULT_READAHEAD_SIZE (128 << KB_BITS) +#define PCACHE_DEFAULT_POOL_STAT_SIZE (1 << MB_BITS) enum { NODE_SUCCESS_STATUS = 0, @@ -181,6 +188,7 @@ enum { }; #define PCNODE(_n) ((PCNode *)(_n)) +#define LRNODE(_n) ((LRNode *)(_n)) static inline void pcache_node_unref(BDRVPCacheState *s, PCNode *node) { @@ -262,6 +270,11 @@ static PCNode *pcache_node_search(struct RbRoot *root, RbNodeKey *key) return node == NULL ? NULL : pcache_node_ref(node); } +static inline LRNode *lreq_node_search(struct RbRoot *root, RbNodeKey *key) +{ + return node_search(root, key); +} + static void *node_insert(struct RbRoot *root, BlockNode *node) { struct RbNode **new = &(root->rb_node), *parent = NULL; @@ -288,6 +301,11 @@ static inline PCNode *pcache_node_insert(struct RbRoot *root, PCNode *node) return pcache_node_ref(node_insert(root, &node->cm)); } +static inline LRNode *lreq_node_insert(struct RbRoot *root, LRNode *node) +{ + return node_insert(root, &node->cm); +} + static inline void *pcache_node_alloc(RbNodeKey* key) { PCNode *node = g_slice_alloc(sizeof(*node)); @@ -364,6 +382,34 @@ static void pcache_try_shrink(BDRVPCacheState *s) } } +static void lreq_try_shrink(BDRVPCacheState *s) +{ + while (s->lreq.curr_size > s->cfg.lreq_pool_size) { + LRNode *rmv_node; + /* XXX: need to filter large requests */ + if (QTAILQ_EMPTY(&s->lreq.lru.list)) { + DPRINTF("lru lreq list is empty, but curr_size: %d\n", + s->lreq.curr_size); + break; + } + + qemu_co_mutex_lock(&s->lreq.lru.lock); + rmv_node = LRNODE(QTAILQ_LAST(&s->lreq.lru.list, lru_head)); + qemu_co_mutex_unlock(&s->lreq.lru.lock); + + atomic_sub(&s->lreq.curr_size, rmv_node->cm.nb_sectors); + + qemu_co_mutex_lock(&s->lreq.lru.lock); + QTAILQ_REMOVE(&s->lreq.lru.list, &rmv_node->cm, entry); + qemu_co_mutex_unlock(&s->lreq.lru.lock); + + qemu_co_mutex_lock(&s->lreq.tree.lock); + rb_erase(&rmv_node->cm.rb_node, &s->lreq.tree.root); + qemu_co_mutex_unlock(&s->lreq.tree.lock); + g_slice_free1(sizeof(*rmv_node), rmv_node); + } +} + static PrefCachePartReq *pcache_req_get(PrefCacheAIOCB *acb, PCNode *node) { PrefCachePartReq *req = g_slice_alloc(sizeof(*req)); @@ -437,6 +483,34 @@ static inline PCNode *pcache_node_add(PrefCacheAIOCB *acb, RbNodeKey *key) return node; } +static LRNode *lreq_node_add(PrefCacheAIOCB *acb, RbNodeKey *key) +{ + BDRVPCacheState *s = acb->s; + LRNode *new_node = g_slice_alloc(sizeof(*new_node)); + LRNode *found; + + new_node->cm.sector_num = key->num; + new_node->cm.nb_sectors = key->size; + + qemu_co_mutex_lock(&s->lreq.tree.lock); + found = lreq_node_insert(&s->lreq.tree.root, new_node); + qemu_co_mutex_unlock(&s->lreq.tree.lock); + if (found != new_node) { + g_slice_free1(sizeof(*new_node), new_node); + return NULL; + } + + atomic_add(&s->lreq.curr_size, new_node->cm.nb_sectors); + + lreq_try_shrink(s); + + qemu_co_mutex_lock(&s->lreq.lru.lock); + QTAILQ_INSERT_HEAD(&s->lreq.lru.list, &new_node->cm, entry); + qemu_co_mutex_unlock(&s->lreq.lru.lock); + + return new_node; +} + static uint64_t ranges_overlap_size(uint64_t node1, uint32_t size1, uint64_t node2, uint32_t size2) { @@ -552,13 +626,24 @@ enum { static int32_t pcache_prefetch(PrefCacheAIOCB *acb) { + BDRVPCacheState *s = acb->s; RbNodeKey key; - PCNode *node = NULL; + PCNode *node; prefetch_init_key(acb, &key); - if (pcache_node_find_and_create(acb, &key, &node)) { + + /* add request statistics */ + lreq_node_add(acb, &key); + + qemu_co_mutex_lock(&s->pcache.tree.lock); /* XXX: use get_next_node */ + node = pcache_node_search(&s->pcache.tree.root, &key); + qemu_co_mutex_unlock(&s->pcache.tree.lock); + if (node == NULL) { return PREFETCH_NEW_NODE; } + if (node->status == NODE_SUCCESS_STATUS) { + pcache_lru_node_up(s, node); + } /* Node covers the whole request */ if (node->cm.sector_num <= acb->sector_num && @@ -795,6 +880,30 @@ static bool check_allocated_blocks(BlockDriverState *bs, int64_t sector_num, return true; } +static bool check_lreq_sequence(BDRVPCacheState *s, uint64_t sector_num) +{ + RbNodeKey key; + LRNode *node; + uint32_t cache_line_sz = s->cfg.readahead_size; + + if (sector_num <= cache_line_sz) { + return false; + } + /* check is a previous cache block */ + key.num = sector_num - cache_line_sz; + key.size = cache_line_sz; + + qemu_co_mutex_lock(&s->lreq.tree.lock); + node = lreq_node_search(&s->lreq.tree.root, &key); + qemu_co_mutex_unlock(&s->lreq.tree.lock); + if (node == NULL) { /* requests isn't consistent, + * most likely there is no sense to make readahead. + */ + return false; + } + return node->cm.sector_num > key.num ? false : true; +} + static void pcache_readahead_request(BlockDriverState *bs, PrefCacheAIOCB *acb) { BDRVPCacheState *s = acb->s; @@ -803,6 +912,9 @@ static void pcache_readahead_request(BlockDriverState *bs, PrefCacheAIOCB *acb) uint64_t total_sectors = bdrv_nb_sectors(bs); PCNode *node = NULL; + if (!check_lreq_sequence(acb->s, acb->sector_num)) { + return; + } prefetch_init_key(acb, &key); key.num = key.num + key.size; @@ -841,7 +953,13 @@ static BlockAIOCB *pcache_aio_readv(BlockDriverState *bs, PrefCacheAIOCB *acb = pcache_aio_get(bs, sector_num, qiov, nb_sectors, cb, opaque, PCACHE_AIO_READ); int32_t status = pcache_prefetch(acb); - if (status == PREFETCH_FULL_UP) { + if (status == PREFETCH_NEW_NODE) { + BlockAIOCB *ret = bdrv_aio_readv(bs->file, sector_num, qiov, nb_sectors, + cb, opaque); + pcache_readahead_request(bs, acb); + qemu_aio_unref(acb); /* XXX: fix superfluous alloc */ + return ret; + } else if (status == PREFETCH_FULL_UP) { assert(acb->requests.cnt == 0); complete_aio_request(acb); } else { @@ -885,8 +1003,15 @@ static void pcache_state_init(QemuOpts *opts, BDRVPCacheState *s) qemu_co_mutex_init(&s->pcache.lru.lock); s->pcache.curr_size = 0; + s->lreq.tree.root = RB_ROOT; + qemu_co_mutex_init(&s->lreq.tree.lock); + QTAILQ_INIT(&s->lreq.lru.list); + qemu_co_mutex_init(&s->lreq.lru.lock); + s->lreq.curr_size = 0; + s->cfg.cache_size = cache_size >> BDRV_SECTOR_BITS; s->cfg.readahead_size = readahead_size >> BDRV_SECTOR_BITS; + s->cfg.lreq_pool_size = PCACHE_DEFAULT_POOL_STAT_SIZE >> BDRV_SECTOR_BITS; #ifdef PCACHE_DEBUG QTAILQ_INIT(&s->death_node_list); @@ -946,6 +1071,16 @@ static void pcache_close(BlockDriverState *bs) } DPRINTF("used %d nodes\n", cnt); + cnt = 0; + if (!QTAILQ_EMPTY(&s->lreq.lru.list)) { + QTAILQ_FOREACH_SAFE(node, &s->lreq.lru.list, entry, next) { + QTAILQ_REMOVE(&s->lreq.lru.list, node, entry); + g_slice_free1(sizeof(*node), node); + cnt++; + } + } + DPRINTF("used %d lreq nodes\n", cnt); + #ifdef PCACHE_DEBUG if (!QTAILQ_EMPTY(&s->death_node_list)) { cnt = 0;