From patchwork Wed Jul 18 15:07:47 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 1211681 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 3AFF1DFFFD for ; Wed, 18 Jul 2012 15:09:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754840Ab2GRPJE (ORCPT ); Wed, 18 Jul 2012 11:09:04 -0400 Received: from e06smtp13.uk.ibm.com ([195.75.94.109]:56952 "EHLO e06smtp13.uk.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754819Ab2GRPIu (ORCPT ); Wed, 18 Jul 2012 11:08:50 -0400 Received: from /spool/local by e06smtp13.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 18 Jul 2012 16:08:49 +0100 Received: from d06nrmr1707.portsmouth.uk.ibm.com (9.149.39.225) by e06smtp13.uk.ibm.com (192.168.101.143) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 18 Jul 2012 16:08:42 +0100 Received: from d06av10.portsmouth.uk.ibm.com (d06av10.portsmouth.uk.ibm.com [9.149.37.251]) by d06nrmr1707.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q6IF8ge22666550 for ; Wed, 18 Jul 2012 16:08:42 +0100 Received: from d06av10.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av10.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q6IEkEvL013779 for ; Wed, 18 Jul 2012 10:46:15 -0400 Received: from localhost (sig-9-145-185-169.de.ibm.com [9.145.185.169]) by d06av10.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id q6IEkEhY013737; Wed, 18 Jul 2012 10:46:14 -0400 From: Stefan Hajnoczi To: Cc: , Anthony Liguori , Kevin Wolf , Paolo Bonzini , "Michael S. Tsirkin" , Asias He , Khoa Huynh , Stefan Hajnoczi Subject: [RFC v9 20/27] virtio-blk: Add ioscheduler to detect mergable requests Date: Wed, 18 Jul 2012 16:07:47 +0100 Message-Id: <1342624074-24650-21-git-send-email-stefanha@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1342624074-24650-1-git-send-email-stefanha@linux.vnet.ibm.com> References: <1342624074-24650-1-git-send-email-stefanha@linux.vnet.ibm.com> x-cbid: 12071815-2966-0000-0000-000004C240EA Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org --- hw/dataplane/iosched.h | 78 ++++++++++++++++++++++++++++++++++++++++++++++++ hw/virtio-blk.c | 5 ++++ 2 files changed, 83 insertions(+) create mode 100644 hw/dataplane/iosched.h diff --git a/hw/dataplane/iosched.h b/hw/dataplane/iosched.h new file mode 100644 index 0000000..12ebccc --- /dev/null +++ b/hw/dataplane/iosched.h @@ -0,0 +1,78 @@ +#ifndef IOSCHED_H +#define IOSCHED_H + +#include "hw/dataplane/ioq.h" + +typedef struct { + unsigned long iocbs; + unsigned long merges; + unsigned long sched_calls; +} IOSched; + +static int iocb_cmp(const void *a, const void *b) +{ + const struct iocb *iocb_a = a; + const struct iocb *iocb_b = b; + + /* + * Note that we can't simply subtract req2->sector from req1->sector + * here as that could overflow the return value. + */ + if (iocb_a->u.c.offset > iocb_b->u.c.offset) { + return 1; + } else if (iocb_a->u.c.offset < iocb_b->u.c.offset) { + return -1; + } else { + return 0; + } +} + +static size_t iocb_nbytes(struct iocb *iocb) +{ + struct iovec *iov = iocb->u.c.buf; + size_t nbytes = 0; + size_t i; + for (i = 0; i < iocb->u.c.nbytes; i++) { + nbytes += iov->iov_len; + iov++; + } + return nbytes; +} + +static void iosched_init(IOSched *iosched) +{ + memset(iosched, 0, sizeof *iosched); +} + +static void iosched_print_stats(IOSched *iosched) +{ + fprintf(stderr, "iocbs = %lu merges = %lu sched_calls = %lu\n", + iosched->iocbs, iosched->merges, iosched->sched_calls); + memset(iosched, 0, sizeof *iosched); +} + +static void iosched(IOSched *iosched, struct iocb *unsorted[], unsigned int count) +{ + struct iocb *sorted[count]; + struct iocb *last; + unsigned int i; + + if ((++iosched->sched_calls % 1000) == 0) { + iosched_print_stats(iosched); + } + + memcpy(sorted, unsorted, sizeof sorted); + qsort(sorted, count, sizeof sorted[0], iocb_cmp); + + iosched->iocbs += count; + last = sorted[0]; + for (i = 1; i < count; i++) { + if (last->aio_lio_opcode == sorted[i]->aio_lio_opcode && + last->u.c.offset + iocb_nbytes(last) == sorted[i]->u.c.offset) { + iosched->merges++; + } + last = sorted[i]; + } +} + +#endif /* IOSCHED_H */ diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index f67fdb7..75cb0f2 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -22,6 +22,7 @@ #include "hw/dataplane/event-poll.h" #include "hw/dataplane/vring.h" #include "hw/dataplane/ioq.h" +#include "hw/dataplane/iosched.h" #include "kvm.h" enum { @@ -57,6 +58,7 @@ typedef struct { EventHandler notify_handler; /* virtqueue notify handler */ IOQueue ioqueue; /* Linux AIO queue (should really be per dataplane thread) */ + IOSched iosched; /* I/O scheduler */ VirtIOBlockRequest requests[REQ_MAX]; /* pool of requests, managed by the queue */ } VirtIOBlock; @@ -249,6 +251,8 @@ static bool handle_notify(EventHandler *handler) } } + iosched(&s->iosched, s->ioqueue.queue, s->ioqueue.queue_idx); + /* Submit requests, if any */ int rc = ioq_submit(&s->ioqueue); if (unlikely(rc < 0)) { @@ -289,6 +293,7 @@ static void data_plane_start(VirtIOBlock *s) { int i; + iosched_init(&s->iosched); vring_setup(&s->vring, &s->vdev, 0); /* Set up guest notifier (irq) */