From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:53074) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SrVrv-00061i-OC for qemu-devel@nongnu.org; Wed, 18 Jul 2012 11:08:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SrVrq-0000nQ-KA for qemu-devel@nongnu.org; Wed, 18 Jul 2012 11:08:51 -0400 Received: from e06smtp14.uk.ibm.com ([195.75.94.110]:47185) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SrVrq-0000n4-CN for qemu-devel@nongnu.org; Wed, 18 Jul 2012 11:08:46 -0400 Received: from /spool/local by e06smtp14.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 18 Jul 2012 16:08:45 +0100 Received: from d06av10.portsmouth.uk.ibm.com (d06av10.portsmouth.uk.ibm.com [9.149.37.251]) by d06nrmr1507.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q6IF8gMt2494668 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 q6IEkEvF013779 for ; Wed, 18 Jul 2012 10:46:15 -0400 From: Stefan Hajnoczi Date: Wed, 18 Jul 2012 16:07:47 +0100 Message-Id: <1342624074-24650-21-git-send-email-stefanha@linux.vnet.ibm.com> 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> Subject: [Qemu-devel] [RFC v9 20/27] virtio-blk: Add ioscheduler to detect mergable requests List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Anthony Liguori , Stefan Hajnoczi , kvm@vger.kernel.org, "Michael S. Tsirkin" , Khoa Huynh , Paolo Bonzini , Asias He --- 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) */ -- 1.7.10.4