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).