* [Qemu-devel] [PATCH] Snapshot block device support
@ 2003-07-02 6:50 Rusty Russell
2003-07-02 9:49 ` [Qemu-devel] " Fabrice Bellard
0 siblings, 1 reply; 9+ messages in thread
From: Rusty Russell @ 2003-07-02 6:50 UTC (permalink / raw)
To: Fabrice Bellard; +Cc: qemu-devel
Hi Fabrice,
I haven't got the IDE emulation to work for me yet (is it
supposed to yet?), but this allows the "-snapshot" option and "C-a s"
to commit the disks. The blocks which change are committed to backing
store, and a bitmap of changed blocks is kept.
Diff + new test file below.
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
tests/test_block.c:
================
#define _GNU_SOURCE /* For lseek64 */
#include "../block.c"
#define NUM_SECTORS 2560
static int memisset(const void *mem, int c, size_t len)
{
size_t i;
for (i = 0; i < len; i++)
if (((unsigned char *)mem)[i] != (unsigned char)c)
return 0;
return 1;
}
static int read_test(BlockDriverState *bs, unsigned char contents[])
{
int i;
unsigned char sector[512];
unsigned char ten_sectors[5120];
/* Single read test. */
for (i = 0; i < NUM_SECTORS; i++) {
if (bdrv_read(bs, i, sector, 1) != 0)
return 0;
if (!memisset(sector, contents[i], 512))
return 0;
}
/* Multiple read test. */
for (i = 0; i < NUM_SECTORS - 10; i++) {
int j;
if (bdrv_read(bs, i, ten_sectors, 10) != 0)
return 0;
for (j = 0; j < 10; j++)
if (!memisset(ten_sectors + j*512, contents[i+j], 512))
return 0;
}
return 1;
}
int main(int argc, char *argv[])
{
int fd, i;
unsigned char sector[512];
unsigned char ten_sectors[5120];
unsigned char contents[NUM_SECTORS];
BlockDriverState *bs;
fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0600);
for (i = 0; i < NUM_SECTORS; i++) {
memset(sector, i, sizeof(sector));
if (write(fd, sector, sizeof(sector)) != sizeof(sector))
abort();
contents[i] = i;
}
close(fd);
bs = bdrv_open(argv[1], argv[2] ? 1 : 0);
/* Test data is as we expect. */
if (!read_test(bs, contents))
abort();
/* Single write test. */
memset(sector, 2, sizeof(sector));
if (bdrv_write(bs, 0, sector, 1) != 0)
abort();
contents[0] = 2;
if (!read_test(bs, contents))
abort();
memset(sector, 0, sizeof(sector));
if (bdrv_read(bs, 0, sector, 1) != 0)
abort();
if (!memisset(sector, 2, sizeof(sector)))
abort();
/* Random test */
for (i = 0; i < 10000; i++) {
int j;
int num_sectors = (random() % 10) + 1;
int sect_start = random() % (NUM_SECTORS - num_sectors);
if (random() % 2) {
if (bdrv_read(bs,sect_start,ten_sectors,num_sectors))
abort();
for (j = 0; j < num_sectors; j++)
if (!memisset(ten_sectors + j*512,
contents[sect_start + j],
512))
abort();
} else {
for (j = 0; j < num_sectors; j++) {
contents[sect_start + j] = random();
memset(ten_sectors + j*512,
contents[sect_start + j],
512);
}
if (bdrv_write(bs,sect_start,ten_sectors,num_sectors))
abort();
}
}
if (!read_test(bs, contents))
abort();
if (argv[2]) {
/* Test that it hasn't touched initial file. */
fd = open(argv[1], O_RDONLY);
if (fd < 0)
abort();
for (i = 0; i < NUM_SECTORS; i++) {
if (read(fd, sector, sizeof(sector)) != sizeof(sector))
abort();
if (!memisset(sector, i, sizeof(sector)))
abort();
}
close(fd);
/* Test that commit works. */
bdrv_commit(bs);
fd = open(argv[1], O_RDONLY);
if (fd < 0)
abort();
for (i = 0; i < NUM_SECTORS; i++) {
if (read(fd, sector, sizeof(sector)) != sizeof(sector))
abort();
if (!memisset(sector, contents[i], sizeof(sector)))
abort();
}
close(fd);
}
printf("All tests on %s%s passed!\n", argv[1],
argv[2] ? " (with undo)" : "");
return 0;
}
================
Index: block.c
===================================================================
RCS file: /cvsroot/qemu/qemu/block.c,v
retrieving revision 1.2
diff -u -r1.2 block.c
--- block.c 30 Jun 2003 23:17:31 -0000 1.2
+++ block.c 2 Jul 2003 06:45:08 -0000
@@ -45,9 +45,14 @@
int fd;
int64_t total_sectors;
int read_only;
+ const char *filename;
+
+ /* If snapshot set, this is nonnull and these are used. */
+ unsigned char *changes_map;
+ int changes_fd;
};
-BlockDriverState *bdrv_open(const char *filename)
+BlockDriverState *bdrv_open(const char *filename, int snapshot)
{
BlockDriverState *bs;
int fd;
@@ -56,12 +61,12 @@
bs = malloc(sizeof(BlockDriverState));
if(!bs)
return NULL;
+
bs->read_only = 0;
fd = open(filename, O_RDWR);
if (fd < 0) {
fd = open(filename, O_RDONLY);
if (fd < 0) {
- close(fd);
free(bs);
return NULL;
}
@@ -70,44 +75,176 @@
size = lseek64(fd, 0, SEEK_END);
bs->total_sectors = size / 512;
bs->fd = fd;
+ bs->filename = filename;
+
+ if (snapshot) {
+ /* Lazy paging in of /dev/zero for changes bitmap. */
+ int dev_zero;
+ char template[] = "/tmp/vl.XXXXXX";
+
+ dev_zero = open("/dev/zero", O_RDONLY);
+ if (dev_zero < 0) {
+ close(fd);
+ free(bs);
+ return NULL;
+ }
+
+ bs->changes_map = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE,
+ dev_zero, 0);
+ close(dev_zero);
+ if (bs->changes_map == MAP_FAILED) {
+ close(fd);
+ free(bs);
+ return NULL;
+ }
+
+ /* Now, create a (sparse) temporary file for backing blocks. */
+ bs->changes_fd = mkstemp(template);
+ if (bs->changes_fd < 0) {
+ munmap(bs->changes_map, bs->total_sectors * 512);
+ close(fd);
+ free(bs);
+ return NULL;
+ }
+ /* Delete it. */
+ unlink(template);
+ } else {
+ bs->changes_map = NULL;
+ }
+
return bs;
}
void bdrv_close(BlockDriverState *bs)
{
close(bs->fd);
+ if (bs->changes_map) {
+ munmap(bs->changes_map, bs->total_sectors * 512);
+ close(bs->changes_fd);
+ }
free(bs);
}
+static inline void set_bit(unsigned char *bitmap, int64_t bitnum)
+{
+ bitmap[bitnum / 8] |= (1 << (bitnum%8));
+}
+
+static inline int is_bit_set(const unsigned char *bitmap, int64_t bitnum)
+{
+ return !!(bitmap[bitnum / 8] & (1 << (bitnum%8)));
+}
+
+void bdrv_commit(BlockDriverState *bs)
+{
+ int64_t i;
+ unsigned char *changes_map;
+
+ if (!bs->changes_map) {
+ fprintf(stderr, "Already committing to %s\n", bs->filename);
+ return;
+ }
+
+ if (bs->read_only) {
+ fprintf(stderr, "Can't commit to %s: read-only\n", bs->filename);
+ return;
+ }
+
+ changes_map = bs->changes_map;
+ for (i = 0; i < bs->total_sectors; i++) {
+ if (is_bit_set(changes_map, i)) {
+ unsigned char sector[512];
+ if (bdrv_read(bs, i, sector, 1) != 0) {
+ fprintf(stderr, "Error reading sector %lli: aborting commit\n",
+ (long long)i);
+ return;
+ }
+
+ /* Make bdrv_write write to real file for a moment. */
+ bs->changes_map = NULL;
+ if (bdrv_write(bs, i, sector, 1) != 0) {
+ fprintf(stderr, "Error writing sector %lli: aborting commit\n",
+ (long long)i);
+ bs->changes_map = changes_map;
+ return;
+ }
+ bs->changes_map = changes_map;
+ }
+ }
+ fprintf(stderr, "Committed snapshot to %s\n", bs->filename);
+}
+
+/* Return true if first block has been changed (ie. current version is
+ * in backing store). Set the number of continuous blocks for which
+ * that is true. */
+static int is_changed(const unsigned char *bitmap,
+ int64_t sector_num, int nb_sectors,
+ int *num_same)
+{
+ int changed;
+
+ if (!bitmap || nb_sectors == 0) {
+ *num_same = nb_sectors;
+ return 0;
+ }
+
+ changed = is_bit_set(bitmap, sector_num);
+ for (*num_same = 1; *num_same < nb_sectors; (*num_same)++) {
+ if (is_bit_set(bitmap, sector_num + *num_same) != changed)
+ break;
+ }
+
+ return changed;
+}
+
/* return -1 if error */
int bdrv_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors)
{
- int ret;
+ int ret, num_same, fd;
- lseek64(bs->fd, sector_num * 512, SEEK_SET);
- ret = read(bs->fd, buf, nb_sectors * 512);
- if (ret != nb_sectors * 512)
+ fd = bs->fd;
+ if (is_changed(bs->changes_map, sector_num, nb_sectors, &num_same))
+ fd = bs->changes_fd;
+
+ lseek64(fd, sector_num * 512, SEEK_SET);
+ ret = read(fd, buf, num_same * 512);
+ if (ret != num_same * 512) {
+ fprintf(stderr, "Block: Failed to read %i sectors at %lli\n",
+ num_same, (long long)sector_num);
return -1;
- else
- return 0;
+ }
+
+ /* Recurse to do rest of blocks. */
+ if (num_same < nb_sectors)
+ return bdrv_read(bs, sector_num + num_same, buf + 512 * num_same,
+ nb_sectors - num_same);
+ return 0;
}
/* return -1 if error */
int bdrv_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
- int ret;
+ int ret, fd, i;
- if (bs->read_only)
- return -1;
+ fd = bs->fd;
+
+ if (bs->changes_map)
+ fd = bs->changes_fd;
+ else if (bs->read_only)
+ return -1;
- lseek64(bs->fd, sector_num * 512, SEEK_SET);
- ret = write(bs->fd, buf, nb_sectors * 512);
+ lseek64(fd, sector_num * 512, SEEK_SET);
+ ret = write(fd, buf, nb_sectors * 512);
if (ret != nb_sectors * 512)
return -1;
- else
- return 0;
+
+ if (bs->changes_map)
+ for (i = 0; i < nb_sectors; i++)
+ set_bit(bs->changes_map, sector_num + i);
+
+ return 0;
}
void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr)
Index: vl.c
===================================================================
RCS file: /cvsroot/qemu/qemu/vl.c,v
retrieving revision 1.10
diff -u -r1.10 vl.c
--- vl.c 1 Jul 2003 16:27:45 -0000 1.10
+++ vl.c 2 Jul 2003 06:45:09 -0000
@@ -52,6 +52,7 @@
#define DEBUG_LOGFILE "/tmp/vl.log"
#define DEFAULT_NETWORK_SCRIPT "/etc/vl-ifup"
+#define MAX_DISKS 2
//#define DEBUG_UNUSED_IOPORT
//#define DEBUG_IRQ_LATENCY
@@ -63,6 +64,8 @@
#define INITRD_LOAD_ADDR 0x00400000
#define KERNEL_PARAMS_ADDR 0x00090000
+BlockDriverState *bs_table[MAX_DISKS];
+
/* from plex86 (BSD license) */
struct __attribute__ ((packed)) linux_params {
// For 0x00..0x3f, see 'struct screen_info' in linux/include/linux/tty.h.
@@ -1265,6 +1268,7 @@
printf("\n"
"C-a h print this help\n"
"C-a x exit emulatior\n"
+ "C-a s save disk data back to file (if -snapshot)\n"
"C-a b send break (magic sysrq)\n"
"C-a C-a send C-a\n"
);
@@ -1282,6 +1286,14 @@
case 'x':
exit(0);
break;
+ case 's': {
+ int i;
+
+ for (i = 0; i < MAX_DISKS; i++)
+ if (bs_table[i])
+ bdrv_commit(bs_table[i]);
+ break;
+ }
case 'b':
/* send break */
s->rbr = 0;
@@ -1976,8 +1988,6 @@
/* set to 1 set disable mult support */
#define MAX_MULT_SECTORS 8
-#define MAX_DISKS 2
-
struct IDEState;
typedef void EndTransferFunc(struct IDEState *);
@@ -2009,7 +2019,6 @@
uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
} IDEState;
-BlockDriverState *bs_table[MAX_DISKS];
IDEState ide_state[MAX_DISKS];
static void padstr(char *str, const char *src, int len)
@@ -2577,6 +2586,7 @@
"-initrd file use 'file' as initial ram disk\n"
"-hda file use 'file' as hard disk 0 image\n"
"-hdb file use 'file' as hard disk 1 image\n"
+ "-snapshot write to temporary files instead of disk files\n"
"-m megs set virtual RAM size to megs MB\n"
"-n script set network init script [default=%s]\n"
"\n"
@@ -2595,12 +2605,13 @@
{ "initrd", 1, NULL, 0, },
{ "hda", 1, NULL, 0, },
{ "hdb", 1, NULL, 0, },
+ { "snapshot", 0, NULL, 0, },
{ NULL, 0, NULL, 0 },
};
int main(int argc, char **argv)
{
- int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index;
+ int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, snapshot, long_index;
struct linux_params *params;
struct sigaction act;
struct itimerval itv;
@@ -2617,6 +2628,7 @@
pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);
use_gdbstub = 0;
gdbstub_port = DEFAULT_GDBSTUB_PORT;
+ snapshot = 0;
for(;;) {
c = getopt_long_only(argc, argv, "hm:dn:sp:", long_options, &long_index);
if (c == -1)
@@ -2633,6 +2645,9 @@
case 2:
hd_filename[1] = optarg;
break;
+ case 3:
+ snapshot = 1;
+ break;
}
break;
case 'h':
@@ -2679,7 +2694,7 @@
/* open the virtual block devices */
for(i = 0; i < MAX_DISKS; i++) {
if (hd_filename[i]) {
- bs_table[i] = bdrv_open(hd_filename[i]);
+ bs_table[i] = bdrv_open(hd_filename[i], snapshot);
if (!bs_table[i]) {
fprintf(stderr, "vl: could not open hard disk image '%s\n",
hd_filename[i]);
Index: vl.h
===================================================================
RCS file: /cvsroot/qemu/qemu/vl.h,v
retrieving revision 1.1
diff -u -r1.1 vl.h
--- vl.h 30 Jun 2003 10:03:06 -0000 1.1
+++ vl.h 2 Jul 2003 06:45:09 -0000
@@ -27,13 +27,13 @@
/* block.c */
typedef struct BlockDriverState BlockDriverState;
-BlockDriverState *bdrv_open(const char *filename);
+BlockDriverState *bdrv_open(const char *filename, int snapshot);
void bdrv_close(BlockDriverState *bs);
int bdrv_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors);
int bdrv_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors);
void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr);
-
+void bdrv_commit(BlockDriverState *bs);
#endif /* VL_H */
Index: tests/Makefile
===================================================================
RCS file: /cvsroot/qemu/qemu/tests/Makefile,v
retrieving revision 1.21
diff -u -r1.21 Makefile
--- tests/Makefile 15 Jun 2003 20:42:31 -0000 1.21
+++ tests/Makefile 2 Jul 2003 06:45:10 -0000
@@ -6,7 +6,7 @@
ifeq ($(ARCH),i386)
TESTS=testclone testsig testthread sha1-i386 test-i386 runcom
endif
-TESTS+=sha1 test_path
+TESTS+=sha1 test_path test_block
QEMU=../qemu
@@ -28,6 +28,12 @@
test_path: test_path.c
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
./$@ || { rm $@; exit 1; }
+
+test_block: test_block.c
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
+ ./$@ test_block_data || { rm -f $@ test_block_data; exit 1; }
+ ./$@ test_block_data undo || { rm -f $@ test_block_data; exit 1; }
+ @rm -f test_block_data
# i386 emulation test (test various opcodes) */
test-i386: test-i386.c test-i386-code16.S test-i386-vm86.S \
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] Re: [PATCH] Snapshot block device support
2003-07-02 6:50 [Qemu-devel] [PATCH] Snapshot block device support Rusty Russell
@ 2003-07-02 9:49 ` Fabrice Bellard
2003-07-02 10:04 ` Thomas Glanzmann
2003-07-02 23:54 ` Rusty Russell
0 siblings, 2 replies; 9+ messages in thread
From: Fabrice Bellard @ 2003-07-02 9:49 UTC (permalink / raw)
To: Rusty Russell; +Cc: qemu-devel
I had plans to implement "copy on write" disk images...I find your
approach original. My initial plan was just to add a second disk image
for each disk containing the changes. It should be easy to do it from
your code (for example by adding options '-hdacow file' where file is
the snapshot file you use).
About IDE, it is working (at least with kernel 2.4.20). Someone has even
compiled a linux kernel inside QEMU (slowdown factor of about 15), so vl
begins to be usable for real tasks. There are still known problems if
several processes use floating point at the same time.
Fabrice.
Rusty Russell wrote:
> Hi Fabrice,
>
> I haven't got the IDE emulation to work for me yet (is it
> supposed to yet?), but this allows the "-snapshot" option and "C-a s"
> to commit the disks. The blocks which change are committed to backing
> store, and a bitmap of changed blocks is kept.
>
> Diff + new test file below.
> Rusty.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] Re: [PATCH] Snapshot block device support
2003-07-02 9:49 ` [Qemu-devel] " Fabrice Bellard
@ 2003-07-02 10:04 ` Thomas Glanzmann
2003-07-02 23:54 ` Rusty Russell
1 sibling, 0 replies; 9+ messages in thread
From: Thomas Glanzmann @ 2003-07-02 10:04 UTC (permalink / raw)
To: qemu-devel
> About IDE, it is working (at least with kernel 2.4.20). Someone has even
> compiled a linux kernel inside QEMU (slowdown factor of about 15), so vl
I still have some problems with 2.4.21: there are some ide error message
during booting and shutdowning the VM. I make you a test setup ready on
my site.
Greetings,
Thomas
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] Re: [PATCH] Snapshot block device support
2003-07-02 9:49 ` [Qemu-devel] " Fabrice Bellard
2003-07-02 10:04 ` Thomas Glanzmann
@ 2003-07-02 23:54 ` Rusty Russell
2003-07-04 14:51 ` Fabrice Bellard
1 sibling, 1 reply; 9+ messages in thread
From: Rusty Russell @ 2003-07-02 23:54 UTC (permalink / raw)
To: Fabrice Bellard; +Cc: qemu-devel
In message <3F02AA9D.1030307@free.fr> you write:
> I had plans to implement "copy on write" disk images...I find your
> approach original. My initial plan was just to add a second disk image
> for each disk containing the changes. It should be easy to do it from
> your code (for example by adding options '-hdacow file' where file is
> the snapshot file you use).
Sure: I used a temporary (unlinked) file because I couldn't see much
point in keeping it around. Since most filesystems do sparse files,
it's quite efficient, too.
-hdacow with an optional argument would work really well, if that's
desired behaviour.
I'm glad I finally beat you to implementing something: you're usually
too quick 8)
> About IDE, it is working (at least with kernel 2.4.20). Someone has even
> compiled a linux kernel inside QEMU (slowdown factor of about 15), so vl
> begins to be usable for real tasks. There are still known problems if
> several processes use floating point at the same time.
OK, I'm getting errors with IDE on 2.5, but shouldn't be too hard to
track down.
Thanks!
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] Re: [PATCH] Snapshot block device support
2003-07-02 23:54 ` Rusty Russell
@ 2003-07-04 14:51 ` Fabrice Bellard
2003-07-06 2:26 ` Rusty Russell
0 siblings, 1 reply; 9+ messages in thread
From: Fabrice Bellard @ 2003-07-04 14:51 UTC (permalink / raw)
To: Rusty Russell; +Cc: qemu-devel
Rusty Russell wrote:
> In message <3F02AA9D.1030307@free.fr> you write:
>
>> I had plans to implement "copy on write" disk images...I find your
>> approach original. My initial plan was just to add a second disk
>> image for each disk containing the changes. It should be easy to
>> do it from your code (for example by adding options '-hdacow file'
>> where file is the snapshot file you use).
>
>
> Sure: I used a temporary (unlinked) file because I couldn't see much
> point in keeping it around. Since most filesystems do sparse files,
> it's quite efficient, too.
>
> -hdacow with an optional argument would work really well, if that's
desired
> behaviour.
>
> I'm glad I finally beat you to implementing something: you're
> usually too quick 8)
Well, I don't have to maintain parts of the Linux kernel at the same
time :-)
I am going to modify your patch today so that -hdacow is supported.
>> About IDE, it is working (at least with kernel 2.4.20). Someone
>> has even compiled a linux kernel inside QEMU (slowdown factor of
>> about 15), so vl begins to be usable for real tasks. There are
>> still known problems if several processes use floating point at
>> the same time.
>
>
> OK, I'm getting errors with IDE on 2.5, but shouldn't be too hard to
> track down.
I tested with 2.5.74 and fixed the initial IDE error. I also added the
emulation of the PC 'reset' pin so that vl can be shut down as a normal
Linux system (only hard reset is supported, not power off, as it would
require a more complicated real mode APM bios emulation).
Now I am looking for potential original uses of vl/QEMU !
Fabrice.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] Re: [PATCH] Snapshot block device support
2003-07-04 14:51 ` Fabrice Bellard
@ 2003-07-06 2:26 ` Rusty Russell
2003-07-06 14:08 ` Fabrice Bellard
0 siblings, 1 reply; 9+ messages in thread
From: Rusty Russell @ 2003-07-06 2:26 UTC (permalink / raw)
To: Fabrice Bellard; +Cc: qemu-devel
In message <3F05946D.3060102@free.fr> you write:
> I tested with 2.5.74 and fixed the initial IDE error. I also added the
> emulation of the PC 'reset' pin so that vl can be shut down as a normal
> Linux system (only hard reset is supported, not power off, as it would
> require a more complicated real mode APM bios emulation).
I know someone who might be interested: I'll ask tomorrow.
> Now I am looking for potential original uses of vl/QEMU !
Hmm, what are the chances of SMP? You mentioned something about it
probing addresses you couldn't map, perhaps another job for
CONFIG_QEMU inside the kernel, or is it too invasive?
Even with only one CPU, it helps my debugging to be able to test
CONFIG_SMP=y...
Thanks!
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] Re: [PATCH] Snapshot block device support
2003-07-06 2:26 ` Rusty Russell
@ 2003-07-06 14:08 ` Fabrice Bellard
2003-07-07 8:15 ` Rusty Russell
0 siblings, 1 reply; 9+ messages in thread
From: Fabrice Bellard @ 2003-07-06 14:08 UTC (permalink / raw)
To: Rusty Russell; +Cc: qemu-devel
Rusty Russell wrote:
> In message <3F05946D.3060102@free.fr> you write:
>
>>I tested with 2.5.74 and fixed the initial IDE error. I also added the
>>emulation of the PC 'reset' pin so that vl can be shut down as a normal
>>Linux system (only hard reset is supported, not power off, as it would
>>require a more complicated real mode APM bios emulation).
>
>
> I know someone who might be interested: I'll ask tomorrow.
OK.
>>Now I am looking for potential original uses of vl/QEMU !
>
>
> Hmm, what are the chances of SMP? You mentioned something about it
> probing addresses you couldn't map, perhaps another job for
> CONFIG_QEMU inside the kernel, or is it too invasive?
>
> Even with only one CPU, it helps my debugging to be able to test
> CONFIG_SMP=y...
I realize that SMP simulation can be interesting. I could at least learn
how it works as I never looked at it. The simplest solution would be to
use CONFIG_QEMU to change the FIXADDR_TOP address in fixmap.h (I am
going to test that). I have looked at APIC and IOAPIC simulation in
bochs and it does not seem so complicated. My real problem is how to
simulate several CPUs at the same time. A solution is to use a single
process and to schedule by hand. It is costly because the address space
must be switched between each CPU. Another solution is to use separate
processes, but it complicates the hardware simulation. Any ideas ?
Fabrice.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] Re: [PATCH] Snapshot block device support
2003-07-06 14:08 ` Fabrice Bellard
@ 2003-07-07 8:15 ` Rusty Russell
2003-07-07 12:51 ` Fabrice Bellard
0 siblings, 1 reply; 9+ messages in thread
From: Rusty Russell @ 2003-07-07 8:15 UTC (permalink / raw)
To: Fabrice Bellard; +Cc: qemu-devel
In message <3F082D4D.6010505@free.fr> you write:
> > Even with only one CPU, it helps my debugging to be able to test
> > CONFIG_SMP=y...
>
> I realize that SMP simulation can be interesting. I could at least learn
> how it works as I never looked at it. The simplest solution would be to
> use CONFIG_QEMU to change the FIXADDR_TOP address in fixmap.h (I am
> going to test that). I have looked at APIC and IOAPIC simulation in
> bochs and it does not seem so complicated. My real problem is how to
> simulate several CPUs at the same time. A solution is to use a single
> process and to schedule by hand. It is costly because the address space
> must be switched between each CPU. Another solution is to use separate
> processes, but it complicates the hardware simulation. Any ideas ?
I'd be happy for the moment with a single CPU, as long as an
CONFIG_SMP=y kernel booted.
I don't want to discourge you though! If you were going to actually
simulate multiple CPUS, ideal would be one thread per cpu (which takes
advantage of an SMP host). Switching simply doesn't exercise the race
conditions as much as an SMP host does. I remember TDB bugs where
tdbtorture (multiprocess stress test) passed fine on UP, but blew up
every time on SMP.
Cheers!
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] Re: [PATCH] Snapshot block device support
2003-07-07 8:15 ` Rusty Russell
@ 2003-07-07 12:51 ` Fabrice Bellard
0 siblings, 0 replies; 9+ messages in thread
From: Fabrice Bellard @ 2003-07-07 12:51 UTC (permalink / raw)
To: Rusty Russell; +Cc: qemu-devel
Rusty Russell wrote:
> In message <3F082D4D.6010505@free.fr> you write:
>
>>>Even with only one CPU, it helps my debugging to be able to test
>>>CONFIG_SMP=y...
>>
>>I realize that SMP simulation can be interesting. I could at least learn
>>how it works as I never looked at it. The simplest solution would be to
>>use CONFIG_QEMU to change the FIXADDR_TOP address in fixmap.h (I am
>>going to test that). I have looked at APIC and IOAPIC simulation in
>>bochs and it does not seem so complicated. My real problem is how to
>>simulate several CPUs at the same time. A solution is to use a single
>>process and to schedule by hand. It is costly because the address space
>>must be switched between each CPU. Another solution is to use separate
>>processes, but it complicates the hardware simulation. Any ideas ?
>
>
> I'd be happy for the moment with a single CPU, as long as an
> CONFIG_SMP=y kernel booted.
It should work now, provided you add one patch in the kernel (it is
mentionned now in the documentation).
If you still have problems, you can remove the spin locks in exec.h:327.
> I don't want to discourge you though! If you were going to actually
> simulate multiple CPUS, ideal would be one thread per cpu (which takes
> advantage of an SMP host). Switching simply doesn't exercise the race
> conditions as much as an SMP host does. I remember TDB bugs where
> tdbtorture (multiprocess stress test) passed fine on UP, but blew up
> every time on SMP.
I am going to think about it. There are currently complicated locking
issues in QEMU: even in user mode simulation, clone() support is totally
broken.
Fabrice.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2003-07-07 16:34 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-07-02 6:50 [Qemu-devel] [PATCH] Snapshot block device support Rusty Russell
2003-07-02 9:49 ` [Qemu-devel] " Fabrice Bellard
2003-07-02 10:04 ` Thomas Glanzmann
2003-07-02 23:54 ` Rusty Russell
2003-07-04 14:51 ` Fabrice Bellard
2003-07-06 2:26 ` Rusty Russell
2003-07-06 14:08 ` Fabrice Bellard
2003-07-07 8:15 ` Rusty Russell
2003-07-07 12:51 ` Fabrice Bellard
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).