From patchwork Thu Aug 25 13:44: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: 9299419 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 F2C2760757 for ; Thu, 25 Aug 2016 14:05:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E1B0A292BE for ; Thu, 25 Aug 2016 14:05:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D466029341; Thu, 25 Aug 2016 14:05:09 +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 05FDA292BE for ; Thu, 25 Aug 2016 14:05:08 +0000 (UTC) Received: from localhost ([::1]:56468 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bcvHH-0004wd-3x for patchwork-qemu-devel@patchwork.kernel.org; Thu, 25 Aug 2016 10:05:07 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47256) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bcuyj-0004T9-Mn for qemu-devel@nongnu.org; Thu, 25 Aug 2016 09:46:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bcuyh-0002JI-3r for qemu-devel@nongnu.org; Thu, 25 Aug 2016 09:45:56 -0400 Received: from mail-db5eur01on0113.outbound.protection.outlook.com ([104.47.2.113]:14612 helo=EUR01-DB5-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bcuyY-0002G5-NE; Thu, 25 Aug 2016 09:45:46 -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=aLRRX7NbrGhD5F0XEB/A3ATtBjChAs6SkvNP0ACJPtK8mf73akMkmWwIaVTcNVPnd11OUVdiVOVxyFpS+7ySRbPs3IBrLNAF9Is+Js/FlysXSd3RAONHwfrfcEebcKCODP4RfzReetnmWd9FMz3WsTL3PMzYYCB8sjHzClpdNZQ= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=pbutsykin@virtuozzo.com; Received: from pavelb-Z68P-DS3.sw.ru (195.214.232.10) by DB6PR0802MB2549.eurprd08.prod.outlook.com (10.172.251.147) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.587.9; Thu, 25 Aug 2016 13:45:43 +0000 From: Pavel Butsykin To: , Date: Thu, 25 Aug 2016 16:44:16 +0300 Message-ID: <20160825134421.20231-18-pbutsykin@virtuozzo.com> X-Mailer: git-send-email 2.8.3 In-Reply-To: <20160825134421.20231-1-pbutsykin@virtuozzo.com> References: <20160825134421.20231-1-pbutsykin@virtuozzo.com> MIME-Version: 1.0 X-Originating-IP: [195.214.232.10] X-ClientProxiedBy: AMSPR02CA0013.eurprd02.prod.outlook.com (10.242.225.141) To DB6PR0802MB2549.eurprd08.prod.outlook.com (10.172.251.147) X-MS-Office365-Filtering-Correlation-Id: 88740d12-99b3-4500-5e4e-08d3ccee1ca5 X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2549; 2:IzN6wnHKXjnzGLacHsyz4BgIls4syo4ULYlmkeUz0Q2Tz3ksIzmd+HDrIDqjPbAmWRK4Urx6M4lJROupzVXutK5YF2LghuRYOciZQlaEIkMq7oajI/43gcRVrVakGaaTtDn3TZa2AL4xJDOizXOP2hC2j8uDPwZUYc73cRasYLCcY0L8WLIXLtJo4BA8fO59; 3:OcQSer7BjH9IynSDhqBescCc38hDvUzud8qBISYkMWwsmNDGzh53pqktZy8tfy+pOi99WhU9a5pPbEHJscrOlyB7efwOxl+01/OvQsA4J5jYXsDnpzlG79hoWREJvzuo X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:DB6PR0802MB2549; X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2549; 25:6P5w3w1AzvuOWOkm4nf/Zm33lMCYRF1/IOHReyCYXgk/vMi47P6WvlTQ+bMelSgz1BWh/dk6g1cmcGSEjLAPK8HBKJtnuch5cvG5UIlmQbC3ypbtxvAVArXtWeCg/0Kkqdx45ruLdXUYg51Z8HX4Di789JH82wthC5t1ewOZoHsVDG3LORplYLS9jIq9oiXUvbV39HAg0jmVvQwQiYMFQUfazEMzJdXyUwEtqE/y1i7t7AzIZRbFbVaeUy0IM0xwXaTWw7QT8bvpeaY1rxjSCnOHQEp9tsngxzvRFpGgwg50D9wF1e0aUrFsZMsiCoylFePY5M21HrLetb64dgiypTBKXOVv1XB0j//GIYTr5+FnJR4MHJfWoAlM74nZkdILpctfu2/d7jdlfEjSlttWXZAu2YtdZ7nmy8uDDYZSGkg1BuwMZuKBMPRbfDU9uHly5v8tEdJhfdcGzUoNVcqxBw6MpT/LjPbU4UxzvwCcX1L7dve3aRPO/Y/vfXgzL5jNvBCbMlGYMxy/RH8jQ10ZpQIpo/GEI6RD6hdqMf63LM2sYtxFryulNR5hP4MjtBXUE3Ai3Ch/6zQ3ht//Oq8O9m3E1bSJwASnbogpOPrphZrBnN/oBRlL6mVr5a7RSssXvQFYMatJY51SZd+pHWKtXFO0qsDqW+htMC6wsz8MUHFY1/sSuiPCGXZIoZcmous7Ng+2Emfz6mPsTelDKEgQTw==; 31:gZhuQRdPqO3n+f/e8Ac8wT0Qu4BgO6m0ED3adYVJv44mGrApEYhhpUambliPdh3XIDGfaGVTURvT8B0d6FjyLMD1d3LuSmF4VyM0C0OGRCVwb9MktwDNSUyBiNBbZ2y3Sn+ZMrwaS4pQnNm2btMBSB7wpAviGUxanEFLoi2NvqpcK5vXfRkaQPbc2HYqratUXOgXoIdk1Kal5SVb4WRQ5QQkvsE2HITb5jVfJLQuLcg= 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)(6043046)(6042046); SRVR:DB6PR0802MB2549; BCL:0; PCL:0; RULEID:; SRVR:DB6PR0802MB2549; X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2549; 4:Hi0hgoGI4FUw6LNQJe6n5NK45YluR3FPbj4DKyS0vOKnNHGRuT8NKRdUp8vq5jbFUh9HMwDKvBLMwUMGZ/0ip3n0rkzLvsalQll0QzOu/aIGoaT5+VdxTkIHunQsoV+7OtQw1yivGuU39eu7wU9ZHuMeRxFr41qsh1jMCA8Y/2SYNk5KAkmXSn/9GToG8trvOd3BHj32NzEsPFYmAgAD9VKE0VbH+yWOUVDhRru+AnQmbx6+PPXj7oL86HcMPokq6V5iKZ5VtlPv1I1jJKrlr2g9IyCeRaKtGzS+QLXW7T49hFcgMuFTZHrXxK+MsobIV4vMKSxWQG1Ppwg3XCmqLrcpbWLZisDzLOJP9V2osehQFVxpSA3+NHIPrp2TIezXIA8xo2RwoEnqFrdZ60XnKocr3xsJr0vFd4Sq5dfz2Yo= X-Forefront-PRVS: 0045236D47 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(4630300001)(6009001)(7916002)(189002)(199003)(86362001)(33646002)(1076002)(69596002)(5003940100001)(42186005)(68736007)(189998001)(92566002)(66066001)(106356001)(47776003)(6116002)(3846002)(586003)(36756003)(5001770100001)(97736004)(2906002)(4326007)(2950100001)(5660300001)(76176999)(48376002)(53416004)(105586002)(50466002)(81156014)(8676002)(50226002)(77096005)(81166006)(19580405001)(50986999)(229853001)(101416001)(7846002)(7736002)(305945005)(19580395003)(21314002)(217873001); DIR:OUT; SFP:1102; SCL:1; SRVR:DB6PR0802MB2549; H:pavelb-Z68P-DS3.sw.ru; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A: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; DB6PR0802MB2549; 23:KNLWLlNfWDYfVP7xEzNZHOQlYx2XjbY1mqKz5m6?= =?us-ascii?Q?FzVUBYRXezWUQ5XJasZYEcxqNq/9bQVvdOM8Ogm1jyyq4wkmJaQ6MTfQhASA?= =?us-ascii?Q?laxUQ2CRyDNnL+tw+l5tt99RuS265bFF6Em/hZm/7WUfB3ZFMRsm7fPhN0Pw?= =?us-ascii?Q?v7JyvH69uoPuXMgDmvYZpE3BBcmzbAuLLL3BUVe3vz29ndTF7mxrQoF/MlHg?= =?us-ascii?Q?/f6czPvsV+EITUQ+PmRtCzPZGx0pNPt+SNpbovRRPOZNbc4i+rtxig6UKbU1?= =?us-ascii?Q?gZXLog3Ukq/8dArlNfvGBRYE5WXc9tO+BOvTlaw2wo2xtqeHzGukBELUROPj?= =?us-ascii?Q?osBupTSNhbGyZPolXZ+mPcOmORoZtNbByGXszVDQj2l5t5uhDeW3U1eh5Uzu?= =?us-ascii?Q?yUuHxPix+J/QtGZEnczmPVM4/+jbvqtRQ5635SvGvPq9RIxj2XqzKNkHNfup?= =?us-ascii?Q?jGN3htflQBL2suXVfdPpTGFzwINFm3c+GYIX9HmF+/fgCCSEPIGP881HiLqy?= =?us-ascii?Q?9DFec1n1n/1rftKkQdZfvwaQXso1EpCj6odAeRdiutxYaOvZwo5zCHY5bW7y?= =?us-ascii?Q?NVv2M24mrM/FxaRGLE7Q7MQzDPOlAlHS86Ruy6Yug4CcgvJru13RETGwa342?= =?us-ascii?Q?59PU130kh9mNAvyC/x2rrOWQJygThw5hKmrVxGk2apAnpOzkebXjBKy1YXe9?= =?us-ascii?Q?S0g8cILyEv44OPdcHVm8mEDuoJtnscPXDGMX8synoTe1eRlEcOU86Yi5spI4?= =?us-ascii?Q?bSBW7plm8q3T4ikVFTQ1vYc+eYNGhwWT+ww4X8eK7GDIL0Qo+uo2byXcCgTG?= =?us-ascii?Q?20vprF6LIcOuTmEl6mtJQrHOjZMW7ZmCXFb4jqmXGdE5DspvO/uCIoqfouSo?= =?us-ascii?Q?BzYdA/z7ui9+tDm4gbcPIYM7X72Ewsf4OYYfCYd2f0IAeKyH/HgutpHfWarh?= =?us-ascii?Q?BiOz5Jthc5hrRjfKYHGpXiBBprb8I4dzLkjA98lKlcUJMGj4LBfHd3rFOMV+?= =?us-ascii?Q?4hG0Y+gGmNR8aQdymp2vjf3VNzplwwkaH2fMpOTg4VaVgRd3lELx6IgcSGow?= =?us-ascii?Q?aijHFESInqr0kWNIzHOB8k9Dz8nQBAJDdS4Jksk1vrcyuXtgkqqXMctiB6I5?= =?us-ascii?Q?qjh8RsjDZRh4u0fBkc0sgkpCeYFqe052JG20xkfNELnMPQy5ynDKpht0FWMC?= =?us-ascii?Q?4UwJ7qDp5Ae5RU18=3D?= X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2549; 6:WKTjBEQmrohgTczDTOhA3PgxvlD5EahttpyzAwqQPtu0yaFf5QNbhlPWmWqKOrdcOb55muu/xuSgRHfBhyyyLrlj9XtqI6GJZi/EgJPFEaTtUd9nxapeSnV4MFBsP6CNCtiMej98ZElPksxVb88dW54PyVtq64512lyByp/pIw5bUlsaIW1H9wi7nHY0owL3AiwlRDuX97zFnRdhPLQZl17kGwzKmrtCLV+BaYYvfz3zAkqRfY79+UmHDNiwSB9mOAFW58r57YzDIWlwLRg+dNmNpA34E5whA/61OSeak54BRD1x8X/nghSVyZF2AsOz; 5:UbD5mp6w59nCHtu+XTap1S/WJ2s1MRoxLSS8Zfu/TW/bRwvv1IdAXZQPVLaTd+l55/NUElmpof7QCQxvLv+uZ5IuvP3rJJJ48PJKZ+z56UYc1qUNeL3t6coRWvlaSIHBx5QHvphKpIerkswey+ZvUg==; 24:BdycbEojgM8InfJEK4RXhtnoU2H9bsFl/ofA5MUlpqSNBCCWsQimPFwun/Kzb0M4XHIodsK8MyRB5CAgJXgX313UV+iGrxlI54OsPLmFZDg=; 7:dvNv+5Ju0sSco0ghuZxeAPn/r8QKL09AAUMl2hvHB3WKW+C4rmU2mrfaZhY4fJ6CxhP/EAjKXXyRaOkmfSmsG8B4amJdd8ituQ0ye4sSiy4IsiUHXBKbrDOY2qeKIZ7PpYYaTl5fXDbOQrYU9iSxikQDDQJOvXxsa3asb34vn/glBMqKCb1y1ApJho9oRaxiAD6i5VkF/vgER/WuQXs1YeBxEB6BpcNWbFaOVcFKpQlhX4MvC1/stgPAyvrEIofb SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DB6PR0802MB2549; 20:N5VsEAd7CGdDx0suClYVADtipdhs64ounwH1IOX6mmtzvCXBVyOuvpYe8Cn/gU6uC+mdDrXYOcY8KVtP/lnLtGbn3I00itNf+JeRKwoDkUA//P7ElaBb5B8vAX8jntfJ5WfxkLJeW+32PhbzvZopDDoDQ6Z73ji0sWZXHC/6ikc= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Aug 2016 13:45:43.7458 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB6PR0802MB2549 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 104.47.2.113 Subject: [Qemu-devel] [PATCH RFC 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, den@openvz.org, jsnow@redhat.com, stefanha@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;