From patchwork Tue Aug 9 04:17:50 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhi Yong Wu X-Patchwork-Id: 1047462 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p794La9m030033 for ; Tue, 9 Aug 2011 04:21:36 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750834Ab1HIEVb (ORCPT ); Tue, 9 Aug 2011 00:21:31 -0400 Received: from e6.ny.us.ibm.com ([32.97.182.146]:56154 "EHLO e6.ny.us.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750779Ab1HIEVb (ORCPT ); Tue, 9 Aug 2011 00:21:31 -0400 Received: from d01relay02.pok.ibm.com (d01relay02.pok.ibm.com [9.56.227.234]) by e6.ny.us.ibm.com (8.14.4/8.13.1) with ESMTP id p793vMwk024451 for ; Mon, 8 Aug 2011 23:57:22 -0400 Received: from d01av02.pok.ibm.com (d01av02.pok.ibm.com [9.56.224.216]) by d01relay02.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p794LTGS308660 for ; Tue, 9 Aug 2011 00:21:29 -0400 Received: from d01av02.pok.ibm.com (loopback [127.0.0.1]) by d01av02.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p794LR9B030746 for ; Tue, 9 Aug 2011 01:21:29 -0300 Received: from us.ibm.com (wks563189wss.cn.ibm.com [9.123.136.155] (may be forged)) by d01av02.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with SMTP id p794LMqG030431; Tue, 9 Aug 2011 01:21:22 -0300 Received: by us.ibm.com (sSMTP sendmail emulation); Tue, 9 Aug 2011 12:18:13 +0800 From: Zhi Yong Wu To: qemu-devel@nongnu.org Cc: kvm@vger.kernel.org, stefanha@linux.vnet.ibm.com, mtosatti@redhat.com, anthony@codemonkey.ws, ryanh@us.ibm.com, zwu.kernel@gmail.com, kwolf@redhat.com, pair@us.ibm.com, luowenj@cn.ibm.com, Zhi Yong Wu Subject: [PATCH v5 2/4] block: add the block queue support Date: Tue, 9 Aug 2011 12:17:50 +0800 Message-Id: <1312863472-6901-3-git-send-email-wuzhy@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1312863472-6901-1-git-send-email-wuzhy@linux.vnet.ibm.com> References: <1312863472-6901-1-git-send-email-wuzhy@linux.vnet.ibm.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Tue, 09 Aug 2011 04:21:36 +0000 (UTC) The patch introduce one block queue for QEMU block layer. Signed-off-by: Zhi Yong Wu --- block/blk-queue.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++ block/blk-queue.h | 73 +++++++++++++++++++++++++++ 2 files changed, 214 insertions(+), 0 deletions(-) create mode 100644 block/blk-queue.c create mode 100644 block/blk-queue.h diff --git a/block/blk-queue.c b/block/blk-queue.c new file mode 100644 index 0000000..f36f3e2 --- /dev/null +++ b/block/blk-queue.c @@ -0,0 +1,141 @@ +/* + * QEMU System Emulator queue definition for block layer + * + * Copyright (c) 2011 Zhi Yong Wu + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "block_int.h" +#include "qemu-queue.h" +#include "block/blk-queue.h" + +/* The APIs for block request queue on qemu block layer. + */ + +static void qemu_block_queue_cancel(BlockDriverAIOCB *acb) +{ + qemu_aio_release(acb); +} + +static AIOPool block_queue_pool = { + .aiocb_size = sizeof(struct BlockDriverAIOCB), + .cancel = qemu_block_queue_cancel, +}; + +static void qemu_block_queue_callback(void *opaque, int ret) +{ + BlockDriverAIOCB *acb = opaque; + + qemu_aio_release(acb); +} + +BlockQueue *qemu_new_block_queue(void) +{ + BlockQueue *queue; + + queue = qemu_mallocz(sizeof(BlockQueue)); + + QTAILQ_INIT(&queue->requests); + + return queue; +} + +void qemu_del_block_queue(BlockQueue *queue) +{ + BlockIORequest *request, *next; + + QTAILQ_FOREACH_SAFE(request, &queue->requests, entry, next) { + QTAILQ_REMOVE(&queue->requests, request, entry); + qemu_free(request); + } + + qemu_free(queue); +} + +BlockDriverAIOCB *qemu_block_queue_enqueue(BlockQueue *queue, + BlockDriverState *bs, + BlockRequestHandler *handler, + int64_t sector_num, + QEMUIOVector *qiov, + int nb_sectors, + BlockDriverCompletionFunc *cb, + void *opaque) +{ + BlockIORequest *request; + BlockDriverAIOCB *acb; + + request = qemu_malloc(sizeof(BlockIORequest)); + request->bs = bs; + request->handler = handler; + request->sector_num = sector_num; + request->qiov = qiov; + request->nb_sectors = nb_sectors; + request->cb = cb; + request->opaque = opaque; + + QTAILQ_INSERT_TAIL(&queue->requests, request, entry); + + acb = qemu_aio_get(&block_queue_pool, bs, + qemu_block_queue_callback, opaque); + + request->acb = acb; + + return acb; +} + +int qemu_block_queue_handler(BlockIORequest *request) +{ + int ret; + BlockDriverAIOCB *res; + + /* indicate this req is from block queue */ + request->bs->req_from_queue = true; + + res = request->handler(request->bs, request->sector_num, + request->qiov, request->nb_sectors, + request->cb, request->opaque); + + if (request->acb) { + qemu_block_queue_callback(request->acb, 0); + } + + ret = (res == NULL) ? 0 : 1; + + return ret; +} + +void qemu_block_queue_flush(BlockQueue *queue) +{ + while (!QTAILQ_EMPTY(&queue->requests)) { + BlockIORequest *request = NULL; + int ret = 0; + + request = QTAILQ_FIRST(&queue->requests); + QTAILQ_REMOVE(&queue->requests, request, entry); + + ret = qemu_block_queue_handler(request); + if (ret == 0) { + QTAILQ_INSERT_HEAD(&queue->requests, request, entry); + break; + } + + qemu_free(request); + } +} diff --git a/block/blk-queue.h b/block/blk-queue.h new file mode 100644 index 0000000..281b679 --- /dev/null +++ b/block/blk-queue.h @@ -0,0 +1,73 @@ +/* + * QEMU System Emulator queue declaration for block layer + * + * Copyright (c) 2011 Zhi Yong Wu + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef QEMU_BLOCK_QUEUE_H +#define QEMU_BLOCK_QUEUE_H + +#include "block.h" +#include "qemu-queue.h" +#include "qemu-common.h" + +typedef BlockDriverAIOCB* (BlockRequestHandler) (BlockDriverState *bs, + int64_t sector_num, QEMUIOVector *qiov, + int nb_sectors, BlockDriverCompletionFunc *cb, + void *opaque); + +struct BlockIORequest { + QTAILQ_ENTRY(BlockIORequest) entry; + BlockDriverState *bs; + BlockRequestHandler *handler; + int64_t sector_num; + QEMUIOVector *qiov; + int nb_sectors; + BlockDriverCompletionFunc *cb; + void *opaque; + BlockDriverAIOCB *acb; +}; + +typedef struct BlockIORequest BlockIORequest; + +struct BlockQueue { + QTAILQ_HEAD(requests, BlockIORequest) requests; +}; + +typedef struct BlockQueue BlockQueue; + +BlockQueue *qemu_new_block_queue(void); + +void qemu_del_block_queue(BlockQueue *queue); + +BlockDriverAIOCB *qemu_block_queue_enqueue(BlockQueue *queue, + BlockDriverState *bs, + BlockRequestHandler *handler, + int64_t sector_num, + QEMUIOVector *qiov, + int nb_sectors, + BlockDriverCompletionFunc *cb, + void *opaque); + +int qemu_block_queue_handler(BlockIORequest *request); + +void qemu_block_queue_flush(BlockQueue *queue); +#endif /* QEMU_BLOCK_QUEUE_H */