qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Malinka Rellikwodahs" <aelmalinka@gmail.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] kqemu accelerator page fault
Date: Wed, 7 May 2008 11:37:23 -0400	[thread overview]
Message-ID: <aa2a0fc0805070837h7b42c7chd7a9c7e43545c7eb@mail.gmail.com> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 1150 bytes --]

i've been part of a project that's been creating cluster servers running
windows xp, using qemu on 64bit linux, xp is 32-bit, we were running fine
for a few months and then more recently something changed and it's causing
instability in kqemu, which is causing our xp side servers to just stop
running, we use gentoo linux, which has apparently applied a patch, but that
seems to only have to do with qcow images, since we're using raw images on
lvm partitions i don't believe it is having any affect, i know some c code
and if given the right direction would be willing to trace down what's
causing this instability and help fix it, as a note we have experimented
with the xp memory model turning on large system cache and stopping xp from
writing kernel to pagefile and it seems to have made large improvement (have
not seen crashes since) however it would be nice to at least know what is
causing this issue and how to fix it properly, so we know it doesn't come
back to hurt us, i've attached the gentoo patches just in case for whatever
reason they are relevant, if someone could help me figure out what is going
on it would be much appreciated

[-- Attachment #1.2: Type: text/html, Size: 1187 bytes --]

[-- Attachment #2: qemu-softmmu-0.9.1-block-device-address-range.patch --]
[-- Type: application/octet-stream, Size: 7904 bytes --]

diff -rup kvm-60.orig/qemu/block.c kvm-60.new/qemu/block.c
--- kvm-60.orig/qemu/block.c	2008-02-26 18:44:28.000000000 -0500
+++ kvm-60.new/qemu/block.c	2008-02-26 18:44:52.000000000 -0500
@@ -124,6 +124,60 @@ void path_combine(char *dest, int dest_s
     }
 }
 
+static int bdrv_rd_badreq_sectors(BlockDriverState *bs,
+                                  int64_t sector_num, int nb_sectors)
+{
+    return
+        nb_sectors < 0 ||
+        sector_num < 0 ||
+        nb_sectors > bs->total_sectors ||
+        sector_num > bs->total_sectors - nb_sectors;
+}
+
+static int bdrv_rd_badreq_bytes(BlockDriverState *bs,
+                                int64_t offset, int count)
+{
+    int64_t size = bs->total_sectors << SECTOR_BITS;
+    return
+        count < 0 ||
+        size < 0 ||
+        count > size ||
+        offset > size - count;
+}
+
+static int bdrv_wr_badreq_sectors(BlockDriverState *bs,
+                                  int64_t sector_num, int nb_sectors)
+{
+    if (sector_num < 0 ||
+        nb_sectors < 0)
+        return 1;
+
+    if (sector_num > bs->total_sectors - nb_sectors) {
+        if (bs->autogrow)
+            bs->total_sectors = sector_num + nb_sectors;
+        else
+            return 1;
+    }
+    return 0;
+}
+
+static int bdrv_wr_badreq_bytes(BlockDriverState *bs,
+                                int64_t offset, int count)
+{
+    int64_t size = bs->total_sectors << SECTOR_BITS;
+    if (count < 0 ||
+        offset < 0)
+        return 1;
+
+    if (offset > size - count) {
+        if (bs->autogrow)
+            bs->total_sectors = (offset + count + SECTOR_SIZE - 1) >> SECTOR_BITS;
+        else
+            return 1;
+    }
+    return 0;
+}
+
 
 static void bdrv_register(BlockDriver *bdrv)
 {
@@ -332,6 +386,10 @@ int bdrv_open2(BlockDriverState *bs, con
     bs->read_only = 0;
     bs->is_temporary = 0;
     bs->encrypted = 0;
+    bs->autogrow = 0;
+
+    if (flags & BDRV_O_AUTOGROW)
+        bs->autogrow = 1;
 
     if (flags & BDRV_O_SNAPSHOT) {
         BlockDriverState *bs1;
@@ -376,6 +434,7 @@ int bdrv_open2(BlockDriverState *bs, con
     }
     bs->drv = drv;
     bs->opaque = qemu_mallocz(drv->instance_size);
+    bs->total_sectors = 0; /* driver will set if it does not do getlength */
     if (bs->opaque == NULL && drv->instance_size > 0)
         return -1;
     /* Note: for compatibility, we open disk image files as RDWR, and
@@ -441,6 +500,7 @@ void bdrv_close(BlockDriverState *bs)
         bs->drv = NULL;
 
         /* call the change callback */
+        bs->total_sectors = 0;
         bs->media_changed = 1;
         if (bs->change_cb)
             bs->change_cb(bs->change_opaque);
@@ -506,6 +566,8 @@ int bdrv_read(BlockDriverState *bs, int6
     if (!drv)
         return -ENOMEDIUM;
 
+    if (bdrv_rd_badreq_sectors(bs, sector_num, nb_sectors))
+        return -EDOM;
     if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
             memcpy(buf, bs->boot_sector_data, 512);
         sector_num++;
@@ -546,6 +608,8 @@ int bdrv_write(BlockDriverState *bs, int
         return -ENOMEDIUM;
     if (bs->read_only)
         return -EACCES;
+    if (bdrv_wr_badreq_sectors(bs, sector_num, nb_sectors))
+        return -EDOM;
     if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
         memcpy(bs->boot_sector_data, buf, 512);
     }
@@ -671,6 +735,8 @@ int bdrv_pread(BlockDriverState *bs, int
         return -ENOMEDIUM;
     if (!drv->bdrv_pread)
         return bdrv_pread_em(bs, offset, buf1, count1);
+    if (bdrv_rd_badreq_bytes(bs, offset, count1))
+        return -EDOM;
     return drv->bdrv_pread(bs, offset, buf1, count1);
 }
 
@@ -686,6 +752,8 @@ int bdrv_pwrite(BlockDriverState *bs, in
         return -ENOMEDIUM;
     if (!drv->bdrv_pwrite)
         return bdrv_pwrite_em(bs, offset, buf1, count1);
+    if (bdrv_wr_badreq_bytes(bs, offset, count1))
+        return -EDOM;
     return drv->bdrv_pwrite(bs, offset, buf1, count1);
 }
 
@@ -1091,6 +1159,8 @@ int bdrv_write_compressed(BlockDriverSta
         return -ENOMEDIUM;
     if (!drv->bdrv_write_compressed)
         return -ENOTSUP;
+    if (bdrv_wr_badreq_sectors(bs, sector_num, nb_sectors))
+        return -EDOM;
     return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
 }
 
@@ -1237,6 +1307,8 @@ BlockDriverAIOCB *bdrv_aio_read(BlockDri
 
     if (!drv)
         return NULL;
+    if (bdrv_rd_badreq_sectors(bs, sector_num, nb_sectors))
+        return NULL;
 
     /* XXX: we assume that nb_sectors == 0 is suppored by the async read */
     if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
@@ -1268,6 +1340,8 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDr
         return NULL;
     if (bs->read_only)
         return NULL;
+    if (bdrv_wr_badreq_sectors(bs, sector_num, nb_sectors))
+        return NULL;
     if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
         memcpy(bs->boot_sector_data, buf, 512);
     }
diff -rup kvm-60.orig/qemu/block.h kvm-60.new/qemu/block.h
--- kvm-60.orig/qemu/block.h	2008-01-20 07:35:04.000000000 -0500
+++ kvm-60.new/qemu/block.h	2008-02-26 18:44:52.000000000 -0500
@@ -45,6 +45,7 @@ typedef struct QEMUSnapshotInfo {
                                      it (default for
                                      bdrv_file_open()) */
 #define BDRV_O_DIRECT      0x0020
+#define BDRV_O_AUTOGROW    0x0040 /* Allow backing file to extend when writing past end of file */
 
 #ifndef QEMU_IMG
 void bdrv_info(void);
diff -rup kvm-60.orig/qemu/block_int.h kvm-60.new/qemu/block_int.h
--- kvm-60.orig/qemu/block_int.h	2008-01-20 07:35:04.000000000 -0500
+++ kvm-60.new/qemu/block_int.h	2008-02-26 18:44:52.000000000 -0500
@@ -97,6 +97,7 @@ struct BlockDriverState {
     int locked;    /* if true, the media cannot temporarily be ejected */
     int encrypted; /* if true, the media is encrypted */
     int sg;        /* if true, the device is a /dev/sg* */
+    int autogrow;  /* if true, the backing store can auto-extend to allocate new extents */
     /* event callback when inserting/removing */
     void (*change_cb)(void *opaque);
     void *change_opaque;
diff -rup kvm-60.orig/qemu/block-qcow2.c kvm-60.new/qemu/block-qcow2.c
--- kvm-60.orig/qemu/block-qcow2.c	2008-01-20 07:35:04.000000000 -0500
+++ kvm-60.new/qemu/block-qcow2.c	2008-02-26 18:44:52.000000000 -0500
@@ -191,7 +191,7 @@ static int qcow_open(BlockDriverState *b
     int len, i, shift, ret;
     QCowHeader header;
 
-    ret = bdrv_file_open(&s->hd, filename, flags);
+    ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_AUTOGROW);
     if (ret < 0)
         return ret;
     if (bdrv_pread(s->hd, 0, &header, sizeof(header)) != sizeof(header))
diff -rup kvm-60.orig/qemu/block-qcow.c kvm-60.new/qemu/block-qcow.c
--- kvm-60.orig/qemu/block-qcow.c	2008-01-20 07:35:04.000000000 -0500
+++ kvm-60.new/qemu/block-qcow.c	2008-02-26 18:44:52.000000000 -0500
@@ -95,7 +95,7 @@ static int qcow_open(BlockDriverState *b
     int len, i, shift, ret;
     QCowHeader header;
 
-    ret = bdrv_file_open(&s->hd, filename, flags);
+    ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_AUTOGROW);
     if (ret < 0)
         return ret;
     if (bdrv_pread(s->hd, 0, &header, sizeof(header)) != sizeof(header))
diff -rup kvm-60.orig/qemu/block-vmdk.c kvm-60.new/qemu/block-vmdk.c
--- kvm-60.orig/qemu/block-vmdk.c	2008-01-20 07:35:04.000000000 -0500
+++ kvm-60.new/qemu/block-vmdk.c	2008-02-26 18:44:52.000000000 -0500
@@ -375,7 +375,7 @@ static int vmdk_open(BlockDriverState *b
         flags = BDRV_O_RDONLY;
     fprintf(stderr, "(VMDK) image open: flags=0x%x filename=%s\n", flags, bs->filename);
 
-    ret = bdrv_file_open(&s->hd, filename, flags);
+    ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_AUTOGROW);
     if (ret < 0)
         return ret;
     if (bdrv_pread(s->hd, 0, &magic, sizeof(magic)) != sizeof(magic))

[-- Attachment #3: kqemu-1.3.0_pre11-sched_h.patch --]
[-- Type: application/octet-stream, Size: 329 bytes --]

--- kqemu-linux.c       2007-07-25 13:41:52.000000000 +0200
+++ kqemu-linux.c.new   2007-07-25 14:02:00.000000000 +0200
@@ -26,6 +26,7 @@
 #include <linux/ioctl.h>
 #include <linux/smp_lock.h>
 #include <linux/miscdevice.h>
+#include <linux/sched.h>
 #include <asm/atomic.h>
 #include <asm/processor.h>
 #include <asm/uaccess.h>

                 reply	other threads:[~2008-05-07 15:37 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=aa2a0fc0805070837h7b42c7chd7a9c7e43545c7eb@mail.gmail.com \
    --to=aelmalinka@gmail.com \
    --cc=qemu-devel@nongnu.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).