All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <levinsasha928@gmail.com>
To: penberg@kernel.org
Cc: kvm@vger.kernel.org, Sasha Levin <levinsasha928@gmail.com>
Subject: [PATCH] kvm tools: Use mmap for working with disk image V3
Date: Sat,  9 Apr 2011 15:19:05 +0300	[thread overview]
Message-ID: <1302351545-5214-1-git-send-email-levinsasha928@gmail.com> (raw)

Attempt to use mmap first for working with a disk image, if the attempt is failed (for example, large image on a 32bit system) fallback to using read/write.

Performance (kB/s) test using bonnie++ showed the following improvement:

kvm cmdline: ./kvm run --mem=256 --image=./work/vms/gentoo.img --kernel=/boot/bzImage-git
bonnie++ cmdline: bonnie++ -u 0

Before:
Version  1.96       ------Sequential Output----- --Sequential Input- -Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
tux            480M   673 100 308017  61 288156  49  3286  99 892186  76 +++++ +++
Latency             12998us   50992us   35993us    3000us    1999us     201ms
Version  1.96       ------Sequential Create------ --------Random Create--------
tux                 -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16 +++++ +++ +++++ +++ +++++ +++ +++++ +++ +++++ +++ +++++ +++
Latency              3000us    1000us    1000us    1000us    1998us    1000us

After:
Version  1.96       ------Sequential Output------ --Sequential Input- --Random-
Concurrency   1     -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
tux            480M   672  99 415549  45 310350  52  3495  99 910360  83 +++++ +++
Latency             12998us    7998us   23996us    3998us    1000us     116ms
Version  1.96       ------Sequential Create------ --------Random Create--------
tux                 -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16 +++++ +++ +++++ +++ +++++ +++ +++++ +++ +++++ +++ +++++ +++
Latency              1000us    1000us    1000us    2000us    1000us    1999us

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 tools/kvm/disk-image.c             |   54 +++++++++++++++++++++++++++++------
 tools/kvm/include/kvm/disk-image.h |    2 +-
 2 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/tools/kvm/disk-image.c b/tools/kvm/disk-image.c
index 9deaf45..dbae1e4 100644
--- a/tools/kvm/disk-image.c
+++ b/tools/kvm/disk-image.c
@@ -13,21 +13,31 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-struct disk_image *disk_image__new(int fd, uint64_t size, struct disk_image_operations *ops)
+static int raw_image__read_sector_mmap(struct disk_image *self, uint64_t sector, void *dst, uint32_t dst_len)
 {
-	struct disk_image *self;
+	uint64_t offset = sector << SECTOR_SHIFT;
 
-	self		= malloc(sizeof *self);
-	if (!self)
-		return NULL;
+	if (offset + dst_len > self->size)
+		return -1;
 
-	self->fd	= fd;
-	self->size	= size;
-	self->ops	= ops;
+	memcpy(dst, self->priv + offset, dst_len);
 
-	return self;
+	return 0;
 }
 
+static int raw_image__write_sector_mmap(struct disk_image *self, uint64_t sector, void *src, uint32_t src_len)
+{
+	uint64_t offset = sector << SECTOR_SHIFT;
+
+	if (offset + src_len > self->size)
+		return -1;
+
+	memcpy(self->priv + offset, src, src_len);
+
+	return 0;
+}
+
+
 static int raw_image__read_sector(struct disk_image *self, uint64_t sector, void *dst, uint32_t dst_len)
 {
 	uint64_t offset = sector << SECTOR_SHIFT;
@@ -59,6 +69,27 @@ static struct disk_image_operations raw_image_ops = {
 	.write_sector		= raw_image__write_sector,
 };
 
+static struct disk_image_operations raw_image_mmap_ops = {
+	.read_sector		= raw_image__read_sector_mmap,
+	.write_sector		= raw_image__write_sector_mmap,
+};
+
+struct disk_image *disk_image__new(int fd, uint64_t size)
+{
+	struct disk_image *self;
+
+	self		= malloc(sizeof *self);
+	if (!self)
+		return NULL;
+
+	self->fd	= fd;
+	self->size	= size;
+	self->priv	= mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_NORESERVE, fd, 0);
+	self->ops 	= (self->priv == MAP_FAILED) ? &raw_image_ops : &raw_image_mmap_ops;
+	
+	return self;
+}
+
 static struct disk_image *raw_image__probe(int fd)
 {
 	struct stat st;
@@ -66,7 +97,7 @@ static struct disk_image *raw_image__probe(int fd)
 	if (fstat(fd, &st) < 0)
 		return NULL;
 
-	return disk_image__new(fd, st.st_size, &raw_image_ops);
+	return disk_image__new(fd, st.st_size);
 }
 
 struct disk_image *disk_image__open(const char *filename)
@@ -97,6 +128,9 @@ void disk_image__close(struct disk_image *self)
 	if (self->ops->close)
 		self->ops->close(self);
 
+	if (self->priv != MAP_FAILED)
+		munmap(self->priv, self->size);
+
 	if (close(self->fd) < 0)
 		warning("close() failed");
 
diff --git a/tools/kvm/include/kvm/disk-image.h b/tools/kvm/include/kvm/disk-image.h
index df0a15d..8b78657 100644
--- a/tools/kvm/include/kvm/disk-image.h
+++ b/tools/kvm/include/kvm/disk-image.h
@@ -22,7 +22,7 @@ struct disk_image {
 };
 
 struct disk_image *disk_image__open(const char *filename);
-struct disk_image *disk_image__new(int fd, uint64_t size, struct disk_image_operations *ops);
+struct disk_image *disk_image__new(int fd, uint64_t size);
 void disk_image__close(struct disk_image *self);
 
 static inline int disk_image__read_sector(struct disk_image *self, uint64_t sector, void *dst, uint32_t dst_len)
-- 
1.7.5.rc1


             reply	other threads:[~2011-04-09 12:19 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-09 12:19 Sasha Levin [this message]
2011-04-09 12:38 ` [PATCH] kvm tools: Use mmap for working with disk image V3 Pekka Enberg
2011-04-09 13:26 ` Anthony Liguori
2011-04-09 13:34   ` Pekka Enberg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1302351545-5214-1-git-send-email-levinsasha928@gmail.com \
    --to=levinsasha928@gmail.com \
    --cc=kvm@vger.kernel.org \
    --cc=penberg@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.