[Qemu-devel] Re: [PATCH 6/8] scsi: Split qdev "scsi-disk" into "scsi-hd" and "scsi-cd"
Am 07.07.2010 03:37, schrieb Christoph Hellwig: > On Tue, Jul 06, 2010 at 02:37:47PM +0200, Markus Armbruster wrote: >> Disk vs. CD needs to be in qdev, because it belongs to the drive's >> guest part. > > Looks good, but the scsi-hd name feelds kinda awkward. This is one > case we're I'm really wondering if the compatiblity is worth it or > if we should just keep using scsi-disk for the real disk. In any case the name should be consistent with ide-hd. And I'm not sure if it's really helpful to have ide-drive and ide-disk. Kevin
Re: [Qemu-devel] [PATCH] Makefile: Fix compilation for non-standard host kernel path
On 07/07/2010 01:10 AM, Anthony Liguori wrote: On 07/02/2010 06:15 AM, Prerna Saxena wrote: Set up host kernel include paths specified by --kerneldir When host kernel headers are placed in non-standard paths, the KVM_CFLAGS are presently invoked only for a few .c files (kvm*.c,vhost*.c) and not for other files like machine.c, cpus.c ..etc which also depend on linux/kvm.h I think that's a bug. What's the dependency of machine.c and cpus.c? Both machine.d and cpus.d depend on qemu/kvm.h, which in turn needs linux/kvm.h I am running a custom-compiled kernel for which the headers are placed separately. I pass the kernel source directory to my configure script as follows : [...@zephyr ~]$ configure --prefix=/home/bloat/qemu-git/qemu-bin --enable-kvm --target-list=i386-softmmu,x86_64-softmmu --enable-profiler --disable-docs --kerneldir=/home/bloat/kernels/linux-2.6.35-rc3 [...@zephyr ~]$ make -j2 This is one of the errors I get : (similar ones are flagged for machine.o and cpus.o) CCi386-softmmu/arch_init.o In file included from /home/bloat/qemu-git/qemu/arch_init.c:38: /home/bloat/qemu-git/qemu/kvm.h:22:23: error: linux/kvm.h: No such file or directory make[1]: *** [arch_init.o] Error 1 This is because the location of kernel headers is not passed as a '-I' switch to gcc. IMO adding the KVM_CFLAGS to QEMU_CFLAGS would be required for such cases. Regards, -- Prerna Saxena Linux Technology Centre, IBM Systems and Technology Lab, Bangalore, India
Re: [Qemu-devel] [Bug 595117] Re: qemu-nbd slow and missing "writeback" cache option
2010-06-24 00:16:03 -, Jamie Lokier: > Serge Hallyn wrote: > > The default of qemu-img (of using O_SYNC) is not very sensible > > because anyway, the client (the kernel) uses caches (write-back), > > (and "qemu-nbd -d" doesn't flush those by the way). So if for > > instance qemu-nbd is killed, regardless of whether qemu-nbd uses > > O_SYNC, O_DIRECT or not, the data in the image will not be > > consistent anyway, unless "syncs" are done by the client (like fsync > > on the nbd device or sync mount option), and with qemu-nbd's O_SYNC > > mode, those "sync"s will be extremely slow. > > Do the "client syncs" cause the nbd server to fsync or fdatasync the > file? The clients syncs cause the data to be sent to the server. The server then writes it to disk and each write blocks until the data is written physically on disk with O_SYNC. > > It appears it is because by default the disk image it serves is open > > with O_SYNC. The --nocache option, unintuitively, makes matters a > > bit better because it causes the image to be open with O_DIRECT > > instead of O_SYNC. > [...] > > --cache=off is the same as --nocache (that is use O_DIRECT), > > writethrough is using O_SYNC and is still the default so this patch > > doesn't change the functionality. writeback is none of those flags, > > so is the addition of this patch. The patch also does an fsync upon > > "qemu-nbd -d" to make sure data is flushed to the image before > > removing the nbd. > > I really wish qemu's options didn't give the false impression > "nocache" does less caching than "writethrough". O_DIRECT does > caching in the disk controller/hardware, while O_SYNC hopefully does > not, nowadays. [...] Note that I use the same "none", "writethrough", "writeback" as another utility shipped with qemu for consistency (see vl.c in the source), I don't mind about the words as long as the "writeback" functionality is available. Cheers, Stephane -- qemu-nbd slow and missing "writeback" cache option https://bugs.launchpad.net/bugs/595117 You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. Status in QEMU: Invalid Status in “qemu-kvm” package in Ubuntu: Incomplete Bug description: Binary package hint: qemu-kvm dpkg -l | grep qemu ii kvm 1:84+dfsg-0ubuntu16+0.12.3+noroms+0ubuntu9dummy transitional pacakge from kvm to qemu- ii qemu 0.12.3+noroms-0ubuntu9 dummy transitional pacakge from qemu to qemu ii qemu-common 0.12.3+noroms-0ubuntu9 qemu common functionality (bios, documentati ii qemu-kvm 0.12.3+noroms-0ubuntu9 Full virtualization on i386 and amd64 hardwa ii qemu-kvm-extras 0.12.3+noroms-0ubuntu9 fast processor emulator binaries for non-x86 ii qemu-launcher1.7.4-1ubuntu2 GTK+ front-end to QEMU computer emulator ii qemuctl 0.2-2 controlling GUI for qemu lucid amd64. qemu-nbd is a lot slower when writing to disk than say nbd-server. It appears it is because by default the disk image it serves is open with O_SYNC. The --nocache option, unintuitively, makes matters a bit better because it causes the image to be open with O_DIRECT instead of O_SYNC. The qemu code allows an image to be open without any of those flags, but unfortunately qemu-nbd doesn't have the option to do that (qemu doesn't allow the image to be open with both O_SYNC and O_DIRECT though). The default of qemu-img (of using O_SYNC) is not very sensible because anyway, the client (the kernel) uses caches (write-back), (and "qemu-nbd -d" doesn't flush those by the way). So if for instance qemu-nbd is killed, regardless of whether qemu-nbd uses O_SYNC, O_DIRECT or not, the data in the image will not be consistent anyway, unless "syncs" are done by the client (like fsync on the nbd device or sync mount option), and with qemu-nbd's O_SYNC mode, those "sync"s will be extremely slow. Attached is a patch that adds a --cache={off,none,writethrough,writeback} option to qemu-nbd. --cache=off is the same as --nocache (that is use O_DIRECT), writethrough is using O_SYNC and is still the default so this patch doesn't change the functionality. writeback is none of those flags, so is the addition of this patch. The patch also does an fsync upon "qemu-nbd -d" to make sure data is flushed to the image before removing the nbd. Consider this test scenario: dd bs=1M count=100 of=a < /dev/null qemu-nbd --cache= -c /dev/nbd0 a cp /dev/zero /dev/nbd0 time perl -MIO::Handle -e 'STDOUT->sync or die$!' 1<> /dev/nbd0 With cache=writethrough (the default), it takes over 10 minutes to write those 100MB worth of zeroes.
[Qemu-devel] Hurd Guest Networking
Something recently (within the last week) committed to Git has broken networking on Hurd guests with and without KVM. Does anyone have any idea what it could be? This is the command I'm using: qemu -hda debian-hurd-k16-qemu.img -m 512 -boot c -net nic,model=rtl8139 -net user --enable-kvm -Nigel
[Qemu-devel] Re: [PATCH v2 03/13] raw-posix: Fix test for host CD-ROM
Christoph Hellwig writes: > On Tue, Jul 06, 2010 at 02:08:46PM +0200, Markus Armbruster wrote: >> * Any drive backed by host_floppy now retries. > > I would really prefer not to change the behaviour for this case, it'll > just confuse people looking at the history when finally removing this > hack. I'm fine either way. Kevin?
[Qemu-devel] Re: [PATCH v2 06/13] scsi: Reject unimplemented error actions
Christoph Hellwig writes: > On Tue, Jul 06, 2010 at 02:08:49PM +0200, Markus Armbruster wrote: >> drive_init() doesn't permit rerror for if=scsi, but that's worthless: >> we get it via if=none and -device. >> >> Moreover, scsi-generic doesn't support werror. Since drive_init() >> doesn't catch that, option werror was silently ignored even with >> if=scsi. >> >> Wart: unlike drive_init(), we don't reject the default action when >> it's explicitly specified. That's because we can't distinguish "no >> rerror option" from "rerror=report", or "no werror" from >> "rerror=enospc". Left for another day. > > I can't see a good reason that scsi doesn't support the rerror option, > and implementing is trivial. So while this patch looks correct I'd > rather see rerror implemented for scsi than hacking around the lack of > it. You got a point there. Same for fdc. However, this is the best *I* can do in time for .13. Let's add the missin error action support after the release, okay?
[Qemu-devel] Re: [PATCH 6/8] scsi: Split qdev "scsi-disk" into "scsi-hd" and "scsi-cd"
Kevin Wolf writes: > Am 07.07.2010 03:37, schrieb Christoph Hellwig: >> On Tue, Jul 06, 2010 at 02:37:47PM +0200, Markus Armbruster wrote: >>> Disk vs. CD needs to be in qdev, because it belongs to the drive's >>> guest part. >> >> Looks good, but the scsi-hd name feelds kinda awkward. This is one >> case we're I'm really wondering if the compatiblity is worth it or >> if we should just keep using scsi-disk for the real disk. > > In any case the name should be consistent with ide-hd. And I'm not sure > if it's really helpful to have ide-drive and ide-disk. {ide,scsi}-{hd,cd} is the best consistent set of names I could find within the backward compatibility straightjacket. By the way, we could use a way to mark qdevs and properties deprecated.
[Qemu-devel] Re: [PATCH v2 03/13] raw-posix: Fix test for host CD-ROM
Am 07.07.2010 11:34, schrieb Markus Armbruster: > Christoph Hellwig writes: > >> On Tue, Jul 06, 2010 at 02:08:46PM +0200, Markus Armbruster wrote: >>> * Any drive backed by host_floppy now retries. >> >> I would really prefer not to change the behaviour for this case, it'll >> just confuse people looking at the history when finally removing this >> hack. > > I'm fine either way. Kevin? I don't really care about floppies, and I doubt anyone does. Retaining old behaviour should never be wrong, so if you prefer, I'm okay with it. Kevin
[Qemu-devel] Re: [PATCH 5/8] ide: Split qdev "ide-drive" into "ide-hd" and "ide-cd"
Am 06.07.2010 14:37, schrieb Markus Armbruster: > Disk vs. CD needs to be in qdev, because it belongs to the drive's > guest part. > > Keep ide-drive for backward compatibility. > > Signed-off-by: Markus Armbruster > --- > hw/ide/core.c | 11 +--- > hw/ide/internal.h |2 +- > hw/ide/qdev.c | 72 ++-- > 3 files changed, 66 insertions(+), 19 deletions(-) > > diff --git a/hw/ide/core.c b/hw/ide/core.c > index e20f2e7..1287f11 100644 > --- a/hw/ide/core.c > +++ b/hw/ide/core.c > @@ -2595,13 +2595,15 @@ void ide_bus_reset(IDEBus *bus) > ide_clear_hob(bus); > } > > -int ide_init_drive(IDEState *s, BlockDriverState *bs, > +int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind, > const char *version, const char *serial) > { > int cylinders, heads, secs; > uint64_t nb_sectors; > > s->bs = bs; > +s->drive_kind = kind; > + > bdrv_get_geometry(bs, &nb_sectors); > bdrv_guess_geometry(bs, &cylinders, &heads, &secs); > if (cylinders < 1 || cylinders > 16383) { > @@ -2626,8 +2628,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, > s->smart_autosave = 1; > s->smart_errors = 0; > s->smart_selftest_count = 0; > -if (bdrv_get_type_hint(bs) == BDRV_TYPE_CDROM) { > -s->drive_kind = IDE_CD; > +if (kind == IDE_CD) { > bdrv_set_change_cb(bs, cdrom_change_cb, s); > } else { > if (!bdrv_is_inserted(s->bs)) { > @@ -2692,7 +2693,9 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, > DriveInfo *hd0, > dinfo = i == 0 ? hd0 : hd1; > ide_init1(bus, i); > if (dinfo) { > -if (ide_init_drive(&bus->ifs[i], dinfo->bdrv, NULL, > +if (ide_init_drive(&bus->ifs[i], dinfo->bdrv, > + bdrv_get_type_hint(dinfo->bdrv) == > BDRV_TYPE_CDROM ? IDE_CD : IDE_HD, > + NULL, > *dinfo->serial ? dinfo->serial : NULL) < 0) { > error_report("Can't set up IDE drive %s", dinfo->id); > exit(1); > diff --git a/hw/ide/internal.h b/hw/ide/internal.h > index 4165543..d5de33b 100644 > --- a/hw/ide/internal.h > +++ b/hw/ide/internal.h > @@ -556,7 +556,7 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr); > void ide_data_writel(void *opaque, uint32_t addr, uint32_t val); > uint32_t ide_data_readl(void *opaque, uint32_t addr); > > -int ide_init_drive(IDEState *s, BlockDriverState *bs, > +int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind, > const char *version, const char *serial); > void ide_init2(IDEBus *bus, qemu_irq irq); > void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0, > diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c > index 53468ed..a7f0b22 100644 > --- a/hw/ide/qdev.c > +++ b/hw/ide/qdev.c > @@ -82,7 +82,9 @@ IDEDevice *ide_create_drive(IDEBus *bus, int unit, > DriveInfo *drive) > { > DeviceState *dev; > > -dev = qdev_create(&bus->qbus, "ide-drive"); > +dev = qdev_create(&bus->qbus, > + bdrv_get_type_hint(drive->bdrv) == BDRV_TYPE_CDROM > + ? "ide-hd" : "ide-cd"); > qdev_prop_set_uint32(dev, "unit", unit); > qdev_prop_set_drive_nofail(dev, "drive", drive->bdrv); > qdev_init_nofail(dev); > @@ -102,7 +104,7 @@ typedef struct IDEDrive { > IDEDevice dev; > } IDEDrive; > > -static int ide_drive_initfn(IDEDevice *dev) > +static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind) > { > IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus); > IDEState *s = bus->ifs + dev->unit; > @@ -118,7 +120,7 @@ static int ide_drive_initfn(IDEDevice *dev) > } > } > > -if (ide_init_drive(s, dev->conf.bs, dev->version, serial) < 0) { > +if (ide_init_drive(s, dev->conf.bs, kind, dev->version, serial) < 0) { > return -1; > } > > @@ -131,21 +133,63 @@ static int ide_drive_initfn(IDEDevice *dev) > return 0; > } > > -static IDEDeviceInfo ide_drive_info = { > -.qdev.name = "ide-drive", > -.qdev.size = sizeof(IDEDrive), > -.init = ide_drive_initfn, > -.qdev.props = (Property[]) { > -DEFINE_PROP_UINT32("unit", IDEDrive, dev.unit, -1), > -DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf), > -DEFINE_PROP_STRING("ver", IDEDrive, dev.version), > -DEFINE_PROP_STRING("serial", IDEDrive, dev.serial), > -DEFINE_PROP_END_OF_LIST(), > +static int ide_hd_initfn(IDEDevice *dev) > +{ > +return ide_dev_initfn(dev, IDE_HD); > +} > + > +static int ide_cd_initfn(IDEDevice *dev) > +{ > +return ide_dev_initfn(dev, IDE_CD); > +} > + > +static int ide_drive_initfn(IDEDevice *dev) > +{ > +return ide_dev_initfn(dev, > + bdrv_get_type_hint(dev->conf.bs) == BDRV_TYPE_CDROM > + ? IDE_CD : IDE_HD); > +}
[Qemu-devel] Re: [PATCH 1/2] pci/bridge: allocate PCIBus dynamically for PCIBridge.
On Wed, Jul 07, 2010 at 11:38:58AM +0900, Isaku Yamahata wrote: > On Tue, Jul 06, 2010 at 03:18:52PM +0300, Michael S. Tsirkin wrote: > > On Fri, Jul 02, 2010 at 11:30:11AM +0900, Isaku Yamahata wrote: > > > allocate PCIBus dynamically for PCIBridge and bug fix of > > > pci_unregister_secondary_bus(). > > > > could you make the bugfix a separate patch please? > > Will do. > > > > > This is a preparation for splitting out pci_bridge functions. > > > Since PCIBus is private to pci.c, PCIBridge won't be able to > > > contain PCIBus in its structure. > > > > > > Signed-off-by: Isaku Yamahata > > > > I think this becomes too complex: as bridge configuration affects > > the bus operation, you might end up sticking a pointer to the device > > in the bus. A similar arrangement is in place in with piix_pci, and I would > > love to get rid of it, too. > > I'd glad to look into it, but I'd like to make it sure before digging > into it. > Do you mean i440fx_init() and I440FXState::bus = PCIHostState::bus? > Please a bit more concrete explanation. I am not sure myself yet. Generally I'm not very happy with how interrupts are handled. Specifically: - lots of indirect calls through qemu_irq not type-safe, hard to debug and can not be good for performance need to find a way to chase these pointers at setup time - lots of loops over irq pins and over buses need to precompute and store at setup time, and use bits for booleans - information is duplicated, e.g. piix duplicates irq states need to use from a single place with the last issue, be careful not to break migration: we need to compute and store old data on migration In case of piix_pci interrupts are controlled through PIIX3 device, so we create the host bus, the device on it, and finally make another call to make interrupts on the bus get device as the opaque pointer. All this looks very convoluted. > > > Let's just put PCIBus in a header? It could be a new header > > named pci_internals.h or something like this. > > Sounds a good idea. In fact I had thought the same idea. > I'll go for that way. > > > > --- > > > hw/pci.c | 25 ++--- > > > 1 files changed, 14 insertions(+), 11 deletions(-) > > > > > > diff --git a/hw/pci.c b/hw/pci.c > > > index 08652e8..fdf02d0 100644 > > > --- a/hw/pci.c > > > +++ b/hw/pci.c > > > @@ -286,23 +286,27 @@ PCIBus *pci_register_bus(DeviceState *parent, const > > > char *name, > > > return bus; > > > } > > > > > > -static void pci_register_secondary_bus(PCIBus *parent, > > > - PCIBus *bus, > > > - PCIDevice *dev, > > > - pci_map_irq_fn map_irq, > > > - const char *name) > > > +static PCIBus *pci_register_secondary_bus(PCIBus *parent, > > > + PCIDevice *dev, > > > + pci_map_irq_fn map_irq, > > > + const char *name) > > > { > > > -qbus_create_inplace(&bus->qbus, &pci_bus_info, &dev->qdev, name); > > > +PCIBus *bus; > > > +bus = pci_bus_new(&dev->qdev, name, 0); > > > + > > > bus->map_irq = map_irq; > > > bus->parent_dev = dev; > > > > > > QLIST_INSERT_HEAD(&parent->child, bus, sibling); > > > + > > > +return bus; > > > > This does more than we need: pci_bus_new > > was created for host bus so it will also register in > > reset and vmstate lists. > > I'm bit confused. I've thought that pci_bus_new() was for both root bus > and secondary bus. So I've tried to move out root bus specific stuff > from pci_bus_new(). > > But you claim it's only for root bus, not for secondary bus. > Now I realized why you've rejected such patches so far. > Then, you also mean the current pci_register_secondary_bus() is broken. > I also think it's broken. So how do we want to fix it? > My idea is as follows. > > - introduce something like pci_secondary_bus_new() > (pci_sec_bus_new() for short?) for secondary bus. > fix pci_register_secondary_bus() with it. > > - introduce something like pci_host_bus_new() (or pci_root_bus_new()?) > for pci host bus which is more generic than pci_bus_new(). > It's for > - to avoid confusion. > - to eliminate assumption of pci_bus_new(). > pci_bus_new() assumes that its pci segment is 0. > keep pci_bus_new() as a convenience wrapper of > pci_host_bus_new(segment = 0). Thus we can avoid fixing up > all the caller. > > > > } > > > > > > static void pci_unregister_secondary_bus(PCIBus *bus) > > > { > > > assert(QLIST_EMPTY(&bus->child)); > > > QLIST_REMOVE(bus, sibling); > > > +qbus_free(&bus->qbus); > > > } > > > > > > int pci_bus_num(PCIBus *s) > > > @@ -1527,7 +1531,7 @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, const > > > char *default_
[Qemu-devel] [PATCH v2 0/6] Migration subsections (and ide as example)
v2: - add documentation - improve commit messages - remove debug printf's - rebase latest qemu v1: At the end, here is the migration subsections implementation. As an example I ported the last two ide changes to migration to work with subsections. Notes: - subsections I went for qemu_peek_byte() insteadof adding a subsection part in qemu_loadvm_state() due to two reasons: - it makes mandatory that subsections came after sections (better for error messages) - it makes post_load() for the section to be run after subsections are loaded. I think that running section post_load() and then subsections can make for some subtle errors. How does it works? We have a new array of subsections at the end of each section (it can be NULL). Each subsection is composed of VMStateDescription and a test function. test function checks if subsection is needed or not. if needed, it is just emmited. On load, we peek to see if after a section is loaded, if there is any subsection at the end, and if so, we search for it on this section subsections. - ide: 1st revert is not clear because there has been posterior changes that I honored. only change done is that ide_dummy_transfer_stop to transfer_end_table for it to be complete. - testing. In normal operation this code is not triggered (one of the reason for not wanting to sent it in the 1st place). I used patch attached at the end to trigger it. Commetnts? Later, Juan. diff --git a/hw/ide/core.c b/hw/ide/core.c index 59341a1..a4e6b82 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -421,6 +421,15 @@ static void ide_sector_read(IDEState *s) ide_set_irq(s->bus); ide_set_sector(s, sector_num + n); s->nsector -= n; +if ((s->status & DRQ_STAT)) { +static int val = 1; +if (((val++) == 1000)) { +qemu_aio_flush(); +vm_stop(0); +printf("stopped %d ide_ioport_readaaa\n", val); +} +} + } } @@ -2744,6 +2753,14 @@ static int ide_drive_pio_post_load(void *opaque, int version_id) s->data_ptr = s->io_buffer + s->cur_io_buffer_offset; s->data_end = s->data_ptr + s->cur_io_buffer_len; +printf("addr %p: status %d\n", s, s->status& DRQ_STAT); +printf("\tdata_ptr %p\n", s->data_ptr); +printf("\tdata_end %p\n", s->data_end); +printf("\tio_buffer %p\n", s->io_buffer); +printf("\treq_nb_sectors %d\n", s->req_nb_sectors); +printf("\tidx %d\n", transfer_end_table_idx(s->end_transfer_func)); +printf("\telementary_transfer_size %d\n", s->elementary_transfer_size); +printf("\tpacket_transfer_size %d\n", s->packet_transfer_size); return 0; } @@ -2763,6 +2780,15 @@ static void ide_drive_pio_pre_save(void *opaque) } else { s->end_transfer_fn_idx = idx; } + +printf("addr %p: status %d\n", s, s->status& DRQ_STAT); +printf("\tdata_ptr %p\n", s->data_ptr); +printf("\tdata_end %p\n", s->data_end); +printf("\tio_buffer %p\n", s->io_buffer); +printf("\treq_nb_sectors %d\n", s->req_nb_sectors); +printf("\tidx %d\n", transfer_end_table_idx(s->end_transfer_func)); +printf("\telementary_transfer_size %d\n", s->elementary_transfer_size); +printf("\tpacket_transfer_size %d\n", s->packet_transfer_size); } static bool ide_drive_pio_state_needed(void *opaque) Juan Quintela (6): Revert "ide save/restore pio/atapi cmd transfer fields and io buffer" Revert "ide save/restore current transfer fields" vmstate: add subsections code ide: fix migration in the middle of pio operation ide: fix migration in the middle of a bmdma transfer Initial documentation for migration docs/migration.txt | 303 hw/hw.h|6 + hw/ide/core.c | 72 + hw/ide/pci.c | 38 ++- savevm.c | 86 +++- 5 files changed, 477 insertions(+), 28 deletions(-) create mode 100644 docs/migration.txt
[Qemu-devel] [PATCH 3/6] vmstate: add subsections code
This commit adds subsections for each device section. Subsections is the way to handle information that don't need to be sent to de destination of a migration because its values are not needed. It is the way to handle optional information. Notice that only the source can decide if the information is optional or not. The destination needs to understand all subsections that it receives to have a sucessful load. Signed-off-by: Juan Quintela --- hw/hw.h |6 savevm.c | 86 +- 2 files changed, 91 insertions(+), 1 deletions(-) diff --git a/hw/hw.h b/hw/hw.h index c2de6fe..e3c3db2 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -313,6 +313,11 @@ typedef struct { bool (*field_exists)(void *opaque, int version_id); } VMStateField; +typedef struct VMStateSubsection { +const VMStateDescription *vmsd; +bool (*needed)(void *opaque); +} VMStateSubsection; + struct VMStateDescription { const char *name; int version_id; @@ -323,6 +328,7 @@ struct VMStateDescription { int (*post_load)(void *opaque, int version_id); void (*pre_save)(void *opaque); VMStateField *fields; +const VMStateSubsection *subsections; }; extern const VMStateInfo vmstate_info_int8; diff --git a/savevm.c b/savevm.c index ee27989..7a1de3c 100644 --- a/savevm.c +++ b/savevm.c @@ -551,6 +551,19 @@ int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1) return size1 - size; } +static int qemu_peek_byte(QEMUFile *f) +{ +if (f->is_write) +abort(); + +if (f->buf_index >= f->buf_size) { +qemu_fill_buffer(f); +if (f->buf_index >= f->buf_size) +return 0; +} +return f->buf[f->buf_index]; +} + int qemu_get_byte(QEMUFile *f) { if (f->is_write) @@ -1198,10 +1211,16 @@ void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd, } } +static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd, +void *opaque); +static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, + void *opaque); + int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, void *opaque, int version_id) { VMStateField *field = vmsd->fields; +int ret; if (version_id > vmsd->version_id) { return -EINVAL; @@ -1223,7 +1242,7 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, (!field->field_exists && field->version_id <= version_id)) { void *base_addr = opaque + field->offset; -int ret, i, n_elems = 1; +int i, n_elems = 1; int size = field->size; if (field->flags & VMS_VBUFFER) { @@ -1261,6 +1280,10 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, } field++; } +ret = vmstate_subsection_load(f, vmsd, opaque); +if (ret != 0) { +return ret; +} if (vmsd->post_load) { return vmsd->post_load(opaque, version_id); } @@ -1313,6 +1336,7 @@ void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd, } field++; } +vmstate_subsection_save(f, vmsd, opaque); } static int vmstate_load(QEMUFile *f, SaveStateEntry *se, int version_id) @@ -1341,6 +1365,7 @@ static void vmstate_save(QEMUFile *f, SaveStateEntry *se) #define QEMU_VM_SECTION_PART 0x02 #define QEMU_VM_SECTION_END 0x03 #define QEMU_VM_SECTION_FULL 0x04 +#define QEMU_VM_SUBSECTION 0x05 int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable, int shared) @@ -1529,6 +1554,65 @@ static SaveStateEntry *find_se(const char *idstr, int instance_id) return NULL; } +static const VMStateDescription *vmstate_get_subsection(const VMStateSubsection *sub, char *idstr) +{ +while(sub && sub->needed) { +if (strcmp(idstr, sub->vmsd->name) == 0) { +return sub->vmsd; +} +sub++; +} +return NULL; +} + +static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, + void *opaque) +{ +while (qemu_peek_byte(f) == QEMU_VM_SUBSECTION) { +char idstr[256]; +int ret; +uint8_t version_id, subsection, len; +const VMStateDescription *sub_vmsd; + +subsection = qemu_get_byte(f); +len = qemu_get_byte(f); +qemu_get_buffer(f, (uint8_t *)idstr, len); +idstr[len] = 0; +version_id = qemu_get_be32(f); + +sub_vmsd = vmstate_get_subsection(vmsd->subsections, idstr); +if (sub_vmsd == NULL) { +return -ENOENT; +} +ret = vmstate_load_state(f, sub_vmsd, opaque, version_id); +if (ret) { +return ret; +} +} +return 0; +} + +static void vmstate_subsection_save(QEMUFile *
[Qemu-devel] [PATCH 4/6] ide: fix migration in the middle of pio operation
Signed-off-by: Juan Quintela --- hw/ide/core.c | 90 - hw/ide/internal.h |5 +++ 2 files changed, 94 insertions(+), 1 deletions(-) diff --git a/hw/ide/core.c b/hw/ide/core.c index 8669602..20e639d 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -2660,6 +2660,7 @@ static void ide_init1(IDEBus *bus, int unit) s->unit = unit; s->drive_serial = drive_serial++; s->io_buffer = qemu_blockalign(s->bs, IDE_DMA_BUF_SECTORS*512 + 4); +s->io_buffer_total_len = IDE_DMA_BUF_SECTORS*512 + 4; s->smart_selftest_data = qemu_blockalign(s->bs, 512); s->sector_write_timer = qemu_new_timer(vm_clock, ide_sector_write_timer_cb, s); @@ -2722,6 +2723,26 @@ static bool is_identify_set(void *opaque, int version_id) return s->identify_set != 0; } +static EndTransferFunc* transfer_end_table[] = { +ide_sector_read, +ide_sector_write, +ide_transfer_stop, +ide_atapi_cmd_reply_end, +ide_atapi_cmd, +ide_dummy_transfer_stop, +}; + +static int transfer_end_table_idx(EndTransferFunc *fn) +{ +int i; + +for (i = 0; i < ARRAY_SIZE(transfer_end_table); i++) +if (transfer_end_table[i] == fn) +return i; + +return -1; +} + static int ide_drive_post_load(void *opaque, int version_id) { IDEState *s = opaque; @@ -2735,6 +2756,66 @@ static int ide_drive_post_load(void *opaque, int version_id) return 0; } +static int ide_drive_pio_post_load(void *opaque, int version_id) +{ +IDEState *s = opaque; + +if (s->end_transfer_fn_idx < 0 || +s->end_transfer_fn_idx > ARRAY_SIZE(transfer_end_table)) { +return -EINVAL; +} +s->end_transfer_func = transfer_end_table[s->end_transfer_fn_idx]; +s->data_ptr = s->io_buffer + s->cur_io_buffer_offset; +s->data_end = s->data_ptr + s->cur_io_buffer_len; + +return 0; +} + +static void ide_drive_pio_pre_save(void *opaque) +{ +IDEState *s = opaque; +int idx; + +s->cur_io_buffer_offset = s->data_ptr - s->io_buffer; +s->cur_io_buffer_len = s->data_end - s->data_ptr; + +idx = transfer_end_table_idx(s->end_transfer_func); +if (idx == -1) { +fprintf(stderr, "%s: invalid end_transfer_func for DRQ_STAT\n", +__func__); +s->end_transfer_fn_idx = 2; +} else { +s->end_transfer_fn_idx = idx; +} +} + +static bool ide_drive_pio_state_needed(void *opaque) +{ +IDEState *s = opaque; + +return (s->status & DRQ_STAT) != 0; +} + +const VMStateDescription vmstate_ide_drive_pio_state = { +.name = "ide_drive/pio_state", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.pre_save = ide_drive_pio_pre_save, +.post_load = ide_drive_pio_post_load, +.fields = (VMStateField []) { +VMSTATE_INT32(req_nb_sectors, IDEState), +VMSTATE_VARRAY_INT32(io_buffer, IDEState, io_buffer_total_len, 1, +vmstate_info_uint8, uint8_t), +VMSTATE_INT32(cur_io_buffer_offset, IDEState), +VMSTATE_INT32(cur_io_buffer_len, IDEState), +VMSTATE_UINT8(end_transfer_fn_idx, IDEState), +VMSTATE_INT32(elementary_transfer_size, IDEState), +VMSTATE_INT32(packet_transfer_size, IDEState), +VMSTATE_END_OF_LIST() +} +}; + const VMStateDescription vmstate_ide_drive = { .name = "ide_drive", .version_id = 3, @@ -2762,8 +2843,15 @@ const VMStateDescription vmstate_ide_drive = { VMSTATE_UINT8(sense_key, IDEState), VMSTATE_UINT8(asc, IDEState), VMSTATE_UINT8_V(cdrom_changed, IDEState, 3), -/* XXX: if a transfer is pending, we do not save it yet */ VMSTATE_END_OF_LIST() +}, +.subsections = (VMStateSubsection []) { +{ +.vmsd = &vmstate_ide_drive_pio_state, +.needed = ide_drive_pio_state_needed, +}, { +/* empty */ +} } }; diff --git a/hw/ide/internal.h b/hw/ide/internal.h index 75745ee..4165543 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -419,6 +419,11 @@ struct IDEState { uint8_t *data_ptr; uint8_t *data_end; uint8_t *io_buffer; +/* PIO save/restore */ +int32_t io_buffer_total_len; +int cur_io_buffer_offset; +int cur_io_buffer_len; +uint8_t end_transfer_fn_idx; QEMUTimer *sector_write_timer; /* only used for win2k install hack */ uint32_t irq_count; /* counts IRQs when using win2k install hack */ /* CF-ATA extended error */ -- 1.7.1
[Qemu-devel] [PATCH 1/6] Revert "ide save/restore pio/atapi cmd transfer fields and io buffer"
This reverts commit ed487bb1d69040b9dac64a4fc076d8dd82b131d6. The conflicts are due to commit 4fc8d6711aff7a9c11e402c3d77b481609f9f486 that is a fix to the ide_drive_pre_save() function. It reverts both (and both are reinstantiated later in the series) Conflicts: hw/ide/core.c Signed-off-by: Juan Quintela --- hw/ide/core.c | 62 +--- hw/ide/internal.h |5 2 files changed, 2 insertions(+), 65 deletions(-) diff --git a/hw/ide/core.c b/hw/ide/core.c index af52c2c..8669602 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -2660,7 +2660,6 @@ static void ide_init1(IDEBus *bus, int unit) s->unit = unit; s->drive_serial = drive_serial++; s->io_buffer = qemu_blockalign(s->bs, IDE_DMA_BUF_SECTORS*512 + 4); -s->io_buffer_total_len = IDE_DMA_BUF_SECTORS*512 + 4; s->smart_selftest_data = qemu_blockalign(s->bs, 512); s->sector_write_timer = qemu_new_timer(vm_clock, ide_sector_write_timer_cb, s); @@ -2723,25 +2722,6 @@ static bool is_identify_set(void *opaque, int version_id) return s->identify_set != 0; } -static EndTransferFunc* transfer_end_table[] = { -ide_sector_read, -ide_sector_write, -ide_transfer_stop, -ide_atapi_cmd_reply_end, -ide_atapi_cmd, -}; - -static int transfer_end_table_idx(EndTransferFunc *fn) -{ -int i; - -for (i = 0; i < ARRAY_SIZE(transfer_end_table); i++) -if (transfer_end_table[i] == fn) -return i; - -return -1; -} - static int ide_drive_post_load(void *opaque, int version_id) { IDEState *s = opaque; @@ -2752,45 +2732,14 @@ static int ide_drive_post_load(void *opaque, int version_id) s->cdrom_changed = 1; } } - -if (s->cur_io_buffer_len) { -s->end_transfer_func = transfer_end_table[s->end_transfer_fn_idx]; -s->data_ptr = s->io_buffer + s->cur_io_buffer_offset; -s->data_end = s->data_ptr + s->cur_io_buffer_len; -} - return 0; } -static void ide_drive_pre_save(void *opaque) -{ -IDEState *s = opaque; -int idx; - -s->cur_io_buffer_len = 0; - -if (!(s->status & DRQ_STAT)) -return; - -s->cur_io_buffer_offset = s->data_ptr - s->io_buffer; -s->cur_io_buffer_len = s->data_end - s->data_ptr; - -idx = transfer_end_table_idx(s->end_transfer_func); -if (idx == -1) { -fprintf(stderr, "%s: invalid end_transfer_func for DRQ_STAT\n", -__func__); -s->end_transfer_fn_idx = 2; -} else { -s->end_transfer_fn_idx = idx; -} -} - const VMStateDescription vmstate_ide_drive = { .name = "ide_drive", -.version_id = 4, +.version_id = 3, .minimum_version_id = 0, .minimum_version_id_old = 0, -.pre_save = ide_drive_pre_save, .post_load = ide_drive_post_load, .fields = (VMStateField []) { VMSTATE_INT32(mult_sectors, IDEState), @@ -2813,14 +2762,7 @@ const VMStateDescription vmstate_ide_drive = { VMSTATE_UINT8(sense_key, IDEState), VMSTATE_UINT8(asc, IDEState), VMSTATE_UINT8_V(cdrom_changed, IDEState, 3), -VMSTATE_INT32_V(req_nb_sectors, IDEState, 4), -VMSTATE_VARRAY_INT32(io_buffer, IDEState, io_buffer_total_len, 4, -vmstate_info_uint8, uint8_t), -VMSTATE_INT32_V(cur_io_buffer_offset, IDEState, 4), -VMSTATE_INT32_V(cur_io_buffer_len, IDEState, 4), -VMSTATE_UINT8_V(end_transfer_fn_idx, IDEState, 4), -VMSTATE_INT32_V(elementary_transfer_size, IDEState, 4), -VMSTATE_INT32_V(packet_transfer_size, IDEState, 4), +/* XXX: if a transfer is pending, we do not save it yet */ VMSTATE_END_OF_LIST() } }; diff --git a/hw/ide/internal.h b/hw/ide/internal.h index 4165543..75745ee 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -419,11 +419,6 @@ struct IDEState { uint8_t *data_ptr; uint8_t *data_end; uint8_t *io_buffer; -/* PIO save/restore */ -int32_t io_buffer_total_len; -int cur_io_buffer_offset; -int cur_io_buffer_len; -uint8_t end_transfer_fn_idx; QEMUTimer *sector_write_timer; /* only used for win2k install hack */ uint32_t irq_count; /* counts IRQs when using win2k install hack */ /* CF-ATA extended error */ -- 1.7.1
[Qemu-devel] [PATCH 5/6] ide: fix migration in the middle of a bmdma transfer
It reintroduces Revert "ide save/restore pio/atapi cmd transfer fields and io buffer" but using subsections. Added bonus is the addition of ide_dummy_transfer_stop to transfer_end_table, that was missing. Signed-off-by: Juan Quintela --- hw/ide/pci.c | 30 ++ 1 files changed, 30 insertions(+), 0 deletions(-) diff --git a/hw/ide/pci.c b/hw/ide/pci.c index 780fc5f..4331d77 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -121,6 +121,28 @@ void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val) bm->cur_addr = bm->addr; } +static bool ide_bmdma_current_needed(void *opaque) +{ +BMDMAState *bm = opaque; + +return (bm->cur_prd_len != 0); +} + +static const VMStateDescription vmstate_bmdma_current = { +.name = "ide bmdma_current", +.version_id = 1, +.minimum_version_id = 1, +.minimum_version_id_old = 1, +.fields = (VMStateField []) { +VMSTATE_UINT32(cur_addr, BMDMAState), +VMSTATE_UINT32(cur_prd_last, BMDMAState), +VMSTATE_UINT32(cur_prd_addr, BMDMAState), +VMSTATE_UINT32(cur_prd_len, BMDMAState), +VMSTATE_END_OF_LIST() +} +}; + + static const VMStateDescription vmstate_bmdma = { .name = "ide bmdma", .version_id = 3, @@ -134,6 +156,14 @@ static const VMStateDescription vmstate_bmdma = { VMSTATE_UINT32(nsector, BMDMAState), VMSTATE_UINT8(unit, BMDMAState), VMSTATE_END_OF_LIST() +}, +.subsections = (VMStateSubsection []) { +{ +.vmsd = &vmstate_bmdma_current, +.needed = ide_bmdma_current_needed, +}, { +/* empty */ +} } }; -- 1.7.1
[Qemu-devel] [PATCH 2/6] Revert "ide save/restore current transfer fields"
This reverts commit 42ee76fe82093ba914f0dc83d2decbcf68866144. Signed-off-by: Juan Quintela --- hw/ide/pci.c |8 ++-- 1 files changed, 2 insertions(+), 6 deletions(-) diff --git a/hw/ide/pci.c b/hw/ide/pci.c index 4d95cc5..780fc5f 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -123,7 +123,7 @@ void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val) static const VMStateDescription vmstate_bmdma = { .name = "ide bmdma", -.version_id = 4, +.version_id = 3, .minimum_version_id = 0, .minimum_version_id_old = 0, .fields = (VMStateField []) { @@ -133,10 +133,6 @@ static const VMStateDescription vmstate_bmdma = { VMSTATE_INT64(sector_num, BMDMAState), VMSTATE_UINT32(nsector, BMDMAState), VMSTATE_UINT8(unit, BMDMAState), -VMSTATE_UINT32_V(cur_addr, BMDMAState, 4), -VMSTATE_UINT32_V(cur_prd_last, BMDMAState, 4), -VMSTATE_UINT32_V(cur_prd_addr, BMDMAState, 4), -VMSTATE_UINT32_V(cur_prd_len, BMDMAState, 4), VMSTATE_END_OF_LIST() } }; @@ -156,7 +152,7 @@ static int ide_pci_post_load(void *opaque, int version_id) const VMStateDescription vmstate_ide_pci = { .name = "ide", -.version_id = 4, +.version_id = 3, .minimum_version_id = 0, .minimum_version_id_old = 0, .post_load = ide_pci_post_load, -- 1.7.1
[Qemu-devel] [PATCH 6/6] Initial documentation for migration
Signed-off-by: Juan Quintela --- docs/migration.txt | 303 1 files changed, 303 insertions(+), 0 deletions(-) create mode 100644 docs/migration.txt diff --git a/docs/migration.txt b/docs/migration.txt new file mode 100644 index 000..55120fe --- /dev/null +++ b/docs/migration.txt @@ -0,0 +1,303 @@ += Migration = + +Qemu has code to load/save the state of the guest that it is running. +This are two complementary operations. Saving the state just does +that, saves the state for each device that the guest is running. +Restoring a guest is just the opposite operation: we need to load the +state of each device. + +For this to work, qemu has to be launch with the same arguments the +two times. I.e. it can only restore the state in one guest that has +the same devices that the one it was saved (this last requirement can +be relaxed a bit, but for now we can consider that configuration have +to be exactly the same). + +Once that we are able to save/restore a guest, a new functionality is +requested: migration. This means that qemu is able to start in one +machine and being "migrated" to other machine. I.e. being moved to +other machine. + +Next was the "live migration" functionality. This is important +because some guests run with a lot of state (specially RAM), and it +can take a while to move all state from one machine to another. Live +migration allows the guest to continue running while the state is +transferred. Only while the last part of the state is transfered has +the guest to be stopped. Tipically the time that the guest is +unresponsive during live migration is the low hundred of milliseconds +(notice that this depends on lot of things). + +=== Types of migration === + +Now that we have talked about live migration, there are several ways +to do migration: + +- tcp migration: do the migration using tcp sockets +- unix migration: do the migration using unix sockets +- exec migration: do the migration using the stdin/stdout through a process. +- fd migration: do the migration using an file descriptor that is + passed to qemu. qemu don't cares how this file descriptor is opened. + +All this four migration protocols use the same infraestructure to +save/restore state devices. This infrastructure is shared with the +savevm/loadvm functionality. + +=== State Live Migration == + +This is used for RAM and block devices. It is not yet ported to vmstate. + + +=== What is the common infrastructure === + +Qemu uses a QEMUFile abstraction to be able to do migration. Any type +of migration that what to use qemu infrastructure has to create a +QEMUFile with: + +QEMUFile *qemu_fopen_ops(void *opaque, +QEMUFilePutBufferFunc *put_buffer, + QEMUFileGetBufferFunc *get_buffer, + QEMUFileCloseFunc *close, + QEMUFileRateLimit *rate_limit, + QEMUFileSetRateLimit *set_rate_limit, +QEMUFileGetRateLimit *get_rate_limit); + +The functions have the folliwing functionality: + +This function writes a chunk of data to a file at the given position. +The pos argument can be ignored if the file is only being used for +streaming. The handler should try to write all of the data it can. + +typedef int (QEMUFilePutBufferFunc)(void *opaque, const uint8_t *buf, +int64_t pos, int size); + +Read a chunk of data from a file at the given position. The pos argument +can be ignored if the file is only be used for streaming. The number of +bytes actually read should be returned. + +typedef int (QEMUFileGetBufferFunc)(void *opaque, uint8_t *buf, +int64_t pos, int size); + +Close a file and return an error code + +typedef int (QEMUFileCloseFunc)(void *opaque); + +Called to determine if the file has exceeded it's bandwidth allocation. The +bandwidth capping is a soft limit, not a hard limit. + +typedef int (QEMUFileRateLimit)(void *opaque); + +Called to change the current bandwidth allocation. This function must return +the new actual bandwidth. It should be new_rate if everything goes ok, and +the old rate otherwise + +typedef size_t (QEMUFileSetRateLimit)(void *opaque, size_t new_rate); +typedef size_t (QEMUFileGetRateLimit)(void *opaque); + +You can use any internal state that you need using the opaque void * +pointer that is passed to all functions. + +The rate limiting functions are used to limit the bandwidth used by +qemu migration. + +The important functions for us are put_buffer()/get_buffer() that +allow to write/read a buffer into the QEMUFile. + +=== How to save the state of one device == + +The state of a device is saved using intermediate buffers. There are +some helper functions to assist this saving. + +There is a new concept that we have to explain here: device state +version. When we migrate a device, we save/load the state as a serie +of fields
[Qemu-devel] [SeaBIOS] [PATCH] virtio: Clear interrupt status register in virtio-blk
The VRING_AVAIL_F_NO_INTERRUPT flag is a hint that interrupts should be suppressed. It does not guarantee that interrupts will not be raised. Therefore, make sure to clear the interrupt after each virtio-blk read. This avoids a stuck interrupt interfering with the OS loaded later in the boot process. Signed-off-by: Stefan Hajnoczi --- src/virtio-blk.c |6 ++ src/virtio-pci.h |4 2 files changed, 10 insertions(+), 0 deletions(-) diff --git a/src/virtio-blk.c b/src/virtio-blk.c index 16d9ad8..74af488 100644 --- a/src/virtio-blk.c +++ b/src/virtio-blk.c @@ -62,6 +62,12 @@ virtio_blk_read(struct disk_op_s *op) /* Reclaim virtqueue element */ vring_get_buf(vq, NULL); + +/* Clear interrupt status register. Avoid leaving interrupts stuck if + * VRING_AVAIL_F_NO_INTERRUPT was ignored and interrupts were raised. + */ +vp_get_isr(GET_GLOBAL(vdrive_g->ioaddr)); + return status == VIRTIO_BLK_S_OK ? DISK_RET_SUCCESS : DISK_RET_EBADTRACK; } diff --git a/src/virtio-pci.h b/src/virtio-pci.h index 9da761d..d21d5a5 100644 --- a/src/virtio-pci.h +++ b/src/virtio-pci.h @@ -71,6 +71,10 @@ static inline void vp_set_status(unsigned int ioaddr, u8 status) outb(status, ioaddr + VIRTIO_PCI_STATUS); } +static inline u8 vp_get_isr(unsigned int ioaddr) +{ + return inb(ioaddr + VIRTIO_PCI_ISR); +} static inline void vp_reset(unsigned int ioaddr) { -- 1.7.1
[Qemu-devel] Re: [PATCH 1/2] QMP: Introduce the documentation for query-qdm
On Mon, 5 Jul 2010 16:34:22 -0300 Miguel Di Ciurcio Filho wrote: > Possible values for "type" are defined in the patch on the > qdev_property_type_to_string() function. To spot them in the current > code, hw/qdev.c:77: > > enum PropertyType { > PROP_TYPE_UNSPEC = 0, > PROP_TYPE_UINT8, > PROP_TYPE_UINT16, > PROP_TYPE_UINT32, > PROP_TYPE_INT32, > PROP_TYPE_UINT64, > PROP_TYPE_TADDR, > PROP_TYPE_MACADDR, > PROP_TYPE_DRIVE, > PROP_TYPE_CHR, > PROP_TYPE_STRING, > PROP_TYPE_NETDEV, > PROP_TYPE_VLAN, > PROP_TYPE_PTR, > PROP_TYPE_BIT, > }; > > So it is a mix of json-(string|integer|boolean). It seams to me that a > device_add using QMP will use just use strings. Need to confirm that. There are integers too. Daniel, can you clarify how libvirt is going to use this member? Maybe we could have something like this: "type": { "qdev": "macaddr", "qmp": "string" }
[Qemu-devel] Re: [PATCH 1/2] QMP: Introduce the documentation for query-qdm
On Wed, Jul 07, 2010 at 10:07:09AM -0300, Luiz Capitulino wrote: > On Mon, 5 Jul 2010 16:34:22 -0300 > Miguel Di Ciurcio Filho wrote: > > > Possible values for "type" are defined in the patch on the > > qdev_property_type_to_string() function. To spot them in the current > > code, hw/qdev.c:77: > > > > enum PropertyType { > > PROP_TYPE_UNSPEC = 0, > > PROP_TYPE_UINT8, > > PROP_TYPE_UINT16, > > PROP_TYPE_UINT32, > > PROP_TYPE_INT32, > > PROP_TYPE_UINT64, > > PROP_TYPE_TADDR, > > PROP_TYPE_MACADDR, > > PROP_TYPE_DRIVE, > > PROP_TYPE_CHR, > > PROP_TYPE_STRING, > > PROP_TYPE_NETDEV, > > PROP_TYPE_VLAN, > > PROP_TYPE_PTR, > > PROP_TYPE_BIT, > > }; > > > > So it is a mix of json-(string|integer|boolean). It seams to me that a > > device_add using QMP will use just use strings. Need to confirm that. > > There are integers too. > > Daniel, can you clarify how libvirt is going to use this member? We're not actively planning to use this field. When I wrote the patch originally, I was aiming to provide the maximim semantically useful information possible, rather than just the generic json data type. This ensures that this is fully self-documenting. > Maybe we could have something like this: > > "type": { "qdev": "macaddr", "qmp": "string" } Daniel -- |: Red Hat, Engineering, London-o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org-o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
Re: [Qemu-devel] [PATCH 6/6] Initial documentation for migration
On Wed, 7 Jul 2010, Juan Quintela wrote: > > Signed-off-by: Juan Quintela > --- > docs/migration.txt | 303 > > 1 files changed, 303 insertions(+), 0 deletions(-) > create mode 100644 docs/migration.txt > > diff --git a/docs/migration.txt b/docs/migration.txt > new file mode 100644 > index 000..55120fe > --- /dev/null > +++ b/docs/migration.txt > @@ -0,0 +1,303 @@ > += Migration = > + > +Qemu has code to load/save the state of the guest that it is running. QEMU [..snip..] -- mailto:av1...@comtv.ru
Re: [Qemu-devel] [PATCH] sheepdog: fix compile error on systems without TCP_CORK
It compiles now. On Jul 7, 2010, at 12:25 AM, MORITA Kazutaka wrote: > WIN32 is not only the system which doesn't have TCP_CORK (e.g. OS X). > > Signed-off-by: MORITA Kazutaka > --- > > Betts, I think this patch fix the compile error. Can you try this > one? > > block/sheepdog.c |2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) > > diff --git a/block/sheepdog.c b/block/sheepdog.c > index 69a2494..81aa564 100644 > --- a/block/sheepdog.c > +++ b/block/sheepdog.c > @@ -889,7 +889,7 @@ static int aio_flush_request(void *opaque) > return !QLIST_EMPTY(&s->outstanding_aio_head); > } > > -#ifdef _WIN32 > +#if !defined(SOL_TCP) || !defined(TCP_CORK) > > static int set_cork(int fd, int v) > { > -- > 1.5.6.5 > > >
[Qemu-devel] [PATCH] ehci: uhci-ehci co-existence (handling v1.1 and v2 devices)
Per the EHCI specification a USB 2.0 host controller is comprised of one high-speed controller and 0 to N USB 1.1 companion host controllers (UHCI or OHCI) for low- and full-speed devices. Port routing and control logic determines which HC owns a particular port. See Sections 1.2 and 4.2 of the EHCI specification. http://www.intel.com/technology/usb/download/ehci-r10.pdf In essence a USB 2.0 bus has N ports. Those N ports can be controlled by either the companion controller or the ehci controller. The ports default to the companion controller. At boot if the OS has an EHCI host driver it can take control of the ports by default and when a low/full speed device is connected switch the port to a companion controller. After looking into this for the past 6+ weeks, the port routing and control logic gets rather complex to implement in qemu. To keep the implementation simple I propose keeping the UCHI/OHCI and EHCI buses implemented independently -- using the 0 option for the number of companion host controllers. When USB devices are created they are assigned to a specific bus: .---. | device creation | '---' /\ | UHCI controller || EHCI controller | | | | Low/Full speed dev || High speed devices | qemu's emulated devices already know which USB version they are compatible with, so no need to probe for it. Host based devices can default to ehci (or uhci if preferred) and then use the speed information obtained from the scan to determine if the device should be attached to the uhci bus instead. The changes for this design are fairly small and contained. Furthermore, it extends easily to USB 3.0 in the future. Summary of the changes: 1. add a version based API in usb-bus.c for registering buses and creating devices 2. change the USB device models to attach to a bus based on version - v1 or v2. 3. If a bus is not specified (e.g., usb_create_simple path) default to v1 (for compatibility with existing code). 4. For PC's create a UCHI and EHCI controller in pc_piix.c 5. For host based devices default to ehci and use the speed information to determine if the device should be attached to the uhci bus. The attached patch is a first cut at this path and has worked fairly well in limited testing. Take this as a proof of concept; I'll clean it up if the overall architecture is acceptable. Example: /tmp/qemu.latest/bin/qemu-system-x86_64 -m 1024 -smp 1 -drive file=/images/fc12/disk-1.img,cache=none,media=disk -monitor unix:/tmp/fc12-x86_64,server,nowait -enable-kvm -usb -usbdevice disk:/images/fc12/usb.img -usbdevice net:vlan=2 -net user,vlan=2 -usbdevice serial::telnet::,server,nowait -usbdevice host:2.16 (qemu) info usb Device 0.2, Speed 12 Mb/s, Product QEMU USB Network Interface Device 0.3, Speed 12 Mb/s, Product QEMU USB Hub Device 0.4, Speed 12 Mb/s, Product QEMU USB Serial Device 1.2, Speed 480 Mb/s, Product QEMU USB MSD Device 1.3, Speed 480 Mb/s, Product DT 101 II Signed-off-by: David Ahern --- hw/pc_piix.c|7 + hw/usb-bus.c| 70 +- hw/usb-ehci.c |6 - hw/usb-msd.c|2 +- hw/usb-net.c|6 ++-- hw/usb-ohci.c |2 +- hw/usb-serial.c |4 +- hw/usb-uhci.c |2 +- hw/usb.h|8 -- usb-bsd.c |2 +- usb-linux.c | 22 +++-- 11 files changed, 88 insertions(+), 43 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index dffcbe1..934e336 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -153,11 +153,8 @@ static void pc_init1(ram_addr_t ram_size, idebus[0], idebus[1], floppy_controller, rtc_state); if (pci_enabled && usb_enabled) { -#if 0 usb_uhci_piix3_init(pci_bus, piix3_devfn + 2); -#else -usb_ehci_init(pci_bus, piix3_devfn + 2); -#endif +usb_ehci_init(pci_bus, piix3_devfn + 3); } if (pci_enabled && acpi_enabled) { @@ -167,7 +164,7 @@ static void pc_init1(ram_addr_t ram_size, cmos_s3 = qemu_allocate_irqs(pc_cmos_set_s3_resume, rtc_state, 1); smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1); /* TODO: Populate SPD eeprom data. */ -smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, +smbus = piix4_pm_init(pci_bus, piix3_devfn + 4, 0xb100, isa_reserve_irq(9), *cmos_s3, *smi_irq, kvm_enabled()); for (i = 0; i < 8; i++) { diff --git a/hw/usb-bus.c b/hw/usb-bus.c index b692503..8d02169 100644 --- a/hw/usb-bus.c +++ b/hw/usb-bus.c @@ -14,29 +14,52 @@ static struct
Re: [Qemu-devel] [PATCH] pci: pass bridge update to secondary bus
On Tue, Jul 6, 2010 at 11:23 AM, Michael S. Tsirkin wrote: > bridge config write should trigger updates > on the secondary bus. never on the primary bus. If this is true, shouldn't updates happen on all buses from secondary to subordinate? Do we know which of these are immediately below primary bus? > > Signed-off-by: Michael S. Tsirkin > --- > > Compile-tested only. > Isaku Yamahata, could you review this please? > You wrote the code, and you seem to have some bridged setups. > > hw/pci.c | 4 +++- > 1 files changed, 3 insertions(+), 1 deletions(-) > > diff --git a/hw/pci.c b/hw/pci.c > index 926cf63..011d83e 100644 > --- a/hw/pci.c > +++ b/hw/pci.c > @@ -1513,7 +1513,9 @@ static void pci_bridge_write_config(PCIDevice *d, > /* memory base/limit, prefetchable base/limit and > io base/limit upper 16 */ > ranges_overlap(address, len, PCI_MEMORY_BASE, 20)) { > - pci_bridge_update_mappings(d->bus); > + PCIBridge *s = container_of(d, PCIBridge, dev); > + PCIBus *secondary_bus = &s->bus; > + pci_bridge_update_mappings(secondary_bus); > } > } > > -- > 1.7.2.rc0.14.g41c1c > >
[Qemu-devel] [PATCH] QEMUFileBuffered: indicate that we're ready when the underlying file is ready
QEMUFileBuffered stops writing when the underlying QEMUFile is not ready, and tells its producer so. However, when the underlying QEMUFile becomes ready, it neglects to pass that information along, resulting in stoppage of all data until the next tick (a tenths of a second). Usually this doesn't matter, because most QEMUFiles used with QEMUFileBuffered are almost always ready, but in the case of exec: migration this is not true, due to the small pipe buffers used to connect to the target process. The result is very slow migration. Fix by detecting the readiness notification and propagating it. The detection is a little ugly since QEMUFile overloads put_buffer() to send it, but that's the suject for a different patch. Signed-off-by: Avi Kivity --- buffered_file.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/buffered_file.c b/buffered_file.c index 54dc6c2..a79264f 100644 --- a/buffered_file.c +++ b/buffered_file.c @@ -156,6 +156,14 @@ static int buffered_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, in offset = size; } +if (pos == 0 && size == 0) { +DPRINTF("file is ready\n"); +if (s->bytes_xfer <= s->xfer_limit) { +DPRINTF("notifying client\n"); +s->put_ready(s->opaque); +} +} + return offset; } -- 1.7.1
Re: [Qemu-devel] [Bug 524447] Re: virsh save is very slow
Hi, just wanted to report, I just tried libvirt-0.8.2 which should use larger dd blocksize. save is still painfully slow, about 1MB/s while host is totally idle... regards nik On Tue, Jun 22, 2010 at 07:02:08PM -, Serge Hallyn wrote: > Just a note that the 0.8.1 release available in maverick gives me about > a 50-second save for a 512M memory image (producing 100M outfile). The > patch listed above and suspected of speeding the saves is not in 0.8.1. > When I hand-apply just that patch, saves take about 8 seconds, but > restore fails. Presumably taking the whole of latest git (or 0.8.2 > whenever it is released) will result in both working and fast > save/restore. > > -- > virsh save is very slow > https://bugs.launchpad.net/bugs/524447 > You received this bug notification because you are a member of qemu- > devel-ml, which is subscribed to QEMU. > > Status in libvirt virtualization API: Unknown > Status in QEMU: Invalid > Status in “libvirt” package in Ubuntu: Confirmed > Status in “qemu-kvm” package in Ubuntu: Confirmed > > Bug description: > As reported here: > http://www.redhat.com/archives/libvir-list/2009-December/msg00203.html > > "virsh save" is very slow - it writes the image at around 1MB/sec on my test > system. > > (I think I saw a bug report for this issue on Fedora's bugzilla, but I can't > find it now...) > > Confirmed under Karmic. > > > > -- - Ing. Nikola CIPRICH LinuxBox.cz, s.r.o. 28. rijna 168, 709 01 Ostrava tel.: +420 596 603 142 fax:+420 596 621 273 mobil: +420 777 093 799 www.linuxbox.cz mobil servis: +420 737 238 656 email servis: ser...@linuxbox.cz -
Re: [Qemu-devel] [PATCH] pci: pass bridge update to secondary bus
On Wed, Jul 07, 2010 at 05:31:39PM +, Blue Swirl wrote: > On Tue, Jul 6, 2010 at 11:23 AM, Michael S. Tsirkin wrote: > > bridge config write should trigger updates > > on the secondary bus. never on the primary bus. > > If this is true, shouldn't updates happen on all buses from secondary > to subordinate? Do we know which of these are immediately below > primary bus? pci_bridge_update_mappings does this already. > > > > Signed-off-by: Michael S. Tsirkin > > --- > > > > Compile-tested only. > > Isaku Yamahata, could you review this please? > > You wrote the code, and you seem to have some bridged setups. > > > > hw/pci.c | 4 +++- > > 1 files changed, 3 insertions(+), 1 deletions(-) > > > > diff --git a/hw/pci.c b/hw/pci.c > > index 926cf63..011d83e 100644 > > --- a/hw/pci.c > > +++ b/hw/pci.c > > @@ -1513,7 +1513,9 @@ static void pci_bridge_write_config(PCIDevice *d, > > /* memory base/limit, prefetchable base/limit and > > io base/limit upper 16 */ > > ranges_overlap(address, len, PCI_MEMORY_BASE, 20)) { > > - pci_bridge_update_mappings(d->bus); > > + PCIBridge *s = container_of(d, PCIBridge, dev); > > + PCIBus *secondary_bus = &s->bus; > > + pci_bridge_update_mappings(secondary_bus); > > } > > } > > > > -- > > 1.7.2.rc0.14.g41c1c > > > >
[Qemu-devel] Re: [PATCH, RFC] pci: handle BAR mapping at pci level
On Wed, Jul 07, 2010 at 05:53:08PM +, Blue Swirl wrote: > Add I/O port registration functions which separate registration > from the mapping stage. > > Move IOIO and MMIO BAR mapping to pci.c. > > TODO: fix dirty logging, coalesced MMIO and base address comparisons > (eepro100 etc). Bridge filtering may be broken. Broke virtio-pci and MSIX. legacy vga regions too? > Signed-off-by: Blue Swirl Looks like a good direction to take. > --- > i386 boots but resets. PPC and Sparc64 can't even start. > > Patch also available at > git://repo.or.cz/qemu/blueswirl.git > > It may be worthwhile to break this into some kind of smaller steps. Definitely.
[Qemu-devel] [PATCH] set proper migration status on ->write error
If ->write fails, declare migration status as MIG_STATE_ERROR. Also, in buffered_file.c, ->close the object in case of an error. Fixes "migrate -d "exec:dd of=file", where dd fails to open file. Signed-off-by: Marcelo Tosatti diff --git a/buffered_file.c b/buffered_file.c index 54dc6c2..be147d6 100644 --- a/buffered_file.c +++ b/buffered_file.c @@ -222,8 +222,10 @@ static void buffered_rate_tick(void *opaque) { QEMUFileBuffered *s = opaque; -if (s->has_error) +if (s->has_error) { +buffered_close(s); return; +} qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 100); diff --git a/migration.c b/migration.c index b49964c..5bf2f4e 100644 --- a/migration.c +++ b/migration.c @@ -318,6 +318,8 @@ ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size) if (ret == -EAGAIN) qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s); +else +s->state = MIG_STATE_ERROR; return ret; }
[Qemu-devel] [Bug 586175] Re: Windows XP/2003 doesn't boot
Ran into this problem today with fresh Windows 2003 R2 install on a IDE boot drive. Because the CD-ROM boot bypasses this problem the install completes just fine, until I tell it to boot from the hard disk (via libvirt). Latest available packages from Debian testing; qemu 0.12.4+dfsg-3 qemu-kvm 0.12.4+dfsg-1 qemu-system 0.12.4+dfsg-3 qemu-user 0.12.4+dfsg-3 qemu-utils 0.12.4+dfsg-3 seabios 0.5.1-3 The only thing I've been able to find so far is an odd character in the SeaBIOS string when booting from the hard disk, which isn't there when booting from the CD-ROM image. ** Attachment added: "Screenshot of odd character in SeaBIOS string (VNC)" http://launchpadlibrarian.net/51532804/seabios-odd-character-boot-bug.png -- Windows XP/2003 doesn't boot https://bugs.launchpad.net/bugs/586175 You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. Status in QEMU: Incomplete Status in Debian GNU/Linux: New Status in Fedora: Unknown Bug description: Hello everyone, my qemu doesn't boot any Windows XP/2003 installations if I try to boot the image. If I boot the install cd first, it's boot manager counts down and triggers the boot on it's own. That's kinda stupid. I'm using libvirt, but even by a simple > qemu-kvm -drive file=image.img,media=disk,if=ide,boot=on it won't boot. Qemu hangs at the message "Booting from Hard Disk..." I'm using qemu-kvm-0.12.4 with SeaBIOS 0.5.1 on Gentoo (No-Multilib and AMD64). It's a server, that means I'm using VNC as the primary graphic output but i don't think it should be an issue.
[Qemu-devel] Re: [PATCH, RFC] pci: handle BAR mapping at pci level
On Wed, Jul 7, 2010 at 5:55 PM, Michael S. Tsirkin wrote: > On Wed, Jul 07, 2010 at 05:53:08PM +, Blue Swirl wrote: >> Add I/O port registration functions which separate registration >> from the mapping stage. >> >> Move IOIO and MMIO BAR mapping to pci.c. >> >> TODO: fix dirty logging, coalesced MMIO and base address comparisons >> (eepro100 etc). Bridge filtering may be broken. Broke virtio-pci and MSIX. > > legacy vga regions too? Probably not, because VGA still works nicely at PC boot. > >> Signed-off-by: Blue Swirl > > Looks like a good direction to take. > >> --- >> i386 boots but resets. PPC and Sparc64 can't even start. >> >> Patch also available at >> git://repo.or.cz/qemu/blueswirl.git >> >> It may be worthwhile to break this into some kind of smaller steps. > > Definitely. > One way could be to leave map_func in place but if it's NULL, use newer system. When all callers have converted cleanly, remove extra NULL argument and map_func. It would be nice to have some plan how to convert KVM stuff like dirty logging and coalescing. Any ideas?
Re: [Qemu-devel] [PATCH] set proper migration status on ->write error
On Wed, Jul 7, 2010 at 6:04 PM, Marcelo Tosatti wrote: > > If ->write fails, declare migration status as MIG_STATE_ERROR. > > Also, in buffered_file.c, ->close the object in case of an > error. > > Fixes "migrate -d "exec:dd of=file", where dd fails to open file. > > Signed-off-by: Marcelo Tosatti > > diff --git a/buffered_file.c b/buffered_file.c > index 54dc6c2..be147d6 100644 > --- a/buffered_file.c > +++ b/buffered_file.c > @@ -222,8 +222,10 @@ static void buffered_rate_tick(void *opaque) > { > QEMUFileBuffered *s = opaque; > > - if (s->has_error) > + if (s->has_error) { > + buffered_close(s); > return; > + } > > qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 100); > > diff --git a/migration.c b/migration.c > index b49964c..5bf2f4e 100644 > --- a/migration.c > +++ b/migration.c > @@ -318,6 +318,8 @@ ssize_t migrate_fd_put_buffer(void *opaque, const void > *data, size_t size) > > if (ret == -EAGAIN) > qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s); > + else > + s->state = MIG_STATE_ERROR; Please check CODING_STYLE. It's different from kernel's version.
Re: [Qemu-devel] [PATCH, RFC] pci: handle BAR mapping at pci level
On Wed, 7 Jul 2010, Blue Swirl wrote: > Add I/O port registration functions which separate registration > from the mapping stage. Why? [..snip..] -- mailto:av1...@comtv.ru
[Qemu-devel] [Bug 524447] Re: virsh save is very slow
You may want to try the patch to qemu that avi just posted to the qemu- devel mailing list. I think this would probably fix your issue. -- virsh save is very slow https://bugs.launchpad.net/bugs/524447 You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. Status in libvirt virtualization API: Unknown Status in QEMU: Invalid Status in “libvirt” package in Ubuntu: Confirmed Status in “qemu-kvm” package in Ubuntu: Confirmed Bug description: As reported here: http://www.redhat.com/archives/libvir-list/2009-December/msg00203.html "virsh save" is very slow - it writes the image at around 1MB/sec on my test system. (I think I saw a bug report for this issue on Fedora's bugzilla, but I can't find it now...) Confirmed under Karmic.
[Qemu-devel] Re: [PATCH] set proper migration status on ->write error
Marcelo Tosatti wrote: > If ->write fails, declare migration status as MIG_STATE_ERROR. > > Also, in buffered_file.c, ->close the object in case of an > error. > > Fixes "migrate -d "exec:dd of=file", where dd fails to open file. > > Signed-off-by: Marcelo Tosatti Acked-by: Juan Quintela > diff --git a/buffered_file.c b/buffered_file.c > index 54dc6c2..be147d6 100644 > --- a/buffered_file.c > +++ b/buffered_file.c > @@ -222,8 +222,10 @@ static void buffered_rate_tick(void *opaque) > { > QEMUFileBuffered *s = opaque; > > -if (s->has_error) > +if (s->has_error) { > +buffered_close(s); > return; > +} > > qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 100); > > diff --git a/migration.c b/migration.c > index b49964c..5bf2f4e 100644 > --- a/migration.c > +++ b/migration.c > @@ -318,6 +318,8 @@ ssize_t migrate_fd_put_buffer(void *opaque, const void > *data, size_t size) > > if (ret == -EAGAIN) > qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s); > +else > +s->state = MIG_STATE_ERROR; > > return ret; > }
[Qemu-devel] [PATCH v2 03/18] vnc: add lossy option
The lossy option can be used to enable lossy compression methods like gradient or jpeg. This patch disable them by default. Signed-off-by: Corentin Chary --- qemu-options.hx |7 +++ vnc-encoding-tight.c |4 vnc.c|2 ++ vnc.h|2 ++ 4 files changed, 15 insertions(+), 0 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index d1d2272..2fad881 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -835,6 +835,13 @@ empty, with a @code{deny} policy. Thus no one will be allowed to use the VNC server until the ACLs have been loaded. This can be achieved using the @code{acl} monitor command. +...@item lossy + +Enable lossy compression methods (gradient, JPEG, ...). If this +option is set, VNC client may receive lossy framebuffer updates +depending on its encoding settings. Enabling this option can save +a lot of bandwidth at the expense of quality. + @end table ETEXI diff --git a/vnc-encoding-tight.c b/vnc-encoding-tight.c index 5b69ff0..c1a292b 100644 --- a/vnc-encoding-tight.c +++ b/vnc-encoding-tight.c @@ -228,6 +228,10 @@ tight_detect_smooth_image(VncState *vs, int w, int h) int compression = vs->tight_compression; int quality = vs->tight_quality; +if (!vs->vd->lossy) { +return 0; +} + if (ds_get_bytes_per_pixel(vs->ds) == 1 || vs->clientds.pf.bytes_per_pixel == 1 || w < VNC_TIGHT_DETECT_MIN_WIDTH || h < VNC_TIGHT_DETECT_MIN_HEIGHT) { diff --git a/vnc.c b/vnc.c index 9cf38d1..ccd7aad 100644 --- a/vnc.c +++ b/vnc.c @@ -2482,6 +2482,8 @@ int vnc_display_open(DisplayState *ds, const char *display) #endif } else if (strncmp(options, "acl", 3) == 0) { acl = 1; +} else if (strncmp(options, "lossy", 5) == 0) { +vs->lossy = true; } } diff --git a/vnc.h b/vnc.h index 2a9024d..ec90cd3 100644 --- a/vnc.h +++ b/vnc.h @@ -33,6 +33,7 @@ #include "monitor.h" #include "audio/audio.h" #include +#include #include "keymaps.h" @@ -111,6 +112,7 @@ struct VncDisplay char *display; char *password; int auth; +bool lossy; #ifdef CONFIG_VNC_TLS int subauth; /* Used by VeNCrypt */ VncDisplayTLS tls; -- 1.7.1
[Qemu-devel] [PATCH v2 02/18] vnc: JPEG should be disabled if the client don't set tight quality
Disable JPEG compression by default and only enable it if the VNC client has sent the requested quality. Signed-off-by: Corentin Chary --- vnc.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/vnc.c b/vnc.c index ed0e096..9cf38d1 100644 --- a/vnc.c +++ b/vnc.c @@ -1644,7 +1644,7 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) vs->features = 0; vs->vnc_encoding = 0; vs->tight_compression = 9; -vs->tight_quality = 9; +vs->tight_quality = -1; /* Lossless by default */ vs->absolute = -1; /* -- 1.7.1
[Qemu-devel] [PATCH v2 16/18] vnc: tight: fix rgb_prepare_row
rgb_prepare_row bpp depends on the server display surface, not the client. Signed-off-by: Corentin Chary --- ui/vnc-enc-tight.c | 15 ++- 1 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index 3f19df2..eaa88ce 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -1180,12 +1180,17 @@ DEFINE_RGB_GET_ROW_FUNCTION(32) static void rgb_prepare_row(VncState *vs, uint8_t *dst, int x, int y, int count) { -if (vs->tight.pixel24) -rgb_prepare_row24(vs, dst, x, y, count); -else if (ds_get_bytes_per_pixel(vs->ds) == 4) -rgb_prepare_row32(vs, dst, x, y, count); -else +if (ds_get_bytes_per_pixel(vs->ds) == 4) { +if (vs->ds->surface->pf.rmax == 0xFF && +vs->ds->surface->pf.gmax == 0xFF && +vs->ds->surface->pf.bmax == 0xFF) { +rgb_prepare_row24(vs, dst, x, y, count); +} else { +rgb_prepare_row32(vs, dst, x, y, count); +} +} else { rgb_prepare_row16(vs, dst, x, y, count); +} } #endif /* CONFIG_VNC_JPEG or CONFIG_VNC_PNG */ -- 1.7.1
[Qemu-devel] [PATCH v2 05/18] vnc: rename vnc-encoding-* vnc-enc-*
For the same reason that we don't use vnc-authentication-sasl.c but vnc-auth-sals.c. Because it's to long. Signed-off-by: Corentin Chary --- Makefile.objs|4 ++-- ui/{vnchextile.h => vnc-enc-hextile-template.h} |0 ui/{vnc-encoding-hextile.c => vnc-enc-hextile.c} | 12 ++-- ui/{vnc-encoding-tight.c => vnc-enc-tight.c} |2 +- ui/{vnc-encoding-tight.h => vnc-enc-tight.h} |0 ui/{vnc-encoding-zlib.c => vnc-enc-zlib.c} |0 6 files changed, 9 insertions(+), 9 deletions(-) rename ui/{vnchextile.h => vnc-enc-hextile-template.h} (100%) rename ui/{vnc-encoding-hextile.c => vnc-enc-hextile.c} (93%) rename ui/{vnc-encoding-tight.c => vnc-enc-tight.c} (99%) rename ui/{vnc-encoding-tight.h => vnc-enc-tight.h} (100%) rename ui/{vnc-encoding-zlib.c => vnc-enc-zlib.c} (100%) diff --git a/Makefile.objs b/Makefile.objs index 43b4e16..a0b8200 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -106,8 +106,8 @@ ui-obj-y += keymaps.o ui-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o ui-obj-$(CONFIG_CURSES) += curses.o ui-obj-y += vnc.o d3des.o -ui-obj-y += vnc-encoding-zlib.o vnc-encoding-hextile.o -ui-obj-y += vnc-encoding-tight.o +ui-obj-y += vnc-enc-zlib.o vnc-enc-hextile.o +ui-obj-y += vnc-enc-tight.o ui-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o ui-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o ui-obj-$(CONFIG_COCOA) += cocoa.o diff --git a/ui/vnchextile.h b/ui/vnc-enc-hextile-template.h similarity index 100% rename from ui/vnchextile.h rename to ui/vnc-enc-hextile-template.h diff --git a/ui/vnc-encoding-hextile.c b/ui/vnc-enc-hextile.c similarity index 93% rename from ui/vnc-encoding-hextile.c rename to ui/vnc-enc-hextile.c index 728f25e..fa4b264 100644 --- a/ui/vnc-encoding-hextile.c +++ b/ui/vnc-enc-hextile.c @@ -33,32 +33,32 @@ static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h) } #define BPP 8 -#include "vnchextile.h" +#include "vnc-enc-hextile-template.h" #undef BPP #define BPP 16 -#include "vnchextile.h" +#include "vnc-enc-hextile-template.h" #undef BPP #define BPP 32 -#include "vnchextile.h" +#include "vnc-enc-hextile-template.h" #undef BPP #define GENERIC #define BPP 8 -#include "vnchextile.h" +#include "vnc-enc-hextile-template.h" #undef BPP #undef GENERIC #define GENERIC #define BPP 16 -#include "vnchextile.h" +#include "vnc-enc-hextile-template.h" #undef BPP #undef GENERIC #define GENERIC #define BPP 32 -#include "vnchextile.h" +#include "vnc-enc-hextile-template.h" #undef BPP #undef GENERIC diff --git a/ui/vnc-encoding-tight.c b/ui/vnc-enc-tight.c similarity index 99% rename from ui/vnc-encoding-tight.c rename to ui/vnc-enc-tight.c index c1a292b..358221d 100644 --- a/ui/vnc-encoding-tight.c +++ b/ui/vnc-enc-tight.c @@ -37,7 +37,7 @@ #include "qdict.h" #include "qint.h" #include "vnc.h" -#include "vnc-encoding-tight.h" +#include "vnc-enc-tight.h" /* Compression level stuff. The following array contains various encoder parameters for each of 10 compression levels (0..9). diff --git a/ui/vnc-encoding-tight.h b/ui/vnc-enc-tight.h similarity index 100% rename from ui/vnc-encoding-tight.h rename to ui/vnc-enc-tight.h diff --git a/ui/vnc-encoding-zlib.c b/ui/vnc-enc-zlib.c similarity index 100% rename from ui/vnc-encoding-zlib.c rename to ui/vnc-enc-zlib.c -- 1.7.1
[Qemu-devel] [PATCH v2 17/18] vnc: tight: split send_sub_rect
Split send_sub_rect in send_sub_rect_jpeg and send_sub_rect_nojpeg to remove all these #ifdef CONFIG_JPEG. Signed-off-by: Corentin Chary --- ui/vnc-enc-tight.c | 80 +++ 1 files changed, 55 insertions(+), 25 deletions(-) diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index eaa88ce..86bb49a 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -1452,34 +1452,39 @@ static void vnc_tight_stop(VncState *vs) vs->output = vs->tight.tmp; } -static int send_sub_rect(VncState *vs, int x, int y, int w, int h) +static int send_sub_rect_nojpeg(VncState *vs, int x, int y, int w, int h, +int bg, int fg, int colors, VncPalette *palette) { -VncPalette *palette = NULL; -uint32_t bg = 0, fg = 0; -int colors; -int ret = 0; - -vnc_framebuffer_update(vs, x, y, w, h, vs->tight.type); +int ret; -vnc_tight_start(vs); -vnc_raw_send_framebuffer_update(vs, x, y, w, h); -vnc_tight_stop(vs); +if (colors == 0) { +if (tight_detect_smooth_image(vs, w, h)) { +ret = send_gradient_rect(vs, x, y, w, h); +} else { +ret = send_full_color_rect(vs, x, y, w, h); +} +} else if (colors == 1) { +ret = send_solid_rect(vs); +} else if (colors == 2) { +ret = send_mono_rect(vs, x, y, w, h, bg, fg); +} else if (colors <= 256) { +ret = send_palette_rect(vs, x, y, w, h, palette); +} +return ret; +} -colors = tight_fill_palette(vs, x, y, w * h, &fg, &bg, &palette); +#ifdef CONFIG_VNC_JPEG +static int send_sub_rect_jpeg(VncState *vs, int x, int y, int w, int h, + int bg, int fg, int colors, + VncPalette *palette) +{ +int ret; if (colors == 0) { if (tight_detect_smooth_image(vs, w, h)) { -if (vs->tight.quality == -1) { -ret = send_gradient_rect(vs, x, y, w, h); -} else { -#ifdef CONFIG_VNC_JPEG -int quality = tight_conf[vs->tight.quality].jpeg_quality; +int quality = tight_conf[vs->tight.quality].jpeg_quality; -ret = send_jpeg_rect(vs, x, y, w, h, quality); -#else -ret = send_full_color_rect(vs, x, y, w, h); -#endif -} +ret = send_jpeg_rect(vs, x, y, w, h, quality); } else { ret = send_full_color_rect(vs, x, y, w, h); } @@ -1488,8 +1493,7 @@ static int send_sub_rect(VncState *vs, int x, int y, int w, int h) } else if (colors == 2) { ret = send_mono_rect(vs, x, y, w, h, bg, fg); } else if (colors <= 256) { -#ifdef CONFIG_VNC_JPEG -if (colors > 96 && vs->tight.quality != -1 && vs->tight.quality <= 3 && +if (colors > 96 && tight_detect_smooth_image(vs, w, h)) { int quality = tight_conf[vs->tight.quality].jpeg_quality; @@ -1497,10 +1501,36 @@ static int send_sub_rect(VncState *vs, int x, int y, int w, int h) } else { ret = send_palette_rect(vs, x, y, w, h, palette); } -#else -ret = send_palette_rect(vs, x, y, w, h, palette); +} +return ret; +} #endif + +static int send_sub_rect(VncState *vs, int x, int y, int w, int h) +{ +VncPalette *palette = NULL; +uint32_t bg = 0, fg = 0; +int colors; +int ret = 0; + +vnc_framebuffer_update(vs, x, y, w, h, vs->tight.type); + +vnc_tight_start(vs); +vnc_raw_send_framebuffer_update(vs, x, y, w, h); +vnc_tight_stop(vs); + +colors = tight_fill_palette(vs, x, y, w * h, &fg, &bg, &palette); + +#ifdef CONFIG_VNC_JPEG +if (vs->tight.quality != -1) { +ret = send_sub_rect_jpeg(vs, x, y, w, h, bg, fg, colors, palette); +} else { +ret = send_sub_rect_nojpeg(vs, x, y, w, h, bg, fg, colors, palette); } +#else +ret = send_sub_rect_nojpeg(vs, x, y, w, h, bg, fg, colors, palette); +#endif + palette_destroy(palette); return ret; } -- 1.7.1
[Qemu-devel] [PATCH v2 10/18] vnc: tight: stop using qdict for palette stuff
Profiling with callgrind seems to show that a lot of time is spent in the palette code (mostly due to memory allocation and qdict to int conversion). This patch adds a VncPalette implementation. The palette is stored in a hash table, like qdict, but which does way less memory allocations, and doesn't suffer from the QObject overhead. Signed-off-by: Corentin Chary --- Makefile.objs |2 +- ui/vnc-enc-tight.c | 163 +++ ui/vnc-palette.c | 136 +++ ui/vnc-palette.h | 63 4 files changed, 235 insertions(+), 129 deletions(-) create mode 100644 ui/vnc-palette.c create mode 100644 ui/vnc-palette.h diff --git a/Makefile.objs b/Makefile.objs index a0b8200..bb9806c 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -107,7 +107,7 @@ ui-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o ui-obj-$(CONFIG_CURSES) += curses.o ui-obj-y += vnc.o d3des.o ui-obj-y += vnc-enc-zlib.o vnc-enc-hextile.o -ui-obj-y += vnc-enc-tight.o +ui-obj-y += vnc-enc-tight.o vnc-palette.o ui-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o ui-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o ui-obj-$(CONFIG_COCOA) += cocoa.o diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index e627e00..49a456d 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -39,10 +39,10 @@ #include "qemu-common.h" #include "bswap.h" -#include "qdict.h" #include "qint.h" #include "vnc.h" #include "vnc-enc-tight.h" +#include "vnc-palette.h" /* Compression level stuff. The following array contains various encoder parameters for each of 10 compression levels (0..9). @@ -89,7 +89,7 @@ static const struct { }; static int send_png_rect(VncState *vs, int x, int y, int w, int h, - QDict *palette); + VncPalette *palette); static bool tight_can_send_png_rect(VncState *vs, int w, int h) { @@ -313,74 +313,13 @@ tight_detect_smooth_image(VncState *vs, int w, int h) /* * Code to determine how many different colors used in rectangle. */ - -static void tight_palette_rgb2buf(uint32_t rgb, int bpp, uint8_t buf[6]) -{ -memset(buf, 0, 6); - -if (bpp == 32) { -buf[0] = ((rgb >> 24) & 0xFF); -buf[1] = ((rgb >> 16) & 0xFF); -buf[2] = ((rgb >> 8) & 0xFF); -buf[3] = ((rgb >> 0) & 0xFF); -buf[4] = ((buf[0] & 1) == 0) << 3 | ((buf[1] & 1) == 0) << 2; -buf[4]|= ((buf[2] & 1) == 0) << 1 | ((buf[3] & 1) == 0) << 0; -buf[0] |= 1; -buf[1] |= 1; -buf[2] |= 1; -buf[3] |= 1; -} -if (bpp == 16) { -buf[0] = ((rgb >> 8) & 0xFF); -buf[1] = ((rgb >> 0) & 0xFF); -buf[2] = ((buf[0] & 1) == 0) << 1 | ((buf[1] & 1) == 0) << 0; -buf[0] |= 1; -buf[1] |= 1; -} -} - -static uint32_t tight_palette_buf2rgb(int bpp, const uint8_t *buf) -{ -uint32_t rgb = 0; - -if (bpp == 32) { -rgb |= ((buf[0] & ~1) | !((buf[4] >> 3) & 1)) << 24; -rgb |= ((buf[1] & ~1) | !((buf[4] >> 2) & 1)) << 16; -rgb |= ((buf[2] & ~1) | !((buf[4] >> 1) & 1)) << 8; -rgb |= ((buf[3] & ~1) | !((buf[4] >> 0) & 1)) << 0; -} -if (bpp == 16) { -rgb |= ((buf[0] & ~1) | !((buf[2] >> 1) & 1)) << 8; -rgb |= ((buf[1] & ~1) | !((buf[2] >> 0) & 1)) << 0; -} -return rgb; -} - - -static int tight_palette_insert(QDict *palette, uint32_t rgb, int bpp, int max) -{ -uint8_t key[6]; -int idx = qdict_size(palette); -bool present; - -tight_palette_rgb2buf(rgb, bpp, key); -present = qdict_haskey(palette, (char *)key); -if (idx >= max && !present) { -return 0; -} -if (!present) { -qdict_put(palette, (char *)key, qint_from_int(idx)); -} -return qdict_size(palette); -} - #define DEFINE_FILL_PALETTE_FUNCTION(bpp) \ \ static int \ tight_fill_palette##bpp(VncState *vs, int x, int y, \ int max, size_t count, \ uint32_t *bg, uint32_t *fg, \ -struct QDict **palette) { \ +VncPalette **palette) { \ uint##bpp##_t *data;\ uint##bpp##_t c0, c1, ci; \ int i, n0, n1; \ @@ -427,24 +366,23 @@ static int tight_palette_insert(QDict *palette, uint32_t rgb, int bpp, int max) return 0; \ } \
[Qemu-devel] [PATCH v2 00/18] [PATCH v2 00/18] VNC Updates for 0.13
This set contains all my patchs related to tight and threaded vnc server. Since v1: * Add a fix for jpeg and png with non-24bpp displays * Better default values for vnc options in ./configure * Fixed Tight PNG to use its own encoding number (-260) * Cleaned tight send_sub_rect() Tight JPEG and Move to ui = This set starts by adding JPEG and gradient to tight, then move all ui code in the ui/ subdirectory. Thanks, Since v1: * Format patch with rename detection * Add "lossy" parameter instead of "lossless" * Disable lossy encodings by default * Add a small tight fix (for indexed colors) Since v2: * Rebased on current master * Removed a leak in send_jpeg_rect() Misc === * Add the missing last color while filling palette * Rewrite the palette code without using qdict. I did some profiling using `perf` and a lot of cpu time was spent in qdict, mainly due to memory allocation, hash, and qobject conversion. The new code is faster and uses less memory. Tight PNG == This set introduce a new encoding: VNC_ENCODING_TIGHT_PNG [1] (-260) and a new tight filter VNC_TIGHT_PNG (0x0A). When the client tells it supports the -260 encoding, the server will use tight, but will always send encoding pixels using PNG instead of zlib. If the client also told it support JPEG, then the server can send JPEG, because PNG will only be used in the cases zlib was used in normal tight. This encoding was introduced to speed up HTML5 based VNC clients like noVNC [2], but can also be used on devices like iPhone where PNG can be rendered in hardware. I also made a quick patch to add support for PNG in gtk-vnc [3] and noVNC already support PNG encoding. Note: There is a bug in gtk-vnc when using pixbuf on a 16bit display, which also happens with JPEG. [1] http://wiki.qemu.org/VNC_Tight_PNG [2] http://github.com/kanaka/noVNC/ [3] http://xf.iksaif.net/dev/vnc/gtk-vnc/0001-add-png-support.patch Threaded Server === Since v1: * Moved locks from VncState to VncDisplay because it's only used in vnc_refresh * Use trylock in vnc_refresh. If there is an encoding task still running, reschedule the refresh. This really boost performances and make the vnc server truly asynchroneous. The only blocking lock is the output_mutex which is only held during a simple memcpy(). * Fixed issues found by Paolo, except the exit condition, mainly because we can only have one queue per VncState (due to zstreams), so this is not really an issue. * Rebased on top of jpeg and ui/ patchs Since v2: * renamed vnc-jobs.c vnc-jobs-async.c * added vnc-jobs.h, refactor functions declarations, export vnc_[un]lock_display() and vnc_[un]lock_output() and use them in vnc-jobs-async.c (reported by Avi) * rework exit condition for vnc_worker_thread_loop (Paolo) * abord -> abort (Paolo) * call qemu_thread_self() (Paolo) * Coding style issues (Alexander) * Move from empty macros to empty statis inline (Alexander) Alexander also suggested me to use stw_be_p() defined in cpu-all.h, but when I tried to include cpu-all.h, it broke every thing. Anyway it can be done later since this code is already present in vnc.c. Also vnc_async_encoding_start() could be cleaner if encoding members where in a specific structure, but this is a lot of changes, and as I'm also working on encodings, I want this patch to be easy to rebase. So I'll do as soon as the VNC server is merged. Since v3: * Encoding are data is now in specific structures, that makes vnc_async_encoding_start a lot cleaner. * Added a missing vnc_output_lock(vs) Corentin Chary (18): vnc: tight: add JPEG and gradient subencoding with smooth image detection vnc: JPEG should be disabled if the client don't set tight quality vnc: add lossy option ui: move all ui components in ui/ vnc: rename vnc-encoding-* vnc-enc-* vnc: tight: don't forget do at the last color vnc: tight: remove a memleak in send_jpeg_rect() vnc: tight add PNG encoding vnc: tight: specific zlib level and filters for each compression level vnc: tight: stop using qdict for palette stuff vnc: encapsulate encoding members vnc: fix tight png memory leak qemu-thread: add qemu_mutex/cond_destroy and qemu_mutex_exit vnc: threaded VNC server vnc: add missing lock for vnc_cursor_define() vnc: tight: fix rgb_prepare_row vnc: tight: split send_sub_rect vnc: better default values for VNC options Makefile | 38 +- Makefile.objs | 29 +- Makefile.target|2 + configure | 83 ++ qemu-options.hx|7 + qemu-thread.c | 22 + qemu-thread.h |4 + cocoa.m => ui/cocoa.m |0 curses.c => ui/curses.c|0 curses_keys.h => ui/curses_keys.h |0 d3des.c =>
[Qemu-devel] [PATCH v2 01/18] vnc: tight: add JPEG and gradient subencoding with smooth image detection
Add gradient filter and JPEG compression with an heuristic to detect how lossy the comppression will be. This code has been adapted from libvncserver/tight.c. JPEG support can be enabled/disabled at compile time with --enable-vnc-jpeg and --disable-vnc-jpeg. Signed-off-by: Corentin Chary --- Makefile.target |1 + configure| 33 +++ vnc-encoding-tight.c | 559 +- vnc-encoding-tight.h |5 + vnc.h|4 + 5 files changed, 601 insertions(+), 1 deletions(-) diff --git a/Makefile.target b/Makefile.target index 7489910..eb801df 100644 --- a/Makefile.target +++ b/Makefile.target @@ -177,6 +177,7 @@ LIBS+=-lz QEMU_CFLAGS += $(VNC_TLS_CFLAGS) QEMU_CFLAGS += $(VNC_SASL_CFLAGS) +QEMU_CFLAGS += $(VNC_JPEG_CFLAGS) # xen backend driver support obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o diff --git a/configure b/configure index b68f01a..27791b5 100755 --- a/configure +++ b/configure @@ -268,6 +268,7 @@ uuid="" vde="" vnc_tls="" vnc_sasl="" +vnc_jpeg="" xen="" linux_aio="" attr="" @@ -575,6 +576,10 @@ for opt do ;; --enable-vnc-sasl) vnc_sasl="yes" ;; + --disable-vnc-jpeg) vnc_jpeg="no" + ;; + --enable-vnc-jpeg) vnc_jpeg="yes" + ;; --disable-slirp) slirp="no" ;; --disable-uuid) uuid="no" @@ -825,6 +830,8 @@ echo " --disable-vnc-tlsdisable TLS encryption for VNC server" echo " --enable-vnc-tls enable TLS encryption for VNC server" echo " --disable-vnc-sasl disable SASL encryption for VNC server" echo " --enable-vnc-saslenable SASL encryption for VNC server" +echo " --disable-vnc-jpeg disable JPEG lossy compression for VNC server" +echo " --enable-vnc-jpegenable JPEG lossy compression for VNC server" echo " --disable-curses disable curses output" echo " --enable-curses enable curses output" echo " --disable-curl disable curl connectivity" @@ -1246,6 +1253,27 @@ EOF fi ## +# VNC JPEG detection +if test "$vnc_jpeg" = "yes" ; then +cat > $TMPC < +#include +int main(void) { struct jpeg_compress_struct s; jpeg_create_compress(&s); return 0; } +EOF +vnc_jpeg_cflags="" +vnc_jpeg_libs="-ljpeg" + if compile_prog "$vnc_jpeg_cflags" "$vnc_jpeg_libs" ; then +vnc_jpeg=yes +libs_softmmu="$vnc_jpeg_libs $libs_softmmu" + else +if test "$vnc_jpeg" = "yes" ; then + feature_not_found "vnc-jpeg" +fi +vnc_jpeg=no + fi +fi + +## # fnmatch() probe, used for ACL routines fnmatch="no" cat > $TMPC << EOF @@ -2094,6 +2122,7 @@ echo "Block whitelist $block_drv_whitelist" echo "Mixer emulation $mixemu" echo "VNC TLS support $vnc_tls" echo "VNC SASL support $vnc_sasl" +echo "VNC JPEG support $vnc_jpeg" if test -n "$sparc_cpu"; then echo "Target Sparc Arch $sparc_cpu" fi @@ -2231,6 +2260,10 @@ if test "$vnc_sasl" = "yes" ; then echo "CONFIG_VNC_SASL=y" >> $config_host_mak echo "VNC_SASL_CFLAGS=$vnc_sasl_cflags" >> $config_host_mak fi +if test "$vnc_jpeg" = "yes" ; then + echo "CONFIG_VNC_JPEG=y" >> $config_host_mak + echo "VNC_JPEG_CFLAGS=$vnc_jpeg_cflags" >> $config_host_mak +fi if test "$fnmatch" = "yes" ; then echo "CONFIG_FNMATCH=y" >> $config_host_mak fi diff --git a/vnc-encoding-tight.c b/vnc-encoding-tight.c index faba483..5b69ff0 100644 --- a/vnc-encoding-tight.c +++ b/vnc-encoding-tight.c @@ -26,6 +26,14 @@ * THE SOFTWARE. */ +#include "qemu-common.h" + +#ifdef CONFIG_VNC_JPEG +#include +#include +#endif + +#include "bswap.h" #include "qdict.h" #include "qint.h" #include "vnc.h" @@ -56,6 +64,206 @@ static const struct { }; /* + * Code to guess if given rectangle is suitable for smooth image + * compression (by applying "gradient" filter or JPEG coder). + */ + +static uint +tight_detect_smooth_image24(VncState *vs, int w, int h) +{ +int off; +int x, y, d, dx; +uint c; +uint stats[256]; +int pixels = 0; +int pix, left[3]; +uint errors; +unsigned char *buf = vs->tight.buffer; + +/* + * If client is big-endian, color samples begin from the second + * byte (offset 1) of a 32-bit pixel value. + */ +off = !!(vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG); + +memset(stats, 0, sizeof (stats)); + +for (y = 0, x = 0; y < h && x < w;) { +for (d = 0; d < h - y && d < w - x - VNC_TIGHT_DETECT_SUBROW_WIDTH; + d++) { +for (c = 0; c < 3; c++) { +left[c] = buf[((y+d)*w+x+d)*4+off+c] & 0xFF; +} +for (dx = 1; dx <= VNC_TIGHT_DETECT_SUBROW_WIDTH; dx++) { +for (c = 0; c < 3; c++) { +pix = buf[((y+d)*w+x+d+dx)*4+off+c] & 0xFF; +stats[abs(pix - left[c])]++; +left[c] = pix; +} +pixels++; +} +} +if (w > h) { +
[Qemu-devel] [PATCH v2 13/18] qemu-thread: add qemu_mutex/cond_destroy and qemu_mutex_exit
Add some missing functions in qemu-thread. Currently qemu-thread is only used for io-thread but it will used by the vnc server soon and we need those functions instead of calling pthread directly. Signed-off-by: Corentin Chary --- qemu-thread.c | 22 ++ qemu-thread.h |4 2 files changed, 26 insertions(+), 0 deletions(-) diff --git a/qemu-thread.c b/qemu-thread.c index faf4061..fbc78fe 100644 --- a/qemu-thread.c +++ b/qemu-thread.c @@ -34,6 +34,15 @@ void qemu_mutex_init(QemuMutex *mutex) error_exit(err, __func__); } +void qemu_mutex_destroy(QemuMutex *mutex) +{ +int err; + +err = pthread_mutex_destroy(&mutex->lock); +if (err) +error_exit(err, __func__); +} + void qemu_mutex_lock(QemuMutex *mutex) { int err; @@ -90,6 +99,15 @@ void qemu_cond_init(QemuCond *cond) error_exit(err, __func__); } +void qemu_cond_destroy(QemuCond *cond) +{ +int err; + +err = pthread_cond_destroy(&cond->cond); +if (err) +error_exit(err, __func__); +} + void qemu_cond_signal(QemuCond *cond) { int err; @@ -168,3 +186,7 @@ int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2) return pthread_equal(thread1->thread, thread2->thread); } +void qemu_thread_exit(void *retval) +{ +pthread_exit(retval); +} diff --git a/qemu-thread.h b/qemu-thread.h index 5ef4a3a..19bb30c 100644 --- a/qemu-thread.h +++ b/qemu-thread.h @@ -20,12 +20,14 @@ typedef struct QemuCond QemuCond; typedef struct QemuThread QemuThread; void qemu_mutex_init(QemuMutex *mutex); +void qemu_mutex_destroy(QemuMutex *mutex); void qemu_mutex_lock(QemuMutex *mutex); int qemu_mutex_trylock(QemuMutex *mutex); int qemu_mutex_timedlock(QemuMutex *mutex, uint64_t msecs); void qemu_mutex_unlock(QemuMutex *mutex); void qemu_cond_init(QemuCond *cond); +void qemu_cond_destroy(QemuCond *cond); void qemu_cond_signal(QemuCond *cond); void qemu_cond_broadcast(QemuCond *cond); void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex); @@ -37,4 +39,6 @@ void qemu_thread_create(QemuThread *thread, void qemu_thread_signal(QemuThread *thread, int sig); void qemu_thread_self(QemuThread *thread); int qemu_thread_equal(QemuThread *thread1, QemuThread *thread2); +void qemu_thread_exit(void *retval); + #endif -- 1.7.1
[Qemu-devel] [PATCH v2 08/18] vnc: tight add PNG encoding
Introduce a new encoding: VNC_ENCODING_TIGHT_PNG [1] (-269) with a new tight filter VNC_TIGHT_PNG (0x0A). When the client tells it supports the Tight PNG encoding, the server will use tight, but will always send encoding pixels using PNG instead of zlib. If the client also told it support JPEG, then the server can send JPEG, because PNG will only be used in the cases zlib was used in normal tight. This encoding was introduced to speed up HTML5 based VNC clients like noVNC [2], but can also be used on devices like iPhone where PNG can be rendered in hardware. [1] http://wiki.qemu.org/VNC_Tight_PNG [2] http://github.com/kanaka/noVNC/ Signed-off-by: Corentin Chary --- Makefile.target|1 + configure | 37 ++ ui/vnc-enc-tight.c | 316 +--- ui/vnc-enc-tight.h | 16 ++- ui/vnc.c | 11 +- ui/vnc.h | 15 +++- 6 files changed, 342 insertions(+), 54 deletions(-) diff --git a/Makefile.target b/Makefile.target index eb801df..fa9ec0d 100644 --- a/Makefile.target +++ b/Makefile.target @@ -178,6 +178,7 @@ LIBS+=-lz QEMU_CFLAGS += $(VNC_TLS_CFLAGS) QEMU_CFLAGS += $(VNC_SASL_CFLAGS) QEMU_CFLAGS += $(VNC_JPEG_CFLAGS) +QEMU_CFLAGS += $(VNC_PNG_CFLAGS) # xen backend driver support obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o diff --git a/configure b/configure index 27791b5..eba9606 100755 --- a/configure +++ b/configure @@ -269,6 +269,7 @@ vde="" vnc_tls="" vnc_sasl="" vnc_jpeg="" +vnc_png="" xen="" linux_aio="" attr="" @@ -580,6 +581,10 @@ for opt do ;; --enable-vnc-jpeg) vnc_jpeg="yes" ;; + --disable-vnc-png) vnc_png="no" + ;; + --enable-vnc-png) vnc_png="yes" + ;; --disable-slirp) slirp="no" ;; --disable-uuid) uuid="no" @@ -832,6 +837,8 @@ echo " --disable-vnc-sasl disable SASL encryption for VNC server" echo " --enable-vnc-saslenable SASL encryption for VNC server" echo " --disable-vnc-jpeg disable JPEG lossy compression for VNC server" echo " --enable-vnc-jpegenable JPEG lossy compression for VNC server" +echo " --disable-vnc-pngdisable PNG compression for VNC server" +echo " --enable-vnc-png enable PNG compression for VNC server" echo " --disable-curses disable curses output" echo " --enable-curses enable curses output" echo " --disable-curl disable curl connectivity" @@ -1274,6 +1281,31 @@ EOF fi ## +# VNC PNG detection +if test "$vnc_png" = "yes" ; then +cat > $TMPC < +#include +int main(void) { +png_structp png_ptr; +png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); +return 0; +} +EOF +vnc_png_cflags="" +vnc_png_libs="-lpng" + if compile_prog "$vnc_png_cflags" "$vnc_png_libs" ; then +vnc_png=yes +libs_softmmu="$vnc_png_libs $libs_softmmu" + else +if test "$vnc_png" = "yes" ; then + feature_not_found "vnc-png" +fi +vnc_png=no + fi +fi + +## # fnmatch() probe, used for ACL routines fnmatch="no" cat > $TMPC << EOF @@ -2123,6 +2155,7 @@ echo "Mixer emulation $mixemu" echo "VNC TLS support $vnc_tls" echo "VNC SASL support $vnc_sasl" echo "VNC JPEG support $vnc_jpeg" +echo "VNC PNG support $vnc_png" if test -n "$sparc_cpu"; then echo "Target Sparc Arch $sparc_cpu" fi @@ -2264,6 +2297,10 @@ if test "$vnc_jpeg" = "yes" ; then echo "CONFIG_VNC_JPEG=y" >> $config_host_mak echo "VNC_JPEG_CFLAGS=$vnc_jpeg_cflags" >> $config_host_mak fi +if test "$vnc_png" = "yes" ; then + echo "CONFIG_VNC_PNG=y" >> $config_host_mak + echo "VNC_PNG_CFLAGS=$vnc_png_cflags" >> $config_host_mak +fi if test "$fnmatch" = "yes" ; then echo "CONFIG_FNMATCH=y" >> $config_host_mak fi diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index 4ff88a8..cc57c26 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -26,13 +26,18 @@ * THE SOFTWARE. */ -#include "qemu-common.h" +#include "config-host.h" +#ifdef CONFIG_VNC_PNG +#include +#endif #ifdef CONFIG_VNC_JPEG #include #include #endif +#include "qemu-common.h" + #include "bswap.h" #include "qdict.h" #include "qint.h" @@ -63,6 +68,29 @@ static const struct { { 65536, 2048, 32, 8192, 9, 9, 9, 6, 200, 500, 96, 80, 200, 500 } }; + +static int tight_send_framebuffer_update(VncState *vs, int x, int y, + int w, int h); + +#ifdef CONFIG_VNC_PNG +static int send_png_rect(VncState *vs, int x, int y, int w, int h, + QDict *palette); + +static bool tight_can_send_png_rect(VncState *vs, int w, int h) +{ +if (vs->tight_type != VNC_ENCODING_TIGHT_PNG) { +return false; +} + +if (ds_get_bytes_per_pixel(vs->ds) == 1 || +vs->clientds.pf.bytes_per_pixel == 1) { +return false; +} + +return true; +} +#endif + /* * Code to guess if given rectangle is su
[Qemu-devel] [PATCH v2 04/18] ui: move all ui components in ui/
Move sdl, vnc, curses and cocoa UI into ui/ to cleanup the root directory. Also remove some unnecessary explicit targets from Makefile. Signed-off-by: Corentin Chary --- Makefile | 38 +++- Makefile.objs | 22 ++- cocoa.m => ui/cocoa.m |0 curses.c => ui/curses.c|0 curses_keys.h => ui/curses_keys.h |0 d3des.c => ui/d3des.c |0 d3des.h => ui/d3des.h |0 keymaps.c => ui/keymaps.c |0 keymaps.h => ui/keymaps.h |0 sdl.c => ui/sdl.c |0 sdl_keysym.h => ui/sdl_keysym.h|0 sdl_zoom.c => ui/sdl_zoom.c|0 sdl_zoom.h => ui/sdl_zoom.h|0 sdl_zoom_template.h => ui/sdl_zoom_template.h |0 vnc-auth-sasl.c => ui/vnc-auth-sasl.c |0 vnc-auth-sasl.h => ui/vnc-auth-sasl.h |0 vnc-auth-vencrypt.c => ui/vnc-auth-vencrypt.c |0 vnc-auth-vencrypt.h => ui/vnc-auth-vencrypt.h |0 .../vnc-encoding-hextile.c |0 vnc-encoding-tight.c => ui/vnc-encoding-tight.c|0 vnc-encoding-tight.h => ui/vnc-encoding-tight.h|0 vnc-encoding-zlib.c => ui/vnc-encoding-zlib.c |0 vnc-tls.c => ui/vnc-tls.c |0 vnc-tls.h => ui/vnc-tls.h |0 vnc.c => ui/vnc.c |0 vnc.h => ui/vnc.h |0 vnc_keysym.h => ui/vnc_keysym.h|0 vnchextile.h => ui/vnchextile.h|0 x_keymap.c => ui/x_keymap.c|0 x_keymap.h => ui/x_keymap.h|0 30 files changed, 17 insertions(+), 43 deletions(-) rename cocoa.m => ui/cocoa.m (100%) rename curses.c => ui/curses.c (100%) rename curses_keys.h => ui/curses_keys.h (100%) rename d3des.c => ui/d3des.c (100%) rename d3des.h => ui/d3des.h (100%) rename keymaps.c => ui/keymaps.c (100%) rename keymaps.h => ui/keymaps.h (100%) rename sdl.c => ui/sdl.c (100%) rename sdl_keysym.h => ui/sdl_keysym.h (100%) rename sdl_zoom.c => ui/sdl_zoom.c (100%) rename sdl_zoom.h => ui/sdl_zoom.h (100%) rename sdl_zoom_template.h => ui/sdl_zoom_template.h (100%) rename vnc-auth-sasl.c => ui/vnc-auth-sasl.c (100%) rename vnc-auth-sasl.h => ui/vnc-auth-sasl.h (100%) rename vnc-auth-vencrypt.c => ui/vnc-auth-vencrypt.c (100%) rename vnc-auth-vencrypt.h => ui/vnc-auth-vencrypt.h (100%) rename vnc-encoding-hextile.c => ui/vnc-encoding-hextile.c (100%) rename vnc-encoding-tight.c => ui/vnc-encoding-tight.c (100%) rename vnc-encoding-tight.h => ui/vnc-encoding-tight.h (100%) rename vnc-encoding-zlib.c => ui/vnc-encoding-zlib.c (100%) rename vnc-tls.c => ui/vnc-tls.c (100%) rename vnc-tls.h => ui/vnc-tls.h (100%) rename vnc.c => ui/vnc.c (100%) rename vnc.h => ui/vnc.h (100%) rename vnc_keysym.h => ui/vnc_keysym.h (100%) rename vnchextile.h => ui/vnchextile.h (100%) rename x_keymap.c => ui/x_keymap.c (100%) rename x_keymap.h => ui/x_keymap.h (100%) diff --git a/Makefile b/Makefile index 560eac6..2c74d17 100644 --- a/Makefile +++ b/Makefile @@ -96,42 +96,14 @@ audio/audio.o audio/fmodaudio.o: QEMU_CFLAGS += $(FMOD_CFLAGS) QEMU_CFLAGS+=$(CURL_CFLAGS) -cocoa.o: cocoa.m +ui/cocoa.o: ui/cocoa.m -keymaps.o: keymaps.c keymaps.h +ui/sdl.o audio/sdlaudio.o ui/sdl_zoom.o baum.o: QEMU_CFLAGS += $(SDL_CFLAGS) -sdl_zoom.o: sdl_zoom.c sdl_zoom.h sdl_zoom_template.h - -sdl.o: sdl.c keymaps.h sdl_keysym.h sdl_zoom.h - -sdl.o audio/sdlaudio.o sdl_zoom.o baum.o: QEMU_CFLAGS += $(SDL_CFLAGS) - -acl.o: acl.h acl.c - -vnc.h: vnc-tls.h vnc-auth-vencrypt.h vnc-auth-sasl.h keymaps.h - -vnc.o: vnc.c vnc.h vnc_keysym.h vnchextile.h d3des.c d3des.h acl.h - -vnc.o: QEMU_CFLAGS += $(VNC_TLS_CFLAGS) - -vnc-tls.o: vnc-tls.c vnc.h - -vnc-auth-vencrypt.o: vnc-auth-vencrypt.c vnc.h - -vnc-auth-sasl.o: vnc-auth-sasl.c vnc.h - -vnc-encoding-zlib.o: vnc-encoding-zlib.c vnc.h - -vnc-encoding-hextile.o: vnc-encoding-hextile.c vnc.h - -vnc-encoding-tight.o: vnc-encoding-tight.c vnc.h vnc-encoding-tight.h - -curses.o: curses.c keymaps.h curses_keys.h +ui/vnc.o: QEMU_CFLAGS += $(VNC_TLS_CFLAGS) bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS) -iov.o: iov.c iov.h - ## qemu-img.o: qemu-img-cmds.h @@ -159,7 +131,7 @@ clean: # avoid old build problems by removing potentially incorrect old files rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h rm -f *.o *.d *.a $(TOOLS) TAGS cscope.* *.pod *~ */*~ - rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*
[Qemu-devel] [PATCH v2 09/18] vnc: tight: specific zlib level and filters for each compression level
Disable png filters for lower compression levels. This should lower the CPU consumption and reduce encoding time. This isn't in tight_conf because: * tight_conf structure must not change, because it's shared with other tight implementations (libvncserver, etc..). * it'd exceed the 80 col limit. * PNG_ macros are only defined if CONFIG_VNC_PNG is defined Signed-off-by: Corentin Chary --- ui/vnc-enc-tight.c | 19 ++- 1 files changed, 18 insertions(+), 1 deletions(-) diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index cc57c26..e627e00 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -73,6 +73,21 @@ static int tight_send_framebuffer_update(VncState *vs, int x, int y, int w, int h); #ifdef CONFIG_VNC_PNG +static const struct { +int png_zlib_level, png_filters; +} tight_png_conf[] = { +{ 0, PNG_NO_FILTERS }, +{ 1, PNG_NO_FILTERS }, +{ 2, PNG_NO_FILTERS }, +{ 3, PNG_NO_FILTERS }, +{ 4, PNG_NO_FILTERS }, +{ 5, PNG_ALL_FILTERS }, +{ 6, PNG_ALL_FILTERS }, +{ 7, PNG_ALL_FILTERS }, +{ 8, PNG_ALL_FILTERS }, +{ 9, PNG_ALL_FILTERS }, +}; + static int send_png_rect(VncState *vs, int x, int y, int w, int h, QDict *palette); @@ -1425,7 +1440,8 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h, png_infop info_ptr; png_colorp png_palette = NULL; size_t offset; -int level = tight_conf[vs->tight_compression].raw_zlib_level; +int level = tight_png_conf[vs->tight_compression].png_zlib_level; +int filters = tight_png_conf[vs->tight_compression].png_filters; uint8_t *buf; int dy; @@ -1444,6 +1460,7 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h, png_set_write_fn(png_ptr, (void *) vs, png_write_data, png_flush_data); png_set_compression_level(png_ptr, level); +png_set_filter(png_ptr, PNG_FILTER_TYPE_DEFAULT, filters); if (palette) { color_type = PNG_COLOR_TYPE_PALETTE; -- 1.7.1
[Qemu-devel] [PATCH v2 18/18] vnc: better default values for VNC options
vnc_jpeg and vnc_png are now "auto" by default, this means that if the dependencies are installed (libjpeg or libpng), then they will be enabled. vnc_thread is disabled by default. It should be enabled by default as soon as it's stable enougth. Signed-off-by: Corentin Chary --- configure | 14 +++--- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/configure b/configure index c292a33..1f0b39e 100755 --- a/configure +++ b/configure @@ -270,7 +270,7 @@ vnc_tls="" vnc_sasl="" vnc_jpeg="" vnc_png="" -vnc_thread="" +vnc_thread="no" xen="" linux_aio="" attr="" @@ -842,7 +842,7 @@ echo " --disable-vnc-sasl disable SASL encryption for VNC server" echo " --enable-vnc-saslenable SASL encryption for VNC server" echo " --disable-vnc-jpeg disable JPEG lossy compression for VNC server" echo " --enable-vnc-jpegenable JPEG lossy compression for VNC server" -echo " --disable-vnc-pngdisable PNG compression for VNC server" +echo " --disable-vnc-pngdisable PNG compression for VNC server (default)" echo " --enable-vnc-png enable PNG compression for VNC server" echo " --disable-vnc-thread disable threaded VNC server" echo " --enable-vnc-thread enable threaded VNC server" @@ -1268,7 +1268,7 @@ fi ## # VNC JPEG detection -if test "$vnc_jpeg" = "yes" ; then +if test "$vnc_jpeg" != "no" ; then cat > $TMPC < #include @@ -1289,7 +1289,7 @@ fi ## # VNC PNG detection -if test "$vnc_png" = "yes" ; then +if test "$vnc_png" != "no" ; then cat > $TMPC < #include @@ -2301,15 +2301,15 @@ if test "$vnc_sasl" = "yes" ; then echo "CONFIG_VNC_SASL=y" >> $config_host_mak echo "VNC_SASL_CFLAGS=$vnc_sasl_cflags" >> $config_host_mak fi -if test "$vnc_jpeg" = "yes" ; then +if test "$vnc_jpeg" != "no" ; then echo "CONFIG_VNC_JPEG=y" >> $config_host_mak echo "VNC_JPEG_CFLAGS=$vnc_jpeg_cflags" >> $config_host_mak fi -if test "$vnc_png" = "yes" ; then +if test "$vnc_png" != "no" ; then echo "CONFIG_VNC_PNG=y" >> $config_host_mak echo "VNC_PNG_CFLAGS=$vnc_png_cflags" >> $config_host_mak fi -if test "$vnc_thread" = "yes" ; then +if test "$vnc_thread" != "no" ; then echo "CONFIG_VNC_THREAD=y" >> $config_host_mak echo "CONFIG_THREAD=y" >> $config_host_mak fi -- 1.7.1
[Qemu-devel] [PATCH v2 06/18] vnc: tight: don't forget do at the last color
While using indexed colors, the last color was never added to the palette. Triggered with ubuntu livecd. Signed-off-by: Corentin Chary --- ui/vnc-enc-tight.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index 358221d..ade8e5f 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -393,11 +393,11 @@ static int tight_palette_insert(QDict *palette, uint32_t rgb, int bpp, int max) if (data[i] == ci) {\ continue; \ } else {\ +ci = data[i]; \ if (!tight_palette_insert(*palette, (uint32_t)ci, \ bpp, max)) { \ return 0; \ } \ -ci = data[i]; \ } \ } \ \ -- 1.7.1
[Qemu-devel] [PATCH v2 07/18] vnc: tight: remove a memleak in send_jpeg_rect()
buf was never freed. Signed-off-by: Corentin Chary --- ui/vnc-enc-tight.c |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index ade8e5f..4ff88a8 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -1247,8 +1247,6 @@ static int send_jpeg_rect(VncState *vs, int x, int y, int w, int h, int quality) if (ds_get_bytes_per_pixel(vs->ds) == 1) return send_full_color_rect(vs, w, h); -buf = qemu_malloc(w * 3); -row[0] = buf; buffer_reserve(&vs->tight_jpeg, 2048); cinfo.err = jpeg_std_error(&jerr); @@ -1270,10 +1268,13 @@ static int send_jpeg_rect(VncState *vs, int x, int y, int w, int h, int quality) jpeg_start_compress(&cinfo, true); +buf = qemu_malloc(w * 3); +row[0] = buf; for (dy = 0; dy < h; dy++) { jpeg_prepare_row(vs, buf, x, y + dy, w); jpeg_write_scanlines(&cinfo, row, 1); } +qemu_free(buf); jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); -- 1.7.1
[Qemu-devel] [PATCH v2 11/18] vnc: encapsulate encoding members
This will allow to implement the threaded VNC server in a more cleaner way. Signed-off-by: Corentin Chary --- ui/vnc-enc-hextile.c | 14 ++-- ui/vnc-enc-tight.c | 204 +- ui/vnc-enc-zlib.c| 34 ui/vnc.c |8 +- ui/vnc.h | 59 --- 5 files changed, 163 insertions(+), 156 deletions(-) diff --git a/ui/vnc-enc-hextile.c b/ui/vnc-enc-hextile.c index fa4b264..364a491 100644 --- a/ui/vnc-enc-hextile.c +++ b/ui/vnc-enc-hextile.c @@ -75,7 +75,7 @@ int vnc_hextile_send_framebuffer_update(VncState *vs, int x, has_fg = has_bg = 0; for (j = y; j < (y + h); j += 16) { for (i = x; i < (x + w); i += 16) { -vs->send_hextile_tile(vs, i, j, +vs->hextile.send_tile(vs, i, j, MIN(16, x + w - i), MIN(16, y + h - j), last_bg, last_fg, &has_bg, &has_fg); } @@ -91,25 +91,25 @@ void vnc_hextile_set_pixel_conversion(VncState *vs, int generic) if (!generic) { switch (vs->ds->surface->pf.bits_per_pixel) { case 8: -vs->send_hextile_tile = send_hextile_tile_8; +vs->hextile.send_tile = send_hextile_tile_8; break; case 16: -vs->send_hextile_tile = send_hextile_tile_16; +vs->hextile.send_tile = send_hextile_tile_16; break; case 32: -vs->send_hextile_tile = send_hextile_tile_32; +vs->hextile.send_tile = send_hextile_tile_32; break; } } else { switch (vs->ds->surface->pf.bits_per_pixel) { case 8: -vs->send_hextile_tile = send_hextile_tile_generic_8; +vs->hextile.send_tile = send_hextile_tile_generic_8; break; case 16: -vs->send_hextile_tile = send_hextile_tile_generic_16; +vs->hextile.send_tile = send_hextile_tile_generic_16; break; case 32: -vs->send_hextile_tile = send_hextile_tile_generic_32; +vs->hextile.send_tile = send_hextile_tile_generic_32; break; } } diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index 49a456d..52b81f3 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -93,7 +93,7 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h, static bool tight_can_send_png_rect(VncState *vs, int w, int h) { -if (vs->tight_type != VNC_ENCODING_TIGHT_PNG) { +if (vs->tight.type != VNC_ENCODING_TIGHT_PNG) { return false; } @@ -121,7 +121,7 @@ tight_detect_smooth_image24(VncState *vs, int w, int h) int pixels = 0; int pix, left[3]; uint errors; -unsigned char *buf = vs->tight.buffer; +unsigned char *buf = vs->tight.tight.buffer; /* * If client is big-endian, color samples begin from the second @@ -188,7 +188,7 @@ tight_detect_smooth_image24(VncState *vs, int w, int h) int pixels = 0; \ int sample, sum, left[3]; \ uint errors;\ -unsigned char *buf = vs->tight.buffer; \ +unsigned char *buf = vs->tight.tight.buffer;\ \ endian = ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) !=\ (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)); \ @@ -268,8 +268,8 @@ static int tight_detect_smooth_image(VncState *vs, int w, int h) { uint errors; -int compression = vs->tight_compression; -int quality = vs->tight_quality; +int compression = vs->tight.compression; +int quality = vs->tight.quality; if (!vs->vd->lossy) { return 0; @@ -281,7 +281,7 @@ tight_detect_smooth_image(VncState *vs, int w, int h) return 0; } -if (vs->tight_quality != -1) { +if (vs->tight.quality != -1) { if (w * h < VNC_TIGHT_JPEG_MIN_RECT_SIZE) { return 0; } @@ -292,9 +292,9 @@ tight_detect_smooth_image(VncState *vs, int w, int h) } if (vs->clientds.pf.bytes_per_pixel == 4) { -if (vs->tight_pixel24) { +if (vs->tight.pixel24) { errors = tight_detect_smooth_image24(vs, w, h); -if (vs->tight_quality != -1) { +if (vs->tight.quality != -1) { return (errors < tight_conf[quality].jpeg_threshold24); } return (errors < tight_conf[compression].gradient_threshold24); @@ -324,7 +324,7 @@ tight_detect_smooth_image(VncState *vs, int w, int h) uint##bpp##_t c0, c1, ci; \ int i, n0, n1;
[Qemu-devel] [PATCH v2 12/18] vnc: fix tight png memory leak
The tight.png buffer was never released. Signed-off-by: Corentin Chary --- ui/vnc-enc-tight.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index 52b81f3..3f19df2 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -1674,4 +1674,7 @@ void vnc_tight_clear(VncState *vs) #ifdef CONFIG_VNC_JPEG buffer_free(&vs->tight.jpeg); #endif +#ifdef CONFIG_VNC_PNG +buffer_free(&vs->tight.png); +#endif } -- 1.7.1
[Qemu-devel] [PATCH v2 15/18] vnc: add missing lock for vnc_cursor_define()
All vnc_write() calls must be locked (except the ones present before the protocol initialization). Signed-off-by: Corentin Chary --- ui/vnc.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 7330b2c..7fc40ac 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -796,6 +796,7 @@ static int vnc_cursor_define(VncState *vs) int isize; if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) { +vnc_lock_output(vs); vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE); vnc_write_u8(vs, 0); /* padding */ vnc_write_u16(vs, 1); /* # of rects */ @@ -804,6 +805,7 @@ static int vnc_cursor_define(VncState *vs) isize = c->width * c->height * vs->clientds.pf.bytes_per_pixel; vnc_write_pixels_generic(vs, &pf, c->data, isize); vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize); +vnc_unlock_output(vs); return 0; } return -1; -- 1.7.1
[Qemu-devel] [PATCH v2 14/18] vnc: threaded VNC server
Implement a threaded VNC server using the producer-consumer model. The main thread will push encoding jobs (a list a rectangles to update) in a queue, and the VNC worker thread will consume that queue and send framebuffer updates to the output buffer. The threaded VNC server can be enabled with ./configure --enable-vnc-thread. If you don't want it, just use ./configure --disable-vnc-thread and a syncrhonous queue of job will be used (which as exactly the same behavior as the old queue). If you disable the VNC thread, all thread related code will not be built and there will be no overhead. Signed-off-by: Corentin Chary --- Makefile.objs |7 +- configure | 13 ++ ui/vnc-jobs-async.c | 331 +++ ui/vnc-jobs-sync.c | 73 +++ ui/vnc-jobs.h | 87 ++ ui/vnc.c| 144 +++ ui/vnc.h| 53 - 7 files changed, 682 insertions(+), 26 deletions(-) create mode 100644 ui/vnc-jobs-async.c create mode 100644 ui/vnc-jobs-sync.c create mode 100644 ui/vnc-jobs.h diff --git a/Makefile.objs b/Makefile.objs index bb9806c..4a1eaa1 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -111,10 +111,15 @@ ui-obj-y += vnc-enc-tight.o vnc-palette.o ui-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o ui-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o ui-obj-$(CONFIG_COCOA) += cocoa.o +ifdef CONFIG_VNC_THREAD +ui-obj-y += vnc-jobs-async.o +else +ui-obj-y += vnc-jobs-sync.o +endif common-obj-y += $(addprefix ui/, $(ui-obj-y)) common-obj-y += iov.o acl.o -common-obj-$(CONFIG_IOTHREAD) += qemu-thread.o +common-obj-$(CONFIG_THREAD) += qemu-thread.o common-obj-y += notify.o event_notifier.o common-obj-y += qemu-timer.o diff --git a/configure b/configure index eba9606..c292a33 100755 --- a/configure +++ b/configure @@ -270,6 +270,7 @@ vnc_tls="" vnc_sasl="" vnc_jpeg="" vnc_png="" +vnc_thread="" xen="" linux_aio="" attr="" @@ -585,6 +586,10 @@ for opt do ;; --enable-vnc-png) vnc_png="yes" ;; + --disable-vnc-thread) vnc_thread="no" + ;; + --enable-vnc-thread) vnc_thread="yes" + ;; --disable-slirp) slirp="no" ;; --disable-uuid) uuid="no" @@ -839,6 +844,8 @@ echo " --disable-vnc-jpeg disable JPEG lossy compression for VNC server" echo " --enable-vnc-jpegenable JPEG lossy compression for VNC server" echo " --disable-vnc-pngdisable PNG compression for VNC server" echo " --enable-vnc-png enable PNG compression for VNC server" +echo " --disable-vnc-thread disable threaded VNC server" +echo " --enable-vnc-thread enable threaded VNC server" echo " --disable-curses disable curses output" echo " --enable-curses enable curses output" echo " --disable-curl disable curl connectivity" @@ -2156,6 +2163,7 @@ echo "VNC TLS support $vnc_tls" echo "VNC SASL support $vnc_sasl" echo "VNC JPEG support $vnc_jpeg" echo "VNC PNG support $vnc_png" +echo "VNC thread$vnc_thread" if test -n "$sparc_cpu"; then echo "Target Sparc Arch $sparc_cpu" fi @@ -2301,6 +2309,10 @@ if test "$vnc_png" = "yes" ; then echo "CONFIG_VNC_PNG=y" >> $config_host_mak echo "VNC_PNG_CFLAGS=$vnc_png_cflags" >> $config_host_mak fi +if test "$vnc_thread" = "yes" ; then + echo "CONFIG_VNC_THREAD=y" >> $config_host_mak + echo "CONFIG_THREAD=y" >> $config_host_mak +fi if test "$fnmatch" = "yes" ; then echo "CONFIG_FNMATCH=y" >> $config_host_mak fi @@ -2377,6 +2389,7 @@ if test "$xen" = "yes" ; then fi if test "$io_thread" = "yes" ; then echo "CONFIG_IOTHREAD=y" >> $config_host_mak + echo "CONFIG_THREAD=y" >> $config_host_mak fi if test "$linux_aio" = "yes" ; then echo "CONFIG_LINUX_AIO=y" >> $config_host_mak diff --git a/ui/vnc-jobs-async.c b/ui/vnc-jobs-async.c new file mode 100644 index 000..6e9cf08 --- /dev/null +++ b/ui/vnc-jobs-async.c @@ -0,0 +1,331 @@ +/* + * QEMU VNC display driver + * + * Copyright (C) 2006 Anthony Liguori + * Copyright (C) 2006 Fabrice Bellard + * Copyright (C) 2009 Red Hat, Inc + * Copyright (C) 2010 Corentin Chary + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUT
Re: [Qemu-devel] [PATCH, RFC] pci: handle BAR mapping at pci level
On Wed, Jul 7, 2010 at 7:02 PM, Anthony Liguori wrote: > On 07/07/2010 12:53 PM, Blue Swirl wrote: >> >> Add I/O port registration functions which separate registration >> from the mapping stage. >> >> Move IOIO and MMIO BAR mapping to pci.c. >> >> TODO: fix dirty logging, coalesced MMIO and base address comparisons >> (eepro100 etc). Bridge filtering may be broken. Broke virtio-pci and MSIX. >> >> Signed-off-by: Blue Swirl >> --- >> i386 boots but resets. PPC and Sparc64 can't even start. >> >> Patch also available at >> git://repo.or.cz/qemu/blueswirl.git >> >> It may be worthwhile to break this into some kind of smaller steps. >> >> hw/ac97.c | 60 +++- >> hw/cirrus_vga.c | 40 +++--- >> hw/e1000.c | 37 +--- >> hw/eepro100.c | 77 ++ >> hw/es1370.c | 32 +-- >> hw/ide/cmd646.c | 149 >> +++--- >> hw/ide/piix.c | 74 - >> hw/ide/via.c | 67 ++ >> hw/isa.h | 1 + >> hw/isa_mmio.c | 17 +- >> hw/lsi53c895a.c | 60 ++-- >> hw/macio.c | 107 +++- >> hw/ne2000.c | 66 +++--- >> hw/openpic.c | 36 ++-- >> hw/pci.c | 158 >> >> hw/pci.h | 18 +- >> hw/pcnet.c | 62 ++--- >> hw/ppc_mac.h | 5 +- >> hw/ppc_newworld.c | 2 +- >> hw/ppc_oldworld.c | 4 +- >> hw/rtl8139.c | 42 +- >> hw/sun4u.c | 29 +++-- >> hw/usb-ohci.c | 10 +--- >> hw/usb-uhci.c | 31 +- >> hw/vga-pci.c | 22 +-- >> hw/virtio-pci.c | 39 ++--- >> hw/vmware_vga.c | 107 ++-- >> hw/wdt_i6300esb.c | 38 + >> ioport.c | 119 >> ioport.h | 6 ++ >> 30 files changed, 778 insertions(+), 737 deletions(-) >> >> diff --git a/hw/ac97.c b/hw/ac97.c >> index 4319bc8..28d0c19 100644 >> --- a/hw/ac97.c >> +++ b/hw/ac97.c >> @@ -1234,31 +1234,29 @@ static const VMStateDescription vmstate_ac97 = { >> } >> }; >> >> -static void ac97_map (PCIDevice *pci_dev, int region_num, >> - pcibus_t addr, pcibus_t size, int type) >> -{ >> - AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, pci_dev); >> - PCIDevice *d =&s->dev; >> - >> - if (!region_num) { >> - s->base[0] = addr; >> - register_ioport_read (addr, 256 * 1, 1, nam_readb, d); >> - register_ioport_read (addr, 256 * 2, 2, nam_readw, d); >> - register_ioport_read (addr, 256 * 4, 4, nam_readl, d); >> - register_ioport_write (addr, 256 * 1, 1, nam_writeb, d); >> - register_ioport_write (addr, 256 * 2, 2, nam_writew, d); >> - register_ioport_write (addr, 256 * 4, 4, nam_writel, d); >> - } >> - else { >> - s->base[1] = addr; >> - register_ioport_read (addr, 64 * 1, 1, nabm_readb, d); >> - register_ioport_read (addr, 64 * 2, 2, nabm_readw, d); >> - register_ioport_read (addr, 64 * 4, 4, nabm_readl, d); >> - register_ioport_write (addr, 64 * 1, 1, nabm_writeb, d); >> - register_ioport_write (addr, 64 * 2, 2, nabm_writew, d); >> - register_ioport_write (addr, 64 * 4, 4, nabm_writel, d); >> - } >> -} >> +static IOPortWriteFunc * const nam_writes[] = { >> + nam_writeb, >> + nam_writew, >> + nam_writel, >> +}; >> + >> +static IOPortReadFunc * const nam_reads[] = { >> + nam_readb, >> + nam_readw, >> + nam_readl, >> +}; >> + >> +static IOPortWriteFunc * const nabm_writes[] = { >> + nabm_writeb, >> + nabm_writew, >> + nabm_writel, >> +}; >> + >> +static IOPortReadFunc * const nabm_reads[] = { >> + nabm_readb, >> + nabm_readw, >> + nabm_readl, >> +}; >> >> static void ac97_on_reset (void *opaque) >> { >> @@ -1280,6 +1278,7 @@ static int ac97_initfn (PCIDevice *dev) >> { >> AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, dev); >> uint8_t *c = s->dev.config; >> + int io_index; >> >> pci_config_set_vendor_id (c, PCI_VENDOR_ID_INTEL); /* ro */ >> pci_config_set_device_id (c, PCI_DEVICE_ID_INTEL_82801AA_5); /* ro */ >> @@ -1321,9 +1320,14 @@ static int ac97_initfn (PCIDevice *dev) >> /* TODO: RST# value should be 0. */ >> c[PCI_INTERRUPT_PIN] = 0x01; /* intr_pn interrupt pin ro */ >> >> - pci_register_bar (&s->dev, 0, 256 * 4, PCI_BASE_ADDRESS_SPACE_IO, >> - ac97_map); >> - pci_register_bar (&s->dev, 1, 64 * 4, PCI_BASE_ADDRESS_SPACE_IO, >> ac97_map); >> + pci_register_bar(&s->dev, 0, 256 * 4, PCI_BASE_ADDRESS_SPACE_IO); >> + io_index = cpu_register_io(nam_reads, nam_writes, 256 * 4, s); >> + pci_bar_map(&s->dev, 0, 0, 0, 256 * 4, io_index); >> + >> + pci_re
Re: [Qemu-devel] [PATCH] sheepdog: fix compile error on systems without TCP_CORK
Thanks, applied. It also fixes OpenBSD build. On Wed, Jul 7, 2010 at 6:25 AM, MORITA Kazutaka wrote: > WIN32 is not only the system which doesn't have TCP_CORK (e.g. OS X). > > Signed-off-by: MORITA Kazutaka > --- > > Betts, I think this patch fix the compile error. Can you try this > one? > > block/sheepdog.c | 2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) > > diff --git a/block/sheepdog.c b/block/sheepdog.c > index 69a2494..81aa564 100644 > --- a/block/sheepdog.c > +++ b/block/sheepdog.c > @@ -889,7 +889,7 @@ static int aio_flush_request(void *opaque) > return !QLIST_EMPTY(&s->outstanding_aio_head); > } > > -#ifdef _WIN32 > +#if !defined(SOL_TCP) || !defined(TCP_CORK) > > static int set_cork(int fd, int v) > { > -- > 1.5.6.5 > > >
[Qemu-devel] [PATCH] set proper migration status on ->write error (v2)
If ->write fails, declare migration status as MIG_STATE_ERROR. Also, in buffered_file.c, ->close the object in case of an error. Fixes "migrate -d "exec:dd of=file", where dd fails to open file. Signed-off-by: Marcelo Tosatti diff --git a/buffered_file.c b/buffered_file.c index 54dc6c2..be147d6 100644 --- a/buffered_file.c +++ b/buffered_file.c @@ -222,8 +222,10 @@ static void buffered_rate_tick(void *opaque) { QEMUFileBuffered *s = opaque; -if (s->has_error) +if (s->has_error) { +buffered_close(s); return; +} qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 100); diff --git a/migration.c b/migration.c index b49964c..433f08f 100644 --- a/migration.c +++ b/migration.c @@ -316,8 +316,11 @@ ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size) if (ret == -1) ret = -(s->get_error(s)); -if (ret == -EAGAIN) +if (ret == -EAGAIN) { qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s); +} else { +s->state = MIG_STATE_ERROR; +} return ret; }
Re: [Qemu-devel] [PATCH, RFC] pci: handle BAR mapping at pci level
On Wed, Jul 7, 2010 at 6:15 PM, malc wrote: > On Wed, 7 Jul 2010, Blue Swirl wrote: > >> Add I/O port registration functions which separate registration >> from the mapping stage. > > Why? So that the device code can specify all other parameters except for the I/O port, which will be handled by PCI BAR mappings.
[Qemu-devel] Re: [PATCH] set proper migration status on ->write error (v2)
Marcelo Tosatti wrote: > If ->write fails, declare migration status as MIG_STATE_ERROR. > > Also, in buffered_file.c, ->close the object in case of an > error. > > Fixes "migrate -d "exec:dd of=file", where dd fails to open file. > > Signed-off-by: Marcelo Tosatti Acked-by: Juan Quintela Again, just in case O:-)
[Qemu-devel] [Bug 521994] Re: Windows 98 doesn't detect mouse on qemu and SeaBIOS.
Yes! Using SeaBIOS 6.0 worked for me as well. Thanks LightBit. I've been waiting for this for quite a while. -- Windows 98 doesn't detect mouse on qemu and SeaBIOS. https://bugs.launchpad.net/bugs/521994 You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. Status in QEMU: Confirmed Bug description: A windows 98 guest doesn't detect mouse on recent qemu. I bisected and the result is fd646122418ecefcde228d43821d07da79dd99bb is the first bad commit commit fd646122418ecefcde228d43821d07da79dd99bb Author: Anthony Liguori Date: Fri Oct 30 09:06:09 2009 -0500 Switch pc bios from pc-bios to seabios SeaBIOS is a port of pc-bios to GCC. Besides using a more modern tool chain, SeaBIOS introduces a number of new features including PMM support, better BEV and BCV support, and better PnP support. Signed-off-by: Anthony Liguori I got following messages with DEBUG_BIOS Start bios (version 0.5.1-20100111_132716-squirrel.codemonkey.ws) Ram Size=0x0800 (0x high) CPU Mhz=2271 Found 1 cpu(s) max supported 1 cpu(s) PIIX3/PIIX4 init: elcr=00 0c PCI: bus=0 devfn=0x00: vendor_id=0x8086 device_id=0x1237 PCI: bus=0 devfn=0x08: vendor_id=0x8086 device_id=0x7000 PCI: bus=0 devfn=0x09: vendor_id=0x8086 device_id=0x7010 region 4: 0xc000 PCI: bus=0 devfn=0x0b: vendor_id=0x8086 device_id=0x7113 PCI: bus=0 devfn=0x10: vendor_id=0x1013 device_id=0x00b8 region 0: 0xe000 region 1: 0xe200 region 6: 0xe201 MP table addr=0x000f89b0 MPC table addr=0x000f89c0 size=224 SMBIOS ptr=0x000f8990 table=0x07fffef0 ACPI tables: RSDP=0x000f8960 RSDT=0x07ffde30 Scan for VGA option rom Running option rom at c000:0003 VGABios $Id$ Turning on vga console Starting SeaBIOS (version 0.5.1-20100111_132716-squirrel.codemonkey.ws) Found 0 lpt ports Found 0 serial ports ATA controller 0 at 1f0/3f4/c000 (irq 14 dev 9) ATA controller 1 at 170/374/c008 (irq 15 dev 9) ps2 irq but no data. ata0-0: PCHS=812/16/63 translation=none LCHS=812/16/63 ata0-1: PCHS=1152/16/56 translation=none LCHS=1024/16/56 ps2_recvbyte timeout keyboard initialized Scan for option roms Returned 53248 bytes of ZoneHigh e820 map has 6 items: 0: - 0009f400 = 1 1: 0009f400 - 000a = 2 2: 000f - 0010 = 2 3: 0010 - 07ffd000 = 1 4: 07ffd000 - 0800 = 2 5: fffc - 0001 = 2 enter handle_19: NULL Booting from Hard Disk... Booting from :7c00 pnp call arg1=5 pnp call arg1=0 ps2_recvbyte timeout ps2_recvbyte timeout ps2_recvbyte timeout ps2_recvbyte timeout
[Qemu-devel] [PATCH] Makefile: add fsdev/*.{o,d} to clean
There were fsdev/qemu-fsdev.{o,d} not removed at "make clean". Signed-off-by: Hidetoshi Seto --- Makefile |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Makefile b/Makefile index 560eac6..7b82a33 100644 --- a/Makefile +++ b/Makefile @@ -159,7 +159,7 @@ clean: # avoid old build problems by removing potentially incorrect old files rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h rm -f *.o *.d *.a $(TOOLS) TAGS cscope.* *.pod *~ */*~ - rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d + rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d rm -f qemu-img-cmds.h $(MAKE) -C tests clean for d in $(ALL_SUBDIRS) libhw32 libhw64 libuser libdis libdis-user; do \ -- 1.7.1.1
[Qemu-devel] [PATCH] Makefile: Not every shell support {}
So interpret it by hand. Signed-off-by: Hidetoshi Seto --- Makefile |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/Makefile b/Makefile index 7b82a33..6fc1b2c 100644 --- a/Makefile +++ b/Makefile @@ -171,7 +171,8 @@ distclean: clean rm -f qemu-options.def rm -f config-all-devices.mak rm -f roms/seabios/config.mak roms/vgabios/config.mak - rm -f qemu-{doc,tech}.{info,aux,cp,dvi,fn,info,ky,log,pdf,pg,toc,tp,vr} + rm -f qemu-doc.info qemu-doc.aux qemu-doc.cp qemu-doc.dvi qemu-doc.fn qemu-doc.info qemu-doc.ky qemu-doc.log qemu-doc.pdf qemu-doc.pg qemu-doc.toc qemu-doc.tp qemu-doc.vr + rm -f qemu-tech.info qemu-tech.aux qemu-tech.cp qemu-tech.dvi qemu-tech.fn qemu-tech.info qemu-tech.ky qemu-tech.log qemu-tech.pdf qemu-tech.pg qemu-tech.toc qemu-tech.tp qemu-tech.vr for d in $(TARGET_DIRS) libhw32 libhw64 libuser libdis libdis-user; do \ rm -rf $$d || exit 1 ; \ done -- 1.7.1.1
[Qemu-devel] [RFC v3][PATCH][Tracing] Fix build errors for target i386-linux-user
[PATCH] Separate monitor command handler interfaces and tracing internals. Signed-off-by: Prerna Saxena --- monitor.c | 23 +++ simpletrace.c | 51 +-- tracetool |7 +++ 3 files changed, 59 insertions(+), 22 deletions(-) diff --git a/monitor.c b/monitor.c index 433a3ec..1f89938 100644 --- a/monitor.c +++ b/monitor.c @@ -540,6 +540,29 @@ static void do_change_trace_event_state(Monitor *mon, const QDict *qdict) bool new_state = qdict_get_bool(qdict, "option"); change_trace_event_state(tp_name, new_state); } + +void do_info_trace(Monitor *mon) +{ +unsigned int i; +char rec[MAX_TRACE_STR_LEN]; +unsigned int trace_idx = get_trace_idx(); + +for (i = 0; i < trace_idx ; i++) { +if (format_trace_string(i, rec)) { +monitor_printf(mon, rec); +} +} +} + +void do_info_all_trace_events(Monitor *mon) +{ +unsigned int i; + +for (i = 0; i < NR_TRACE_EVENTS; i++) { +monitor_printf(mon, "%s [Event ID %u] : state %u\n", +trace_list[i].tp_name, i, trace_list[i].state); +} +} #endif static void user_monitor_complete(void *opaque, QObject *ret_data) diff --git a/simpletrace.c b/simpletrace.c index 57c41fc..c7b1e7e 100644 --- a/simpletrace.c +++ b/simpletrace.c @@ -1,8 +1,8 @@ #include #include -#include "monitor.h" #include "trace.h" +/* Remember to update TRACE_REC_SIZE when changing TraceRecord structure */ typedef struct { unsigned long event; unsigned long x1; @@ -69,27 +69,6 @@ void trace5(TraceEventID event, unsigned long x1, unsigned long x2, unsigned lon trace(event, x1, x2, x3, x4, x5); } -void do_info_trace(Monitor *mon) -{ -unsigned int i; - -for (i = 0; i < trace_idx ; i++) { -monitor_printf(mon, "Event %lu : %lx %lx %lx %lx %lx\n", - trace_buf[i].event, trace_buf[i].x1, trace_buf[i].x2, -trace_buf[i].x3, trace_buf[i].x4, trace_buf[i].x5); -} -} - -void do_info_all_trace_events(Monitor *mon) -{ -unsigned int i; - -for (i = 0; i < NR_TRACE_EVENTS; i++) { -monitor_printf(mon, "%s [Event ID %u] : state %u\n", -trace_list[i].tp_name, i, trace_list[i].state); -} -} - static TraceEvent* find_trace_event_by_name(const char *tname) { unsigned int i; @@ -115,3 +94,31 @@ void change_trace_event_state(const char *tname, bool tstate) tp->state = tstate; } } + +/** + * Return the current trace index. + * + */ +unsigned int get_trace_idx(void) +{ +return trace_idx; +} + +/** + * returns formatted TraceRecord at a given index in the trace buffer. + * FORMAT : "Event %lu : %lx %lx %lx %lx %lx\n" + * + * @idx : index in the buffer for which trace record is returned. + * @trace_str : output string passed. + */ +char* format_trace_string(unsigned int idx, char trace_str[]) +{ +TraceRecord rec; +if (idx >= TRACE_BUF_LEN || sizeof(trace_str) >= MAX_TRACE_STR_LEN) { +return NULL; +} +rec = trace_buf[idx]; +sprintf(&trace_str[0], "Event %lu : %lx %lx %lx %lx %lx\n", +rec.event, rec.x1, rec.x2, rec.x3, rec.x4, rec.x5); +return &trace_str[0]; +} diff --git a/tracetool b/tracetool index c77280d..b7a0499 100755 --- a/tracetool +++ b/tracetool @@ -125,6 +125,11 @@ typedef struct { bool state; } TraceEvent; +/* Max size of trace string to be displayed via the monitor. + * Format : "Event %lu : %lx %lx %lx %lx %lx\n" + */ +#define MAX_TRACE_STR_LEN 100 + void trace1(TraceEventID event, unsigned long x1); void trace2(TraceEventID event, unsigned long x1, unsigned long x2); void trace3(TraceEventID event, unsigned long x1, unsigned long x2, unsigned long x3); @@ -133,6 +138,8 @@ void trace5(TraceEventID event, unsigned long x1, unsigned long x2, unsigned lon void do_info_trace(Monitor *mon); void do_info_all_trace_events(Monitor *mon); void change_trace_event_state(const char *tname, bool tstate); +unsigned int get_trace_idx(void); +char* format_trace_string(unsigned int idx, char *trace_str); EOF simple_event_num=0 -- 1.6.2.5 -- Prerna Saxena Linux Technology Centre, IBM Systems and Technology Lab, Bangalore, India
Re: [Qemu-devel] [PATCH 3/3] trace: Flush trace buffer on exit
Hi Stefan, On 07/07/2010 01:44 AM, Stefan Hajnoczi wrote: Signed-off-by: Stefan Hajnoczi --- This applies to the tracing branch at: http://repo.or.cz/w/qemu/stefanha.git/shortlog/refs/heads/tracing-dev simpletrace.c | 23 +++ 1 files changed, 15 insertions(+), 8 deletions(-) diff --git a/simpletrace.c b/simpletrace.c index ace009f..9604ea6 100644 --- a/simpletrace.c +++ b/simpletrace.c @@ -22,6 +22,20 @@ static TraceRecord trace_buf[TRACE_BUF_LEN]; static unsigned int trace_idx; static FILE *trace_fp; +static void flush_trace_buffer(void) +{ +if (!trace_fp) { +trace_fp = fopen("/tmp/trace.log", "w"); +if (trace_fp) { +atexit(flush_trace_buffer); +} +} +if (trace_fp) { +size_t unused; /* for when fwrite(3) is declared warn_unused_result */ +unused = fwrite(trace_buf, trace_idx * sizeof(trace_buf[0]), 1, trace_fp); I think this would be better denoted as : unused = fwrite(trace_buf, trace_idx * sizeof(TraceRecord), 1, trace_fp); +} +} + static void trace(TraceEventID event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4, unsigned long x5) @@ -44,15 +58,8 @@ static void trace(TraceEventID event, unsigned long x1, rec->x5 = x5; if (++trace_idx == TRACE_BUF_LEN) { +flush_trace_buffer(); trace_idx = 0; - -if (!trace_fp) { -trace_fp = fopen("/tmp/trace.log", "w"); -} -if (trace_fp) { -size_t result = fwrite(trace_buf, sizeof trace_buf, 1, trace_fp); -result = result; -} } } I was wondering if we can extend this. One can have a monitor command such as "dump-trace" which would write a partly-filled buffer to file using a call to flush_trace_buffer(). But this has a few caveats. flush_trace_buffer() must reset trace_idx to 0 to prevent duplicate traces to be written once the buffer is filled up. Also, I'm wondering what happens in case qemu is started with -smp 2 or more. We might need to enforce some kind of synchronisation so that threads on other cpus do not log traces while the buffer is being sync'ed. ( For now, I have not been able to get upstream qemu run with -smp. Going forward, this is something that might need to be looked into.) Regards, -- Prerna Saxena Linux Technology Centre, IBM Systems and Technology Lab, Bangalore, India
Re: [Qemu-devel] Re: [PATCH 1/2] pci/bridge: allocate PCIBus dynamically for PCIBridge.
On Wed, Jul 07, 2010 at 02:47:10PM +0300, Michael S. Tsirkin wrote: > > > I think this becomes too complex: as bridge configuration affects > > > the bus operation, you might end up sticking a pointer to the device > > > in the bus. A similar arrangement is in place in with piix_pci, and I > > > would > > > love to get rid of it, too. > > > > I'd glad to look into it, but I'd like to make it sure before digging > > into it. > > Do you mean i440fx_init() and I440FXState::bus = PCIHostState::bus? > > Please a bit more concrete explanation. > > I am not sure myself yet. Generally I'm not very happy with how > interrupts are handled. > > Specifically: > - lots of indirect calls through qemu_irq > not type-safe, hard to debug and can not be good for performance > need to find a way to chase these pointers at setup time > - lots of loops over irq pins and over buses > need to precompute and store at setup time, and use bits for booleans > - information is duplicated, e.g. piix duplicates irq states > need to use from a single place > with the last issue, be careful not to break migration: > we need to compute and store old data on migration > > In case of piix_pci interrupts are controlled through PIIX3 device, so > we create the host bus, the device on it, and finally make another call > to make interrupts on the bus get device as the opaque pointer. > All this looks very convoluted. I see, it's concern about over all piix_pci. Can you please comment on pci_bus_new() issue below? I'm afraid that you missed it. > > > > --- > > > > hw/pci.c | 25 ++--- > > > > 1 files changed, 14 insertions(+), 11 deletions(-) > > > > > > > > diff --git a/hw/pci.c b/hw/pci.c > > > > index 08652e8..fdf02d0 100644 > > > > --- a/hw/pci.c > > > > +++ b/hw/pci.c > > > > @@ -286,23 +286,27 @@ PCIBus *pci_register_bus(DeviceState *parent, > > > > const char *name, > > > > return bus; > > > > } > > > > > > > > -static void pci_register_secondary_bus(PCIBus *parent, > > > > - PCIBus *bus, > > > > - PCIDevice *dev, > > > > - pci_map_irq_fn map_irq, > > > > - const char *name) > > > > +static PCIBus *pci_register_secondary_bus(PCIBus *parent, > > > > + PCIDevice *dev, > > > > + pci_map_irq_fn map_irq, > > > > + const char *name) > > > > { > > > > -qbus_create_inplace(&bus->qbus, &pci_bus_info, &dev->qdev, name); > > > > +PCIBus *bus; > > > > +bus = pci_bus_new(&dev->qdev, name, 0); > > > > + > > > > bus->map_irq = map_irq; > > > > bus->parent_dev = dev; > > > > > > > > QLIST_INSERT_HEAD(&parent->child, bus, sibling); > > > > + > > > > +return bus; > > > > > > This does more than we need: pci_bus_new > > > was created for host bus so it will also register in > > > reset and vmstate lists. > > > > I'm bit confused. I've thought that pci_bus_new() was for both root bus > > and secondary bus. So I've tried to move out root bus specific stuff > > from pci_bus_new(). > > > > But you claim it's only for root bus, not for secondary bus. > > Now I realized why you've rejected such patches so far. > > Then, you also mean the current pci_register_secondary_bus() is broken. > > I also think it's broken. So how do we want to fix it? > > My idea is as follows. > > > > - introduce something like pci_secondary_bus_new() > > (pci_sec_bus_new() for short?) for secondary bus. > > fix pci_register_secondary_bus() with it. > > > > - introduce something like pci_host_bus_new() (or pci_root_bus_new()?) > > for pci host bus which is more generic than pci_bus_new(). > > It's for > > - to avoid confusion. > > - to eliminate assumption of pci_bus_new(). > > pci_bus_new() assumes that its pci segment is 0. > > keep pci_bus_new() as a convenience wrapper of > > pci_host_bus_new(segment = 0). Thus we can avoid fixing up > > all the caller. -- yamahata