Re: [Qemu-devel] [PATCH v3 0/6] Some PCI related cleanup patches

2015-01-26 Thread Hu Tao
On Wed, Jan 21, 2015 at 02:00:58PM +0200, Michael S. Tsirkin wrote:
> On Wed, Jan 21, 2015 at 02:41:33PM +0800, Hu Tao wrote:
> > ping...
> 
> At some point you said "will resend".

I meant resend patch 6.

Patches 1-5 can still apply cleanly.

Regards,
Hu

> 
> > On Thu, Dec 11, 2014 at 10:20:22AM +0800, Hu Tao wrote:
> > > Hi,
> > > 
> > > This is v3 of PCI clenaup series. See each patch for the detail.
> > > 
> > > Regards,
> > > Hu
> > > 
> > > changes:
> > > 
> > > v3:
> > >   - rebase on top of 7fb8da2b886, all 5 patches applied cleanly.
> > >   - new patch: pci: introduce PCI_DEVFN_AUTO
> > > 
> > > v2:
> > >   - remove patch 3 from v1 which is incorrect.
> > >   - rename defined macros as per Marcel's suggestion
> > >   - place macros in pci_host.h as per Marcel's suggestion
> > >   - new patch 'pci: reorganize QEMU_PCI_CAP_*'
> > > 
> > > Hu Tao (6):
> > >   pci: reorganize QEMU_PCI_CAP_*
> > >   pci: introduce pci_host_config_enabled()
> > >   pci: define PCI_HOST_BRIDGE_CONFIG_ADDR and
> > > PCI_HOST_BRIDGE_CONFIG_DATA.
> > >   pci: remove the limit parameter of pci_host_config_read_common
> > >   pci: remove the limit parameter of pci_host_config_write_common
> > >   pci: introduce PCI_DEVFN_AUTO
> > > 
> > >  hw/core/qdev-properties.c |  1 +
> > >  hw/mips/gt64xxx_pci.c |  4 ++--
> > >  hw/pci-host/piix.c|  8 
> > >  hw/pci-host/prep.c|  6 --
> > >  hw/pci-host/q35.c |  8 
> > >  hw/pci/pci.c  |  5 ++---
> > >  hw/pci/pci_host.c | 33 -
> > >  hw/pci/pcie_host.c| 18 ++
> > >  hw/ppc/spapr_pci.c|  6 ++
> > >  include/hw/pci-host/q35.h |  3 ---
> > >  include/hw/pci/pci.h  | 41 ++---
> > >  include/hw/pci/pci_host.h | 14 --
> > >  tests/libqos/pci-pc.c | 25 +
> > >  13 files changed, 92 insertions(+), 80 deletions(-)
> > > 
> > > -- 
> > > 1.9.3
> > > 
> > > 



Re: [Qemu-devel] [PATCH v3 6/6] pci: introduce PCI_DEVFN_AUTO

2015-01-26 Thread Hu Tao
On Wed, Jan 21, 2015 at 02:00:02PM +0200, Michael S. Tsirkin wrote:
> On Thu, Dec 11, 2014 at 10:20:28AM +0800, Hu Tao wrote:
> > Introduce PCI_DEVFN_AUTO rather than using -1 in code.
> > 
> > Signed-off-by: Hu Tao 
> > ---
> >  hw/core/qdev-properties.c | 1 +
> >  hw/pci/pci.c  | 5 ++---
> >  include/hw/pci/pci.h  | 2 ++
> >  3 files changed, 5 insertions(+), 3 deletions(-)
> > 
> > diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> > index 2e47f70..df4ad14 100644
> > --- a/hw/core/qdev-properties.c
> > +++ b/hw/core/qdev-properties.c
> > @@ -6,6 +6,7 @@
> >  #include "net/hub.h"
> >  #include "qapi/visitor.h"
> >  #include "sysemu/char.h"
> > +#include "hw/pci/pci.h"
> >  
> >  void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
> >Error **errp)
> > diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> > index 371699c..73c7dec 100644
> > --- a/hw/pci/pci.c
> > +++ b/hw/pci/pci.c
> > @@ -50,7 +50,7 @@ static char *pcibus_get_fw_dev_path(DeviceState *dev);
> >  static void pcibus_reset(BusState *qbus);
> >  
> >  static Property pci_props[] = {
> > -DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
> > +DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, PCI_DEVFN_AUTO),
> >  DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
> >  DEFINE_PROP_UINT32("rombar",  PCIDevice, rom_bar, 1),
> >  DEFINE_PROP_BIT("multifunction", PCIDevice, cap_present,
> > @@ -801,7 +801,6 @@ static void do_pci_unregister_device(PCIDevice *pci_dev)
> >  address_space_destroy(&pci_dev->bus_master_as);
> >  }
> >  
> > -/* -1 for devfn means auto assign */
> >  static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
> >   const char *name, int devfn)
> >  {
> > @@ -810,7 +809,7 @@ static PCIDevice *do_pci_register_device(PCIDevice 
> > *pci_dev, PCIBus *bus,
> >  PCIConfigWriteFunc *config_write = pc->config_write;
> >  AddressSpace *dma_as;
> >  
> > -if (devfn < 0) {
> > +if (devfn == PCI_DEVFN_AUTO) {
> 
> How do we know we found all places that do this?

Good question! Actually I found other places creating devfn=-1 pci
devices, by calling pci_create_simple_multifunction() and
pci_create_simple(). But I don't have a solid way to discover all these
places. So we should keep the original code here.

Please drop this patch.

Thanks,
Hu

> How do we know parameter was already validate for
> other values < 0?
> Can you pls mention in the commit log why you think
> it's safe?
> 
> 
> >  for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);
> >  devfn += PCI_FUNC_MAX) {
> >  if (!bus->devices[devfn])
> > diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
> > index b18759a..9206b12 100644
> > --- a/include/hw/pci/pci.h
> > +++ b/include/hw/pci/pci.h
> > @@ -164,6 +164,8 @@ enum {
> >  QEMU_PCIE_SLTCAP_PCP= (1 << QEMU_PCIE_SLTCAP_PCP_BITNR),
> >  };
> >  
> > +#define PCI_DEVFN_AUTO -1
> > +
> >  #define TYPE_PCI_DEVICE "pci-device"
> >  #define PCI_DEVICE(obj) \
> >   OBJECT_CHECK(PCIDevice, (obj), TYPE_PCI_DEVICE)
> > -- 
> > 1.9.3



Re: [Qemu-devel] [PATCH v3 0/6] Some PCI related cleanup patches

2015-01-20 Thread Hu Tao
ping...

On Thu, Dec 11, 2014 at 10:20:22AM +0800, Hu Tao wrote:
> Hi,
> 
> This is v3 of PCI clenaup series. See each patch for the detail.
> 
> Regards,
> Hu
> 
> changes:
> 
> v3:
>   - rebase on top of 7fb8da2b886, all 5 patches applied cleanly.
>   - new patch: pci: introduce PCI_DEVFN_AUTO
> 
> v2:
>   - remove patch 3 from v1 which is incorrect.
>   - rename defined macros as per Marcel's suggestion
>   - place macros in pci_host.h as per Marcel's suggestion
>   - new patch 'pci: reorganize QEMU_PCI_CAP_*'
> 
> Hu Tao (6):
>   pci: reorganize QEMU_PCI_CAP_*
>   pci: introduce pci_host_config_enabled()
>   pci: define PCI_HOST_BRIDGE_CONFIG_ADDR and
> PCI_HOST_BRIDGE_CONFIG_DATA.
>   pci: remove the limit parameter of pci_host_config_read_common
>   pci: remove the limit parameter of pci_host_config_write_common
>   pci: introduce PCI_DEVFN_AUTO
> 
>  hw/core/qdev-properties.c |  1 +
>  hw/mips/gt64xxx_pci.c |  4 ++--
>  hw/pci-host/piix.c|  8 
>  hw/pci-host/prep.c|  6 --
>  hw/pci-host/q35.c |  8 
>  hw/pci/pci.c  |  5 ++---
>  hw/pci/pci_host.c | 33 -
>  hw/pci/pcie_host.c| 18 ++
>  hw/ppc/spapr_pci.c|  6 ++
>  include/hw/pci-host/q35.h |  3 ---
>  include/hw/pci/pci.h  | 41 ++---
>  include/hw/pci/pci_host.h | 14 --
>  tests/libqos/pci-pc.c | 25 +
>  13 files changed, 92 insertions(+), 80 deletions(-)
> 
> -- 
> 1.9.3
> 
> 



[Qemu-devel] [PATCH v3 RESEND 6/6] pci: introduce PCI_DEVFN_AUTO

2014-12-10 Thread Hu Tao
Introduce PCI_DEVFN_AUTO rather than using -1 in code.

Signed-off-by: Hu Tao 
---
 hw/pci/pci.c | 5 ++---
 include/hw/pci/pci.h | 2 ++
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 371699c..73c7dec 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -50,7 +50,7 @@ static char *pcibus_get_fw_dev_path(DeviceState *dev);
 static void pcibus_reset(BusState *qbus);
 
 static Property pci_props[] = {
-DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
+DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, PCI_DEVFN_AUTO),
 DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
 DEFINE_PROP_UINT32("rombar",  PCIDevice, rom_bar, 1),
 DEFINE_PROP_BIT("multifunction", PCIDevice, cap_present,
@@ -801,7 +801,6 @@ static void do_pci_unregister_device(PCIDevice *pci_dev)
 address_space_destroy(&pci_dev->bus_master_as);
 }
 
-/* -1 for devfn means auto assign */
 static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
  const char *name, int devfn)
 {
@@ -810,7 +809,7 @@ static PCIDevice *do_pci_register_device(PCIDevice 
*pci_dev, PCIBus *bus,
 PCIConfigWriteFunc *config_write = pc->config_write;
 AddressSpace *dma_as;
 
-if (devfn < 0) {
+if (devfn == PCI_DEVFN_AUTO) {
 for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);
 devfn += PCI_FUNC_MAX) {
 if (!bus->devices[devfn])
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index b18759a..9206b12 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -164,6 +164,8 @@ enum {
 QEMU_PCIE_SLTCAP_PCP= (1 << QEMU_PCIE_SLTCAP_PCP_BITNR),
 };
 
+#define PCI_DEVFN_AUTO -1
+
 #define TYPE_PCI_DEVICE "pci-device"
 #define PCI_DEVICE(obj) \
  OBJECT_CHECK(PCIDevice, (obj), TYPE_PCI_DEVICE)
-- 
1.9.3




Re: [Qemu-devel] [PATCH v3 6/6] pci: introduce PCI_DEVFN_AUTO

2014-12-10 Thread Hu Tao
On Thu, Dec 11, 2014 at 10:20:28AM +0800, Hu Tao wrote:
> Introduce PCI_DEVFN_AUTO rather than using -1 in code.
> 
> Signed-off-by: Hu Tao 
> ---
>  hw/core/qdev-properties.c | 1 +
>  hw/pci/pci.c  | 5 ++---
>  include/hw/pci/pci.h  | 2 ++
>  3 files changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> index 2e47f70..df4ad14 100644
> --- a/hw/core/qdev-properties.c
> +++ b/hw/core/qdev-properties.c
> @@ -6,6 +6,7 @@
>  #include "net/hub.h"
>  #include "qapi/visitor.h"
>  #include "sysemu/char.h"
> +#include "hw/pci/pci.h"

Oops, this one shouldn't be here, will resend.

Regards,
Hu



[Qemu-devel] [PATCH v3 6/6] pci: introduce PCI_DEVFN_AUTO

2014-12-10 Thread Hu Tao
Introduce PCI_DEVFN_AUTO rather than using -1 in code.

Signed-off-by: Hu Tao 
---
 hw/core/qdev-properties.c | 1 +
 hw/pci/pci.c  | 5 ++---
 include/hw/pci/pci.h  | 2 ++
 3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 2e47f70..df4ad14 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -6,6 +6,7 @@
 #include "net/hub.h"
 #include "qapi/visitor.h"
 #include "sysemu/char.h"
+#include "hw/pci/pci.h"
 
 void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
   Error **errp)
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 371699c..73c7dec 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -50,7 +50,7 @@ static char *pcibus_get_fw_dev_path(DeviceState *dev);
 static void pcibus_reset(BusState *qbus);
 
 static Property pci_props[] = {
-DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
+DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, PCI_DEVFN_AUTO),
 DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
 DEFINE_PROP_UINT32("rombar",  PCIDevice, rom_bar, 1),
 DEFINE_PROP_BIT("multifunction", PCIDevice, cap_present,
@@ -801,7 +801,6 @@ static void do_pci_unregister_device(PCIDevice *pci_dev)
 address_space_destroy(&pci_dev->bus_master_as);
 }
 
-/* -1 for devfn means auto assign */
 static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
  const char *name, int devfn)
 {
@@ -810,7 +809,7 @@ static PCIDevice *do_pci_register_device(PCIDevice 
*pci_dev, PCIBus *bus,
 PCIConfigWriteFunc *config_write = pc->config_write;
 AddressSpace *dma_as;
 
-if (devfn < 0) {
+if (devfn == PCI_DEVFN_AUTO) {
 for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);
 devfn += PCI_FUNC_MAX) {
 if (!bus->devices[devfn])
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index b18759a..9206b12 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -164,6 +164,8 @@ enum {
 QEMU_PCIE_SLTCAP_PCP= (1 << QEMU_PCIE_SLTCAP_PCP_BITNR),
 };
 
+#define PCI_DEVFN_AUTO -1
+
 #define TYPE_PCI_DEVICE "pci-device"
 #define PCI_DEVICE(obj) \
  OBJECT_CHECK(PCIDevice, (obj), TYPE_PCI_DEVICE)
-- 
1.9.3




[Qemu-devel] [PATCH v3 3/6] pci: define PCI_HOST_BRIDGE_CONFIG_ADDR and PCI_HOST_BRIDGE_CONFIG_DATA.

2014-12-10 Thread Hu Tao
PCI_HOST_BRIDGE_CONFIG_ADDR and PCI_HOST_BRIDGE_CONFIG_DATA are
defined in PCI specification, so move them to common place.

Signed-off-by: Hu Tao 
Reviewed-by: Marcel Apfelbaum 
---
 hw/pci-host/piix.c|  8 
 hw/pci-host/prep.c|  6 --
 hw/pci-host/q35.c |  8 
 include/hw/pci-host/q35.h |  3 ---
 include/hw/pci/pci_host.h |  5 +
 tests/libqos/pci-pc.c | 25 +
 6 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 1530038..76f3757 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -288,11 +288,11 @@ static void i440fx_pcihost_realize(DeviceState *dev, 
Error **errp)
 PCIHostState *s = PCI_HOST_BRIDGE(dev);
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
-sysbus_add_io(sbd, 0xcf8, &s->conf_mem);
-sysbus_init_ioports(sbd, 0xcf8, 4);
+sysbus_add_io(sbd, PCI_HOST_BRIDGE_CONFIG_ADDR, &s->conf_mem);
+sysbus_init_ioports(sbd, PCI_HOST_BRIDGE_CONFIG_ADDR, 4);
 
-sysbus_add_io(sbd, 0xcfc, &s->data_mem);
-sysbus_init_ioports(sbd, 0xcfc, 4);
+sysbus_add_io(sbd, PCI_HOST_BRIDGE_CONFIG_DATA, &s->data_mem);
+sysbus_init_ioports(sbd, PCI_HOST_BRIDGE_CONFIG_DATA, 4);
 }
 
 static int i440fx_initfn(PCIDevice *dev)
diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index 1de3681..2ae21ad 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -228,11 +228,13 @@ static void raven_pcihost_realizefn(DeviceState *d, Error 
**errp)
 
 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, s,
   "pci-conf-idx", 4);
-memory_region_add_subregion(&s->pci_io, 0xcf8, &h->conf_mem);
+memory_region_add_subregion(&s->pci_io, PCI_HOST_BRIDGE_CONFIG_ADDR,
+&h->conf_mem);
 
 memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops, s,
   "pci-conf-data", 4);
-memory_region_add_subregion(&s->pci_io, 0xcfc, &h->data_mem);
+memory_region_add_subregion(&s->pci_io, PCI_HOST_BRIDGE_CONFIG_DATA,
+&h->data_mem);
 
 memory_region_init_io(&h->mmcfg, OBJECT(s), &raven_pci_io_ops, s,
   "pciio", 0x0040);
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index b20bad8..666afea 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -41,11 +41,11 @@ static void q35_host_realize(DeviceState *dev, Error **errp)
 Q35PCIHost *s = Q35_HOST_DEVICE(dev);
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
-sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_ADDR, &pci->conf_mem);
-sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_ADDR, 4);
+sysbus_add_io(sbd, PCI_HOST_BRIDGE_CONFIG_ADDR, &pci->conf_mem);
+sysbus_init_ioports(sbd, PCI_HOST_BRIDGE_CONFIG_ADDR, 4);
 
-sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, &pci->data_mem);
-sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, 4);
+sysbus_add_io(sbd, PCI_HOST_BRIDGE_CONFIG_DATA, &pci->data_mem);
+sysbus_init_ioports(sbd, PCI_HOST_BRIDGE_CONFIG_DATA, 4);
 
 pci->bus = pci_bus_new(DEVICE(s), "pcie.0",
s->mch.pci_address_space, s->mch.address_space_io,
diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
index 025d6e6..3a026b0 100644
--- a/include/hw/pci-host/q35.h
+++ b/include/hw/pci-host/q35.h
@@ -82,9 +82,6 @@ typedef struct Q35PCIHost {
 /* PCI configuration */
 #define MCH_HOST_BRIDGE"MCH"
 
-#define MCH_HOST_BRIDGE_CONFIG_ADDR0xcf8
-#define MCH_HOST_BRIDGE_CONFIG_DATA0xcfc
-
 /* D0:F0 configuration space */
 #define MCH_HOST_BRIDGE_REVISION_DEFAULT   0x0
 
diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
index b48791d..2bae45a 100644
--- a/include/hw/pci/pci_host.h
+++ b/include/hw/pci/pci_host.h
@@ -30,6 +30,11 @@
 
 #include "hw/sysbus.h"
 
+/* PCI configuration */
+
+#define PCI_HOST_BRIDGE_CONFIG_ADDR  0xcf8
+#define PCI_HOST_BRIDGE_CONFIG_DATA  0xcfc
+
 #define TYPE_PCI_HOST_BRIDGE "pci-host-bridge"
 #define PCI_HOST_BRIDGE(obj) \
 OBJECT_CHECK(PCIHostState, (obj), TYPE_PCI_HOST_BRIDGE)
diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c
index 6dba0db..e4c3c11 100644
--- a/tests/libqos/pci-pc.c
+++ b/tests/libqos/pci-pc.c
@@ -14,6 +14,7 @@
 #include "libqos/pci-pc.h"
 
 #include "hw/pci/pci_regs.h"
+#include "hw/pci/pci_host.h"
 
 #include "qemu-common.h"
 #include "qemu/host-utils.h"
@@ -113,38 +114,38 @@ static void qpci_pc_io_writel(QPCIBus *bus, void *addr, 
uint32_t value)
 
 static uint8_t qpci_pc_config_readb(QPCIBus *bus, int devfn, uint8_t offset)
 {
-outl(0xcf8, (1U << 31) | (de

[Qemu-devel] [PATCH v3 2/6] pci: introduce pci_host_config_enabled()

2014-12-10 Thread Hu Tao
This makes code more readable.

Signed-off-by: Hu Tao 
Reviewed-by: Marcel Apfelbaum 
---
 hw/mips/gt64xxx_pci.c | 4 ++--
 hw/pci/pci_host.c | 5 +++--
 include/hw/pci/pci_host.h | 5 +
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index 1f2fe5f..f118c9c 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -564,7 +564,7 @@ static void gt64120_writel (void *opaque, hwaddr addr,
 if (!(s->regs[GT_PCI0_CMD] & 1) && (phb->config_reg & 0x00fff800)) {
 val = bswap32(val);
 }
-if (phb->config_reg & (1u << 31)) {
+if (pci_host_config_enabled(phb)) {
 pci_data_write(phb->bus, phb->config_reg, val, 4);
 }
 break;
@@ -804,7 +804,7 @@ static uint64_t gt64120_readl (void *opaque,
 val = phb->config_reg;
 break;
 case GT_PCI0_CFGDATA:
-if (!(phb->config_reg & (1 << 31))) {
+if (!pci_host_config_enabled(phb)) {
 val = 0x;
 } else {
 val = pci_data_read(phb->bus, phb->config_reg, 4);
diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index 3e26f92..9bc47d8 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -133,8 +133,9 @@ static void pci_host_data_write(void *opaque, hwaddr addr,
 PCIHostState *s = opaque;
 PCI_DPRINTF("write addr " TARGET_FMT_plx " len %d val %x\n",
 addr, len, (unsigned)val);
-if (s->config_reg & (1u << 31))
+if (pci_host_config_enabled(s)) {
 pci_data_write(s->bus, s->config_reg | (addr & 3), val, len);
+}
 }
 
 static uint64_t pci_host_data_read(void *opaque,
@@ -142,7 +143,7 @@ static uint64_t pci_host_data_read(void *opaque,
 {
 PCIHostState *s = opaque;
 uint32_t val;
-if (!(s->config_reg & (1U << 31))) {
+if (!pci_host_config_enabled(s)) {
 return 0x;
 }
 val = pci_data_read(s->bus, s->config_reg | (addr & 3), len);
diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
index ba31595..b48791d 100644
--- a/include/hw/pci/pci_host.h
+++ b/include/hw/pci/pci_host.h
@@ -65,6 +65,11 @@ uint32_t pci_host_config_read_common(PCIDevice *pci_dev, 
uint32_t addr,
 void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len);
 uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len);
 
+static inline bool pci_host_config_enabled(struct PCIHostState *pci_host)
+{
+return pci_host->config_reg & (1U << 31);
+}
+
 extern const MemoryRegionOps pci_host_conf_le_ops;
 extern const MemoryRegionOps pci_host_conf_be_ops;
 extern const MemoryRegionOps pci_host_data_le_ops;
-- 
1.9.3




[Qemu-devel] [PATCH v3 4/6] pci: remove the limit parameter of pci_host_config_read_common

2014-12-10 Thread Hu Tao
Since the limit parameter is always set to the size of pci device's
configuration space, and we can determine the size from the type of pci
device.

Signed-off-by: Hu Tao 
---
 hw/pci/pci_host.c | 15 +++
 hw/pci/pcie_host.c|  9 +
 hw/ppc/spapr_pci.c|  3 +--
 include/hw/pci/pci_host.h |  2 +-
 4 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index 9bc47d8..2b11551 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -58,12 +58,20 @@ void pci_host_config_write_common(PCIDevice *pci_dev, 
uint32_t addr,
 }
 
 uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
- uint32_t limit, uint32_t len)
+ uint32_t len)
 {
+uint32_t limit = pci_config_size(pci_dev);
 uint32_t ret;
 
 assert(len <= 4);
-ret = pci_dev->config_read(pci_dev, addr, MIN(len, limit - addr));
+
+if (limit <= addr) {
+/* conventional pci device can be behind pcie-to-pci bridge.
+   256 <= addr < 4K has no effects. */
+ret = ~0x0;
+} else {
+ret = pci_dev->config_read(pci_dev, addr, MIN(len, limit - addr));
+}
 trace_pci_cfg_read(pci_dev->name, PCI_SLOT(pci_dev->devfn),
PCI_FUNC(pci_dev->devfn), addr, ret);
 
@@ -95,8 +103,7 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
 return ~0x0;
 }
 
-val = pci_host_config_read_common(pci_dev, config_addr,
-  PCI_CONFIG_SPACE_SIZE, len);
+val = pci_host_config_read_common(pci_dev, config_addr, len);
 PCI_DPRINTF("%s: %s: addr=%02"PRIx32" val=%08"PRIx32" len=%d\n",
 __func__, pci_dev->name, config_addr, val, len);
 
diff --git a/hw/pci/pcie_host.c b/hw/pci/pcie_host.c
index 3db038f..cf8587b 100644
--- a/hw/pci/pcie_host.c
+++ b/hw/pci/pcie_host.c
@@ -62,19 +62,12 @@ static uint64_t pcie_mmcfg_data_read(void *opaque,
 PCIBus *s = e->pci.bus;
 PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, mmcfg_addr);
 uint32_t addr;
-uint32_t limit;
 
 if (!pci_dev) {
 return ~0x0;
 }
 addr = PCIE_MMCFG_CONFOFFSET(mmcfg_addr);
-limit = pci_config_size(pci_dev);
-if (limit <= addr) {
-/* conventional pci device can be behind pcie-to-pci bridge.
-   256 <= addr < 4K has no effects. */
-return ~0x0;
-}
-return pci_host_config_read_common(pci_dev, addr, limit, len);
+return pci_host_config_read_common(pci_dev, addr, len);
 }
 
 static const MemoryRegionOps pcie_mmcfg_ops = {
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 21b95b3..59c6608 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -105,8 +105,7 @@ static void finish_read_pci_config(sPAPREnvironment *spapr, 
uint64_t buid,
 return;
 }
 
-val = pci_host_config_read_common(pci_dev, addr,
-  pci_config_size(pci_dev), size);
+val = pci_host_config_read_common(pci_dev, addr, size);
 
 rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 rtas_st(rets, 1, val);
diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
index 2bae45a..72a1b8b 100644
--- a/include/hw/pci/pci_host.h
+++ b/include/hw/pci/pci_host.h
@@ -65,7 +65,7 @@ typedef struct PCIHostBridgeClass {
 void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
   uint32_t limit, uint32_t val, uint32_t len);
 uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
- uint32_t limit, uint32_t len);
+ uint32_t len);
 
 void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len);
 uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len);
-- 
1.9.3




[Qemu-devel] [PATCH v3 0/6] Some PCI related cleanup patches

2014-12-10 Thread Hu Tao
Hi,

This is v3 of PCI clenaup series. See each patch for the detail.

Regards,
Hu

changes:

v3:
  - rebase on top of 7fb8da2b886, all 5 patches applied cleanly.
  - new patch: pci: introduce PCI_DEVFN_AUTO

v2:
  - remove patch 3 from v1 which is incorrect.
  - rename defined macros as per Marcel's suggestion
  - place macros in pci_host.h as per Marcel's suggestion
  - new patch 'pci: reorganize QEMU_PCI_CAP_*'

Hu Tao (6):
  pci: reorganize QEMU_PCI_CAP_*
  pci: introduce pci_host_config_enabled()
  pci: define PCI_HOST_BRIDGE_CONFIG_ADDR and
PCI_HOST_BRIDGE_CONFIG_DATA.
  pci: remove the limit parameter of pci_host_config_read_common
  pci: remove the limit parameter of pci_host_config_write_common
  pci: introduce PCI_DEVFN_AUTO

 hw/core/qdev-properties.c |  1 +
 hw/mips/gt64xxx_pci.c |  4 ++--
 hw/pci-host/piix.c|  8 
 hw/pci-host/prep.c|  6 --
 hw/pci-host/q35.c |  8 
 hw/pci/pci.c  |  5 ++---
 hw/pci/pci_host.c | 33 -
 hw/pci/pcie_host.c| 18 ++
 hw/ppc/spapr_pci.c|  6 ++
 include/hw/pci-host/q35.h |  3 ---
 include/hw/pci/pci.h  | 41 ++---
 include/hw/pci/pci_host.h | 14 --
 tests/libqos/pci-pc.c | 25 +
 13 files changed, 92 insertions(+), 80 deletions(-)

-- 
1.9.3




[Qemu-devel] [PATCH v3 1/6] pci: reorganize QEMU_PCI_CAP_*

2014-12-10 Thread Hu Tao
This makes code more readable.

Signed-off-by: Hu Tao 
Reviewed-by: Marcel Apfelbaum 
---
 include/hw/pci/pci.h | 39 ---
 1 file changed, 20 insertions(+), 19 deletions(-)

diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index c352c7b..b18759a 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -142,25 +142,26 @@ enum {
 
 /* Bits in cap_present field. */
 enum {
-QEMU_PCI_CAP_MSI = 0x1,
-QEMU_PCI_CAP_MSIX = 0x2,
-QEMU_PCI_CAP_EXPRESS = 0x4,
-
-/* multifunction capable device */
-#define QEMU_PCI_CAP_MULTIFUNCTION_BITNR3
-QEMU_PCI_CAP_MULTIFUNCTION = (1 << QEMU_PCI_CAP_MULTIFUNCTION_BITNR),
-
-/* command register SERR bit enabled */
-#define QEMU_PCI_CAP_SERR_BITNR 4
-QEMU_PCI_CAP_SERR = (1 << QEMU_PCI_CAP_SERR_BITNR),
-/* Standard hot plug controller. */
-#define QEMU_PCI_SHPC_BITNR 5
-QEMU_PCI_CAP_SHPC = (1 << QEMU_PCI_SHPC_BITNR),
-#define QEMU_PCI_SLOTID_BITNR 6
-QEMU_PCI_CAP_SLOTID = (1 << QEMU_PCI_SLOTID_BITNR),
-/* PCI Express capability - Power Controller Present */
-#define QEMU_PCIE_SLTCAP_PCP_BITNR 7
-QEMU_PCIE_SLTCAP_PCP = (1 << QEMU_PCIE_SLTCAP_PCP_BITNR),
+QEMU_PCI_CAP_MSI_BITNR = 0,
+QEMU_PCI_CAP_MSIX_BITNR,
+QEMU_PCI_CAP_EXPRESS_BITNR,
+QEMU_PCI_CAP_MULTIFUNCTION_BITNR, /* multifunction capable device */
+QEMU_PCI_CAP_SERR_BITNR,  /* command register SERR bit enabled */
+QEMU_PCI_SHPC_BITNR,  /* Standard hot plug controller */
+QEMU_PCI_SLOTID_BITNR,
+QEMU_PCIE_SLTCAP_PCP_BITNR, /* PCI Express capability - Power Controller
+   Present */
+};
+
+enum {
+QEMU_PCI_CAP_MSI= (1 << QEMU_PCI_CAP_MSI_BITNR),
+QEMU_PCI_CAP_MSIX   = (1 << QEMU_PCI_CAP_MSIX_BITNR),
+QEMU_PCI_CAP_EXPRESS= (1 << QEMU_PCI_CAP_EXPRESS_BITNR),
+QEMU_PCI_CAP_MULTIFUNCTION  = (1 << QEMU_PCI_CAP_MULTIFUNCTION_BITNR),
+QEMU_PCI_CAP_SERR   = (1 << QEMU_PCI_CAP_SERR_BITNR),
+QEMU_PCI_CAP_SHPC   = (1 << QEMU_PCI_SHPC_BITNR),
+QEMU_PCI_CAP_SLOTID = (1 << QEMU_PCI_SLOTID_BITNR),
+QEMU_PCIE_SLTCAP_PCP= (1 << QEMU_PCIE_SLTCAP_PCP_BITNR),
 };
 
 #define TYPE_PCI_DEVICE "pci-device"
-- 
1.9.3




[Qemu-devel] [PATCH v3 5/6] pci: remove the limit parameter of pci_host_config_write_common

2014-12-10 Thread Hu Tao
Since the limit parameter is always set to the size of pci device's
configuration space, and we can determine the size from the type of pci
device.

Signed-off-by: Hu Tao 
---
 hw/pci/pci_host.c | 13 ++---
 hw/pci/pcie_host.c|  9 +
 hw/ppc/spapr_pci.c|  3 +--
 include/hw/pci/pci_host.h |  2 +-
 4 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index 2b11551..4a59b0e 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -49,8 +49,16 @@ static inline PCIDevice *pci_dev_find_by_addr(PCIBus *bus, 
uint32_t addr)
 }
 
 void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
-  uint32_t limit, uint32_t val, uint32_t len)
+  uint32_t val, uint32_t len)
 {
+uint32_t limit = pci_config_size(pci_dev);
+
+if (limit <= addr) {
+/* conventional pci device can be behind pcie-to-pci bridge.
+   256 <= addr < 4K has no effects. */
+return;
+}
+
 assert(len <= 4);
 trace_pci_cfg_write(pci_dev->name, PCI_SLOT(pci_dev->devfn),
 PCI_FUNC(pci_dev->devfn), addr, val);
@@ -89,8 +97,7 @@ void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, 
int len)
 
 PCI_DPRINTF("%s: %s: addr=%02" PRIx32 " val=%08" PRIx32 " len=%d\n",
 __func__, pci_dev->name, config_addr, val, len);
-pci_host_config_write_common(pci_dev, config_addr, PCI_CONFIG_SPACE_SIZE,
- val, len);
+pci_host_config_write_common(pci_dev, config_addr, val, len);
 }
 
 uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
diff --git a/hw/pci/pcie_host.c b/hw/pci/pcie_host.c
index cf8587b..e3a2a80 100644
--- a/hw/pci/pcie_host.c
+++ b/hw/pci/pcie_host.c
@@ -39,19 +39,12 @@ static void pcie_mmcfg_data_write(void *opaque, hwaddr 
mmcfg_addr,
 PCIBus *s = e->pci.bus;
 PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, mmcfg_addr);
 uint32_t addr;
-uint32_t limit;
 
 if (!pci_dev) {
 return;
 }
 addr = PCIE_MMCFG_CONFOFFSET(mmcfg_addr);
-limit = pci_config_size(pci_dev);
-if (limit <= addr) {
-/* conventional pci device can be behind pcie-to-pci bridge.
-   256 <= addr < 4K has no effects. */
-return;
-}
-pci_host_config_write_common(pci_dev, addr, limit, val, len);
+pci_host_config_write_common(pci_dev, addr, val, len);
 }
 
 static uint64_t pcie_mmcfg_data_read(void *opaque,
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 59c6608..8c566dd 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -171,8 +171,7 @@ static void finish_write_pci_config(sPAPREnvironment 
*spapr, uint64_t buid,
 return;
 }
 
-pci_host_config_write_common(pci_dev, addr, pci_config_size(pci_dev),
- val, size);
+pci_host_config_write_common(pci_dev, addr, val, size);
 
 rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
index 72a1b8b..67e007f 100644
--- a/include/hw/pci/pci_host.h
+++ b/include/hw/pci/pci_host.h
@@ -63,7 +63,7 @@ typedef struct PCIHostBridgeClass {
 
 /* common internal helpers for PCI/PCIe hosts, cut off overflows */
 void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
-  uint32_t limit, uint32_t val, uint32_t len);
+  uint32_t val, uint32_t len);
 uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
  uint32_t len);
 
-- 
1.9.3




Re: [Qemu-devel] [PATCH v2 0/5] Some PCI related cleanup patches

2014-11-05 Thread Hu Tao
On Wed, Nov 05, 2014 at 07:48:10PM +0200, Michael S. Tsirkin wrote:
> On Wed, Nov 05, 2014 at 05:02:41PM +0800, Hu Tao wrote:
> > Hi,
> > 
> > This is v2 of PCI clenaup series. See each patch for the detail.
> 
> Thanks for the patches!
> 
> Pls note this is all not 2.2 material.
> Pls resubmit after 2.2 is out.

Sure.

Regards,
Hu



[Qemu-devel] [RFC PATCH 0/6] pci cleanup: remove pci_config_set_*

2014-11-05 Thread Hu Tao
Hi,

This series removes pci_config_set_*.  The main purpose is for API
consistency. Detailed reasons:

  - pci_config_set_* are not complete. 1) Only part of registers in
predefined header portion of PCI Configuration Space are
supported. 2) Lack of get_ counterparts.

  - pci_set_word() and friends are extensively used in qemu. They
are used both for predefined registers and device specific
registers.

  - another option is to complete the pci_config_set_* for all
predefined registers (though they will co-exist with pci_set_*).
Hence the RFC.

Hu Tao (6):
  pci: remove pci_config_set_vendor_id
  pci: remove pci_config_set_device_id
  pci: remove pci_config_set_revision
  pci: remove pci_config_set_class
  pci: remove pci_config_set_prog_interface
  pci: remove pci_config_set_interrupt_pin

 hw/audio/intel-hda.c   |  2 +-
 hw/block/nvme.c|  4 ++--
 hw/i2c/smbus_ich9.c|  2 +-
 hw/i386/xen/xen_platform.c |  2 +-
 hw/i386/xen/xen_pvdevice.c |  2 +-
 hw/ide/ich.c   |  4 ++--
 hw/ide/via.c   |  2 +-
 hw/isa/i82378.c|  2 +-
 hw/isa/vt82c686.c  |  2 +-
 hw/mips/gt64xxx_pci.c  |  2 +-
 hw/misc/ivshmem.c  |  2 +-
 hw/misc/vfio.c |  2 +-
 hw/pci-bridge/i82801b11.c  |  2 +-
 hw/pci-host/bonito.c   |  2 +-
 hw/pci-host/ppce500.c  |  2 +-
 hw/pci/pci.c   |  8 
 hw/pci/pci_bridge.c|  2 +-
 hw/scsi/vmw_pvscsi.c   |  2 +-
 hw/usb/hcd-uhci.c  |  2 +-
 hw/virtio/virtio-pci.c |  2 +-
 include/hw/pci/pci.h   | 36 
 21 files changed, 25 insertions(+), 61 deletions(-)

-- 
1.9.3




[Qemu-devel] [PATCH 6/6] pci: remove pci_config_set_interrupt_pin

2014-11-05 Thread Hu Tao
See also commit 'pci: remove pci_config_set_vendor_id'.

Signed-off-by: Hu Tao 
---
 hw/audio/intel-hda.c | 2 +-
 hw/i2c/smbus_ich9.c  | 2 +-
 hw/ide/ich.c | 2 +-
 hw/isa/i82378.c  | 2 +-
 hw/misc/ivshmem.c| 2 +-
 hw/misc/vfio.c   | 2 +-
 hw/scsi/vmw_pvscsi.c | 2 +-
 hw/usb/hcd-uhci.c| 2 +-
 include/hw/pci/pci.h | 6 --
 9 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index 2885231..50ff3dd 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -1133,7 +1133,7 @@ static int intel_hda_init(PCIDevice *pci)
 
 d->name = object_get_typename(OBJECT(d));
 
-pci_config_set_interrupt_pin(conf, 1);
+pci_set_byte(conf + PCI_INTERRUPT_PIN, 1);
 
 /* HDCTL off 0x40 bit 0 selects signaling mode (1-HDA, 0 - Ac97) 18.1.19 */
 conf[0x40] = 0x01;
diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c
index 0803dc4..ce14450 100644
--- a/hw/i2c/smbus_ich9.c
+++ b/hw/i2c/smbus_ich9.c
@@ -76,7 +76,7 @@ static int ich9_smbus_initfn(PCIDevice *d)
 ICH9SMBState *s = ICH9_SMB_DEVICE(d);
 
 /* TODO? D31IP.SMIP in chipset configuration space */
-pci_config_set_interrupt_pin(d->config, 0x01); /* interrupt pin 1 */
+pci_set_byte(d->config + PCI_INTERRUPT_PIN, 0x01); /* interrupt pin 1 */
 
 pci_set_byte(d->config + ICH9_SMB_HOSTC, 0);
 /* TODO bar0, bar1: 64bit BAR support*/
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 0263579..0be60f6 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -111,7 +111,7 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
 
 dev->config[PCI_CACHE_LINE_SIZE] = 0x08;  /* Cache line size */
 dev->config[PCI_LATENCY_TIMER]   = 0x00;  /* Latency timer */
-pci_config_set_interrupt_pin(dev->config, 1);
+pci_set_byte(dev->config + PCI_INTERRUPT_PIN, 1);
 
 /* XXX Software should program this register */
 dev->config[0x90]   = 1 << 6; /* Address Map Register - AHCI mode */
diff --git a/hw/isa/i82378.c b/hw/isa/i82378.c
index a7d9aa6..7399121 100644
--- a/hw/isa/i82378.c
+++ b/hw/isa/i82378.c
@@ -73,7 +73,7 @@ static int i82378_initfn(PCIDevice *pci)
 pci_set_word(pci_conf + PCI_STATUS,
  PCI_STATUS_DEVSEL_MEDIUM);
 
-pci_config_set_interrupt_pin(pci_conf, 1); /* interrupt pin 0 */
+pci_set_byte(pci_conf + PCI_INTERRUPT_PIN, 1); /* interrupt pin 0 */
 
 isabus = isa_bus_new(dev, pci_address_space_io(pci));
 
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 5d272c8..06573ea 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -747,7 +747,7 @@ static int pci_ivshmem_init(PCIDevice *dev)
 pci_conf = dev->config;
 pci_conf[PCI_COMMAND] = PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
 
-pci_config_set_interrupt_pin(pci_conf, 1);
+pci_set_byte(pci_conf + PCI_INTERRUPT_PIN, 1);
 
 s->shm_fd = 0;
 
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index fd318a1..151d77e 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -561,7 +561,7 @@ static int vfio_enable_intx(VFIODevice *vdev)
 vfio_disable_interrupts(vdev);
 
 vdev->intx.pin = pin - 1; /* Pin A (1) -> irq[0] */
-pci_config_set_interrupt_pin(vdev->pdev.config, pin);
+pci_set_byte(vdev->pdev.config + PCI_INTERRUPT_PIN, pin);
 
 #ifdef CONFIG_KVM
 /*
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index d3a92fb..6f3a48d 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -1077,7 +1077,7 @@ pvscsi_init(PCIDevice *pci_dev)
 pci_dev->config[PCI_LATENCY_TIMER] = 0xff;
 
 /* Interrupt pin A */
-pci_config_set_interrupt_pin(pci_dev->config, 1);
+pci_set_byte(pci_dev->config + PCI_INTERRUPT_PIN, 1);
 
 memory_region_init_io(&s->io_space, OBJECT(s), &pvscsi_ops, s,
   "pvscsi-io", PVSCSI_MEM_SPACE_SIZE);
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 4a4215d..4e2efd9 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -1202,7 +1202,7 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
 /* TODO: reset value should be 0. */
 pci_conf[USB_SBRN] = USB_RELEASE_1; // release number
 
-pci_config_set_interrupt_pin(pci_conf, u->info.irq_pin + 1);
+pci_set_byte(pci_conf + PCI_INTERRUPT_PIN, u->info.irq_pin + 1);
 
 if (s->masterbus) {
 USBPort *ports[NB_PORTS];
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 1294e23..1da4be7 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -461,12 +461,6 @@ pci_get_quad(const uint8_t *config)
 return le64_to_cpup((const uint64_t *)config);
 }
 
-static inline void
-pci_config_set_interrupt_pin(uint8_t *pci_config, uint8_t val)
-{
-pci_set_byte(&pci_config[PCI_INTERRUPT_PIN], val);
-}
-
 /*
  * helper functions to do bit mask operation on configuration space.
  * Just to set bit, use test-and-set and discard returned value.
-- 
1.9.3




[Qemu-devel] [PATCH 1/6] pci: remove pci_config_set_vendor_id

2014-11-05 Thread Hu Tao
Use pci_set_word() instead. The main purpose is for API
consistency. Detailed reasons:

  - pci_config_set_* are not complete. 1) Only part of registers in
predefined header portion of PCI Configuration Space are
supported. 2) Lack of get_ counterparts.

  - pci_set_word() and friends are extensively used in qemu. They
are used both for predefined registers and device specific
registers.

  - another option is to complete the pci_config_set_* for all
predefined registers (though they will co-exist with pci_set_*).
Hence the RFC.

Signed-off-by: Hu Tao 
---
 hw/pci/pci.c | 2 +-
 include/hw/pci/pci.h | 6 --
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 371699c..6c544ed 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -840,7 +840,7 @@ static PCIDevice *do_pci_register_device(PCIDevice 
*pci_dev, PCIBus *bus,
 pci_dev->irq_state = 0;
 pci_config_alloc(pci_dev);
 
-pci_config_set_vendor_id(pci_dev->config, pc->vendor_id);
+pci_set_word(pci_dev->config + PCI_VENDOR_ID, pc->vendor_id);
 pci_config_set_device_id(pci_dev->config, pc->device_id);
 pci_config_set_revision(pci_dev->config, pc->revision);
 pci_config_set_class(pci_dev->config, pc->class_id);
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index c352c7b..390aa83 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -462,12 +462,6 @@ pci_get_quad(const uint8_t *config)
 }
 
 static inline void
-pci_config_set_vendor_id(uint8_t *pci_config, uint16_t val)
-{
-pci_set_word(&pci_config[PCI_VENDOR_ID], val);
-}
-
-static inline void
 pci_config_set_device_id(uint8_t *pci_config, uint16_t val)
 {
 pci_set_word(&pci_config[PCI_DEVICE_ID], val);
-- 
1.9.3




[Qemu-devel] [PATCH 4/6] pci: remove pci_config_set_class

2014-11-05 Thread Hu Tao
See also commit 'pci: remove pci_config_set_vendor_id'.

Signed-off-by: Hu Tao 
---
 hw/block/nvme.c| 2 +-
 hw/pci-host/ppce500.c  | 2 +-
 hw/pci/pci.c   | 2 +-
 hw/pci/pci_bridge.c| 2 +-
 hw/virtio/virtio-pci.c | 2 +-
 include/hw/pci/pci.h   | 6 --
 6 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index b6263dc..8d7ed78 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -768,7 +768,7 @@ static int nvme_init(PCIDevice *pci_dev)
 pci_conf = pci_dev->config;
 pci_conf[PCI_INTERRUPT_PIN] = 1;
 pci_config_set_prog_interface(pci_dev->config, 0x2);
-pci_config_set_class(pci_dev->config, PCI_CLASS_STORAGE_EXPRESS);
+pci_set_word(pci_dev->config + PCI_CLASS_DEVICE, 
PCI_CLASS_STORAGE_EXPRESS);
 pcie_endpoint_cap_init(&n->parent_obj, 0x80);
 
 n->num_namespaces = 1;
diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
index 1b4c0f0..aa4ed76 100644
--- a/hw/pci-host/ppce500.c
+++ b/hw/pci-host/ppce500.c
@@ -337,7 +337,7 @@ static int e500_pcihost_bridge_initfn(PCIDevice *d)
 PPCE500CCSRState *ccsr = CCSR(container_get(qdev_get_machine(),
   "/e500-ccsr"));
 
-pci_config_set_class(d->config, PCI_CLASS_BRIDGE_PCI);
+pci_set_word(d->config + PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_PCI);
 d->config[PCI_HEADER_TYPE] =
 (d->config[PCI_HEADER_TYPE] & PCI_HEADER_TYPE_MULTI_FUNCTION) |
 PCI_HEADER_TYPE_BRIDGE;
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index fdab941..05f8c9e 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -843,7 +843,7 @@ static PCIDevice *do_pci_register_device(PCIDevice 
*pci_dev, PCIBus *bus,
 pci_set_word(pci_dev->config + PCI_VENDOR_ID, pc->vendor_id);
 pci_set_word(pci_dev->config + PCI_DEVICE_ID, pc->device_id);
 pci_set_byte(pci_dev->config + PCI_REVISION_ID, pc->revision);
-pci_config_set_class(pci_dev->config, pc->class_id);
+pci_set_word(pci_dev->config + PCI_CLASS_DEVICE, pc->class_id);
 
 if (!pc->is_bridge) {
 if (pc->subsystem_vendor_id || pc->subsystem_id) {
diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
index 40c97b1..04a5c10 100644
--- a/hw/pci/pci_bridge.c
+++ b/hw/pci/pci_bridge.c
@@ -350,7 +350,7 @@ int pci_bridge_initfn(PCIDevice *dev, const char *typename)
  *PCI_COMMAND_VGA_PALETTE);
  */
 
-pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_PCI);
+pci_set_word(dev->config + PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_PCI);
 dev->config[PCI_HEADER_TYPE] =
 (dev->config[PCI_HEADER_TYPE] & PCI_HEADER_TYPE_MULTI_FUNCTION) |
 PCI_HEADER_TYPE_BRIDGE;
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index dde1d73..c1bf96c 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -965,7 +965,7 @@ static void virtio_pci_device_plugged(DeviceState *d)
 
 config = proxy->pci_dev.config;
 if (proxy->class_code) {
-pci_config_set_class(config, proxy->class_code);
+pci_set_word(config + PCI_CLASS_DEVICE, proxy->class_code);
 }
 pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
  pci_get_word(config + PCI_VENDOR_ID));
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 5106b44..eb9a2c3 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -462,12 +462,6 @@ pci_get_quad(const uint8_t *config)
 }
 
 static inline void
-pci_config_set_class(uint8_t *pci_config, uint16_t val)
-{
-pci_set_word(&pci_config[PCI_CLASS_DEVICE], val);
-}
-
-static inline void
 pci_config_set_prog_interface(uint8_t *pci_config, uint8_t val)
 {
 pci_set_byte(&pci_config[PCI_CLASS_PROG], val);
-- 
1.9.3




[Qemu-devel] [PATCH 5/6] pci: remove pci_config_set_prog_interface

2014-11-05 Thread Hu Tao
See also commit 'pci: remove pci_config_set_vendor_id'.

Signed-off-by: Hu Tao 
---
 hw/block/nvme.c| 2 +-
 hw/i386/xen/xen_platform.c | 2 +-
 hw/i386/xen/xen_pvdevice.c | 2 +-
 hw/ide/ich.c   | 2 +-
 hw/ide/via.c   | 2 +-
 hw/isa/vt82c686.c  | 2 +-
 hw/mips/gt64xxx_pci.c  | 2 +-
 hw/pci-bridge/i82801b11.c  | 2 +-
 hw/pci-host/bonito.c   | 2 +-
 include/hw/pci/pci.h   | 6 --
 10 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 8d7ed78..d9bc149 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -767,7 +767,7 @@ static int nvme_init(PCIDevice *pci_dev)
 
 pci_conf = pci_dev->config;
 pci_conf[PCI_INTERRUPT_PIN] = 1;
-pci_config_set_prog_interface(pci_dev->config, 0x2);
+pci_set_byte(pci_dev->config + PCI_CLASS_PROG, 0x2);
 pci_set_word(pci_dev->config + PCI_CLASS_DEVICE, 
PCI_CLASS_STORAGE_EXPRESS);
 pcie_endpoint_cap_init(&n->parent_obj, 0x80);
 
diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c
index 28b324a..bcf7038 100644
--- a/hw/i386/xen/xen_platform.c
+++ b/hw/i386/xen/xen_platform.c
@@ -393,7 +393,7 @@ static int xen_platform_initfn(PCIDevice *dev)
 
 pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
 
-pci_config_set_prog_interface(pci_conf, 0);
+pci_set_byte(pci_conf + PCI_CLASS_PROG, 0);
 
 pci_conf[PCI_INTERRUPT_PIN] = 1;
 
diff --git a/hw/i386/xen/xen_pvdevice.c b/hw/i386/xen/xen_pvdevice.c
index c218947..7ebc919 100644
--- a/hw/i386/xen/xen_pvdevice.c
+++ b/hw/i386/xen/xen_pvdevice.c
@@ -88,7 +88,7 @@ static int xen_pv_init(PCIDevice *pci_dev)
 
 pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_MEMORY);
 
-pci_config_set_prog_interface(pci_conf, 0);
+pci_set_byte(pci_conf + PCI_CLASS_PROG, 0);
 
 pci_conf[PCI_INTERRUPT_PIN] = 1;
 
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index fb1d095..0263579 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -107,7 +107,7 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
 
 ahci_init(&d->ahci, DEVICE(dev), pci_get_address_space(dev), 6);
 
-pci_config_set_prog_interface(dev->config, AHCI_PROGMODE_MAJOR_REV_1);
+pci_set_byte(dev->config + PCI_CLASS_PROG, AHCI_PROGMODE_MAJOR_REV_1);
 
 dev->config[PCI_CACHE_LINE_SIZE] = 0x08;  /* Cache line size */
 dev->config[PCI_LATENCY_TIMER]   = 0x00;  /* Latency timer */
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 4d8089d..bd80821 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -177,7 +177,7 @@ static int vt82c686b_ide_initfn(PCIDevice *dev)
 PCIIDEState *d = PCI_IDE(dev);
 uint8_t *pci_conf = dev->config;
 
-pci_config_set_prog_interface(pci_conf, 0x8a); /* legacy ATA mode */
+pci_set_byte(pci_conf + PCI_CLASS_PROG, 0x8a); /* legacy ATA mode */
 pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0);
 
 qemu_register_reset(via_reset, d);
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index e0c235c..773d102 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -435,7 +435,7 @@ static int vt82c686b_initfn(PCIDevice *d)
 isa_bus = isa_bus_new(&d->qdev, pci_address_space_io(d));
 
 pci_conf = d->config;
-pci_config_set_prog_interface(pci_conf, 0x0);
+pci_set_byte(pci_conf + PCI_CLASS_PROG, 0x0);
 
 wmask = d->wmask;
 for (i = 0x00; i < 0xff; i++) {
diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index 1f2fe5f..02488b0 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -1157,7 +1157,7 @@ static int gt64120_pci_init(PCIDevice *d)
 pci_set_word(d->config + PCI_COMMAND, 0);
 pci_set_word(d->config + PCI_STATUS,
  PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM);
-pci_config_set_prog_interface(d->config, 0);
+pci_set_byte(d->config + PCI_CLASS_PROG, 0);
 pci_set_long(d->config + PCI_BASE_ADDRESS_0, 0x0008);
 pci_set_long(d->config + PCI_BASE_ADDRESS_1, 0x0108);
 pci_set_long(d->config + PCI_BASE_ADDRESS_2, 0x1c00);
diff --git a/hw/pci-bridge/i82801b11.c b/hw/pci-bridge/i82801b11.c
index 14cd7fd..79e5445 100644
--- a/hw/pci-bridge/i82801b11.c
+++ b/hw/pci-bridge/i82801b11.c
@@ -71,7 +71,7 @@ static int i82801b11_bridge_initfn(PCIDevice *d)
 if (rc < 0) {
 goto err_bridge;
 }
-pci_config_set_prog_interface(d->config, PCI_CLASS_BRIDGE_PCI_INF_SUB);
+pci_set_byte(d->config + PCI_CLASS_PROG, PCI_CLASS_BRIDGE_PCI_INF_SUB);
 return 0;
 
 err_bridge:
diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 56292ad..061fe8c 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -712,7 +712,7 @@ static int bonito_initfn(PCIDevice *dev)
 PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
 
 /* Bonito North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined" 
*/
-pci_config_set_prog_interface(dev->conf

[Qemu-devel] [PATCH 2/6] pci: remove pci_config_set_device_id

2014-11-05 Thread Hu Tao
See also commit 'pci: remove pci_config_set_vendor_id'.

Signed-off-by: Hu Tao 
---
 hw/pci/pci.c | 2 +-
 include/hw/pci/pci.h | 6 --
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 6c544ed..e5d192d 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -841,7 +841,7 @@ static PCIDevice *do_pci_register_device(PCIDevice 
*pci_dev, PCIBus *bus,
 pci_config_alloc(pci_dev);
 
 pci_set_word(pci_dev->config + PCI_VENDOR_ID, pc->vendor_id);
-pci_config_set_device_id(pci_dev->config, pc->device_id);
+pci_set_word(pci_dev->config + PCI_DEVICE_ID, pc->device_id);
 pci_config_set_revision(pci_dev->config, pc->revision);
 pci_config_set_class(pci_dev->config, pc->class_id);
 
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 390aa83..b659192 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -462,12 +462,6 @@ pci_get_quad(const uint8_t *config)
 }
 
 static inline void
-pci_config_set_device_id(uint8_t *pci_config, uint16_t val)
-{
-pci_set_word(&pci_config[PCI_DEVICE_ID], val);
-}
-
-static inline void
 pci_config_set_revision(uint8_t *pci_config, uint8_t val)
 {
 pci_set_byte(&pci_config[PCI_REVISION_ID], val);
-- 
1.9.3




[Qemu-devel] [PATCH 3/6] pci: remove pci_config_set_revision

2014-11-05 Thread Hu Tao
See also commit 'pci: remove pci_config_set_vendor_id'.

Signed-off-by: Hu Tao 
---
 hw/pci/pci.c | 2 +-
 include/hw/pci/pci.h | 6 --
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index e5d192d..fdab941 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -842,7 +842,7 @@ static PCIDevice *do_pci_register_device(PCIDevice 
*pci_dev, PCIBus *bus,
 
 pci_set_word(pci_dev->config + PCI_VENDOR_ID, pc->vendor_id);
 pci_set_word(pci_dev->config + PCI_DEVICE_ID, pc->device_id);
-pci_config_set_revision(pci_dev->config, pc->revision);
+pci_set_byte(pci_dev->config + PCI_REVISION_ID, pc->revision);
 pci_config_set_class(pci_dev->config, pc->class_id);
 
 if (!pc->is_bridge) {
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index b659192..5106b44 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -462,12 +462,6 @@ pci_get_quad(const uint8_t *config)
 }
 
 static inline void
-pci_config_set_revision(uint8_t *pci_config, uint8_t val)
-{
-pci_set_byte(&pci_config[PCI_REVISION_ID], val);
-}
-
-static inline void
 pci_config_set_class(uint8_t *pci_config, uint16_t val)
 {
 pci_set_word(&pci_config[PCI_CLASS_DEVICE], val);
-- 
1.9.3




[Qemu-devel] [PATCH v2 4/5] pci: remove the limit parameter of pci_host_config_read_common

2014-11-05 Thread Hu Tao
Since the limit parameter is always set to the size of pci device's
configuration space, and we can determine the size from the type of pci
device.

Signed-off-by: Hu Tao 
---
 hw/pci/pci_host.c | 15 +++
 hw/pci/pcie_host.c|  9 +
 hw/ppc/spapr_pci.c|  3 +--
 include/hw/pci/pci_host.h |  2 +-
 4 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index 9bc47d8..2b11551 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -58,12 +58,20 @@ void pci_host_config_write_common(PCIDevice *pci_dev, 
uint32_t addr,
 }
 
 uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
- uint32_t limit, uint32_t len)
+ uint32_t len)
 {
+uint32_t limit = pci_config_size(pci_dev);
 uint32_t ret;
 
 assert(len <= 4);
-ret = pci_dev->config_read(pci_dev, addr, MIN(len, limit - addr));
+
+if (limit <= addr) {
+/* conventional pci device can be behind pcie-to-pci bridge.
+   256 <= addr < 4K has no effects. */
+ret = ~0x0;
+} else {
+ret = pci_dev->config_read(pci_dev, addr, MIN(len, limit - addr));
+}
 trace_pci_cfg_read(pci_dev->name, PCI_SLOT(pci_dev->devfn),
PCI_FUNC(pci_dev->devfn), addr, ret);
 
@@ -95,8 +103,7 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
 return ~0x0;
 }
 
-val = pci_host_config_read_common(pci_dev, config_addr,
-  PCI_CONFIG_SPACE_SIZE, len);
+val = pci_host_config_read_common(pci_dev, config_addr, len);
 PCI_DPRINTF("%s: %s: addr=%02"PRIx32" val=%08"PRIx32" len=%d\n",
 __func__, pci_dev->name, config_addr, val, len);
 
diff --git a/hw/pci/pcie_host.c b/hw/pci/pcie_host.c
index 3db038f..cf8587b 100644
--- a/hw/pci/pcie_host.c
+++ b/hw/pci/pcie_host.c
@@ -62,19 +62,12 @@ static uint64_t pcie_mmcfg_data_read(void *opaque,
 PCIBus *s = e->pci.bus;
 PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, mmcfg_addr);
 uint32_t addr;
-uint32_t limit;
 
 if (!pci_dev) {
 return ~0x0;
 }
 addr = PCIE_MMCFG_CONFOFFSET(mmcfg_addr);
-limit = pci_config_size(pci_dev);
-if (limit <= addr) {
-/* conventional pci device can be behind pcie-to-pci bridge.
-   256 <= addr < 4K has no effects. */
-return ~0x0;
-}
-return pci_host_config_read_common(pci_dev, addr, limit, len);
+return pci_host_config_read_common(pci_dev, addr, len);
 }
 
 static const MemoryRegionOps pcie_mmcfg_ops = {
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index ad0da7f..7f38117 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -105,8 +105,7 @@ static void finish_read_pci_config(sPAPREnvironment *spapr, 
uint64_t buid,
 return;
 }
 
-val = pci_host_config_read_common(pci_dev, addr,
-  pci_config_size(pci_dev), size);
+val = pci_host_config_read_common(pci_dev, addr, size);
 
 rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 rtas_st(rets, 1, val);
diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
index 2bae45a..72a1b8b 100644
--- a/include/hw/pci/pci_host.h
+++ b/include/hw/pci/pci_host.h
@@ -65,7 +65,7 @@ typedef struct PCIHostBridgeClass {
 void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
   uint32_t limit, uint32_t val, uint32_t len);
 uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
- uint32_t limit, uint32_t len);
+ uint32_t len);
 
 void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len);
 uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len);
-- 
1.9.3




[Qemu-devel] [PATCH v2 5/5] pci: remove the limit parameter of pci_host_config_write_common

2014-11-05 Thread Hu Tao
Since the limit parameter is always set to the size of pci device's
configuration space, and we can determine the size from the type of pci
device.

Signed-off-by: Hu Tao 
---
 hw/pci/pci_host.c | 13 ++---
 hw/pci/pcie_host.c|  9 +
 hw/ppc/spapr_pci.c|  3 +--
 include/hw/pci/pci_host.h |  2 +-
 4 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index 2b11551..4a59b0e 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -49,8 +49,16 @@ static inline PCIDevice *pci_dev_find_by_addr(PCIBus *bus, 
uint32_t addr)
 }
 
 void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
-  uint32_t limit, uint32_t val, uint32_t len)
+  uint32_t val, uint32_t len)
 {
+uint32_t limit = pci_config_size(pci_dev);
+
+if (limit <= addr) {
+/* conventional pci device can be behind pcie-to-pci bridge.
+   256 <= addr < 4K has no effects. */
+return;
+}
+
 assert(len <= 4);
 trace_pci_cfg_write(pci_dev->name, PCI_SLOT(pci_dev->devfn),
 PCI_FUNC(pci_dev->devfn), addr, val);
@@ -89,8 +97,7 @@ void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, 
int len)
 
 PCI_DPRINTF("%s: %s: addr=%02" PRIx32 " val=%08" PRIx32 " len=%d\n",
 __func__, pci_dev->name, config_addr, val, len);
-pci_host_config_write_common(pci_dev, config_addr, PCI_CONFIG_SPACE_SIZE,
- val, len);
+pci_host_config_write_common(pci_dev, config_addr, val, len);
 }
 
 uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
diff --git a/hw/pci/pcie_host.c b/hw/pci/pcie_host.c
index cf8587b..e3a2a80 100644
--- a/hw/pci/pcie_host.c
+++ b/hw/pci/pcie_host.c
@@ -39,19 +39,12 @@ static void pcie_mmcfg_data_write(void *opaque, hwaddr 
mmcfg_addr,
 PCIBus *s = e->pci.bus;
 PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, mmcfg_addr);
 uint32_t addr;
-uint32_t limit;
 
 if (!pci_dev) {
 return;
 }
 addr = PCIE_MMCFG_CONFOFFSET(mmcfg_addr);
-limit = pci_config_size(pci_dev);
-if (limit <= addr) {
-/* conventional pci device can be behind pcie-to-pci bridge.
-   256 <= addr < 4K has no effects. */
-return;
-}
-pci_host_config_write_common(pci_dev, addr, limit, val, len);
+pci_host_config_write_common(pci_dev, addr, val, len);
 }
 
 static uint64_t pcie_mmcfg_data_read(void *opaque,
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 7f38117..f306d42 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -171,8 +171,7 @@ static void finish_write_pci_config(sPAPREnvironment 
*spapr, uint64_t buid,
 return;
 }
 
-pci_host_config_write_common(pci_dev, addr, pci_config_size(pci_dev),
- val, size);
+pci_host_config_write_common(pci_dev, addr, val, size);
 
 rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
index 72a1b8b..67e007f 100644
--- a/include/hw/pci/pci_host.h
+++ b/include/hw/pci/pci_host.h
@@ -63,7 +63,7 @@ typedef struct PCIHostBridgeClass {
 
 /* common internal helpers for PCI/PCIe hosts, cut off overflows */
 void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
-  uint32_t limit, uint32_t val, uint32_t len);
+  uint32_t val, uint32_t len);
 uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
  uint32_t len);
 
-- 
1.9.3




[Qemu-devel] [PATCH v2 0/5] Some PCI related cleanup patches

2014-11-05 Thread Hu Tao
Hi,

This is v2 of PCI clenaup series. See each patch for the detail.

changes:
v2:
  - remove patch 3 from v1 which is incorrect.
  - rename defined macros as per Marcel's suggestion
  - place macros in pci_host.h as per Marcel's suggestion
  - new patch 'pci: reorganize QEMU_PCI_CAP_*'

Hu Tao (5):
  pci: reorganize QEMU_PCI_CAP_*
  pci: introduce pci_host_config_enabled()
  pci: define PCI_HOST_BRIDGE_CONFIG_ADDR and
PCI_HOST_BRIDGE_CONFIG_DATA.
  pci: remove the limit parameter of pci_host_config_read_common
  pci: remove the limit parameter of pci_host_config_write_common

 hw/mips/gt64xxx_pci.c |  4 ++--
 hw/pci-host/piix.c|  8 
 hw/pci-host/prep.c|  6 --
 hw/pci-host/q35.c |  8 
 hw/pci/pci_host.c | 33 -
 hw/pci/pcie_host.c| 18 ++
 hw/ppc/spapr_pci.c|  6 ++
 include/hw/pci-host/q35.h |  3 ---
 include/hw/pci/pci.h  | 39 ---
 include/hw/pci/pci_host.h | 14 --
 tests/libqos/pci-pc.c | 25 +
 11 files changed, 87 insertions(+), 77 deletions(-)

-- 
1.9.3




[Qemu-devel] [PATCH v2 3/5] pci: define PCI_HOST_BRIDGE_CONFIG_ADDR and PCI_HOST_BRIDGE_CONFIG_DATA.

2014-11-05 Thread Hu Tao
PCI_HOST_BRIDGE_CONFIG_ADDR and PCI_HOST_BRIDGE_CONFIG_DATA are
defined in PCI specification, so move them to common place.

Signed-off-by: Hu Tao 
---
 hw/pci-host/piix.c|  8 
 hw/pci-host/prep.c|  6 --
 hw/pci-host/q35.c |  8 
 include/hw/pci-host/q35.h |  3 ---
 include/hw/pci/pci_host.h |  5 +
 tests/libqos/pci-pc.c | 25 +
 6 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 1530038..76f3757 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -288,11 +288,11 @@ static void i440fx_pcihost_realize(DeviceState *dev, 
Error **errp)
 PCIHostState *s = PCI_HOST_BRIDGE(dev);
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
-sysbus_add_io(sbd, 0xcf8, &s->conf_mem);
-sysbus_init_ioports(sbd, 0xcf8, 4);
+sysbus_add_io(sbd, PCI_HOST_BRIDGE_CONFIG_ADDR, &s->conf_mem);
+sysbus_init_ioports(sbd, PCI_HOST_BRIDGE_CONFIG_ADDR, 4);
 
-sysbus_add_io(sbd, 0xcfc, &s->data_mem);
-sysbus_init_ioports(sbd, 0xcfc, 4);
+sysbus_add_io(sbd, PCI_HOST_BRIDGE_CONFIG_DATA, &s->data_mem);
+sysbus_init_ioports(sbd, PCI_HOST_BRIDGE_CONFIG_DATA, 4);
 }
 
 static int i440fx_initfn(PCIDevice *dev)
diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index 1de3681..2ae21ad 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -228,11 +228,13 @@ static void raven_pcihost_realizefn(DeviceState *d, Error 
**errp)
 
 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, s,
   "pci-conf-idx", 4);
-memory_region_add_subregion(&s->pci_io, 0xcf8, &h->conf_mem);
+memory_region_add_subregion(&s->pci_io, PCI_HOST_BRIDGE_CONFIG_ADDR,
+&h->conf_mem);
 
 memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops, s,
   "pci-conf-data", 4);
-memory_region_add_subregion(&s->pci_io, 0xcfc, &h->data_mem);
+memory_region_add_subregion(&s->pci_io, PCI_HOST_BRIDGE_CONFIG_DATA,
+&h->data_mem);
 
 memory_region_init_io(&h->mmcfg, OBJECT(s), &raven_pci_io_ops, s,
   "pciio", 0x0040);
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index b20bad8..666afea 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -41,11 +41,11 @@ static void q35_host_realize(DeviceState *dev, Error **errp)
 Q35PCIHost *s = Q35_HOST_DEVICE(dev);
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
-sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_ADDR, &pci->conf_mem);
-sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_ADDR, 4);
+sysbus_add_io(sbd, PCI_HOST_BRIDGE_CONFIG_ADDR, &pci->conf_mem);
+sysbus_init_ioports(sbd, PCI_HOST_BRIDGE_CONFIG_ADDR, 4);
 
-sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, &pci->data_mem);
-sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, 4);
+sysbus_add_io(sbd, PCI_HOST_BRIDGE_CONFIG_DATA, &pci->data_mem);
+sysbus_init_ioports(sbd, PCI_HOST_BRIDGE_CONFIG_DATA, 4);
 
 pci->bus = pci_bus_new(DEVICE(s), "pcie.0",
s->mch.pci_address_space, s->mch.address_space_io,
diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
index 025d6e6..3a026b0 100644
--- a/include/hw/pci-host/q35.h
+++ b/include/hw/pci-host/q35.h
@@ -82,9 +82,6 @@ typedef struct Q35PCIHost {
 /* PCI configuration */
 #define MCH_HOST_BRIDGE"MCH"
 
-#define MCH_HOST_BRIDGE_CONFIG_ADDR0xcf8
-#define MCH_HOST_BRIDGE_CONFIG_DATA0xcfc
-
 /* D0:F0 configuration space */
 #define MCH_HOST_BRIDGE_REVISION_DEFAULT   0x0
 
diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
index b48791d..2bae45a 100644
--- a/include/hw/pci/pci_host.h
+++ b/include/hw/pci/pci_host.h
@@ -30,6 +30,11 @@
 
 #include "hw/sysbus.h"
 
+/* PCI configuration */
+
+#define PCI_HOST_BRIDGE_CONFIG_ADDR  0xcf8
+#define PCI_HOST_BRIDGE_CONFIG_DATA  0xcfc
+
 #define TYPE_PCI_HOST_BRIDGE "pci-host-bridge"
 #define PCI_HOST_BRIDGE(obj) \
 OBJECT_CHECK(PCIHostState, (obj), TYPE_PCI_HOST_BRIDGE)
diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c
index 6dba0db..e4c3c11 100644
--- a/tests/libqos/pci-pc.c
+++ b/tests/libqos/pci-pc.c
@@ -14,6 +14,7 @@
 #include "libqos/pci-pc.h"
 
 #include "hw/pci/pci_regs.h"
+#include "hw/pci/pci_host.h"
 
 #include "qemu-common.h"
 #include "qemu/host-utils.h"
@@ -113,38 +114,38 @@ static void qpci_pc_io_writel(QPCIBus *bus, void *addr, 
uint32_t value)
 
 static uint8_t qpci_pc_config_readb(QPCIBus *bus, int devfn, uint8_t offset)
 {
-outl(0xcf8, (1U << 31) | (devfn << 8) | offset)

[Qemu-devel] [PATCH v2 1/5] pci: reorganize QEMU_PCI_CAP_*

2014-11-05 Thread Hu Tao
This makes code more readable.

Signed-off-by: Hu Tao 
---
 include/hw/pci/pci.h | 39 ---
 1 file changed, 20 insertions(+), 19 deletions(-)

diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index c352c7b..b18759a 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -142,25 +142,26 @@ enum {
 
 /* Bits in cap_present field. */
 enum {
-QEMU_PCI_CAP_MSI = 0x1,
-QEMU_PCI_CAP_MSIX = 0x2,
-QEMU_PCI_CAP_EXPRESS = 0x4,
-
-/* multifunction capable device */
-#define QEMU_PCI_CAP_MULTIFUNCTION_BITNR3
-QEMU_PCI_CAP_MULTIFUNCTION = (1 << QEMU_PCI_CAP_MULTIFUNCTION_BITNR),
-
-/* command register SERR bit enabled */
-#define QEMU_PCI_CAP_SERR_BITNR 4
-QEMU_PCI_CAP_SERR = (1 << QEMU_PCI_CAP_SERR_BITNR),
-/* Standard hot plug controller. */
-#define QEMU_PCI_SHPC_BITNR 5
-QEMU_PCI_CAP_SHPC = (1 << QEMU_PCI_SHPC_BITNR),
-#define QEMU_PCI_SLOTID_BITNR 6
-QEMU_PCI_CAP_SLOTID = (1 << QEMU_PCI_SLOTID_BITNR),
-/* PCI Express capability - Power Controller Present */
-#define QEMU_PCIE_SLTCAP_PCP_BITNR 7
-QEMU_PCIE_SLTCAP_PCP = (1 << QEMU_PCIE_SLTCAP_PCP_BITNR),
+QEMU_PCI_CAP_MSI_BITNR = 0,
+QEMU_PCI_CAP_MSIX_BITNR,
+QEMU_PCI_CAP_EXPRESS_BITNR,
+QEMU_PCI_CAP_MULTIFUNCTION_BITNR, /* multifunction capable device */
+QEMU_PCI_CAP_SERR_BITNR,  /* command register SERR bit enabled */
+QEMU_PCI_SHPC_BITNR,  /* Standard hot plug controller */
+QEMU_PCI_SLOTID_BITNR,
+QEMU_PCIE_SLTCAP_PCP_BITNR, /* PCI Express capability - Power Controller
+   Present */
+};
+
+enum {
+QEMU_PCI_CAP_MSI= (1 << QEMU_PCI_CAP_MSI_BITNR),
+QEMU_PCI_CAP_MSIX   = (1 << QEMU_PCI_CAP_MSIX_BITNR),
+QEMU_PCI_CAP_EXPRESS= (1 << QEMU_PCI_CAP_EXPRESS_BITNR),
+QEMU_PCI_CAP_MULTIFUNCTION  = (1 << QEMU_PCI_CAP_MULTIFUNCTION_BITNR),
+QEMU_PCI_CAP_SERR   = (1 << QEMU_PCI_CAP_SERR_BITNR),
+QEMU_PCI_CAP_SHPC   = (1 << QEMU_PCI_SHPC_BITNR),
+QEMU_PCI_CAP_SLOTID = (1 << QEMU_PCI_SLOTID_BITNR),
+QEMU_PCIE_SLTCAP_PCP= (1 << QEMU_PCIE_SLTCAP_PCP_BITNR),
 };
 
 #define TYPE_PCI_DEVICE "pci-device"
-- 
1.9.3




[Qemu-devel] [PATCH v2 2/5] pci: introduce pci_host_config_enabled()

2014-11-05 Thread Hu Tao
This makes code more readable.

Signed-off-by: Hu Tao 
---
 hw/mips/gt64xxx_pci.c | 4 ++--
 hw/pci/pci_host.c | 5 +++--
 include/hw/pci/pci_host.h | 5 +
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index 1f2fe5f..f118c9c 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -564,7 +564,7 @@ static void gt64120_writel (void *opaque, hwaddr addr,
 if (!(s->regs[GT_PCI0_CMD] & 1) && (phb->config_reg & 0x00fff800)) {
 val = bswap32(val);
 }
-if (phb->config_reg & (1u << 31)) {
+if (pci_host_config_enabled(phb)) {
 pci_data_write(phb->bus, phb->config_reg, val, 4);
 }
 break;
@@ -804,7 +804,7 @@ static uint64_t gt64120_readl (void *opaque,
 val = phb->config_reg;
 break;
 case GT_PCI0_CFGDATA:
-if (!(phb->config_reg & (1 << 31))) {
+if (!pci_host_config_enabled(phb)) {
 val = 0x;
 } else {
 val = pci_data_read(phb->bus, phb->config_reg, 4);
diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index 3e26f92..9bc47d8 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -133,8 +133,9 @@ static void pci_host_data_write(void *opaque, hwaddr addr,
 PCIHostState *s = opaque;
 PCI_DPRINTF("write addr " TARGET_FMT_plx " len %d val %x\n",
 addr, len, (unsigned)val);
-if (s->config_reg & (1u << 31))
+if (pci_host_config_enabled(s)) {
 pci_data_write(s->bus, s->config_reg | (addr & 3), val, len);
+}
 }
 
 static uint64_t pci_host_data_read(void *opaque,
@@ -142,7 +143,7 @@ static uint64_t pci_host_data_read(void *opaque,
 {
 PCIHostState *s = opaque;
 uint32_t val;
-if (!(s->config_reg & (1U << 31))) {
+if (!pci_host_config_enabled(s)) {
 return 0x;
 }
 val = pci_data_read(s->bus, s->config_reg | (addr & 3), len);
diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
index ba31595..b48791d 100644
--- a/include/hw/pci/pci_host.h
+++ b/include/hw/pci/pci_host.h
@@ -65,6 +65,11 @@ uint32_t pci_host_config_read_common(PCIDevice *pci_dev, 
uint32_t addr,
 void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len);
 uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len);
 
+static inline bool pci_host_config_enabled(struct PCIHostState *pci_host)
+{
+return pci_host->config_reg & (1U << 31);
+}
+
 extern const MemoryRegionOps pci_host_conf_le_ops;
 extern const MemoryRegionOps pci_host_conf_be_ops;
 extern const MemoryRegionOps pci_host_data_le_ops;
-- 
1.9.3




Re: [Qemu-devel] [PATCH 2/5] pc: define PC_PCI_CONFIG_ADDR and PC_PCI_CONFIG_DATA

2014-11-05 Thread Hu Tao
On Tue, Nov 04, 2014 at 03:44:35PM +0200, Marcel Apfelbaum wrote:
> On Tue, 2014-11-04 at 17:12 +0800, Hu Tao wrote:
> > PC_PCI_CONFIG_ADDR and PC_PCI_CONFIG_DATA are defined in PCI
> > specification, so move them to common place.
> > 
> > Signed-off-by: Hu Tao 
> > ---
> >  hw/pci-host/piix.c|  8 
> >  hw/pci-host/q35.c |  8 
> >  include/hw/pci-host/q35.h |  3 ---
> >  include/hw/pci/pci.h  |  5 +
> >  tests/libqos/pci-pc.c | 24 
> >  5 files changed, 25 insertions(+), 23 deletions(-)
> > 
> > diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
> > index 1530038..eb92bde 100644
> > --- a/hw/pci-host/piix.c
> > +++ b/hw/pci-host/piix.c
> > @@ -288,11 +288,11 @@ static void i440fx_pcihost_realize(DeviceState *dev, 
> > Error **errp)
> >  PCIHostState *s = PCI_HOST_BRIDGE(dev);
> >  SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
> >  
> > -sysbus_add_io(sbd, 0xcf8, &s->conf_mem);
> > -sysbus_init_ioports(sbd, 0xcf8, 4);
> > +sysbus_add_io(sbd, PC_PCI_CONFIG_ADDR, &s->conf_mem);
> > +sysbus_init_ioports(sbd, PC_PCI_CONFIG_ADDR, 4);
> >  
> > -sysbus_add_io(sbd, 0xcfc, &s->data_mem);
> > -sysbus_init_ioports(sbd, 0xcfc, 4);
> > +sysbus_add_io(sbd, PC_PCI_CONFIG_DATA, &s->data_mem);
> > +sysbus_init_ioports(sbd, PC_PCI_CONFIG_DATA, 4);
> >  }
> >  
> >  static int i440fx_initfn(PCIDevice *dev)
> > diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
> > index b20bad8..9e66835 100644
> > --- a/hw/pci-host/q35.c
> > +++ b/hw/pci-host/q35.c
> > @@ -41,11 +41,11 @@ static void q35_host_realize(DeviceState *dev, Error 
> > **errp)
> >  Q35PCIHost *s = Q35_HOST_DEVICE(dev);
> >  SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
> >  
> > -sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_ADDR, &pci->conf_mem);
> > -sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_ADDR, 4);
> > +sysbus_add_io(sbd, PC_PCI_CONFIG_ADDR, &pci->conf_mem);
> > +sysbus_init_ioports(sbd, PC_PCI_CONFIG_ADDR, 4);
> >  
> > -sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, &pci->data_mem);
> > -sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, 4);
> > +sysbus_add_io(sbd, PC_PCI_CONFIG_DATA, &pci->data_mem);
> > +sysbus_init_ioports(sbd, PC_PCI_CONFIG_DATA, 4);
> >  
> >  pci->bus = pci_bus_new(DEVICE(s), "pcie.0",
> > s->mch.pci_address_space, 
> > s->mch.address_space_io,
> > diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
> > index 025d6e6..3a026b0 100644
> > --- a/include/hw/pci-host/q35.h
> > +++ b/include/hw/pci-host/q35.h
> > @@ -82,9 +82,6 @@ typedef struct Q35PCIHost {
> >  /* PCI configuration */
> >  #define MCH_HOST_BRIDGE"MCH"
> >  
> > -#define MCH_HOST_BRIDGE_CONFIG_ADDR0xcf8
> > -#define MCH_HOST_BRIDGE_CONFIG_DATA0xcfc
> > -
> >  /* D0:F0 configuration space */
> >  #define MCH_HOST_BRIDGE_REVISION_DEFAULT   0x0
> >  
> > diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
> > index 3d42d7f..e42589a 100644
> > --- a/include/hw/pci/pci.h
> > +++ b/include/hw/pci/pci.h
> > @@ -13,6 +13,11 @@
> >  
> >  #include "hw/pci/pcie.h"
> >  
> > +/* PCI configuration */
> > +
> > +#define PC_PCI_CONFIG_ADDR  0xcf8
> > +#define PC_PCI_CONFIG_DATA  0xcfc
> I would move the macros also to hw/pci/pci_host.h,
> and only personal opinion, change them to
> PCI_HOST_BRIDGE_...

Done.

Regards,
Hu



Re: [Qemu-devel] [PATCH 1/5] pci: introduce PC_PCI_CONFIG_ENABLED()

2014-11-05 Thread Hu Tao
On Tue, Nov 04, 2014 at 03:41:11PM +0200, Marcel Apfelbaum wrote:
> Hi,
> 
> On Tue, 2014-11-04 at 17:12 +0800, Hu Tao wrote:
> > This makes code more readable.
> > 
> > Signed-off-by: Hu Tao 
> > ---
> >  hw/mips/gt64xxx_pci.c | 4 ++--
> >  hw/pci/pci_host.c | 5 +++--
> >  include/hw/pci/pci.h  | 2 ++
> >  3 files changed, 7 insertions(+), 4 deletions(-)
> > 
> > diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
> > index 1f2fe5f..a49dbd7 100644
> > --- a/hw/mips/gt64xxx_pci.c
> > +++ b/hw/mips/gt64xxx_pci.c
> > @@ -564,7 +564,7 @@ static void gt64120_writel (void *opaque, hwaddr addr,
> >  if (!(s->regs[GT_PCI0_CMD] & 1) && (phb->config_reg & 0x00fff800)) 
> > {
> >  val = bswap32(val);
> >  }
> > -if (phb->config_reg & (1u << 31)) {
> > +if (PC_PCI_CONFIG_ENABLED(phb->config_reg)) 
> I really like readable MACROS instead of magic numbers,
> however I have 3 suggestions:
> 1. PC_PCI_CONFIG_ENABLED is still not really clear, because
> of the "PC" prefix that is too wide in my IMHO (maybe 
> PCI_HOST_BRIDGE_CONFIG_ENABLED)
> when this macro refers only to host bridges.  
> 2. Maybe go the "extra mile" and let the macro receive
> a host bridge as parameter PCI_HOST_BRIDGE_CONFIG_ENABLED(host_bridge).

Sounds reasonable. I changed it to an inline function and prefixed it
with pci_host_ to follow the convention in pci_host.c.

> 3. Maybe make it an inline function? Just wondering
>  
> >  pci_data_write(phb->bus, phb->config_reg, val, 4);
> >  }
> >  break;
> > @@ -804,7 +804,7 @@ static uint64_t gt64120_readl (void *opaque,
> >  val = phb->config_reg;
> >  break;
> >  case GT_PCI0_CFGDATA:
> > -if (!(phb->config_reg & (1 << 31))) {
> > +if (!PC_PCI_CONFIG_ENABLED(phb->config_reg)) {
> >  val = 0x;
> >  } else {
> >  val = pci_data_read(phb->bus, phb->config_reg, 4);
> > diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
> > index 3e26f92..f2a69ea 100644
> > --- a/hw/pci/pci_host.c
> > +++ b/hw/pci/pci_host.c
> > @@ -133,8 +133,9 @@ static void pci_host_data_write(void *opaque, hwaddr 
> > addr,
> >  PCIHostState *s = opaque;
> >  PCI_DPRINTF("write addr " TARGET_FMT_plx " len %d val %x\n",
> >  addr, len, (unsigned)val);
> > -if (s->config_reg & (1u << 31))
> > +if (PC_PCI_CONFIG_ENABLED(s->config_reg)) {
> >  pci_data_write(s->bus, s->config_reg | (addr & 3), val, len);
> > +}
> >  }
> >  
> >  static uint64_t pci_host_data_read(void *opaque,
> > @@ -142,7 +143,7 @@ static uint64_t pci_host_data_read(void *opaque,
> >  {
> >  PCIHostState *s = opaque;
> >  uint32_t val;
> > -if (!(s->config_reg & (1U << 31))) {
> > +if (!PC_PCI_CONFIG_ENABLED(s->config_reg)) {
> >  return 0x;
> >  }
> >  val = pci_data_read(s->bus, s->config_reg | (addr & 3), len);
> > diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
> > index c352c7b..3d42d7f 100644
> > --- a/include/hw/pci/pci.h
> > +++ b/include/hw/pci/pci.h
> > @@ -13,6 +13,8 @@
> >  
> >  #include "hw/pci/pcie.h"
> >  
> > +#define PC_PCI_CONFIG_ENABLED(addr) (addr & (1U << 31))
> Again, maybe move this to "hw/pci/pci_host" since is specific to host bridges?

Done.

Thanks!

> 
> Thanks,
> Marcel
> > +
> >  /* PCI bus */
> >  
> >  #define PCI_DEVFN(slot, func)   slot) & 0x1f) << 3) | ((func) & 0x07))
> 
> 
> 



Re: [Qemu-devel] [RESEND PATCH v4 09/10] acpi: Add hardware implementation for memory hot unplug.

2014-11-04 Thread Hu Tao
On Wed, Nov 05, 2014 at 01:49:54PM +0800, Tang Chen wrote:

<...>

> -  2-7: reserved, OSPM must clear them before writing to register
> +  2: set by hardware after it has emitted devive eject event for

s/devive/device/

Regards,
Hu



Re: [Qemu-devel] [PATCH 3/5] pci: move initialization of pci's conf_addr and conf_data to common place

2014-11-04 Thread Hu Tao
On Tue, Nov 04, 2014 at 04:21:41PM +0200, Marcel Apfelbaum wrote:
> On Tue, 2014-11-04 at 17:12 +0800, Hu Tao wrote:
> > So that standard pci host device can share them.
> > 
> > Signed-off-by: Hu Tao 
> > ---
> >  hw/pci-host/piix.c | 20 
> >  hw/pci-host/q35.c  |  7 ---
> >  hw/pci/pci_host.c  | 32 
> >  3 files changed, 32 insertions(+), 27 deletions(-)
> > 
> > diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
> > index eb92bde..683465c 100644
> > --- a/hw/pci-host/piix.c
> > +++ b/hw/pci-host/piix.c
> > @@ -256,14 +256,8 @@ static void i440fx_pcihost_get_pci_hole64_end(Object 
> > *obj, Visitor *v,
> >  
> >  static void i440fx_pcihost_initfn(Object *obj)
> >  {
> > -PCIHostState *s = PCI_HOST_BRIDGE(obj);
> >  I440FXState *d = I440FX_PCI_HOST_BRIDGE(obj);
> >  
> > -memory_region_init_io(&s->conf_mem, obj, &pci_host_conf_le_ops, s,
> > -  "pci-conf-idx", 4);
> > -memory_region_init_io(&s->data_mem, obj, &pci_host_data_le_ops, s,
> > -  "pci-conf-data", 4);
> > -
> >  object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "int",
> >  i440fx_pcihost_get_pci_hole_start,
> >  NULL, NULL, NULL, NULL);
> > @@ -283,18 +277,6 @@ static void i440fx_pcihost_initfn(Object *obj)
> >  d->pci_info.w32.end = IO_APIC_DEFAULT_ADDRESS;
> >  }
> >  
> > -static void i440fx_pcihost_realize(DeviceState *dev, Error **errp)
> > -{
> > -PCIHostState *s = PCI_HOST_BRIDGE(dev);
> > -SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
> > -
> > -sysbus_add_io(sbd, PC_PCI_CONFIG_ADDR, &s->conf_mem);
> > -sysbus_init_ioports(sbd, PC_PCI_CONFIG_ADDR, 4);
> > -
> > -sysbus_add_io(sbd, PC_PCI_CONFIG_DATA, &s->data_mem);
> > -sysbus_init_ioports(sbd, PC_PCI_CONFIG_DATA, 4);
> > -}
> > -
> >  static int i440fx_initfn(PCIDevice *dev)
> >  {
> >  PCII440FXState *d = I440FX_PCI_DEVICE(dev);
> > @@ -755,8 +737,6 @@ static void i440fx_pcihost_class_init(ObjectClass 
> > *klass, void *data)
> >  PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
> >  
> >  hc->root_bus_path = i440fx_pcihost_root_bus_path;
> > -dc->realize = i440fx_pcihost_realize;
> > -dc->fw_name = "pci";
> >  dc->props = i440fx_props;
> >  }
> >  
> > diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
> > index 9e66835..81eddd7 100644
> > --- a/hw/pci-host/q35.c
> > +++ b/hw/pci-host/q35.c
> > @@ -138,18 +138,11 @@ static void q35_host_class_init(ObjectClass *klass, 
> > void *data)
> >  dc->realize = q35_host_realize;
> >  dc->props = mch_props;
> >  set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
> > -dc->fw_name = "pci";
> >  }
> >  
> >  static void q35_host_initfn(Object *obj)
> >  {
> >  Q35PCIHost *s = Q35_HOST_DEVICE(obj);
> > -PCIHostState *phb = PCI_HOST_BRIDGE(obj);
> > -
> > -memory_region_init_io(&phb->conf_mem, obj, &pci_host_conf_le_ops, phb,
> > -  "pci-conf-idx", 4);
> > -memory_region_init_io(&phb->data_mem, obj, &pci_host_data_le_ops, phb,
> > -  "pci-conf-data", 4);
> >  
> >  object_initialize(&s->mch, sizeof(s->mch), TYPE_MCH_PCI_DEVICE);
> >  object_property_add_child(OBJECT(s), "mch", OBJECT(&s->mch), NULL);
> > diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
> > index f2a69ea..406c747 100644
> > --- a/hw/pci/pci_host.c
> > +++ b/hw/pci/pci_host.c
> > @@ -176,12 +176,44 @@ const MemoryRegionOps pci_host_data_be_ops = {
> >  .endianness = DEVICE_BIG_ENDIAN,
> >  };
> >  
> > +static void pci_host_initfn(Object *obj)
> > +{
> > +PCIHostState *phb = PCI_HOST_BRIDGE(obj);
> > +
> > +memory_region_init_io(&phb->conf_mem, obj, &pci_host_conf_le_ops, phb,
> > +  "pci-conf-idx", 4);
> > +memory_region_init_io(&phb->data_mem, obj, &pci_host_data_le_ops, phb,
> > +  "pci-conf-data", 4);
> > +}
> > +
> > +static void pci_host_realize(DeviceState *dev, Error **errp)
> > +{
> > +PCIHostState *s = PCI_HOST_BRIDGE(dev);
> > +   

[Qemu-devel] [PATCH 2/5] pc: define PC_PCI_CONFIG_ADDR and PC_PCI_CONFIG_DATA

2014-11-04 Thread Hu Tao
PC_PCI_CONFIG_ADDR and PC_PCI_CONFIG_DATA are defined in PCI
specification, so move them to common place.

Signed-off-by: Hu Tao 
---
 hw/pci-host/piix.c|  8 
 hw/pci-host/q35.c |  8 
 include/hw/pci-host/q35.h |  3 ---
 include/hw/pci/pci.h  |  5 +
 tests/libqos/pci-pc.c | 24 
 5 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 1530038..eb92bde 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -288,11 +288,11 @@ static void i440fx_pcihost_realize(DeviceState *dev, 
Error **errp)
 PCIHostState *s = PCI_HOST_BRIDGE(dev);
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
-sysbus_add_io(sbd, 0xcf8, &s->conf_mem);
-sysbus_init_ioports(sbd, 0xcf8, 4);
+sysbus_add_io(sbd, PC_PCI_CONFIG_ADDR, &s->conf_mem);
+sysbus_init_ioports(sbd, PC_PCI_CONFIG_ADDR, 4);
 
-sysbus_add_io(sbd, 0xcfc, &s->data_mem);
-sysbus_init_ioports(sbd, 0xcfc, 4);
+sysbus_add_io(sbd, PC_PCI_CONFIG_DATA, &s->data_mem);
+sysbus_init_ioports(sbd, PC_PCI_CONFIG_DATA, 4);
 }
 
 static int i440fx_initfn(PCIDevice *dev)
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index b20bad8..9e66835 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -41,11 +41,11 @@ static void q35_host_realize(DeviceState *dev, Error **errp)
 Q35PCIHost *s = Q35_HOST_DEVICE(dev);
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
-sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_ADDR, &pci->conf_mem);
-sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_ADDR, 4);
+sysbus_add_io(sbd, PC_PCI_CONFIG_ADDR, &pci->conf_mem);
+sysbus_init_ioports(sbd, PC_PCI_CONFIG_ADDR, 4);
 
-sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, &pci->data_mem);
-sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, 4);
+sysbus_add_io(sbd, PC_PCI_CONFIG_DATA, &pci->data_mem);
+sysbus_init_ioports(sbd, PC_PCI_CONFIG_DATA, 4);
 
 pci->bus = pci_bus_new(DEVICE(s), "pcie.0",
s->mch.pci_address_space, s->mch.address_space_io,
diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
index 025d6e6..3a026b0 100644
--- a/include/hw/pci-host/q35.h
+++ b/include/hw/pci-host/q35.h
@@ -82,9 +82,6 @@ typedef struct Q35PCIHost {
 /* PCI configuration */
 #define MCH_HOST_BRIDGE"MCH"
 
-#define MCH_HOST_BRIDGE_CONFIG_ADDR0xcf8
-#define MCH_HOST_BRIDGE_CONFIG_DATA0xcfc
-
 /* D0:F0 configuration space */
 #define MCH_HOST_BRIDGE_REVISION_DEFAULT   0x0
 
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 3d42d7f..e42589a 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -13,6 +13,11 @@
 
 #include "hw/pci/pcie.h"
 
+/* PCI configuration */
+
+#define PC_PCI_CONFIG_ADDR  0xcf8
+#define PC_PCI_CONFIG_DATA  0xcfc
+
 #define PC_PCI_CONFIG_ENABLED(addr) (addr & (1U << 31))
 
 /* PCI bus */
diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c
index 6dba0db..2762608 100644
--- a/tests/libqos/pci-pc.c
+++ b/tests/libqos/pci-pc.c
@@ -113,38 +113,38 @@ static void qpci_pc_io_writel(QPCIBus *bus, void *addr, 
uint32_t value)
 
 static uint8_t qpci_pc_config_readb(QPCIBus *bus, int devfn, uint8_t offset)
 {
-outl(0xcf8, (1U << 31) | (devfn << 8) | offset);
-return inb(0xcfc);
+outl(PC_PCI_CONFIG_ADDR, (1U << 31) | (devfn << 8) | offset);
+return inb(PC_PCI_CONFIG_DATA);
 }
 
 static uint16_t qpci_pc_config_readw(QPCIBus *bus, int devfn, uint8_t offset)
 {
-outl(0xcf8, (1U << 31) | (devfn << 8) | offset);
-return inw(0xcfc);
+outl(PC_PCI_CONFIG_ADDR, (1U << 31) | (devfn << 8) | offset);
+return inw(PC_PCI_CONFIG_DATA);
 }
 
 static uint32_t qpci_pc_config_readl(QPCIBus *bus, int devfn, uint8_t offset)
 {
-outl(0xcf8, (1U << 31) | (devfn << 8) | offset);
-return inl(0xcfc);
+outl(PC_PCI_CONFIG_ADDR, (1U << 31) | (devfn << 8) | offset);
+return inl(PC_PCI_CONFIG_DATA);
 }
 
 static void qpci_pc_config_writeb(QPCIBus *bus, int devfn, uint8_t offset, 
uint8_t value)
 {
-outl(0xcf8, (1U << 31) | (devfn << 8) | offset);
-outb(0xcfc, value);
+outl(PC_PCI_CONFIG_ADDR, (1U << 31) | (devfn << 8) | offset);
+outb(PC_PCI_CONFIG_DATA, value);
 }
 
 static void qpci_pc_config_writew(QPCIBus *bus, int devfn, uint8_t offset, 
uint16_t value)
 {
-outl(0xcf8, (1U << 31) | (devfn << 8) | offset);
-outw(0xcfc, value);
+outl(PC_PCI_CONFIG_ADDR, (1U << 31) | (devfn << 8) | offset);
+outw(PC_PCI_CONFIG_DATA, value);
 }
 
 static void qpci_pc_config_writel(QPCIBus *bus, int devfn, uint8_t offset, 
uint32_t value)
 {
-outl(0xcf8, (1U << 31) | (devfn << 8) | offset);
-outl(0xcfc, value);
+outl(PC_PCI_CONFIG_ADDR, (1U << 31) | (devfn << 8) | offset);
+outl(PC_PCI_CONFIG_DATA, value);
 }
 
 static void *qpci_pc_iomap(QPCIBus *bus, QPCIDevice *dev, int barno, uint64_t 
*sizeptr)
-- 
1.9.3




[Qemu-devel] [PATCH 0/5] Some PCI related cleanup patches

2014-11-04 Thread Hu Tao
Hi,

This series includes 5 PCI clenaup patches. See each patch for the
detail.

Hu Tao (5):
  pci: introduce PC_PCI_CONFIG_ENABLED()
  pc: define PC_PCI_CONFIG_ADDR and PC_PCI_CONFIG_DATA
  pci: move initialization of pci's conf_addr and conf_data to common
place
  pci: remove the limit parameter of pci_host_config_read_common
  pci: remove the limit parameter of pci_host_config_write_common

 hw/mips/gt64xxx_pci.c |  4 +--
 hw/pci-host/piix.c| 20 ---
 hw/pci-host/q35.c | 15 +++
 hw/pci/pci_host.c | 65 ---
 hw/pci/pcie_host.c| 18 ++---
 hw/ppc/spapr_pci.c|  6 ++---
 include/hw/pci-host/q35.h |  3 ---
 include/hw/pci/pci.h  |  7 +
 include/hw/pci/pci_host.h |  4 +--
 tests/libqos/pci-pc.c | 24 -
 10 files changed, 87 insertions(+), 79 deletions(-)

-- 
1.9.3




[Qemu-devel] [PATCH 1/5] pci: introduce PC_PCI_CONFIG_ENABLED()

2014-11-04 Thread Hu Tao
This makes code more readable.

Signed-off-by: Hu Tao 
---
 hw/mips/gt64xxx_pci.c | 4 ++--
 hw/pci/pci_host.c | 5 +++--
 include/hw/pci/pci.h  | 2 ++
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index 1f2fe5f..a49dbd7 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -564,7 +564,7 @@ static void gt64120_writel (void *opaque, hwaddr addr,
 if (!(s->regs[GT_PCI0_CMD] & 1) && (phb->config_reg & 0x00fff800)) {
 val = bswap32(val);
 }
-if (phb->config_reg & (1u << 31)) {
+if (PC_PCI_CONFIG_ENABLED(phb->config_reg)) {
 pci_data_write(phb->bus, phb->config_reg, val, 4);
 }
 break;
@@ -804,7 +804,7 @@ static uint64_t gt64120_readl (void *opaque,
 val = phb->config_reg;
 break;
 case GT_PCI0_CFGDATA:
-if (!(phb->config_reg & (1 << 31))) {
+if (!PC_PCI_CONFIG_ENABLED(phb->config_reg)) {
 val = 0x;
 } else {
 val = pci_data_read(phb->bus, phb->config_reg, 4);
diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index 3e26f92..f2a69ea 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -133,8 +133,9 @@ static void pci_host_data_write(void *opaque, hwaddr addr,
 PCIHostState *s = opaque;
 PCI_DPRINTF("write addr " TARGET_FMT_plx " len %d val %x\n",
 addr, len, (unsigned)val);
-if (s->config_reg & (1u << 31))
+if (PC_PCI_CONFIG_ENABLED(s->config_reg)) {
 pci_data_write(s->bus, s->config_reg | (addr & 3), val, len);
+}
 }
 
 static uint64_t pci_host_data_read(void *opaque,
@@ -142,7 +143,7 @@ static uint64_t pci_host_data_read(void *opaque,
 {
 PCIHostState *s = opaque;
 uint32_t val;
-if (!(s->config_reg & (1U << 31))) {
+if (!PC_PCI_CONFIG_ENABLED(s->config_reg)) {
 return 0x;
 }
 val = pci_data_read(s->bus, s->config_reg | (addr & 3), len);
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index c352c7b..3d42d7f 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -13,6 +13,8 @@
 
 #include "hw/pci/pcie.h"
 
+#define PC_PCI_CONFIG_ENABLED(addr) (addr & (1U << 31))
+
 /* PCI bus */
 
 #define PCI_DEVFN(slot, func)   slot) & 0x1f) << 3) | ((func) & 0x07))
-- 
1.9.3




[Qemu-devel] [PATCH 4/5] pci: remove the limit parameter of pci_host_config_read_common

2014-11-04 Thread Hu Tao
Since the limit parameter is always set to the size of pci device's
configuration space, and we can determine the size from the type of pci
device.

Signed-off-by: Hu Tao 
---
 hw/pci/pci_host.c | 15 +++
 hw/pci/pcie_host.c|  9 +
 hw/ppc/spapr_pci.c|  3 +--
 include/hw/pci/pci_host.h |  2 +-
 4 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index 406c747..937660c 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -58,12 +58,20 @@ void pci_host_config_write_common(PCIDevice *pci_dev, 
uint32_t addr,
 }
 
 uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
- uint32_t limit, uint32_t len)
+ uint32_t len)
 {
+uint32_t limit = pci_config_size(pci_dev);
 uint32_t ret;
 
 assert(len <= 4);
-ret = pci_dev->config_read(pci_dev, addr, MIN(len, limit - addr));
+
+if (limit <= addr) {
+/* conventional pci device can be behind pcie-to-pci bridge.
+   256 <= addr < 4K has no effects. */
+ret = ~0x0;
+} else {
+ret = pci_dev->config_read(pci_dev, addr, MIN(len, limit - addr));
+}
 trace_pci_cfg_read(pci_dev->name, PCI_SLOT(pci_dev->devfn),
PCI_FUNC(pci_dev->devfn), addr, ret);
 
@@ -95,8 +103,7 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
 return ~0x0;
 }
 
-val = pci_host_config_read_common(pci_dev, config_addr,
-  PCI_CONFIG_SPACE_SIZE, len);
+val = pci_host_config_read_common(pci_dev, config_addr, len);
 PCI_DPRINTF("%s: %s: addr=%02"PRIx32" val=%08"PRIx32" len=%d\n",
 __func__, pci_dev->name, config_addr, val, len);
 
diff --git a/hw/pci/pcie_host.c b/hw/pci/pcie_host.c
index 3db038f..cf8587b 100644
--- a/hw/pci/pcie_host.c
+++ b/hw/pci/pcie_host.c
@@ -62,19 +62,12 @@ static uint64_t pcie_mmcfg_data_read(void *opaque,
 PCIBus *s = e->pci.bus;
 PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, mmcfg_addr);
 uint32_t addr;
-uint32_t limit;
 
 if (!pci_dev) {
 return ~0x0;
 }
 addr = PCIE_MMCFG_CONFOFFSET(mmcfg_addr);
-limit = pci_config_size(pci_dev);
-if (limit <= addr) {
-/* conventional pci device can be behind pcie-to-pci bridge.
-   256 <= addr < 4K has no effects. */
-return ~0x0;
-}
-return pci_host_config_read_common(pci_dev, addr, limit, len);
+return pci_host_config_read_common(pci_dev, addr, len);
 }
 
 static const MemoryRegionOps pcie_mmcfg_ops = {
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index ad0da7f..7f38117 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -105,8 +105,7 @@ static void finish_read_pci_config(sPAPREnvironment *spapr, 
uint64_t buid,
 return;
 }
 
-val = pci_host_config_read_common(pci_dev, addr,
-  pci_config_size(pci_dev), size);
+val = pci_host_config_read_common(pci_dev, addr, size);
 
 rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 rtas_st(rets, 1, val);
diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
index ba31595..4a79945 100644
--- a/include/hw/pci/pci_host.h
+++ b/include/hw/pci/pci_host.h
@@ -60,7 +60,7 @@ typedef struct PCIHostBridgeClass {
 void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
   uint32_t limit, uint32_t val, uint32_t len);
 uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
- uint32_t limit, uint32_t len);
+ uint32_t len);
 
 void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len);
 uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len);
-- 
1.9.3




[Qemu-devel] [PATCH 5/5] pci: remove the limit parameter of pci_host_config_write_common

2014-11-04 Thread Hu Tao
Since the limit parameter is always set to the size of pci device's
configuration space, and we can determine the size from the type of pci
device.

Signed-off-by: Hu Tao 
---
 hw/pci/pci_host.c | 13 ++---
 hw/pci/pcie_host.c|  9 +
 hw/ppc/spapr_pci.c|  3 +--
 include/hw/pci/pci_host.h |  2 +-
 4 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index 937660c..f525fe5 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -49,8 +49,16 @@ static inline PCIDevice *pci_dev_find_by_addr(PCIBus *bus, 
uint32_t addr)
 }
 
 void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
-  uint32_t limit, uint32_t val, uint32_t len)
+  uint32_t val, uint32_t len)
 {
+uint32_t limit = pci_config_size(pci_dev);
+
+if (limit <= addr) {
+/* conventional pci device can be behind pcie-to-pci bridge.
+   256 <= addr < 4K has no effects. */
+return;
+}
+
 assert(len <= 4);
 trace_pci_cfg_write(pci_dev->name, PCI_SLOT(pci_dev->devfn),
 PCI_FUNC(pci_dev->devfn), addr, val);
@@ -89,8 +97,7 @@ void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, 
int len)
 
 PCI_DPRINTF("%s: %s: addr=%02" PRIx32 " val=%08" PRIx32 " len=%d\n",
 __func__, pci_dev->name, config_addr, val, len);
-pci_host_config_write_common(pci_dev, config_addr, PCI_CONFIG_SPACE_SIZE,
- val, len);
+pci_host_config_write_common(pci_dev, config_addr, val, len);
 }
 
 uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
diff --git a/hw/pci/pcie_host.c b/hw/pci/pcie_host.c
index cf8587b..e3a2a80 100644
--- a/hw/pci/pcie_host.c
+++ b/hw/pci/pcie_host.c
@@ -39,19 +39,12 @@ static void pcie_mmcfg_data_write(void *opaque, hwaddr 
mmcfg_addr,
 PCIBus *s = e->pci.bus;
 PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, mmcfg_addr);
 uint32_t addr;
-uint32_t limit;
 
 if (!pci_dev) {
 return;
 }
 addr = PCIE_MMCFG_CONFOFFSET(mmcfg_addr);
-limit = pci_config_size(pci_dev);
-if (limit <= addr) {
-/* conventional pci device can be behind pcie-to-pci bridge.
-   256 <= addr < 4K has no effects. */
-return;
-}
-pci_host_config_write_common(pci_dev, addr, limit, val, len);
+pci_host_config_write_common(pci_dev, addr, val, len);
 }
 
 static uint64_t pcie_mmcfg_data_read(void *opaque,
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 7f38117..f306d42 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -171,8 +171,7 @@ static void finish_write_pci_config(sPAPREnvironment 
*spapr, uint64_t buid,
 return;
 }
 
-pci_host_config_write_common(pci_dev, addr, pci_config_size(pci_dev),
- val, size);
+pci_host_config_write_common(pci_dev, addr, val, size);
 
 rtas_st(rets, 0, RTAS_OUT_SUCCESS);
 }
diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h
index 4a79945..9364f08 100644
--- a/include/hw/pci/pci_host.h
+++ b/include/hw/pci/pci_host.h
@@ -58,7 +58,7 @@ typedef struct PCIHostBridgeClass {
 
 /* common internal helpers for PCI/PCIe hosts, cut off overflows */
 void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
-  uint32_t limit, uint32_t val, uint32_t len);
+  uint32_t val, uint32_t len);
 uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
  uint32_t len);
 
-- 
1.9.3




[Qemu-devel] [PATCH 3/5] pci: move initialization of pci's conf_addr and conf_data to common place

2014-11-04 Thread Hu Tao
So that standard pci host device can share them.

Signed-off-by: Hu Tao 
---
 hw/pci-host/piix.c | 20 
 hw/pci-host/q35.c  |  7 ---
 hw/pci/pci_host.c  | 32 
 3 files changed, 32 insertions(+), 27 deletions(-)

diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index eb92bde..683465c 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -256,14 +256,8 @@ static void i440fx_pcihost_get_pci_hole64_end(Object *obj, 
Visitor *v,
 
 static void i440fx_pcihost_initfn(Object *obj)
 {
-PCIHostState *s = PCI_HOST_BRIDGE(obj);
 I440FXState *d = I440FX_PCI_HOST_BRIDGE(obj);
 
-memory_region_init_io(&s->conf_mem, obj, &pci_host_conf_le_ops, s,
-  "pci-conf-idx", 4);
-memory_region_init_io(&s->data_mem, obj, &pci_host_data_le_ops, s,
-  "pci-conf-data", 4);
-
 object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "int",
 i440fx_pcihost_get_pci_hole_start,
 NULL, NULL, NULL, NULL);
@@ -283,18 +277,6 @@ static void i440fx_pcihost_initfn(Object *obj)
 d->pci_info.w32.end = IO_APIC_DEFAULT_ADDRESS;
 }
 
-static void i440fx_pcihost_realize(DeviceState *dev, Error **errp)
-{
-PCIHostState *s = PCI_HOST_BRIDGE(dev);
-SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
-
-sysbus_add_io(sbd, PC_PCI_CONFIG_ADDR, &s->conf_mem);
-sysbus_init_ioports(sbd, PC_PCI_CONFIG_ADDR, 4);
-
-sysbus_add_io(sbd, PC_PCI_CONFIG_DATA, &s->data_mem);
-sysbus_init_ioports(sbd, PC_PCI_CONFIG_DATA, 4);
-}
-
 static int i440fx_initfn(PCIDevice *dev)
 {
 PCII440FXState *d = I440FX_PCI_DEVICE(dev);
@@ -755,8 +737,6 @@ static void i440fx_pcihost_class_init(ObjectClass *klass, 
void *data)
 PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
 
 hc->root_bus_path = i440fx_pcihost_root_bus_path;
-dc->realize = i440fx_pcihost_realize;
-dc->fw_name = "pci";
 dc->props = i440fx_props;
 }
 
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 9e66835..81eddd7 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -138,18 +138,11 @@ static void q35_host_class_init(ObjectClass *klass, void 
*data)
 dc->realize = q35_host_realize;
 dc->props = mch_props;
 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
-dc->fw_name = "pci";
 }
 
 static void q35_host_initfn(Object *obj)
 {
 Q35PCIHost *s = Q35_HOST_DEVICE(obj);
-PCIHostState *phb = PCI_HOST_BRIDGE(obj);
-
-memory_region_init_io(&phb->conf_mem, obj, &pci_host_conf_le_ops, phb,
-  "pci-conf-idx", 4);
-memory_region_init_io(&phb->data_mem, obj, &pci_host_data_le_ops, phb,
-  "pci-conf-data", 4);
 
 object_initialize(&s->mch, sizeof(s->mch), TYPE_MCH_PCI_DEVICE);
 object_property_add_child(OBJECT(s), "mch", OBJECT(&s->mch), NULL);
diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index f2a69ea..406c747 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -176,12 +176,44 @@ const MemoryRegionOps pci_host_data_be_ops = {
 .endianness = DEVICE_BIG_ENDIAN,
 };
 
+static void pci_host_initfn(Object *obj)
+{
+PCIHostState *phb = PCI_HOST_BRIDGE(obj);
+
+memory_region_init_io(&phb->conf_mem, obj, &pci_host_conf_le_ops, phb,
+  "pci-conf-idx", 4);
+memory_region_init_io(&phb->data_mem, obj, &pci_host_data_le_ops, phb,
+  "pci-conf-data", 4);
+}
+
+static void pci_host_realize(DeviceState *dev, Error **errp)
+{
+PCIHostState *s = PCI_HOST_BRIDGE(dev);
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+sysbus_add_io(sbd, PC_PCI_CONFIG_ADDR, &s->conf_mem);
+sysbus_init_ioports(sbd, PC_PCI_CONFIG_ADDR, 4);
+
+sysbus_add_io(sbd, PC_PCI_CONFIG_DATA, &s->data_mem);
+sysbus_init_ioports(sbd, PC_PCI_CONFIG_DATA, 4);
+}
+
+static void pci_host_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->realize = pci_host_realize;
+dc->fw_name = "pci";
+}
+
 static const TypeInfo pci_host_type_info = {
 .name = TYPE_PCI_HOST_BRIDGE,
 .parent = TYPE_SYS_BUS_DEVICE,
 .abstract = true,
 .class_size = sizeof(PCIHostBridgeClass),
+.class_init = pci_host_class_init,
 .instance_size = sizeof(PCIHostState),
+.instance_init = pci_host_initfn,
 };
 
 static void pci_host_register_types(void)
-- 
1.9.3




[Qemu-devel] [PATCH] exec: don't exit if failed to preallocate memory for memory-backend-file

2014-09-26 Thread Hu Tao
When using monitor command object_add to add a memory backend file
but failed to preallocate memory for it, qemu exits silently. So a
unexpected user input, e.g. a too large size of memory-backend-file
can crash the guest.

This is the case of -mem-prealloc, not memory-backend-file,prealloc=y.

The problem can be reproduced as follows:

1. run qemu with -mem-prealloc:

  ./x86_64-softmmu/qemu-system-x86_64 -hda f18.img \
  -m 512 -mem-prealloc -qmp unix:/tmp/m,server,nowait \
  -monitor stdio -enable-kvm

2. add a memory-backend-file object from qemu monitor whose size is
   larger than host memory(assume host has 4G memory total):

   (qemu)object_add memory-backend-file,size=4G,mem-path=/hugepages,id=mem-file0

Without this patch, qemu quits with message:

  unable to map backing store for hugepages: Cannot allocate memory

With this patch, qemu gives the same message, but continues running.

Signed-off-by: Hu Tao 
---
 exec.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/exec.c b/exec.c
index 759055d..eed5da2 100644
--- a/exec.c
+++ b/exec.c
@@ -1163,9 +1163,9 @@ static void *file_ram_alloc(RAMBlock *block,
 return area;
 
 error:
-if (mem_prealloc) {
+if (area && area != MAP_FAILED) {
 error_report("%s\n", error_get_pretty(*errp));
-exit(1);
+munmap(area, memory);
 }
 return NULL;
 }
-- 
1.9.3




Re: [Qemu-devel] [PATCH] vl: Adjust the place of calling mlockall to speedup VM's startup

2014-09-23 Thread Hu Tao
On Tue, Sep 23, 2014 at 11:30:26AM +0300, Michael S. Tsirkin wrote:
> On Tue, Sep 23, 2014 at 03:57:47PM +0800, zhanghailiang wrote:
> > If we configure mlock=on and memory policy=bind at the same time,
> > It will consume lots of time for system to treat with memory,
> > especially when call mbind after mlockall.
> > 
> > Adjust the place of calling mlockall, calling mbind before mlockall
> > can remarkably reduce the time of VM's startup.
> > 
> > Signed-off-by: zhanghailiang 
> 
> The idea makes absolute sense to me:
> bind after lock will force data copy of
> all pages. bind before lock gives us an
> indication where to put data on fault in.

Agreed.

> 
> Acked-by: Michael S. Tsirkin 
> 
> 
> > ---
> > Hi,
> > 
> > Actually, for mbind and mlockall, i have made a test about the time 
> > consuming 
> > for the different call sequence. 
> > 
> > The results is shown below. It is obviously that mlockall called before 
> > mbind is 
> > more time-consuming.
> > 
> > Besides, this patch is OK with memory hotplug.
> > 
> > TEST CODE:
> > if (mbind_first) {
> > printf("mbind --> mlockall\n");
> > mbind(ptr, ram_size/2, MPOL_BIND, &node0mask, 2,
> >   MPOL_MF_STRICT | MPOL_MF_MOVE);
> > mbind(ptr + ram_size/2, ram_size/2, MPOL_BIND, &node1mask, 2,
> >   MPOL_MF_STRICT | MPOL_MF_MOVE);
> > mlockall(MCL_CURRENT | MCL_FUTURE);
> > } else {
> > printf("mlockall --> mbind\n");
> > mlockall(MCL_CURRENT | MCL_FUTURE);
> > mbind(ptr, ram_size/2, MPOL_BIND, &node0mask, 2 ,
> >   MPOL_MF_STRICT | MPOL_MF_MOVE);
> > mbind(ptr + ram_size/2, ram_size/2, MPOL_BIND, &node1mask, 2,
> >   MPOL_MF_STRICT | MPOL_MF_MOVE);
> > }
> > 
> > RESULT 1:
> > #time /home/test_mbind 10240 0
> > memroy size 10737418240
> > mlockall --> mbind
> > 
> > real0m11.886s
> > user0m0.004s
> > sys 0m11.865s
> > #time /home/test_mbind 10240 1
> > memroy size 10737418240
> > mbind --> mlockall
> > 
> > real0m5.334s
> > user0m0.000s
> > sys 0m5.324s
> > 
> > RESULT 2:
> > #time /home/test_mbind 4096 0
> > memroy size 4294967296
> > mlockall --> mbind
> > 
> > real0m5.503s
> > user0m0.000s
> > sys 0m5.492s
> > #time /home/test_mbind 4096 1
> > memroy size 4294967296
> > mbind --> mlockall
> > 
> > real0m2.139s
> > user0m0.000s
> > sys 0m2.132s
> > 
> > Best Regards,
> > zhanghailiang
> > ---
> >  vl.c | 11 +--
> >  1 file changed, 5 insertions(+), 6 deletions(-)
> > 
> > diff --git a/vl.c b/vl.c
> > index dc792fe..adf4770 100644
> > --- a/vl.c
> > +++ b/vl.c
> > @@ -134,6 +134,7 @@ const char* keyboard_layout = NULL;
> >  ram_addr_t ram_size;
> >  const char *mem_path = NULL;
> >  int mem_prealloc = 0; /* force preallocation of physical target memory */
> > +int enable_mlock = false;

Why not bool?

Regards,
Hu



Re: [Qemu-devel] [PATCH 1/2] pc-dimm: No numa option shouldn't break hotplug memory feature

2014-09-17 Thread Hu Tao
On Wed, Sep 17, 2014 at 02:19:05PM +0400, Andrey Korolyov wrote:
> On Wed, Sep 17, 2014 at 2:00 PM, Tang Chen  wrote:
> > Add Andrey Korolyov 
> >
> > On 09/17/2014 04:32 PM, Hu Tao wrote:
> >>
> >> On Tue, Sep 16, 2014 at 06:39:15PM +0800, zhanghailiang wrote:
> >>>
> >>> If we do not configure numa option, memory hotplug should work as well.
> >>> It should not depend on numa option.
> >>>
> >>> Steps to reproduce:
> >>> (1) Start VM: qemu-kvm -m 1024,slots=4,maxmem=8G
> >>> (2) Hotplug memory
> >>> It will fail and reports:
> >>> "'DIMM property node has value 0' which exceeds the number of numa nodes:
> >>> 0"
> >>>
> >> I rememberd Tang Chen had a patch for this bug, this is what Andrey
> >> suggested:
> >>
> >>I thnk that there should be no
> >>cases when dimm is plugged (and check from patch is fired up) without
> >>actually populated NUMA, because not every OS will workaround this by
> >>faking the node.
> >
> >
> > According to Andrey Korolyov , memory hotplug should not
> > work without SRAT. So maybe forcing to create a NUMA node and SRAT will be
> > better idea.
> >
> > I'm have been working on it.
> >
> > Thanks.
> >
> >
> >>
> >> https://lists.nongnu.org/archive/html/qemu-devel/2014-08/msg04587.html
> >>
> >> Have you tested this patch with Windows guest?
> >>
> >> Regards,
> >> Hu
> >>
> >>
> >
> 
> Thanks, is there will be a place to guard against misconfiguration in
> the dimm properties for NUMA too? For example, right now I may specify
> just one node for a topo and assign dimms to more than one node, which
> will pass argument checks and will result in memory allocation errors
> in guest.

Yes, there is, in function pc_dimm_realize().

Regards,
Hu



Re: [Qemu-devel] [PATCH 1/2] pc-dimm: No numa option shouldn't break hotplug memory feature

2014-09-17 Thread Hu Tao
On Tue, Sep 16, 2014 at 06:39:15PM +0800, zhanghailiang wrote:
> If we do not configure numa option, memory hotplug should work as well.
> It should not depend on numa option.
> 
> Steps to reproduce:
> (1) Start VM: qemu-kvm -m 1024,slots=4,maxmem=8G
> (2) Hotplug memory
> It will fail and reports:
> "'DIMM property node has value 0' which exceeds the number of numa nodes: 0"
> 

I rememberd Tang Chen had a patch for this bug, this is what Andrey suggested:

  I thnk that there should be no
  cases when dimm is plugged (and check from patch is fired up) without
  actually populated NUMA, because not every OS will workaround this by
  faking the node.

https://lists.nongnu.org/archive/html/qemu-devel/2014-08/msg04587.html

Have you tested this patch with Windows guest?

Regards,
Hu



Re: [Qemu-devel] [PATCH v15 0/5] qcow2, raw: add preallocation=full and preallocation=falloc

2014-09-16 Thread Hu Tao
On Tue, Sep 16, 2014 at 12:19:58PM +0200, Kevin Wolf wrote:
> Am 16.09.2014 um 12:10 hat Hu Tao geschrieben:
> > ping...
> 
> Sorry, forgot to send the mail when I merged it. This is in master now.

Thank you very much!

Regards,
Hu

> 
> Kevin
> 
> > On Fri, Sep 12, 2014 at 05:22:45PM +0800, Hu Tao wrote:
> > > ping?
> > > 
> > > On Wed, Sep 10, 2014 at 05:05:44PM +0800, Hu Tao wrote:
> > > > This series adds two preallocation mode to qcow2 and raw:
> > > > 
> > > > Option preallocation=full preallocates disk space for image by writing
> > > > zeros to disk, this ensures disk space in any cases.
> > > > 
> > > > Option preallocation=falloc preallocates disk space by calling
> > > > posix_fallocate(). This is faster than preallocation=full.
> > > > 
> > > > Note: there is a false positive reported by checkpatch.pl to patch 1.
> > > > 
> > > > changes to v14:
> > > > 
> > > >   - add detailed commit message to patch 1
> > > >   - change the coding style as Eric and Benoît suggested (patch 3)
> > > >   - use break as Benoît suggested (patch 4)
> > > > 
> > > > changes to v13:
> > > > 
> > > >   - rebase (patch 3 in v13 is already in)
> > > >   - don't convert file size to sector size in hdev_create(), too (patch 
> > > > 2)
> > > >   - reintroduce preallocation=falloc. (patch 3)
> > > >   - split the implementation of preallocation=full in v13 into
> > > > preallocation=falloc and preallocation=full (patch 4)
> > > > 
> > > > changes to v12:
> > > > 
> > > >   - remove dependence on minimal_blob_size() (patch 6)
> > > >   - remove preallocation=falloc. (patch 4)
> > > >   - preallocation=full tries posix_fallocate() first then writing
> > > > zeros (patch 5)
> > > >   - round up file size for all formats (patch 1)
> > > >   - avoid converting file size for more formats (patch 2)
> > > > 
> > > > changes to v11:
> > > > 
> > > >  - fix test case 049 (patch 4)
> > > >  - unsigned nl2e -> uint64_t nl2e (patch 6)
> > > >  - use >> instead of / (patch 6)
> > > > 
> > > > changes to v10:
> > > > 
> > > >   - PreallocMode is moved from file qapi-schema.json to 
> > > > qapi/block-core.json
> > > >   - introdues preallocation=falloc, no changes to preallocation=metadata
> > > >   - using minimal_blob_size() to calculate metadata size for qcow2
> > > >   - indentation fix in file blockdev.c
> > > > 
> > > > changes to v9:
> > > > 
> > > >  - use ROUND_UP to do round up
> > > >  - split the round up into its own patch and add test case
> > > >  - new patch rename parse_enum_option to qapi_enum_parse and make it 
> > > > public
> > > >  - reuse qapi_enum_parse
> > > > 
> > > > changes to v8:
> > > > 
> > > >  - round up image file size to nearest sector size
> > > >  - dont' blindly lose error info
> > > >  - target for 2.1 rather than 2.0
> > > >  - and, rebase to latest git tree
> > > > 
> > > > changes to v5:
> > > > 
> > > >   - add `Since 2.0' to PreallocMode
> > > >   - apply total_size change to raw-win32.c as well
> > > > 
> > > > changes to v4:
> > > > 
> > > >   - fix wrong calculation of qcow2 metadata size in v4
> > > >   - remove raw_preallocate2()
> > > >   - better error out path in raw_create()
> > > >   - fix coding style
> > > > 
> > > > changes to v3:
> > > > 
> > > >   - remove bdrv_preallocate and make preallocation a
> > > > bdrv_create_file option
> > > >   - prealloc_mode -> PreallocMode and add it to QAPI
> > > >   - fix return value in raw_preallocate2
> > > > 
> > > > changes to v2:
> > > > 
> > > >   - Fix comments to v2 by Fam.
> > > >   - qcow2: first fallocate disk space, then allocate metadata. This 
> > > > avoids
> > > > the problem in v2 that bdrv_preallocate may clear all information in
> > > > metadata. This does not necessarily map all data clusters 
> > > > sequentially
> > > > but doe

Re: [Qemu-devel] [PATCH v15 0/5] qcow2, raw: add preallocation=full and preallocation=falloc

2014-09-16 Thread Hu Tao
ping...

On Fri, Sep 12, 2014 at 05:22:45PM +0800, Hu Tao wrote:
> ping?
> 
> On Wed, Sep 10, 2014 at 05:05:44PM +0800, Hu Tao wrote:
> > This series adds two preallocation mode to qcow2 and raw:
> > 
> > Option preallocation=full preallocates disk space for image by writing
> > zeros to disk, this ensures disk space in any cases.
> > 
> > Option preallocation=falloc preallocates disk space by calling
> > posix_fallocate(). This is faster than preallocation=full.
> > 
> > Note: there is a false positive reported by checkpatch.pl to patch 1.
> > 
> > changes to v14:
> > 
> >   - add detailed commit message to patch 1
> >   - change the coding style as Eric and Benoît suggested (patch 3)
> >   - use break as Benoît suggested (patch 4)
> > 
> > changes to v13:
> > 
> >   - rebase (patch 3 in v13 is already in)
> >   - don't convert file size to sector size in hdev_create(), too (patch 2)
> >   - reintroduce preallocation=falloc. (patch 3)
> >   - split the implementation of preallocation=full in v13 into
> > preallocation=falloc and preallocation=full (patch 4)
> > 
> > changes to v12:
> > 
> >   - remove dependence on minimal_blob_size() (patch 6)
> >   - remove preallocation=falloc. (patch 4)
> >   - preallocation=full tries posix_fallocate() first then writing
> > zeros (patch 5)
> >   - round up file size for all formats (patch 1)
> >   - avoid converting file size for more formats (patch 2)
> > 
> > changes to v11:
> > 
> >  - fix test case 049 (patch 4)
> >  - unsigned nl2e -> uint64_t nl2e (patch 6)
> >  - use >> instead of / (patch 6)
> > 
> > changes to v10:
> > 
> >   - PreallocMode is moved from file qapi-schema.json to qapi/block-core.json
> >   - introdues preallocation=falloc, no changes to preallocation=metadata
> >   - using minimal_blob_size() to calculate metadata size for qcow2
> >   - indentation fix in file blockdev.c
> > 
> > changes to v9:
> > 
> >  - use ROUND_UP to do round up
> >  - split the round up into its own patch and add test case
> >  - new patch rename parse_enum_option to qapi_enum_parse and make it public
> >  - reuse qapi_enum_parse
> > 
> > changes to v8:
> > 
> >  - round up image file size to nearest sector size
> >  - dont' blindly lose error info
> >  - target for 2.1 rather than 2.0
> >  - and, rebase to latest git tree
> > 
> > changes to v5:
> > 
> >   - add `Since 2.0' to PreallocMode
> >   - apply total_size change to raw-win32.c as well
> > 
> > changes to v4:
> > 
> >   - fix wrong calculation of qcow2 metadata size in v4
> >   - remove raw_preallocate2()
> >   - better error out path in raw_create()
> >   - fix coding style
> > 
> > changes to v3:
> > 
> >   - remove bdrv_preallocate and make preallocation a
> > bdrv_create_file option
> >   - prealloc_mode -> PreallocMode and add it to QAPI
> >   - fix return value in raw_preallocate2
> > 
> > changes to v2:
> > 
> >   - Fix comments to v2 by Fam.
> >   - qcow2: first fallocate disk space, then allocate metadata. This avoids
> > the problem in v2 that bdrv_preallocate may clear all information in
> > metadata. This does not necessarily map all data clusters sequentially
> > but does keep information in metadata. Peter, is this acceptable?
> > 
> > 
> > Hu Tao (5):
> >   block: round up file size to nearest sector
> >   block: don't convert file size to sector size
> >   qapi: introduce PreallocMode and new PreallocModes full and falloc.
> >   raw-posix: Add falloc and full preallocation option
> >   qcow2: Add falloc and full preallocation option
> > 
> >  block/archipelago.c  |   3 +-
> >  block/cow.c  |   3 +-
> >  block/gluster.c  |   9 ++--
> >  block/iscsi.c|   4 +-
> >  block/nfs.c  |   3 +-
> >  block/qcow.c |   7 +--
> >  block/qcow2.c|  82 +--
> >  block/qed.c  |   3 +-
> >  block/raw-posix.c| 102 
> > ++-
> >  block/raw-win32.c|   6 +--
> >  block/rbd.c  |   3 +-
> >  block/sheepdog.c |   3 +-
> >  block/ssh.c  |   3 +-
> >  block/vdi.c  |   3 +-
> >  block/vhdx.c  

[Qemu-devel] [PATCH v2 2/2] configure: check for pixman-1 version

2014-09-14 Thread Hu Tao
commit a93a3af9 introduces use of PIXMAN_TYPE_RGBA, but it's only available
in pixman >= 0.21.8. If pixman doesn't meet the version requirement, qemu
will fail to build with following message:

qemu/ui/qemu-pixman.c: In function ‘qemu_pixelformat_from_pixman’:
qemu/ui/qemu-pixman.c:42: error: ‘PIXMAN_TYPE_RGBA’ undeclared (first use in 
this function)
qemu/ui/qemu-pixman.c:42: error: (Each undeclared identifier is reported only 
once
qemu/ui/qemu-pixman.c:42: error: for each function it appears in.)

This patch fixes the problem by checking the pixman version.

Signed-off-by: Hu Tao 
---
 configure | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 961bf6f..1a9daa5 100755
--- a/configure
+++ b/configure
@@ -2737,7 +2737,7 @@ fi
 if test "$pixman" = ""; then
   if test "$want_tools" = "no" -a "$softmmu" = "no"; then
 pixman="none"
-  elif $pkg_config pixman-1 > /dev/null 2>&1; then
+  elif $pkg_config --atleast-version=0.21.8 pixman-1 > /dev/null 2>&1; then
 pixman="system"
   else
 pixman="internal"
@@ -2753,11 +2753,12 @@ if test "$pixman" = "none"; then
   pixman_cflags=
   pixman_libs=
 elif test "$pixman" = "system"; then
+  # pixman version has been checked above
   pixman_cflags=`$pkg_config --cflags pixman-1`
   pixman_libs=`$pkg_config --libs pixman-1`
 else
   if test ! -d ${source_path}/pixman/pixman; then
-error_exit "pixman not present. Your options:" \
+error_exit "pixman >= 0.21.8 not present. Your options:" \
 "  (1) Preferred: Install the pixman devel package (any recent" \
 "  distro should have packages as Xorg needs pixman too)." \
 "  (2) Fetch the pixman submodule, using:" \
-- 
1.9.3




[Qemu-devel] [PATCH v2 1/2] pixman: update internal copy to pixman-0.32.6

2014-09-14 Thread Hu Tao
commit a93a3af9 introduces use of PIXMAN_TYPE_RGBA, but it's only available
in pixman >= 0.21.8. Although commit f27b2e1d bumped pixman to pixman-0.28.2,
but the change was reverted later by 7b1b5d19.

This patch updates internal copy of pixman to pixman-0.32.6 to fix the
problem.

Signed-off-by: Hu Tao 
---
 pixman | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pixman b/pixman
index 97336fa..87eea99 16
--- a/pixman
+++ b/pixman
@@ -1 +1 @@
-Subproject commit 97336fad32acf802003855cd8bd6477fa49a12e3
+Subproject commit 87eea99e443b389c978cf37efc52788bf03a0ee0
-- 
1.9.3




[Qemu-devel] [PATCH v2 0/2] fix building failure with pixman

2014-09-14 Thread Hu Tao
commit a93a3af9 introduces use of PIXMAN_TYPE_RGBA, but it's only available
in pixman >= 0.21.8. If pixman doesn't meet the version requirement, qemu
will fail to build with following message:

qemu/ui/qemu-pixman.c: In function ‘qemu_pixelformat_from_pixman’:
qemu/ui/qemu-pixman.c:42: error: ‘PIXMAN_TYPE_RGBA’ undeclared (first use in 
this function)
qemu/ui/qemu-pixman.c:42: error: (Each undeclared identifier is reported only 
once
qemu/ui/qemu-pixman.c:42: error: for each function it appears in.)

This series fixes this problem, also bumps pixman to pixman-0.32.6.

changes to v1:
  - bump pixman to pixman-0.32.6

Hu Tao (2):
  pixman: update internal copy to pixman-0.32.6
  configure: check for pixman-1 version

 configure | 5 +++--
 pixman| 2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)

-- 
1.9.3




Re: [Qemu-devel] [PATCH] configure: check for pixman-1 version

2014-09-14 Thread Hu Tao
CCed Paolo

On Mon, Sep 15, 2014 at 10:41:09AM +0800, Hu Tao wrote:
> On Sun, Sep 14, 2014 at 07:23:20PM -0700, Peter Maydell wrote:
> > On 14 September 2014 18:53, Hu Tao  wrote:
> > > commit a93a3af9 introduces use of PIXMAN_TYPE_RGBA, but it's only 
> > > available
> > > in pixman >= 0.21.8. If pixman doesn't meet the version requirement, qemu
> > > will fail to build with following message:
> > >
> > > /home/hutao/qemu/ui/qemu-pixman.c: In function 
> > > ‘qemu_pixelformat_from_pixman’:
> > > /home/hutao/qemu/ui/qemu-pixman.c:42: error: ‘PIXMAN_TYPE_RGBA’ 
> > > undeclared (first use in this function)
> > > /home/hutao/qemu/ui/qemu-pixman.c:42: error: (Each undeclared identifier 
> > > is reported only once
> > > /home/hutao/qemu/ui/qemu-pixman.c:42: error: for each function it appears 
> > > in.)
> > >
> > > This patch fixes the problem by checking the pixman version.
> > 
> > This alone is not sufficient, because the version of pixman
> > we have in our submodule is only 0.18.4. We also need to
> > bump that if we want to use newer versions (and to note
> > the increased dependency in our release notes next time
> > round).
> 
> Oh. I didn't noticed that. Should we just bump to the latest stable
> pixman? or choose a best version?

commit f27b2e1d bumped to pixman-0.28.2, but reverted later by 7b1b5d19 
(mistakenly?)

Regards,
Hu



Re: [Qemu-devel] [PATCH] configure: check for pixman-1 version

2014-09-14 Thread Hu Tao
On Sun, Sep 14, 2014 at 07:23:20PM -0700, Peter Maydell wrote:
> On 14 September 2014 18:53, Hu Tao  wrote:
> > commit a93a3af9 introduces use of PIXMAN_TYPE_RGBA, but it's only available
> > in pixman >= 0.21.8. If pixman doesn't meet the version requirement, qemu
> > will fail to build with following message:
> >
> > /home/hutao/qemu/ui/qemu-pixman.c: In function 
> > ‘qemu_pixelformat_from_pixman’:
> > /home/hutao/qemu/ui/qemu-pixman.c:42: error: ‘PIXMAN_TYPE_RGBA’ undeclared 
> > (first use in this function)
> > /home/hutao/qemu/ui/qemu-pixman.c:42: error: (Each undeclared identifier is 
> > reported only once
> > /home/hutao/qemu/ui/qemu-pixman.c:42: error: for each function it appears 
> > in.)
> >
> > This patch fixes the problem by checking the pixman version.
> 
> This alone is not sufficient, because the version of pixman
> we have in our submodule is only 0.18.4. We also need to
> bump that if we want to use newer versions (and to note
> the increased dependency in our release notes next time
> round).

Oh. I didn't noticed that. Should we just bump to the latest stable
pixman? or choose a best version?

Regards,
Hu



Re: [Qemu-devel] [Bug 1368791] [NEW] qemu build fails on Ubuntu 10.04 LTS since recent pixman changes

2014-09-14 Thread Hu Tao
On Fri, Sep 12, 2014 at 02:19:44PM +, Andreas Gustafsson wrote:
> Public bug reported:
> 
> Since commit 0dfa7e30126364c434a48cb37a1a41119e536c2a, the qemu git
> mainline no longer builds on Ubuntu 10.04 LTS.  The build fails with:
> 
>   CCui/input.o
> ui/qemu-pixman.c: In function 'qemu_pixelformat_from_pixman':
> ui/qemu-pixman.c:42: error: 'PIXMAN_TYPE_RGBA' undeclared (first use in this 
> function)
> ui/qemu-pixman.c:42: error: (Each undeclared identifier is reported only once
> ui/qemu-pixman.c:42: error: for each function it appears in.)
> make: *** [ui/qemu-pixman.o] Error 1
> 

Hi Andreas,

does this patch fix your problem?
https://lists.nongnu.org/archive/html/qemu-devel/2014-09/msg02880.html

Regards,
Hu



[Qemu-devel] [PATCH] configure: check for pixman-1 version

2014-09-14 Thread Hu Tao
commit a93a3af9 introduces use of PIXMAN_TYPE_RGBA, but it's only available
in pixman >= 0.21.8. If pixman doesn't meet the version requirement, qemu
will fail to build with following message:

/home/hutao/qemu/ui/qemu-pixman.c: In function ‘qemu_pixelformat_from_pixman’:
/home/hutao/qemu/ui/qemu-pixman.c:42: error: ‘PIXMAN_TYPE_RGBA’ undeclared 
(first use in this function)
/home/hutao/qemu/ui/qemu-pixman.c:42: error: (Each undeclared identifier is 
reported only once
/home/hutao/qemu/ui/qemu-pixman.c:42: error: for each function it appears in.)

This patch fixes the problem by checking the pixman version.

Reported-by: Andreas Gustafsson 
Signed-off-by: Hu Tao 
---
 configure | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 961bf6f..1a9daa5 100755
--- a/configure
+++ b/configure
@@ -2737,7 +2737,7 @@ fi
 if test "$pixman" = ""; then
   if test "$want_tools" = "no" -a "$softmmu" = "no"; then
 pixman="none"
-  elif $pkg_config pixman-1 > /dev/null 2>&1; then
+  elif $pkg_config --atleast-version=0.21.8 pixman-1 > /dev/null 2>&1; then
 pixman="system"
   else
 pixman="internal"
@@ -2753,11 +2753,12 @@ if test "$pixman" = "none"; then
   pixman_cflags=
   pixman_libs=
 elif test "$pixman" = "system"; then
+  # pixman version has been checked above
   pixman_cflags=`$pkg_config --cflags pixman-1`
   pixman_libs=`$pkg_config --libs pixman-1`
 else
   if test ! -d ${source_path}/pixman/pixman; then
-error_exit "pixman not present. Your options:" \
+error_exit "pixman >= 0.21.8 not present. Your options:" \
 "  (1) Preferred: Install the pixman devel package (any recent" \
 "  distro should have packages as Xorg needs pixman too)." \
 "  (2) Fetch the pixman submodule, using:" \
-- 
1.8.0




Re: [Qemu-devel] [PATCH v15 0/5] qcow2, raw: add preallocation=full and preallocation=falloc

2014-09-12 Thread Hu Tao
ping?

On Wed, Sep 10, 2014 at 05:05:44PM +0800, Hu Tao wrote:
> This series adds two preallocation mode to qcow2 and raw:
> 
> Option preallocation=full preallocates disk space for image by writing
> zeros to disk, this ensures disk space in any cases.
> 
> Option preallocation=falloc preallocates disk space by calling
> posix_fallocate(). This is faster than preallocation=full.
> 
> Note: there is a false positive reported by checkpatch.pl to patch 1.
> 
> changes to v14:
> 
>   - add detailed commit message to patch 1
>   - change the coding style as Eric and Benoît suggested (patch 3)
>   - use break as Benoît suggested (patch 4)
> 
> changes to v13:
> 
>   - rebase (patch 3 in v13 is already in)
>   - don't convert file size to sector size in hdev_create(), too (patch 2)
>   - reintroduce preallocation=falloc. (patch 3)
>   - split the implementation of preallocation=full in v13 into
> preallocation=falloc and preallocation=full (patch 4)
> 
> changes to v12:
> 
>   - remove dependence on minimal_blob_size() (patch 6)
>   - remove preallocation=falloc. (patch 4)
>   - preallocation=full tries posix_fallocate() first then writing
> zeros (patch 5)
>   - round up file size for all formats (patch 1)
>   - avoid converting file size for more formats (patch 2)
> 
> changes to v11:
> 
>  - fix test case 049 (patch 4)
>  - unsigned nl2e -> uint64_t nl2e (patch 6)
>  - use >> instead of / (patch 6)
> 
> changes to v10:
> 
>   - PreallocMode is moved from file qapi-schema.json to qapi/block-core.json
>   - introdues preallocation=falloc, no changes to preallocation=metadata
>   - using minimal_blob_size() to calculate metadata size for qcow2
>   - indentation fix in file blockdev.c
> 
> changes to v9:
> 
>  - use ROUND_UP to do round up
>  - split the round up into its own patch and add test case
>  - new patch rename parse_enum_option to qapi_enum_parse and make it public
>  - reuse qapi_enum_parse
> 
> changes to v8:
> 
>  - round up image file size to nearest sector size
>  - dont' blindly lose error info
>  - target for 2.1 rather than 2.0
>  - and, rebase to latest git tree
> 
> changes to v5:
> 
>   - add `Since 2.0' to PreallocMode
>   - apply total_size change to raw-win32.c as well
> 
> changes to v4:
> 
>   - fix wrong calculation of qcow2 metadata size in v4
>   - remove raw_preallocate2()
>   - better error out path in raw_create()
>   - fix coding style
> 
> changes to v3:
> 
>   - remove bdrv_preallocate and make preallocation a
> bdrv_create_file option
>   - prealloc_mode -> PreallocMode and add it to QAPI
>   - fix return value in raw_preallocate2
> 
> changes to v2:
> 
>   - Fix comments to v2 by Fam.
>   - qcow2: first fallocate disk space, then allocate metadata. This avoids
> the problem in v2 that bdrv_preallocate may clear all information in
> metadata. This does not necessarily map all data clusters sequentially
> but does keep information in metadata. Peter, is this acceptable?
> 
> 
> Hu Tao (5):
>   block: round up file size to nearest sector
>   block: don't convert file size to sector size
>   qapi: introduce PreallocMode and new PreallocModes full and falloc.
>   raw-posix: Add falloc and full preallocation option
>   qcow2: Add falloc and full preallocation option
> 
>  block/archipelago.c  |   3 +-
>  block/cow.c  |   3 +-
>  block/gluster.c  |   9 ++--
>  block/iscsi.c|   4 +-
>  block/nfs.c  |   3 +-
>  block/qcow.c |   7 +--
>  block/qcow2.c|  82 +--
>  block/qed.c  |   3 +-
>  block/raw-posix.c| 102 
> ++-
>  block/raw-win32.c|   6 +--
>  block/rbd.c  |   3 +-
>  block/sheepdog.c |   3 +-
>  block/ssh.c  |   3 +-
>  block/vdi.c  |   3 +-
>  block/vhdx.c |   3 +-
>  block/vmdk.c |   3 +-
>  block/vpc.c  |   3 +-
>  qapi/block-core.json |  17 +++
>  qemu-doc.texi|  17 +--
>  qemu-img.texi|  17 +--
>  tests/qemu-iotests/049.out   |   2 +-
>  tests/qemu-iotests/082.out   |  54 ++---
>  tests/qemu-iotests/104   |  57 ++
>  tests/qemu-iotests/104.out   |  12 +
>  tests/qemu-iotests/common.filter |  21 
>  tests/qemu-iotests/group |   1 +
>  26 files changed, 344 insertions(+), 97 deletions(-)
>  create mode 100755 tests/qemu-iotests/104
>  create mode 100644 tests/qemu-iotests/104.out
> 
> -- 
> 1.9.3
> 



[Qemu-devel] [PATCH v15 2/5] block: don't convert file size to sector size

2014-09-10 Thread Hu Tao
and avoid converting it back later.

Signed-off-by: Hu Tao 
Reviewed-by: Max Reitz 
Reviewed-by: Benoît Canet 
---
 block/gluster.c   |  9 -
 block/qcow.c  |  8 
 block/qcow2.c | 10 +-
 block/raw-posix.c | 12 ++--
 block/raw-win32.c |  6 +++---
 5 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/block/gluster.c b/block/gluster.c
index 65c7a58..1eb3a8c 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -494,8 +494,8 @@ static int qemu_gluster_create(const char *filename,
 goto out;
 }
 
-total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
-  BDRV_SECTOR_SIZE);
+total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 
 tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
 if (!tmp || !strcmp(tmp, "off")) {
@@ -516,9 +516,8 @@ static int qemu_gluster_create(const char *filename,
 if (!fd) {
 ret = -errno;
 } else {
-if (!glfs_ftruncate(fd, total_size * BDRV_SECTOR_SIZE)) {
-if (prealloc && qemu_gluster_zerofill(fd, 0,
-total_size * BDRV_SECTOR_SIZE)) {
+if (!glfs_ftruncate(fd, total_size)) {
+if (prealloc && qemu_gluster_zerofill(fd, 0, total_size)) {
 ret = -errno;
 }
 } else {
diff --git a/block/qcow.c b/block/qcow.c
index 041af26..a87bd69 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -725,8 +725,8 @@ static int qcow_create(const char *filename, QemuOpts 
*opts, Error **errp)
 BlockDriverState *qcow_bs;
 
 /* Read out options */
-total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
-  BDRV_SECTOR_SIZE);
+total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
 if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
 flags |= BLOCK_FLAG_ENCRYPT;
@@ -754,7 +754,7 @@ static int qcow_create(const char *filename, QemuOpts 
*opts, Error **errp)
 memset(&header, 0, sizeof(header));
 header.magic = cpu_to_be32(QCOW_MAGIC);
 header.version = cpu_to_be32(QCOW_VERSION);
-header.size = cpu_to_be64(total_size * 512);
+header.size = cpu_to_be64(total_size);
 header_size = sizeof(header);
 backing_filename_len = 0;
 if (backing_file) {
@@ -776,7 +776,7 @@ static int qcow_create(const char *filename, QemuOpts 
*opts, Error **errp)
 }
 header_size = (header_size + 7) & ~7;
 shift = header.cluster_bits + header.l2_bits;
-l1_size = ((total_size * 512) + (1LL << shift) - 1) >> shift;
+l1_size = (total_size + (1LL << shift) - 1) >> shift;
 
 header.l1_table_offset = cpu_to_be64(header_size);
 if (flags & BLOCK_FLAG_ENCRYPT) {
diff --git a/block/qcow2.c b/block/qcow2.c
index c8050e5..cf27c3f 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1859,7 +1859,7 @@ static int qcow2_create2(const char *filename, int64_t 
total_size,
 }
 
 /* Okay, now that we have a valid image, let's give it the right size */
-ret = bdrv_truncate(bs, total_size * BDRV_SECTOR_SIZE);
+ret = bdrv_truncate(bs, total_size);
 if (ret < 0) {
 error_setg_errno(errp, -ret, "Could not resize image");
 goto out;
@@ -1912,7 +1912,7 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 char *backing_file = NULL;
 char *backing_fmt = NULL;
 char *buf = NULL;
-uint64_t sectors = 0;
+uint64_t size = 0;
 int flags = 0;
 size_t cluster_size = DEFAULT_CLUSTER_SIZE;
 int prealloc = 0;
@@ -1921,8 +1921,8 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 int ret;
 
 /* Read out options */
-sectors = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
-   BDRV_SECTOR_SIZE);
+size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+BDRV_SECTOR_SIZE);
 backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
 backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
 if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
@@ -1972,7 +1972,7 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 goto finish;
 }
 
-ret = qcow2_create2(filename, sectors, backing_file, backing_fmt, flags,
+ret = qcow2_create2(filename, size, backing_file, backing_fmt, flags,
 cluster_size, prealloc, opts, version, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 9c22e3f..7208c05 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1369,8 +1369,8 @@ static int ra

[Qemu-devel] [PATCH v15 3/5] qapi: introduce PreallocMode and new PreallocModes full and falloc.

2014-09-10 Thread Hu Tao
This patch prepares for the subsequent patches.

Signed-off-by: Hu Tao 
Reviewed-by: Max Reitz 
Reviewed-by: Kevin Wolf 
Reviewed-by: Eric Blake 
---
 block/qcow2.c  | 28 ++--
 qapi/block-core.json   | 17 +
 tests/qemu-iotests/049.out |  2 +-
 3 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index cf27c3f..2d68b51 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -30,6 +30,7 @@
 #include "qemu/error-report.h"
 #include "qapi/qmp/qerror.h"
 #include "qapi/qmp/qbool.h"
+#include "qapi/util.h"
 #include "trace.h"
 #include "qemu/option_int.h"
 
@@ -1738,7 +1739,7 @@ static int preallocate(BlockDriverState *bs)
 
 static int qcow2_create2(const char *filename, int64_t total_size,
  const char *backing_file, const char *backing_format,
- int flags, size_t cluster_size, int prealloc,
+ int flags, size_t cluster_size, PreallocMode prealloc,
  QemuOpts *opts, int version,
  Error **errp)
 {
@@ -1876,7 +1877,7 @@ static int qcow2_create2(const char *filename, int64_t 
total_size,
 }
 
 /* And if we're supposed to preallocate metadata, do that now */
-if (prealloc) {
+if (prealloc == PREALLOC_MODE_METADATA) {
 BDRVQcowState *s = bs->opaque;
 qemu_co_mutex_lock(&s->lock);
 ret = preallocate(bs);
@@ -1915,7 +1916,7 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 uint64_t size = 0;
 int flags = 0;
 size_t cluster_size = DEFAULT_CLUSTER_SIZE;
-int prealloc = 0;
+PreallocMode prealloc;
 int version = 3;
 Error *local_err = NULL;
 int ret;
@@ -1931,12 +1932,11 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE,
  DEFAULT_CLUSTER_SIZE);
 buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
-if (!buf || !strcmp(buf, "off")) {
-prealloc = 0;
-} else if (!strcmp(buf, "metadata")) {
-prealloc = 1;
-} else {
-error_setg(errp, "Invalid preallocation mode: '%s'", buf);
+prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
+   PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
+   &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
 ret = -EINVAL;
 goto finish;
 }
@@ -1958,7 +1958,15 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 flags |= BLOCK_FLAG_LAZY_REFCOUNTS;
 }
 
-if (backing_file && prealloc) {
+if (prealloc != PREALLOC_MODE_OFF &&
+prealloc != PREALLOC_MODE_METADATA) {
+ret = -EINVAL;
+error_setg(errp, "Unsupported preallocate mode: %s",
+   PreallocMode_lookup[prealloc]);
+goto finish;
+}
+
+if (backing_file && prealloc != PREALLOC_MODE_OFF) {
 error_setg(errp, "Backing file and preallocation cannot be used at "
"the same time");
 ret = -EINVAL;
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 68945c2..fe6e025 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1703,3 +1703,20 @@
 'len'   : 'int',
 'offset': 'int',
 'speed' : 'int' } }
+
+# @PreallocMode
+#
+# Preallocation mode of QEMU image file
+#
+# @off: no preallocation
+# @metadata: preallocate only for metadata
+# @falloc: like @full preallocation but allocate disk space by
+#  posix_fallocate() rather than writing zeros.
+# @full: preallocate all data by writing zeros to device to ensure disk
+#space is really available. @full preallocation also sets up
+#metadata correctly.
+#
+# Since 2.2
+##
+{ 'enum': 'PreallocMode',
+  'data': [ 'off', 'metadata', 'falloc', 'full' ] }
diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out
index 71ca44d..09ca0ae 100644
--- a/tests/qemu-iotests/049.out
+++ b/tests/qemu-iotests/049.out
@@ -179,7 +179,7 @@ qemu-img create -f qcow2 -o preallocation=metadata 
TEST_DIR/t.qcow2 64M
 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off 
cluster_size=65536 preallocation='metadata' lazy_refcounts=off 
 
 qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M
-qemu-img: TEST_DIR/t.qcow2: Invalid preallocation mode: '1234'
+qemu-img: TEST_DIR/t.qcow2: invalid parameter value: 1234
 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off 
cluster_size=65536 preallocation='1234' lazy_refcounts=off 
 
 == Check encryption option ==
-- 
1.9.3




[Qemu-devel] [PATCH v15 0/5] qcow2, raw: add preallocation=full and preallocation=falloc

2014-09-10 Thread Hu Tao
This series adds two preallocation mode to qcow2 and raw:

Option preallocation=full preallocates disk space for image by writing
zeros to disk, this ensures disk space in any cases.

Option preallocation=falloc preallocates disk space by calling
posix_fallocate(). This is faster than preallocation=full.

Note: there is a false positive reported by checkpatch.pl to patch 1.

changes to v14:

  - add detailed commit message to patch 1
  - change the coding style as Eric and Benoît suggested (patch 3)
  - use break as Benoît suggested (patch 4)

changes to v13:

  - rebase (patch 3 in v13 is already in)
  - don't convert file size to sector size in hdev_create(), too (patch 2)
  - reintroduce preallocation=falloc. (patch 3)
  - split the implementation of preallocation=full in v13 into
preallocation=falloc and preallocation=full (patch 4)

changes to v12:

  - remove dependence on minimal_blob_size() (patch 6)
  - remove preallocation=falloc. (patch 4)
  - preallocation=full tries posix_fallocate() first then writing
zeros (patch 5)
  - round up file size for all formats (patch 1)
  - avoid converting file size for more formats (patch 2)

changes to v11:

 - fix test case 049 (patch 4)
 - unsigned nl2e -> uint64_t nl2e (patch 6)
 - use >> instead of / (patch 6)

changes to v10:

  - PreallocMode is moved from file qapi-schema.json to qapi/block-core.json
  - introdues preallocation=falloc, no changes to preallocation=metadata
  - using minimal_blob_size() to calculate metadata size for qcow2
  - indentation fix in file blockdev.c

changes to v9:

 - use ROUND_UP to do round up
 - split the round up into its own patch and add test case
 - new patch rename parse_enum_option to qapi_enum_parse and make it public
 - reuse qapi_enum_parse

changes to v8:

 - round up image file size to nearest sector size
 - dont' blindly lose error info
 - target for 2.1 rather than 2.0
 - and, rebase to latest git tree

changes to v5:

  - add `Since 2.0' to PreallocMode
  - apply total_size change to raw-win32.c as well

changes to v4:

  - fix wrong calculation of qcow2 metadata size in v4
  - remove raw_preallocate2()
  - better error out path in raw_create()
  - fix coding style

changes to v3:

  - remove bdrv_preallocate and make preallocation a
bdrv_create_file option
  - prealloc_mode -> PreallocMode and add it to QAPI
  - fix return value in raw_preallocate2

changes to v2:

  - Fix comments to v2 by Fam.
  - qcow2: first fallocate disk space, then allocate metadata. This avoids
the problem in v2 that bdrv_preallocate may clear all information in
metadata. This does not necessarily map all data clusters sequentially
but does keep information in metadata. Peter, is this acceptable?


Hu Tao (5):
  block: round up file size to nearest sector
  block: don't convert file size to sector size
  qapi: introduce PreallocMode and new PreallocModes full and falloc.
  raw-posix: Add falloc and full preallocation option
  qcow2: Add falloc and full preallocation option

 block/archipelago.c  |   3 +-
 block/cow.c  |   3 +-
 block/gluster.c  |   9 ++--
 block/iscsi.c|   4 +-
 block/nfs.c  |   3 +-
 block/qcow.c |   7 +--
 block/qcow2.c|  82 +--
 block/qed.c  |   3 +-
 block/raw-posix.c| 102 ++-
 block/raw-win32.c|   6 +--
 block/rbd.c  |   3 +-
 block/sheepdog.c |   3 +-
 block/ssh.c  |   3 +-
 block/vdi.c  |   3 +-
 block/vhdx.c |   3 +-
 block/vmdk.c |   3 +-
 block/vpc.c  |   3 +-
 qapi/block-core.json |  17 +++
 qemu-doc.texi|  17 +--
 qemu-img.texi|  17 +--
 tests/qemu-iotests/049.out   |   2 +-
 tests/qemu-iotests/082.out   |  54 ++---
 tests/qemu-iotests/104   |  57 ++
 tests/qemu-iotests/104.out   |  12 +
 tests/qemu-iotests/common.filter |  21 
 tests/qemu-iotests/group |   1 +
 26 files changed, 344 insertions(+), 97 deletions(-)
 create mode 100755 tests/qemu-iotests/104
 create mode 100644 tests/qemu-iotests/104.out

-- 
1.9.3




[Qemu-devel] [PATCH v15 4/5] raw-posix: Add falloc and full preallocation option

2014-09-10 Thread Hu Tao
This patch adds a new option preallocation for raw format, and implements
falloc and full preallocation.

Signed-off-by: Hu Tao 
Reviewed-by: Max Reitz 
---
 block/raw-posix.c | 92 +++
 qemu-doc.texi |  9 ++
 qemu-img.texi |  9 ++
 3 files changed, 91 insertions(+), 19 deletions(-)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 7208c05..a253697 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -30,6 +30,7 @@
 #include "block/thread-pool.h"
 #include "qemu/iov.h"
 #include "raw-aio.h"
+#include "qapi/util.h"
 
 #if defined(__APPLE__) && (__MACH__)
 #include 
@@ -1365,6 +1366,9 @@ static int raw_create(const char *filename, QemuOpts 
*opts, Error **errp)
 int result = 0;
 int64_t total_size = 0;
 bool nocow = false;
+PreallocMode prealloc;
+char *buf = NULL;
+Error *local_err = NULL;
 
 strstart(filename, "file:", &filename);
 
@@ -1372,37 +1376,82 @@ static int raw_create(const char *filename, QemuOpts 
*opts, Error **errp)
 total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
   BDRV_SECTOR_SIZE);
 nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false);
+buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
+prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
+   PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
+   &local_err);
+g_free(buf);
+if (local_err) {
+error_propagate(errp, local_err);
+result = -EINVAL;
+goto out;
+}
 
 fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
0644);
 if (fd < 0) {
 result = -errno;
 error_setg_errno(errp, -result, "Could not create file");
-} else {
-if (nocow) {
+goto out;
+}
+
+if (nocow) {
 #ifdef __linux__
-/* Set NOCOW flag to solve performance issue on fs like btrfs.
- * This is an optimisation. The FS_IOC_SETFLAGS ioctl return value
- * will be ignored since any failure of this operation should not
- * block the left work.
- */
-int attr;
-if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) {
-attr |= FS_NOCOW_FL;
-ioctl(fd, FS_IOC_SETFLAGS, &attr);
-}
-#endif
+/* Set NOCOW flag to solve performance issue on fs like btrfs.
+ * This is an optimisation. The FS_IOC_SETFLAGS ioctl return value
+ * will be ignored since any failure of this operation should not
+ * block the left work.
+ */
+int attr;
+if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) {
+attr |= FS_NOCOW_FL;
+ioctl(fd, FS_IOC_SETFLAGS, &attr);
 }
+#endif
+}
+
+if (ftruncate(fd, total_size) != 0) {
+result = -errno;
+error_setg_errno(errp, -result, "Could not resize file");
+goto out_close;
+}
 
-if (ftruncate(fd, total_size) != 0) {
-result = -errno;
-error_setg_errno(errp, -result, "Could not resize file");
+if (prealloc == PREALLOC_MODE_FALLOC) {
+/* posix_fallocate() doesn't set errno. */
+result = -posix_fallocate(fd, 0, total_size);
+if (result != 0) {
+error_setg_errno(errp, -result,
+ "Could not preallocate data for the new file");
 }
-if (qemu_close(fd) != 0) {
-result = -errno;
-error_setg_errno(errp, -result, "Could not close the new file");
+} else if (prealloc == PREALLOC_MODE_FULL) {
+buf = g_malloc0(65536);
+int64_t num = 0, left = total_size;
+
+while (left > 0) {
+num = MIN(left, 65536);
+result = write(fd, buf, num);
+if (result < 0) {
+result = -errno;
+error_setg_errno(errp, -result,
+ "Could not write to the new file");
+break;
+}
+left -= num;
 }
+fsync(fd);
+g_free(buf);
+} else if (prealloc != PREALLOC_MODE_OFF) {
+result = -EINVAL;
+error_setg(errp, "Unsupported preallocation mode: %s",
+   PreallocMode_lookup[prealloc]);
 }
+
+out_close:
+if (qemu_close(fd) != 0 && result == 0) {
+result = -errno;
+error_setg_errno(errp, -result, "Could not close the new file");
+}
+out:
 return result;
 }
 
@@ -1585,6 +1634,11 @@ static QemuOptsList raw_create_opts = {
 .type = QEMU_OPT_BOOL,
 .help = "Turn off copy-on-write (valid only on btrfs)"
 },
+{
+.name = BLOCK_OPT_PREALLOC,
+

[Qemu-devel] [PATCH v15 1/5] block: round up file size to nearest sector

2014-09-10 Thread Hu Tao
Currently the file size requested by user is rounded down to nearest
sector, causing the actual file size could be a bit less than the size
user requested. Since some formats (like qcow2) record virtual disk
size in bytes, this can make the last few bytes cannot be accessed.

This patch fixes it by rounding up file size to nearest sector so that
the actual file size is no less than the requested file size.

Signed-off-by: Hu Tao 
Reviewed-by: Kevin Wolf 
Reviewed-by: Eric Blake 
Reviewed-by: Max Reitz 
---
 block/archipelago.c  |  3 ++-
 block/cow.c  |  3 ++-
 block/gluster.c  |  4 +--
 block/iscsi.c|  4 +--
 block/nfs.c  |  3 ++-
 block/qcow.c |  3 ++-
 block/qcow2.c|  3 ++-
 block/qed.c  |  3 ++-
 block/raw-posix.c|  8 +++---
 block/raw-win32.c|  4 +--
 block/rbd.c  |  3 ++-
 block/sheepdog.c |  3 ++-
 block/ssh.c  |  3 ++-
 block/vdi.c  |  3 ++-
 block/vhdx.c |  3 ++-
 block/vmdk.c |  3 ++-
 block/vpc.c  |  3 ++-
 tests/qemu-iotests/104   | 57 
 tests/qemu-iotests/104.out   | 12 +
 tests/qemu-iotests/common.filter | 21 +++
 tests/qemu-iotests/group |  1 +
 21 files changed, 127 insertions(+), 23 deletions(-)
 create mode 100755 tests/qemu-iotests/104
 create mode 100644 tests/qemu-iotests/104.out

diff --git a/block/archipelago.c b/block/archipelago.c
index 22a7daa..06c51f9 100644
--- a/block/archipelago.c
+++ b/block/archipelago.c
@@ -708,7 +708,8 @@ static int qemu_archipelago_create(const char *filename,
 
 parse_filename_opts(filename, errp, &volname, &segment_name, &mport,
 &vport);
-total_size = qemu_opt_get_size_del(options, BLOCK_OPT_SIZE, 0);
+total_size = ROUND_UP(qemu_opt_get_size_del(options, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 
 if (segment_name == NULL) {
 segment_name = g_strdup("archipelago");
diff --git a/block/cow.c b/block/cow.c
index 6ee4833..c3769fe 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -335,7 +335,8 @@ static int cow_create(const char *filename, QemuOpts *opts, 
Error **errp)
 BlockDriverState *cow_bs = NULL;
 
 /* Read out options */
-image_sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
+image_sectors = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 
0),
+ BDRV_SECTOR_SIZE);
 image_filename = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
 
 ret = bdrv_create_file(filename, opts, &local_err);
diff --git a/block/gluster.c b/block/gluster.c
index 1912cf9..65c7a58 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -494,8 +494,8 @@ static int qemu_gluster_create(const char *filename,
 goto out;
 }
 
-total_size =
-qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
+total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 
 tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
 if (!tmp || !strcmp(tmp, "off")) {
diff --git a/block/iscsi.c b/block/iscsi.c
index 3e19202..84bcae8 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1531,8 +1531,8 @@ static int iscsi_create(const char *filename, QemuOpts 
*opts, Error **errp)
 bs = bdrv_new("", &error_abort);
 
 /* Read out options */
-total_size =
-qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
+total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 bs->opaque = g_new0(struct IscsiLun, 1);
 iscsilun = bs->opaque;
 
diff --git a/block/nfs.c b/block/nfs.c
index 194f301..c76e368 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -418,7 +418,8 @@ static int nfs_file_create(const char *url, QemuOpts *opts, 
Error **errp)
 client->aio_context = qemu_get_aio_context();
 
 /* Read out options */
-total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 
 ret = nfs_client_open(client, url, O_CREAT, errp);
 if (ret < 0) {
diff --git a/block/qcow.c b/block/qcow.c
index 67c237f..041af26 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -725,7 +725,8 @@ static int qcow_create(const char *filename, QemuOpts 
*opts, Error **errp)
 BlockDriverState *qcow_bs;
 
 /* Read out options */
-total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
+total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+   

[Qemu-devel] [PATCH v15 5/5] qcow2: Add falloc and full preallocation option

2014-09-10 Thread Hu Tao
preallocation=falloc allocates disk space by posix_fallocate(),
preallocation=full allocates disk space by writing zeros to disk.
Both modes imply preallocation=metadata.

Signed-off-by: Hu Tao 
Reviewed-by: Max Reitz 
---
 block/qcow2.c  | 63 ++
 qemu-doc.texi  |  8 +++---
 qemu-img.texi  |  8 +++---
 tests/qemu-iotests/082.out | 54 +++
 4 files changed, 90 insertions(+), 43 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 2d68b51..0daf25c 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1772,6 +1772,56 @@ static int qcow2_create2(const char *filename, int64_t 
total_size,
 Error *local_err = NULL;
 int ret;
 
+if (prealloc == PREALLOC_MODE_FULL || prealloc == PREALLOC_MODE_FALLOC) {
+int64_t meta_size = 0;
+uint64_t nreftablee, nrefblocke, nl1e, nl2e;
+int64_t aligned_total_size = align_offset(total_size, cluster_size);
+
+/* header: 1 cluster */
+meta_size += cluster_size;
+
+/* total size of L2 tables */
+nl2e = aligned_total_size / cluster_size;
+nl2e = align_offset(nl2e, cluster_size / sizeof(uint64_t));
+meta_size += nl2e * sizeof(uint64_t);
+
+/* total size of L1 tables */
+nl1e = nl2e * sizeof(uint64_t) / cluster_size;
+nl1e = align_offset(nl1e, cluster_size / sizeof(uint64_t));
+meta_size += nl1e * sizeof(uint64_t);
+
+/* total size of refcount blocks
+ *
+ * note: every host cluster is reference-counted, including metadata
+ * (even refcount blocks are recursively included).
+ * Let:
+ *   a = total_size (this is the guest disk size)
+ *   m = meta size not including refcount blocks and refcount tables
+ *   c = cluster size
+ *   y1 = number of refcount blocks entries
+ *   y2 = meta size including everything
+ * then,
+ *   y1 = (y2 + a)/c
+ *   y2 = y1 * sizeof(u16) + y1 * sizeof(u16) * sizeof(u64) / c + m
+ * we can get y1:
+ *   y1 = (a + m) / (c - sizeof(u16) - sizeof(u16) * sizeof(u64) / c)
+ */
+nrefblocke = (aligned_total_size + meta_size + cluster_size) /
+(cluster_size - sizeof(uint16_t) -
+ 1.0 * sizeof(uint16_t) * sizeof(uint64_t) / cluster_size);
+nrefblocke = align_offset(nrefblocke, cluster_size / sizeof(uint16_t));
+meta_size += nrefblocke * sizeof(uint16_t);
+
+/* total size of refcount tables */
+nreftablee = nrefblocke * sizeof(uint16_t) / cluster_size;
+nreftablee = align_offset(nreftablee, cluster_size / sizeof(uint64_t));
+meta_size += nreftablee * sizeof(uint64_t);
+
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
+aligned_total_size + meta_size);
+qemu_opt_set(opts, BLOCK_OPT_PREALLOC, PreallocMode_lookup[prealloc]);
+}
+
 ret = bdrv_create_file(filename, opts, &local_err);
 if (ret < 0) {
 error_propagate(errp, local_err);
@@ -1877,7 +1927,7 @@ static int qcow2_create2(const char *filename, int64_t 
total_size,
 }
 
 /* And if we're supposed to preallocate metadata, do that now */
-if (prealloc == PREALLOC_MODE_METADATA) {
+if (prealloc != PREALLOC_MODE_OFF) {
 BDRVQcowState *s = bs->opaque;
 qemu_co_mutex_lock(&s->lock);
 ret = preallocate(bs);
@@ -1958,14 +2008,6 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 flags |= BLOCK_FLAG_LAZY_REFCOUNTS;
 }
 
-if (prealloc != PREALLOC_MODE_OFF &&
-prealloc != PREALLOC_MODE_METADATA) {
-ret = -EINVAL;
-error_setg(errp, "Unsupported preallocate mode: %s",
-   PreallocMode_lookup[prealloc]);
-goto finish;
-}
-
 if (backing_file && prealloc != PREALLOC_MODE_OFF) {
 error_setg(errp, "Backing file and preallocation cannot be used at "
"the same time");
@@ -2526,7 +2568,8 @@ static QemuOptsList qcow2_create_opts = {
 {
 .name = BLOCK_OPT_PREALLOC,
 .type = QEMU_OPT_STRING,
-.help = "Preallocation mode (allowed values: off, metadata)"
+.help = "Preallocation mode (allowed values: off, metadata, "
+"falloc, full)"
 },
 {
 .name = BLOCK_OPT_LAZY_REFCOUNTS,
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 1f289d6..ef3be72 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -584,9 +584,11 @@ sizes can improve the image file size whereas larger 
cluster sizes generally
 provide better performance.
 
 @item preallocation
-Preallocation mode (allowed values: off, metadata). An image with preallocated
-metadata is initially larger but can improve performance when the im

Re: [Qemu-devel] [PATCH v14 1/5] block: round up file size to nearest sector

2014-09-09 Thread Hu Tao
On Wed, Sep 10, 2014 at 09:50:02AM +0800, Hu Tao wrote:
> On Tue, Sep 09, 2014 at 02:12:18PM +0200, Benoît Canet wrote:

...

> > 
> > seems correct but the patch does not apply anymore on latest Kevin/block
> > branch neither with git am nor with git apply..
> > Could you rebase ?
> 
> I made it on top of master. I'll respin basing on Kevin/block.

I can apply it basing on http://repo.or.cz/qemu/kevin.git block. Am I
using the wrong block branch?

Regards,
Hu



Re: [Qemu-devel] [PATCH v7 RESEND 0/8] memory API improvements and bug fixes for memory backends

2014-09-09 Thread Hu Tao
On Tue, Sep 09, 2014 at 01:29:21PM +0200, Paolo Bonzini wrote:
> Il 09/09/2014 07:27, Hu Tao ha scritto:
> > This is merely a rebase of v7, and fixes two merge conflicts.
> > 
> > This series includes two parts:
> >  
> >   1. part 1 includes patches 1-4, which improves error handling of
> >  memory_region_init_ram, memory_region_init_ram_ptr and
> >  memory_region_init_rom_device
> >  
> >   2. part 2 includes patches 5-8, each fixes a bug of memory backend.
> >  
> > changes:
> > 
> >   v7:
> >   - split the memory-file preallocation fix into its own patch(patch 6)
> >   - some commit messages tweaks
> > 
> >   v6:
> >   - split patch 6 in v5 into 2
> >   - use local_err instead of errp
> >   - typo fixes
> > 
> >   v5:
> >   - don't introduce _may_fail and _nofail versions of memory API
> >   - the patches order of bug fix and memory API change is exchanged, first
> > comes the API change, then bug fix.
> > 
> >   v4:
> >   - fix build on 32bit host
> >   - add memory API renaming
> >   - rebase on latest master
> > 
> >   v3:
> >   - introduce memory_region_init_ram_may_fail and
> > memory_region_init_ram_ptr_may_fail
> >   - address comments by MST
> >   - missing the functions renaming. will send later.
> > 
> >   v2:
> >   - split patch 1 in v1 into 2 patches
> >   - don't rely on ram_block_add to return -1
> >   - error message tweak in file_ram_alloc
> >   - add error messages reported by qemu to commit message of patch 3
> > 
> >   v1:
> >   - initial version
> > 
> > 
> > Hu Tao (8):
> >   exec: add parameter errp to qemu_ram_alloc and qemu_ram_alloc_from_ptr
> >   memory: add parameter errp to memory_region_init_ram
> >   memory: add parameter errp to memory_region_init_ram_ptr
> >   memory: add parameter errp to memory_region_init_rom_device
> >   hostmem-ram: don't exit qemu if size of memory-backend-ram is way too
> > big
> >   exec: file_ram_alloc: don't exit if failed to preallocate memory
> >   exec: report error when memory < hpagesize
> >   exec: add parameter errp to gethugepagesize
> > 
> >  backends/hostmem-ram.c   |  2 +-
> >  exec.c   | 60 
> > ++--
> >  hw/alpha/typhoon.c   |  3 +-
> >  hw/arm/armv7m.c  |  7 ++--
> >  hw/arm/cubieboard.c  |  2 +-
> >  hw/arm/digic_boards.c|  2 +-
> >  hw/arm/exynos4210.c  |  9 ++---
> >  hw/arm/highbank.c|  5 +--
> >  hw/arm/integratorcp.c|  5 +--
> >  hw/arm/kzm.c |  4 +--
> >  hw/arm/mainstone.c   |  3 +-
> >  hw/arm/musicpal.c|  6 ++--
> >  hw/arm/omap1.c   |  6 ++--
> >  hw/arm/omap2.c   |  6 ++--
> >  hw/arm/omap_sx1.c|  6 ++--
> >  hw/arm/palm.c|  3 +-
> >  hw/arm/pxa2xx.c  | 11 +++---
> >  hw/arm/realview.c|  9 +++--
> >  hw/arm/spitz.c   |  2 +-
> >  hw/arm/strongarm.c   |  3 +-
> >  hw/arm/tosa.c|  2 +-
> >  hw/arm/versatilepb.c |  3 +-
> >  hw/arm/vexpress.c| 15 +---
> >  hw/arm/virt.c|  3 +-
> >  hw/arm/xilinx_zynq.c |  6 ++--
> >  hw/block/onenand.c   |  2 +-
> >  hw/block/pflash_cfi01.c  |  2 +-
> >  hw/block/pflash_cfi02.c  |  2 +-
> >  hw/core/loader.c |  2 +-
> >  hw/cris/axis_dev88.c |  6 ++--
> >  hw/display/cg3.c |  6 ++--
> >  hw/display/g364fb.c  |  2 +-
> >  hw/display/qxl.c |  6 ++--
> >  hw/display/sm501.c   |  2 +-
> >  hw/display/tc6393xb.c|  3 +-
> >  hw/display/tcx.c |  5 +--
> >  hw/display/vga.c |  3 +-
> >  hw/display/vmware_vga.c  |  3 +-
> >  hw/i386/kvm/pci-assign.c |  6 ++--
> >  hw/i386/pc.c |  3 +-
> >  hw/i386/pc_sysfw.c   |  5 +--
> >

Re: [Qemu-devel] [PATCH v7 RESEND 4/8] memory: add parameter errp to memory_region_init_rom_device

2014-09-09 Thread Hu Tao
On Tue, Sep 09, 2014 at 01:20:57PM +0200, Paolo Bonzini wrote:
> Il 09/09/2014 07:27, Hu Tao ha scritto:
> > Add parameter errp to memory_region_init_rom_device and update all call
> > sites to pass in &error_abort.
> > 
> > Reviewed-by: Peter Crosthwaite 
> > Signed-off-by: Hu Tao 
> 
> Better not use error_abort if we can avoid it, and here it's particularly
> easy...

Is error_abort deprecated?

Regards,
Hu



Re: [Qemu-devel] [PATCH v14 4/5] raw-posix: Add falloc and full preallocation option

2014-09-09 Thread Hu Tao
On Tue, Sep 09, 2014 at 03:21:49PM +0200, Benoît Canet wrote:
> The Tuesday 09 Sep 2014 à 11:54:30 (+0800), Hu Tao wrote :
> > This patch adds a new option preallocation for raw format, and implements
> > falloc and full preallocation.
> > 
> > Signed-off-by: Hu Tao 
> > Reviewed-by: Max Reitz 
> > ---
> >  block/raw-posix.c | 93 
> > +++
> >  qemu-doc.texi |  9 ++
> >  qemu-img.texi |  9 ++
> >  3 files changed, 92 insertions(+), 19 deletions(-)
> > 
> > diff --git a/block/raw-posix.c b/block/raw-posix.c
> > index 7208c05..27c854c 100644
> > --- a/block/raw-posix.c
> > +++ b/block/raw-posix.c
> > @@ -30,6 +30,7 @@
> >  #include "block/thread-pool.h"
> >  #include "qemu/iov.h"
> >  #include "raw-aio.h"
> > +#include "qapi/util.h"
> >  
> >  #if defined(__APPLE__) && (__MACH__)
> >  #include 
> > @@ -1365,6 +1366,9 @@ static int raw_create(const char *filename, QemuOpts 
> > *opts, Error **errp)
> >  int result = 0;
> >  int64_t total_size = 0;
> >  bool nocow = false;
> > +PreallocMode prealloc;
> > +char *buf = NULL;
> > +Error *local_err = NULL;
> >  
> >  strstart(filename, "file:", &filename);
> >  
> > @@ -1372,37 +1376,83 @@ static int raw_create(const char *filename, 
> > QemuOpts *opts, Error **errp)
> >  total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
> >BDRV_SECTOR_SIZE);
> >  nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false);
> > +buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
> > +prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
> > +   PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
> > +   &local_err);
> > +g_free(buf);
> > +if (local_err) {
> > +error_propagate(errp, local_err);
> > +result = -EINVAL;
> > +goto out;
> > +}
> >  
> >  fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
> > 0644);
> >  if (fd < 0) {
> >  result = -errno;
> >  error_setg_errno(errp, -result, "Could not create file");
> > -} else {
> > -if (nocow) {
> > +goto out;
> > +}
> > +
> > +if (nocow) {
> >  #ifdef __linux__
> > -/* Set NOCOW flag to solve performance issue on fs like btrfs.
> > - * This is an optimisation. The FS_IOC_SETFLAGS ioctl return 
> > value
> > - * will be ignored since any failure of this operation should 
> > not
> > - * block the left work.
> > - */
> > -int attr;
> > -if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) {
> > -attr |= FS_NOCOW_FL;
> > -ioctl(fd, FS_IOC_SETFLAGS, &attr);
> > -}
> > -#endif
> > +/* Set NOCOW flag to solve performance issue on fs like btrfs.
> > + * This is an optimisation. The FS_IOC_SETFLAGS ioctl return value
> > + * will be ignored since any failure of this operation should not
> > + * block the left work.
> > + */
> > +int attr;
> > +if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) {
> > +attr |= FS_NOCOW_FL;
> > +ioctl(fd, FS_IOC_SETFLAGS, &attr);
> >  }
> > +#endif
> > +}
> >  
> > -if (ftruncate(fd, total_size) != 0) {
> > -result = -errno;
> > -error_setg_errno(errp, -result, "Could not resize file");
> > +if (ftruncate(fd, total_size) != 0) {
> > +result = -errno;
> > +error_setg_errno(errp, -result, "Could not resize file");
> > +goto out_close;
> > +}
> > +
> > +if (prealloc == PREALLOC_MODE_FALLOC) {
> > +/* posix_fallocate() doesn't set errno. */
> > +result = -posix_fallocate(fd, 0, total_size);
> > +if (result != 0) {
> > +error_setg_errno(errp, -result,
> > + "Could not preallocate data for the new 
> > file");
> 
> Here you choose not to goto out_close but let the code flow lead to it.
> 
> >  }
> 
> > -if (qemu_close(fd) != 0) {
> > -result = -errno;
> > -  

Re: [Qemu-devel] [PATCH v14 1/5] block: round up file size to nearest sector

2014-09-09 Thread Hu Tao
On Tue, Sep 09, 2014 at 02:12:18PM +0200, Benoît Canet wrote:
> The Tuesday 09 Sep 2014 à 11:54:27 (+0800), Hu Tao wrote :
> 
> Taking the time to systematically write a nice sentence in
> the commit message body about why your commit exists and
> explaining the long term purpose of the patch will:
> 
> -improve the quality of your commit
> -please everyone involved in the review
> -ultimately help your to get the patch merged faster

Okay.

> 
> > Signed-off-by: Hu Tao 
> > Reviewed-by: Kevin Wolf 
> > Reviewed-by: Eric Blake 
> > Reviewed-by: Max Reitz 
> > ---
> >  block/archipelago.c  |  3 ++-
> >  block/cow.c  |  3 ++-
> >  block/gluster.c  |  4 +--
> >  block/iscsi.c|  4 +--
> >  block/nfs.c  |  3 ++-
> >  block/qcow.c |  3 ++-
> >  block/qcow2.c|  3 ++-
> >  block/qed.c  |  3 ++-
> >  block/raw-posix.c|  8 +++---
> >  block/raw-win32.c|  4 +--
> >  block/rbd.c  |  3 ++-
> >  block/sheepdog.c |  3 ++-
> >  block/ssh.c  |  3 ++-
> >  block/vdi.c  |  3 ++-
> >  block/vhdx.c |  3 ++-
> >  block/vmdk.c |  3 ++-
> >  block/vpc.c  |  3 ++-
> >  tests/qemu-iotests/104   | 57 
> > 
> >  tests/qemu-iotests/104.out   | 12 +
> >  tests/qemu-iotests/common.filter | 21 +++
> >  tests/qemu-iotests/group |  1 +
> >  21 files changed, 127 insertions(+), 23 deletions(-)
> >  create mode 100755 tests/qemu-iotests/104
> >  create mode 100644 tests/qemu-iotests/104.out
> > 
> > diff --git a/block/archipelago.c b/block/archipelago.c
> > index 22a7daa..06c51f9 100644
> > --- a/block/archipelago.c
> > +++ b/block/archipelago.c
> > @@ -708,7 +708,8 @@ static int qemu_archipelago_create(const char *filename,
> >  
> >  parse_filename_opts(filename, errp, &volname, &segment_name, &mport,
> >  &vport);
> > -total_size = qemu_opt_get_size_del(options, BLOCK_OPT_SIZE, 0);
> > +total_size = ROUND_UP(qemu_opt_get_size_del(options, BLOCK_OPT_SIZE, 
> > 0),
> > +  BDRV_SECTOR_SIZE);
> >  
> >  if (segment_name == NULL) {
> >  segment_name = g_strdup("archipelago");
> > diff --git a/block/cow.c b/block/cow.c
> > index 6ee4833..c3769fe 100644
> > --- a/block/cow.c
> > +++ b/block/cow.c
> > @@ -335,7 +335,8 @@ static int cow_create(const char *filename, QemuOpts 
> > *opts, Error **errp)
> >  BlockDriverState *cow_bs = NULL;
> >  
> >  /* Read out options */
> > -image_sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
> > +image_sectors = DIV_ROUND_UP(qemu_opt_get_size_del(opts, 
> > BLOCK_OPT_SIZE, 0),
> > + BDRV_SECTOR_SIZE);
> >  image_filename = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
> >  
> >  ret = bdrv_create_file(filename, opts, &local_err);
> > diff --git a/block/gluster.c b/block/gluster.c
> > index 1912cf9..65c7a58 100644
> > --- a/block/gluster.c
> > +++ b/block/gluster.c
> > @@ -494,8 +494,8 @@ static int qemu_gluster_create(const char *filename,
> >  goto out;
> >  }
> >  
> > -total_size =
> > -qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
> > +total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 
> > 0),
> > +  BDRV_SECTOR_SIZE);
> >  
> >  tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
> >  if (!tmp || !strcmp(tmp, "off")) {
> > diff --git a/block/iscsi.c b/block/iscsi.c
> > index 3e19202..84bcae8 100644
> > --- a/block/iscsi.c
> > +++ b/block/iscsi.c
> > @@ -1531,8 +1531,8 @@ static int iscsi_create(const char *filename, 
> > QemuOpts *opts, Error **errp)
> >  bs = bdrv_new("", &error_abort);
> >  
> >  /* Read out options */
> > -total_size =
> > -qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
> > +total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 
> > 0),
> > +  BDRV_SECTOR_SIZE);
> >  bs->opaque = g_new0(struct IscsiLun, 1);
> >  iscsil

Re: [Qemu-devel] [PATCH v14 3/5] qapi: introduce PreallocMode and new PreallocModes full and falloc.

2014-09-09 Thread Hu Tao
On Tue, Sep 09, 2014 at 06:42:13AM -0600, Eric Blake wrote:
> On 09/08/2014 09:54 PM, Hu Tao wrote:
> > This patch prepares for the subsequent patches.
> > 
> > Signed-off-by: Hu Tao 
> > Reviewed-by: Max Reitz 
> > Reviewed-by: Kevin Wolf 
> > ---
> >  block/qcow2.c  | 23 +++
> >  qapi/block-core.json   | 17 +
> >  tests/qemu-iotests/049.out |  2 +-
> >  3 files changed, 33 insertions(+), 9 deletions(-)
> > 
> 
> >  buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
> > -if (!buf || !strcmp(buf, "off")) {
> > -prealloc = 0;
> > -} else if (!strcmp(buf, "metadata")) {
> > -prealloc = 1;
> > -} else {
> > -error_setg(errp, "Invalid preallocation mode: '%s'", buf);
> > +prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
> > +   PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
> > +   &local_err);
> > +if (local_err) {
> > +error_propagate(errp, local_err);
> >  ret = -EINVAL;
> >  goto finish;
> >  }
> > @@ -1958,6 +1958,13 @@ static int qcow2_create(const char *filename, 
> > QemuOpts *opts, Error **errp)
> >  flags |= BLOCK_FLAG_LAZY_REFCOUNTS;
> >  }
> >  
> > +if (prealloc && prealloc != PREALLOC_MODE_METADATA) {
> > +ret = -EINVAL;
> > +error_setg(errp, "Unsupported preallocate mode: %s",
> > +   PreallocMode_lookup[prealloc]);
> > +goto finish;
> > +}
> 
> I _still_ think this looks weird, and would be better as either:
> 
> if (prealloc != PREALLOC_MODE_NONE &&
> prealloc != PREALLOC_MODE_METADATA) {
> 
> to make it obvious that you are filtering for two acceptable modes, or as:
> 
> if (prealloc == PREALLOC_MODE_FALLOC ||
> prealloc == PREALLOC_MODE_FULL) {
> 
> to make it obvious the modes that you do not support.  But my complaint
> is not strong enough to prevent this patch, especially if later in the
> series revisits this code.

After reading Benoît's comment, I understand why you think the code
looks weird. I'll change it as you suggested. Thanks! 

> 
> Reviewed-by: Eric Blake 
> 
> -- 
> Eric Blake   eblake redhat com+1-919-301-3266
> Libvirt virtualization library http://libvirt.org
> 





Re: [Qemu-devel] [PATCH v14 3/5] qapi: introduce PreallocMode and new PreallocModes full and falloc.

2014-09-09 Thread Hu Tao
On Tue, Sep 09, 2014 at 02:45:56PM +0200, Benoît Canet wrote:
> The Tuesday 09 Sep 2014 à 11:54:29 (+0800), Hu Tao wrote :
> > This patch prepares for the subsequent patches.
> > 
> > Signed-off-by: Hu Tao 
> > Reviewed-by: Max Reitz 
> > Reviewed-by: Kevin Wolf 
> > ---
> >  block/qcow2.c  | 23 +++
> >  qapi/block-core.json   | 17 +
> >  tests/qemu-iotests/049.out |  2 +-
> >  3 files changed, 33 insertions(+), 9 deletions(-)
> > 
> > diff --git a/block/qcow2.c b/block/qcow2.c
> > index cf27c3f..94d1225 100644
> > --- a/block/qcow2.c
> > +++ b/block/qcow2.c
> > @@ -30,6 +30,7 @@
> >  #include "qemu/error-report.h"
> >  #include "qapi/qmp/qerror.h"
> >  #include "qapi/qmp/qbool.h"
> > +#include "qapi/util.h"
> >  #include "trace.h"
> >  #include "qemu/option_int.h"
> >  
> > @@ -1738,7 +1739,7 @@ static int preallocate(BlockDriverState *bs)
> >  
> >  static int qcow2_create2(const char *filename, int64_t total_size,
> >   const char *backing_file, const char 
> > *backing_format,
> > - int flags, size_t cluster_size, int prealloc,
> > + int flags, size_t cluster_size, PreallocMode 
> > prealloc,
> >   QemuOpts *opts, int version,
> >   Error **errp)
> 
> below that.
> 
> Carefull study of the code tell us that here prealloc will be 0 or 1
> but i think you could prepare a bit sooner the next patch by doing:
> 
> -if (prealloc) {  
>
> +if (prealloc == PREALLOC_MODE_METADATA) {
> BDRVQcowState *s = bs->opaque;
> 
> in the same qcow2_create2 function.
> 
> 
> If you do so someone who start reading the code at this precise commit will
> not have to lookup the declaration order of PreallocMode in the QAPI file.

Thanks for your suggestion, I think this makes much sense.

Regards,
Hu



[Qemu-devel] [PATCH v7 RESEND 7/8] exec: report error when memory < hpagesize

2014-09-08 Thread Hu Tao
Report an error when memory < hpagesize in file_ram_alloc() so callers
can handle the error.

If user adds a memory-backend-file object using object_add command,
specifying a size that is less than huge page size, qemu will core dump
with message:

  Bad ram offset f000
  Aborted (core dumped)

This patch fixes the problem. With this patch, qemu reports error
message like:

  qemu-system-x86_64: -object 
memory-backend-file,mem-path=/hugepages,id=mem-file0,size=1M: memory
  size 0x10 must be equal to or larger than huge page size 0x20

Signed-off-by: Hu Tao 
---
 exec.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/exec.c b/exec.c
index 0362cd8..21af6c9 100644
--- a/exec.c
+++ b/exec.c
@@ -1059,9 +1059,9 @@ static void *file_ram_alloc(RAMBlock *block,
 char *filename;
 char *sanitized_name;
 char *c;
-void *area;
+void *area = NULL;
 int fd;
-unsigned long hpagesize;
+uint64_t hpagesize;
 
 hpagesize = gethugepagesize(path);
 if (!hpagesize) {
@@ -1069,7 +1069,10 @@ static void *file_ram_alloc(RAMBlock *block,
 }
 
 if (memory < hpagesize) {
-return NULL;
+error_setg(errp, "memory size 0x" RAM_ADDR_FMT " must be equal to "
+   "or larger than huge page size 0x%" PRIx64,
+   memory, hpagesize);
+goto error;
 }
 
 if (kvm_enabled() && !kvm_has_sync_mmu()) {
-- 
1.9.3




[Qemu-devel] [PATCH v7 RESEND 6/8] exec: file_ram_alloc: don't exit if failed to preallocate memory

2014-09-08 Thread Hu Tao
When using monitor command object_add to add a memory backend file
but failed to preallocate memory for it, qemu exits silently. In
the case we'd better give an error message and keep guest running.

The problem can be reproduced as follows:

1. run qemu with -mem-prealloc
2. (monitor)object_add 
memory-backend-file,size=10G,mem-path=/hugepages,id=mem-file0

Signed-off-by: Hu Tao 
---
 exec.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/exec.c b/exec.c
index 2b9c4c5..0362cd8 100644
--- a/exec.c
+++ b/exec.c
@@ -1129,8 +1129,8 @@ static void *file_ram_alloc(RAMBlock *block,
 return area;
 
 error:
-if (mem_prealloc) {
-exit(1);
+if (area && area != MAP_FAILED) {
+munmap(area, memory);
 }
 return NULL;
 }
-- 
1.9.3




[Qemu-devel] [PATCH v7 RESEND 8/8] exec: add parameter errp to gethugepagesize

2014-09-08 Thread Hu Tao
Add parameter errp to gethugepagesize thus callers can handle errors.

If user adds a memory-backend-file object using object_add command,
specifying a non-existing directory for property mem-path, qemu will
core dump with message:

  /nonexistingdir: No such file or directory
  Bad ram offset f000
  Aborted (core dumped)

This patch fixes the problem. With this patch, qemu reports an error
message like:

  qemu-system-x86_64: -object 
memory-backend-file,mem-path=/nonexistingdir,id=mem-file0,size=128M:
  failed to get page size of file /nonexistingdir: No such file or directory

Signed-off-by: Hu Tao 
Reviewed-by: Peter Crosthwaite 
---
 exec.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/exec.c b/exec.c
index 21af6c9..0f70c04 100644
--- a/exec.c
+++ b/exec.c
@@ -1031,7 +1031,7 @@ void qemu_mutex_unlock_ramlist(void)
 
 #define HUGETLBFS_MAGIC   0x958458f6
 
-static long gethugepagesize(const char *path)
+static long gethugepagesize(const char *path, Error **errp)
 {
 struct statfs fs;
 int ret;
@@ -1041,7 +1041,8 @@ static long gethugepagesize(const char *path)
 } while (ret != 0 && errno == EINTR);
 
 if (ret != 0) {
-perror(path);
+error_setg_errno(errp, errno, "failed to get page size of file %s",
+ path);
 return 0;
 }
 
@@ -1062,9 +1063,11 @@ static void *file_ram_alloc(RAMBlock *block,
 void *area = NULL;
 int fd;
 uint64_t hpagesize;
+Error *local_err = NULL;
 
-hpagesize = gethugepagesize(path);
-if (!hpagesize) {
+hpagesize = gethugepagesize(path, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
 goto error;
 }
 
-- 
1.9.3




[Qemu-devel] [PATCH v7 RESEND 2/8] memory: add parameter errp to memory_region_init_ram

2014-09-08 Thread Hu Tao
Add parameter errp to memory_region_init_ram and update all call sites
to pass in &error_abort.

Signed-off-by: Hu Tao 
Reviewed-by: Peter Crosthwaite 
---
 backends/hostmem-ram.c   |  2 +-
 hw/alpha/typhoon.c   |  3 ++-
 hw/arm/armv7m.c  |  7 ---
 hw/arm/cubieboard.c  |  2 +-
 hw/arm/digic_boards.c|  2 +-
 hw/arm/exynos4210.c  |  9 +
 hw/arm/highbank.c|  5 +++--
 hw/arm/integratorcp.c|  5 +++--
 hw/arm/kzm.c |  4 ++--
 hw/arm/mainstone.c   |  3 ++-
 hw/arm/musicpal.c|  6 --
 hw/arm/omap1.c   |  6 --
 hw/arm/omap2.c   |  6 --
 hw/arm/omap_sx1.c|  6 --
 hw/arm/palm.c|  3 ++-
 hw/arm/pxa2xx.c  | 11 +++
 hw/arm/realview.c|  9 ++---
 hw/arm/spitz.c   |  2 +-
 hw/arm/strongarm.c   |  3 ++-
 hw/arm/tosa.c|  2 +-
 hw/arm/versatilepb.c |  3 ++-
 hw/arm/vexpress.c| 15 ++-
 hw/arm/virt.c|  3 ++-
 hw/arm/xilinx_zynq.c |  6 --
 hw/block/onenand.c   |  2 +-
 hw/core/loader.c |  2 +-
 hw/cris/axis_dev88.c |  6 --
 hw/display/cg3.c |  6 --
 hw/display/qxl.c |  6 +++---
 hw/display/sm501.c   |  2 +-
 hw/display/tc6393xb.c|  3 ++-
 hw/display/tcx.c |  5 +++--
 hw/display/vga.c |  3 ++-
 hw/display/vmware_vga.c  |  3 ++-
 hw/i386/kvm/pci-assign.c |  3 ++-
 hw/i386/pc.c |  3 ++-
 hw/i386/pc_sysfw.c   |  5 +++--
 hw/input/milkymist-softusb.c |  4 ++--
 hw/lm32/lm32_boards.c|  6 --
 hw/lm32/milkymist.c  |  3 ++-
 hw/m68k/an5206.c |  4 ++--
 hw/m68k/dummy_m68k.c |  2 +-
 hw/m68k/mcf5208.c|  4 ++--
 hw/microblaze/petalogix_ml605_mmu.c  |  5 +++--
 hw/microblaze/petalogix_s3adsp1800_mmu.c |  6 --
 hw/mips/mips_fulong2e.c  |  5 +++--
 hw/mips/mips_jazz.c  |  8 +---
 hw/mips/mips_malta.c |  6 --
 hw/mips/mips_mipssim.c   |  6 --
 hw/mips/mips_r4k.c   |  5 +++--
 hw/moxie/moxiesim.c  |  4 ++--
 hw/net/milkymist-minimac2.c  |  2 +-
 hw/openrisc/openrisc_sim.c   |  2 +-
 hw/pci-host/prep.c   |  3 ++-
 hw/pci/pci.c |  2 +-
 hw/ppc/mac_newworld.c|  3 ++-
 hw/ppc/mac_oldworld.c|  3 ++-
 hw/ppc/ppc405_boards.c   |  8 +---
 hw/ppc/ppc405_uc.c   |  3 ++-
 hw/s390x/s390-virtio-ccw.c   |  2 +-
 hw/s390x/s390-virtio.c   |  2 +-
 hw/sh4/r2d.c |  2 +-
 hw/sh4/shix.c|  8 +---
 hw/sparc/leon3.c |  4 ++--
 hw/sparc/sun4m.c | 10 ++
 hw/sparc64/sun4u.c   |  6 --
 hw/unicore32/puv3.c  |  3 ++-
 hw/xtensa/sim.c  |  4 ++--
 hw/xtensa/xtfpga.c   |  8 +---
 include/exec/memory.h|  4 +++-
 memory.c |  5 +++--
 numa.c   |  4 ++--
 xen-hvm.c|  3 ++-
 73 files changed, 203 insertions(+), 128 deletions(-)

diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c
index d9a8290..e55d066 100644
--- a/backends/hostmem-ram.c
+++ b/backends/hostmem-ram.c
@@ -27,7 +27,7 @@ ram_backend_memory_alloc(HostMemoryBackend *backend, Error 
**errp)
 
 path = object_get_canonical_path_component(OBJECT(backend));
 memory_region_init_ram(&backend->mr, OBJECT(backend), path,
-   backend->size);
+   backend->size, &error_abort);
 g_free(path);
 }
 
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index 31947d9..5310006 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -844,7 +844,8 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
 
 /* Main memory region, 0x00...  Real hardware supports 32GB,
but the address space hole reserved at this point is 8TB.  */
-memory_region_init_ram(&s->ram_region

[Qemu-devel] [PATCH v7 RESEND 3/8] memory: add parameter errp to memory_region_init_ram_ptr

2014-09-08 Thread Hu Tao
Add parameter errp to memory_region_init_ram_ptr and update all call
sites to pass in &error_abort.

Reviewed-by: Peter Crosthwaite 
Signed-off-by: Hu Tao 
---
 hw/display/g364fb.c  | 2 +-
 hw/i386/kvm/pci-assign.c | 3 ++-
 hw/misc/ivshmem.c| 5 +++--
 hw/misc/vfio.c   | 3 ++-
 hw/ppc/spapr.c   | 2 +-
 include/exec/memory.h| 4 +++-
 memory.c | 5 +++--
 7 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/hw/display/g364fb.c b/hw/display/g364fb.c
index 46f7b41..cce33ae 100644
--- a/hw/display/g364fb.c
+++ b/hw/display/g364fb.c
@@ -487,7 +487,7 @@ static void g364fb_init(DeviceState *dev, G364State *s)
 
 memory_region_init_io(&s->mem_ctrl, NULL, &g364fb_ctrl_ops, s, "ctrl", 
0x18);
 memory_region_init_ram_ptr(&s->mem_vram, NULL, "vram",
-   s->vram_size, s->vram);
+   s->vram_size, s->vram, &error_abort);
 vmstate_register_ram(&s->mem_vram, dev);
 memory_region_set_coalescing(&s->mem_vram);
 }
diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
index 13b9de0..b37d606 100644
--- a/hw/i386/kvm/pci-assign.c
+++ b/hw/i386/kvm/pci-assign.c
@@ -456,7 +456,8 @@ static void assigned_dev_register_regions(PCIRegion 
*io_regions,
  object_get_typename(OBJECT(pci_dev)), i);
 memory_region_init_ram_ptr(&pci_dev->v_addrs[i].real_iomem,
OBJECT(pci_dev), name,
-   cur_region->size, virtbase);
+   cur_region->size, virtbase,
+   &error_abort);
 vmstate_register_ram(&pci_dev->v_addrs[i].real_iomem,
  &pci_dev->dev.qdev);
 }
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index bd9d718..906a6b5 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -352,7 +352,7 @@ static void create_shared_memory_BAR(IVShmemState *s, int 
fd) {
 ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
 
 memory_region_init_ram_ptr(&s->ivshmem, OBJECT(s), "ivshmem.bar2",
-   s->ivshmem_size, ptr);
+   s->ivshmem_size, ptr, &error_abort);
 vmstate_register_ram(&s->ivshmem, DEVICE(s));
 memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
 
@@ -480,7 +480,8 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, 
int flags)
 map_ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED,
 incoming_fd, 0);
 memory_region_init_ram_ptr(&s->ivshmem, OBJECT(s),
-   "ivshmem.bar2", s->ivshmem_size, map_ptr);
+   "ivshmem.bar2", s->ivshmem_size, map_ptr,
+   &error_abort);
 vmstate_register_ram(&s->ivshmem, DEVICE(s));
 
 IVSHMEM_DPRINTF("guest h/w addr = %p, size = %" PRIu64 "\n",
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index 40dcaa6..abb8d1b 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -2910,7 +2910,8 @@ static int vfio_mmap_bar(VFIODevice *vdev, VFIOBAR *bar,
 goto empty_region;
 }
 
-memory_region_init_ram_ptr(submem, OBJECT(vdev), name, size, *map);
+memory_region_init_ram_ptr(submem, OBJECT(vdev), name, size, *map,
+   &error_abort);
 } else {
 empty_region:
 /* Create a zero sized sub-region to make cleanup easy. */
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 2ab4460..3c4aaf0 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1402,7 +1402,7 @@ static void ppc_spapr_init(MachineState *machine)
 if (rma_alloc_size && rma) {
 rma_region = g_new(MemoryRegion, 1);
 memory_region_init_ram_ptr(rma_region, NULL, "ppc_spapr.rma",
-   rma_alloc_size, rma);
+   rma_alloc_size, rma, &error_abort);
 vmstate_register_ram_global(rma_region);
 memory_region_add_subregion(sysmem, 0, rma_region);
 }
diff --git a/include/exec/memory.h b/include/exec/memory.h
index fd4131b..dcb35a2 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -351,12 +351,14 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
  * @name: the name of the region.
  * @size: size of the region.
  * @ptr: memory to be mapped; must contain at least @size bytes.
+ * @errp: pointer to Error*, to store an error if it happens.
  */
 void memory_region_init_ram_ptr(MemoryRegion *mr,
 struct O

[Qemu-devel] [PATCH v7 RESEND 5/8] hostmem-ram: don't exit qemu if size of memory-backend-ram is way too big

2014-09-08 Thread Hu Tao
When using monitor command object_add to add a memory backend whose
size is way too big to allocate memory for it, qemu just exits. In
the case we'd better give an error message and keep guest running.

The problem can be reproduced as follows:

1. run qemu
2. (monitor)object_add memory-backend-ram,size=10G,id=ram0

Reviewed-by: Peter Crosthwaite 
Signed-off-by: Hu Tao 
---
 backends/hostmem-ram.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c
index e55d066..a67a134 100644
--- a/backends/hostmem-ram.c
+++ b/backends/hostmem-ram.c
@@ -27,7 +27,7 @@ ram_backend_memory_alloc(HostMemoryBackend *backend, Error 
**errp)
 
 path = object_get_canonical_path_component(OBJECT(backend));
 memory_region_init_ram(&backend->mr, OBJECT(backend), path,
-   backend->size, &error_abort);
+   backend->size, errp);
 g_free(path);
 }
 
-- 
1.9.3




[Qemu-devel] [PATCH v7 RESEND 4/8] memory: add parameter errp to memory_region_init_rom_device

2014-09-08 Thread Hu Tao
Add parameter errp to memory_region_init_rom_device and update all call
sites to pass in &error_abort.

Reviewed-by: Peter Crosthwaite 
Signed-off-by: Hu Tao 
---
 hw/block/pflash_cfi01.c | 2 +-
 hw/block/pflash_cfi02.c | 2 +-
 include/exec/memory.h   | 4 +++-
 memory.c| 5 +++--
 4 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 593fbc5..4d51bfd 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -773,7 +773,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error 
**errp)
 memory_region_init_rom_device(
 &pfl->mem, OBJECT(dev),
 pfl->be ? &pflash_cfi01_ops_be : &pflash_cfi01_ops_le, pfl,
-pfl->name, total_len);
+pfl->name, total_len, &error_abort);
 vmstate_register_ram(&pfl->mem, DEVICE(pfl));
 pfl->storage = memory_region_get_ram_ptr(&pfl->mem);
 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem);
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index e196f4d..29bb0dc 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -608,7 +608,7 @@ static void pflash_cfi02_realize(DeviceState *dev, Error 
**errp)
 
 memory_region_init_rom_device(&pfl->orig_mem, OBJECT(pfl), pfl->be ?
   &pflash_cfi02_ops_be : &pflash_cfi02_ops_le,
-  pfl, pfl->name, chip_len);
+  pfl, pfl->name, chip_len, &error_abort);
 vmstate_register_ram(&pfl->orig_mem, DEVICE(pfl));
 pfl->storage = memory_region_get_ram_ptr(&pfl->orig_mem);
 pfl->chip_len = chip_len;
diff --git a/include/exec/memory.h b/include/exec/memory.h
index dcb35a2..4921d27 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -388,13 +388,15 @@ void memory_region_init_alias(MemoryRegion *mr,
  * @ops: callbacks for write access handling.
  * @name: the name of the region.
  * @size: size of the region.
+ * @errp: pointer to Error*, to store an error if it happens.
  */
 void memory_region_init_rom_device(MemoryRegion *mr,
struct Object *owner,
const MemoryRegionOps *ops,
void *opaque,
const char *name,
-   uint64_t size);
+   uint64_t size,
+   Error **errp);
 
 /**
  * memory_region_init_reservation: Initialize a memory region that reserves
diff --git a/memory.c b/memory.c
index ffe24ff..38c29df 100644
--- a/memory.c
+++ b/memory.c
@@ -1202,7 +1202,8 @@ void memory_region_init_rom_device(MemoryRegion *mr,
const MemoryRegionOps *ops,
void *opaque,
const char *name,
-   uint64_t size)
+   uint64_t size,
+   Error **errp)
 {
 memory_region_init(mr, owner, name, size);
 mr->ops = ops;
@@ -1210,7 +1211,7 @@ void memory_region_init_rom_device(MemoryRegion *mr,
 mr->terminates = true;
 mr->rom_device = true;
 mr->destructor = memory_region_destructor_rom_device;
-mr->ram_addr = qemu_ram_alloc(size, mr, &error_abort);
+mr->ram_addr = qemu_ram_alloc(size, mr, errp);
 }
 
 void memory_region_init_iommu(MemoryRegion *mr,
-- 
1.9.3




[Qemu-devel] [PATCH v7 RESEND 1/8] exec: add parameter errp to qemu_ram_alloc and qemu_ram_alloc_from_ptr

2014-09-08 Thread Hu Tao
Add parameter errp to qemu_ram_alloc and qemu_ram_alloc_from_ptr so that
we can handle errors.

Signed-off-by: Hu Tao 
Reviewed-by: Peter Crosthwaite 
---
 exec.c  | 36 +++-
 include/exec/ram_addr.h |  4 ++--
 memory.c|  6 +++---
 3 files changed, 32 insertions(+), 14 deletions(-)

diff --git a/exec.c b/exec.c
index 7dddcc8..2b9c4c5 100644
--- a/exec.c
+++ b/exec.c
@@ -1259,7 +1259,7 @@ static int memory_try_enable_merging(void *addr, size_t 
len)
 return qemu_madvise(addr, len, QEMU_MADV_MERGEABLE);
 }
 
-static ram_addr_t ram_block_add(RAMBlock *new_block)
+static ram_addr_t ram_block_add(RAMBlock *new_block, Error **errp)
 {
 RAMBlock *block;
 ram_addr_t old_ram_size, new_ram_size;
@@ -1276,9 +1276,11 @@ static ram_addr_t ram_block_add(RAMBlock *new_block)
 } else {
 new_block->host = phys_mem_alloc(new_block->length);
 if (!new_block->host) {
-fprintf(stderr, "Cannot set up guest memory '%s': %s\n",
-memory_region_name(new_block->mr), strerror(errno));
-exit(1);
+error_setg_errno(errp, errno,
+ "cannot set up guest memory '%s'",
+ memory_region_name(new_block->mr));
+qemu_mutex_unlock_ramlist();
+return -1;
 }
 memory_try_enable_merging(new_block->host, new_block->length);
 }
@@ -1329,6 +1331,8 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, 
MemoryRegion *mr,
 Error **errp)
 {
 RAMBlock *new_block;
+ram_addr_t addr;
+Error *local_err = NULL;
 
 if (xen_enabled()) {
 error_setg(errp, "-mem-path not supported with Xen");
@@ -1358,14 +1362,22 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, 
MemoryRegion *mr,
 return -1;
 }
 
-return ram_block_add(new_block);
+addr = ram_block_add(new_block, &local_err);
+if (local_err) {
+g_free(new_block);
+error_propagate(errp, local_err);
+return -1;
+}
+return addr;
 }
 #endif
 
 ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
-   MemoryRegion *mr)
+   MemoryRegion *mr, Error **errp)
 {
 RAMBlock *new_block;
+ram_addr_t addr;
+Error *local_err = NULL;
 
 size = TARGET_PAGE_ALIGN(size);
 new_block = g_malloc0(sizeof(*new_block));
@@ -1376,12 +1388,18 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, 
void *host,
 if (host) {
 new_block->flags |= RAM_PREALLOC;
 }
-return ram_block_add(new_block);
+addr = ram_block_add(new_block, &local_err);
+if (local_err) {
+g_free(new_block);
+error_propagate(errp, local_err);
+return -1;
+}
+return addr;
 }
 
-ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr)
+ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr, Error **errp)
 {
-return qemu_ram_alloc_from_ptr(size, NULL, mr);
+return qemu_ram_alloc_from_ptr(size, NULL, mr, errp);
 }
 
 void qemu_ram_free_from_ptr(ram_addr_t addr)
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 6593be1..cf1d4c7 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -26,8 +26,8 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, 
MemoryRegion *mr,
 bool share, const char *mem_path,
 Error **errp);
 ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
-   MemoryRegion *mr);
-ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
+   MemoryRegion *mr, Error **errp);
+ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr, Error **errp);
 int qemu_get_ram_fd(ram_addr_t addr);
 void *qemu_get_ram_block_host_ptr(ram_addr_t addr);
 void *qemu_get_ram_ptr(ram_addr_t addr);
diff --git a/memory.c b/memory.c
index 1bae951..17cf40d 100644
--- a/memory.c
+++ b/memory.c
@@ -1148,7 +1148,7 @@ void memory_region_init_ram(MemoryRegion *mr,
 mr->ram = true;
 mr->terminates = true;
 mr->destructor = memory_region_destructor_ram;
-mr->ram_addr = qemu_ram_alloc(size, mr);
+mr->ram_addr = qemu_ram_alloc(size, mr, &error_abort);
 }
 
 #ifdef __linux__
@@ -1178,7 +1178,7 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
 mr->ram = true;
 mr->terminates = true;
 mr->destructor = memory_region_destructor_ram_from_ptr;
-mr->ram_addr = qemu_ram_alloc_from_ptr(size, ptr, mr);
+mr->ram_addr = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_abort);
 }
 
 void memory_region_init_alias(MemoryRegion *mr,
@@ -1208,7 +1208,7 @@ void mem

[Qemu-devel] [PATCH v7 RESEND 0/8] memory API improvements and bug fixes for memory backends

2014-09-08 Thread Hu Tao
This is merely a rebase of v7, and fixes two merge conflicts.

This series includes two parts:
 
  1. part 1 includes patches 1-4, which improves error handling of
 memory_region_init_ram, memory_region_init_ram_ptr and
 memory_region_init_rom_device
 
  2. part 2 includes patches 5-8, each fixes a bug of memory backend.
 
changes:

  v7:
  - split the memory-file preallocation fix into its own patch(patch 6)
  - some commit messages tweaks

  v6:
  - split patch 6 in v5 into 2
  - use local_err instead of errp
  - typo fixes

  v5:
  - don't introduce _may_fail and _nofail versions of memory API
  - the patches order of bug fix and memory API change is exchanged, first
comes the API change, then bug fix.

  v4:
  - fix build on 32bit host
  - add memory API renaming
  - rebase on latest master

  v3:
  - introduce memory_region_init_ram_may_fail and
memory_region_init_ram_ptr_may_fail
  - address comments by MST
  - missing the functions renaming. will send later.

  v2:
  - split patch 1 in v1 into 2 patches
  - don't rely on ram_block_add to return -1
  - error message tweak in file_ram_alloc
  - add error messages reported by qemu to commit message of patch 3

  v1:
  - initial version


Hu Tao (8):
  exec: add parameter errp to qemu_ram_alloc and qemu_ram_alloc_from_ptr
  memory: add parameter errp to memory_region_init_ram
  memory: add parameter errp to memory_region_init_ram_ptr
  memory: add parameter errp to memory_region_init_rom_device
  hostmem-ram: don't exit qemu if size of memory-backend-ram is way too
big
  exec: file_ram_alloc: don't exit if failed to preallocate memory
  exec: report error when memory < hpagesize
  exec: add parameter errp to gethugepagesize

 backends/hostmem-ram.c   |  2 +-
 exec.c   | 60 ++--
 hw/alpha/typhoon.c   |  3 +-
 hw/arm/armv7m.c  |  7 ++--
 hw/arm/cubieboard.c  |  2 +-
 hw/arm/digic_boards.c|  2 +-
 hw/arm/exynos4210.c  |  9 ++---
 hw/arm/highbank.c|  5 +--
 hw/arm/integratorcp.c|  5 +--
 hw/arm/kzm.c |  4 +--
 hw/arm/mainstone.c   |  3 +-
 hw/arm/musicpal.c|  6 ++--
 hw/arm/omap1.c   |  6 ++--
 hw/arm/omap2.c   |  6 ++--
 hw/arm/omap_sx1.c|  6 ++--
 hw/arm/palm.c|  3 +-
 hw/arm/pxa2xx.c  | 11 +++---
 hw/arm/realview.c|  9 +++--
 hw/arm/spitz.c   |  2 +-
 hw/arm/strongarm.c   |  3 +-
 hw/arm/tosa.c|  2 +-
 hw/arm/versatilepb.c |  3 +-
 hw/arm/vexpress.c| 15 +---
 hw/arm/virt.c|  3 +-
 hw/arm/xilinx_zynq.c |  6 ++--
 hw/block/onenand.c   |  2 +-
 hw/block/pflash_cfi01.c  |  2 +-
 hw/block/pflash_cfi02.c  |  2 +-
 hw/core/loader.c |  2 +-
 hw/cris/axis_dev88.c |  6 ++--
 hw/display/cg3.c |  6 ++--
 hw/display/g364fb.c  |  2 +-
 hw/display/qxl.c |  6 ++--
 hw/display/sm501.c   |  2 +-
 hw/display/tc6393xb.c|  3 +-
 hw/display/tcx.c |  5 +--
 hw/display/vga.c |  3 +-
 hw/display/vmware_vga.c  |  3 +-
 hw/i386/kvm/pci-assign.c |  6 ++--
 hw/i386/pc.c |  3 +-
 hw/i386/pc_sysfw.c   |  5 +--
 hw/input/milkymist-softusb.c |  4 +--
 hw/lm32/lm32_boards.c|  6 ++--
 hw/lm32/milkymist.c  |  3 +-
 hw/m68k/an5206.c |  4 +--
 hw/m68k/dummy_m68k.c |  2 +-
 hw/m68k/mcf5208.c|  4 +--
 hw/microblaze/petalogix_ml605_mmu.c  |  5 +--
 hw/microblaze/petalogix_s3adsp1800_mmu.c |  6 ++--
 hw/mips/mips_fulong2e.c  |  5 +--
 hw/mips/mips_jazz.c  |  8 +++--
 hw/mips/mips_malta.c |  6 ++--
 hw/mips/mips_mipssim.c   |  6 ++--
 hw/mips/mips_r4k.c   |  5 +--
 hw/misc/ivshmem.c|  5 +--
 hw/misc/vfio.c   |  3 +-
 hw/moxie/moxiesim.c  |  4 +--
 hw/net/milkymist-minimac2.c  |  2 +-
 hw/openrisc/openrisc_sim.c   |  2 +-
 hw/pci-host/prep.c   |  3 +-
 hw/pci/pci.c |  2 +-
 hw/ppc/mac_newworld.c|  3 +-
 hw/ppc/mac_oldworld.c|  3 +-

[Qemu-devel] [PATCH v14 4/5] raw-posix: Add falloc and full preallocation option

2014-09-08 Thread Hu Tao
This patch adds a new option preallocation for raw format, and implements
falloc and full preallocation.

Signed-off-by: Hu Tao 
Reviewed-by: Max Reitz 
---
 block/raw-posix.c | 93 +++
 qemu-doc.texi |  9 ++
 qemu-img.texi |  9 ++
 3 files changed, 92 insertions(+), 19 deletions(-)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 7208c05..27c854c 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -30,6 +30,7 @@
 #include "block/thread-pool.h"
 #include "qemu/iov.h"
 #include "raw-aio.h"
+#include "qapi/util.h"
 
 #if defined(__APPLE__) && (__MACH__)
 #include 
@@ -1365,6 +1366,9 @@ static int raw_create(const char *filename, QemuOpts 
*opts, Error **errp)
 int result = 0;
 int64_t total_size = 0;
 bool nocow = false;
+PreallocMode prealloc;
+char *buf = NULL;
+Error *local_err = NULL;
 
 strstart(filename, "file:", &filename);
 
@@ -1372,37 +1376,83 @@ static int raw_create(const char *filename, QemuOpts 
*opts, Error **errp)
 total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
   BDRV_SECTOR_SIZE);
 nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false);
+buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
+prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
+   PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
+   &local_err);
+g_free(buf);
+if (local_err) {
+error_propagate(errp, local_err);
+result = -EINVAL;
+goto out;
+}
 
 fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
0644);
 if (fd < 0) {
 result = -errno;
 error_setg_errno(errp, -result, "Could not create file");
-} else {
-if (nocow) {
+goto out;
+}
+
+if (nocow) {
 #ifdef __linux__
-/* Set NOCOW flag to solve performance issue on fs like btrfs.
- * This is an optimisation. The FS_IOC_SETFLAGS ioctl return value
- * will be ignored since any failure of this operation should not
- * block the left work.
- */
-int attr;
-if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) {
-attr |= FS_NOCOW_FL;
-ioctl(fd, FS_IOC_SETFLAGS, &attr);
-}
-#endif
+/* Set NOCOW flag to solve performance issue on fs like btrfs.
+ * This is an optimisation. The FS_IOC_SETFLAGS ioctl return value
+ * will be ignored since any failure of this operation should not
+ * block the left work.
+ */
+int attr;
+if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) {
+attr |= FS_NOCOW_FL;
+ioctl(fd, FS_IOC_SETFLAGS, &attr);
 }
+#endif
+}
 
-if (ftruncate(fd, total_size) != 0) {
-result = -errno;
-error_setg_errno(errp, -result, "Could not resize file");
+if (ftruncate(fd, total_size) != 0) {
+result = -errno;
+error_setg_errno(errp, -result, "Could not resize file");
+goto out_close;
+}
+
+if (prealloc == PREALLOC_MODE_FALLOC) {
+/* posix_fallocate() doesn't set errno. */
+result = -posix_fallocate(fd, 0, total_size);
+if (result != 0) {
+error_setg_errno(errp, -result,
+ "Could not preallocate data for the new file");
 }
-if (qemu_close(fd) != 0) {
-result = -errno;
-error_setg_errno(errp, -result, "Could not close the new file");
+} else if (prealloc == PREALLOC_MODE_FULL) {
+buf = g_malloc0(65536);
+int64_t num = 0, left = total_size;
+
+while (left > 0) {
+num = MIN(left, 65536);
+result = write(fd, buf, num);
+if (result < 0) {
+result = -errno;
+error_setg_errno(errp, -result,
+ "Could not write to the new file");
+g_free(buf);
+goto out_close;
+}
+left -= num;
 }
+fsync(fd);
+g_free(buf);
+} else if (prealloc != PREALLOC_MODE_OFF) {
+result = -EINVAL;
+error_setg(errp, "Unsupported preallocation mode: %s",
+   PreallocMode_lookup[prealloc]);
 }
+
+out_close:
+if (qemu_close(fd) != 0 && result == 0) {
+result = -errno;
+error_setg_errno(errp, -result, "Could not close the new file");
+}
+out:
 return result;
 }
 
@@ -1585,6 +1635,11 @@ static QemuOptsList raw_create_opts = {
 .type = QEMU_OPT_BOOL,
 .help = "Turn off copy-on-write (valid only on btrfs)"
 },
+{

[Qemu-devel] [PATCH v14 5/5] qcow2: Add falloc and full preallocation option

2014-09-08 Thread Hu Tao
preallocation=falloc allocates disk space by posix_fallocate(),
preallocation=full allocates disk space by writing zeros to disk.
Both modes imply preallocation=metadata.

Signed-off-by: Hu Tao 
Reviewed-by: Max Reitz 
---
 block/qcow2.c  | 62 +++---
 qemu-doc.texi  |  8 +++---
 qemu-img.texi  |  8 +++---
 tests/qemu-iotests/082.out | 54 
 4 files changed, 90 insertions(+), 42 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 94d1225..375c6a6 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1772,6 +1772,56 @@ static int qcow2_create2(const char *filename, int64_t 
total_size,
 Error *local_err = NULL;
 int ret;
 
+if (prealloc == PREALLOC_MODE_FULL || prealloc == PREALLOC_MODE_FALLOC) {
+int64_t meta_size = 0;
+uint64_t nreftablee, nrefblocke, nl1e, nl2e;
+int64_t aligned_total_size = align_offset(total_size, cluster_size);
+
+/* header: 1 cluster */
+meta_size += cluster_size;
+
+/* total size of L2 tables */
+nl2e = aligned_total_size / cluster_size;
+nl2e = align_offset(nl2e, cluster_size / sizeof(uint64_t));
+meta_size += nl2e * sizeof(uint64_t);
+
+/* total size of L1 tables */
+nl1e = nl2e * sizeof(uint64_t) / cluster_size;
+nl1e = align_offset(nl1e, cluster_size / sizeof(uint64_t));
+meta_size += nl1e * sizeof(uint64_t);
+
+/* total size of refcount blocks
+ *
+ * note: every host cluster is reference-counted, including metadata
+ * (even refcount blocks are recursively included).
+ * Let:
+ *   a = total_size (this is the guest disk size)
+ *   m = meta size not including refcount blocks and refcount tables
+ *   c = cluster size
+ *   y1 = number of refcount blocks entries
+ *   y2 = meta size including everything
+ * then,
+ *   y1 = (y2 + a)/c
+ *   y2 = y1 * sizeof(u16) + y1 * sizeof(u16) * sizeof(u64) / c + m
+ * we can get y1:
+ *   y1 = (a + m) / (c - sizeof(u16) - sizeof(u16) * sizeof(u64) / c)
+ */
+nrefblocke = (aligned_total_size + meta_size + cluster_size) /
+(cluster_size - sizeof(uint16_t) -
+ 1.0 * sizeof(uint16_t) * sizeof(uint64_t) / cluster_size);
+nrefblocke = align_offset(nrefblocke, cluster_size / sizeof(uint16_t));
+meta_size += nrefblocke * sizeof(uint16_t);
+
+/* total size of refcount tables */
+nreftablee = nrefblocke * sizeof(uint16_t) / cluster_size;
+nreftablee = align_offset(nreftablee, cluster_size / sizeof(uint64_t));
+meta_size += nreftablee * sizeof(uint64_t);
+
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
+aligned_total_size + meta_size);
+qemu_opt_set(opts, BLOCK_OPT_PREALLOC, PreallocMode_lookup[prealloc]);
+}
+
 ret = bdrv_create_file(filename, opts, &local_err);
 if (ret < 0) {
 error_propagate(errp, local_err);
@@ -1877,7 +1927,7 @@ static int qcow2_create2(const char *filename, int64_t 
total_size,
 }
 
 /* And if we're supposed to preallocate metadata, do that now */
-if (prealloc) {
+if (prealloc != PREALLOC_MODE_OFF) {
 BDRVQcowState *s = bs->opaque;
 qemu_co_mutex_lock(&s->lock);
 ret = preallocate(bs);
@@ -1958,13 +2008,6 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 flags |= BLOCK_FLAG_LAZY_REFCOUNTS;
 }
 
-if (prealloc && prealloc != PREALLOC_MODE_METADATA) {
-ret = -EINVAL;
-error_setg(errp, "Unsupported preallocate mode: %s",
-   PreallocMode_lookup[prealloc]);
-goto finish;
-}
-
 if (backing_file && prealloc) {
 error_setg(errp, "Backing file and preallocation cannot be used at "
"the same time");
@@ -2525,7 +2568,8 @@ static QemuOptsList qcow2_create_opts = {
 {
 .name = BLOCK_OPT_PREALLOC,
 .type = QEMU_OPT_STRING,
-.help = "Preallocation mode (allowed values: off, metadata)"
+.help = "Preallocation mode (allowed values: off, metadata, "
+"falloc, full)"
 },
 {
 .name = BLOCK_OPT_LAZY_REFCOUNTS,
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 1f289d6..ef3be72 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -584,9 +584,11 @@ sizes can improve the image file size whereas larger 
cluster sizes generally
 provide better performance.
 
 @item preallocation
-Preallocation mode (allowed values: off, metadata). An image with preallocated
-metadata is initially larger but can improve performance when the image needs
-to grow.
+Preallocation mode (allowed values: @code{off}, @code{me

[Qemu-devel] [PATCH v14 3/5] qapi: introduce PreallocMode and new PreallocModes full and falloc.

2014-09-08 Thread Hu Tao
This patch prepares for the subsequent patches.

Signed-off-by: Hu Tao 
Reviewed-by: Max Reitz 
Reviewed-by: Kevin Wolf 
---
 block/qcow2.c  | 23 +++
 qapi/block-core.json   | 17 +
 tests/qemu-iotests/049.out |  2 +-
 3 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index cf27c3f..94d1225 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -30,6 +30,7 @@
 #include "qemu/error-report.h"
 #include "qapi/qmp/qerror.h"
 #include "qapi/qmp/qbool.h"
+#include "qapi/util.h"
 #include "trace.h"
 #include "qemu/option_int.h"
 
@@ -1738,7 +1739,7 @@ static int preallocate(BlockDriverState *bs)
 
 static int qcow2_create2(const char *filename, int64_t total_size,
  const char *backing_file, const char *backing_format,
- int flags, size_t cluster_size, int prealloc,
+ int flags, size_t cluster_size, PreallocMode prealloc,
  QemuOpts *opts, int version,
  Error **errp)
 {
@@ -1915,7 +1916,7 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 uint64_t size = 0;
 int flags = 0;
 size_t cluster_size = DEFAULT_CLUSTER_SIZE;
-int prealloc = 0;
+PreallocMode prealloc;
 int version = 3;
 Error *local_err = NULL;
 int ret;
@@ -1931,12 +1932,11 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE,
  DEFAULT_CLUSTER_SIZE);
 buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
-if (!buf || !strcmp(buf, "off")) {
-prealloc = 0;
-} else if (!strcmp(buf, "metadata")) {
-prealloc = 1;
-} else {
-error_setg(errp, "Invalid preallocation mode: '%s'", buf);
+prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
+   PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
+   &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
 ret = -EINVAL;
 goto finish;
 }
@@ -1958,6 +1958,13 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 flags |= BLOCK_FLAG_LAZY_REFCOUNTS;
 }
 
+if (prealloc && prealloc != PREALLOC_MODE_METADATA) {
+ret = -EINVAL;
+error_setg(errp, "Unsupported preallocate mode: %s",
+   PreallocMode_lookup[prealloc]);
+goto finish;
+}
+
 if (backing_file && prealloc) {
 error_setg(errp, "Backing file and preallocation cannot be used at "
"the same time");
diff --git a/qapi/block-core.json b/qapi/block-core.json
index a685d02..a29dbe1 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1697,3 +1697,20 @@
 'len'   : 'int',
 'offset': 'int',
 'speed' : 'int' } }
+
+# @PreallocMode
+#
+# Preallocation mode of QEMU image file
+#
+# @off: no preallocation
+# @metadata: preallocate only for metadata
+# @falloc: like @full preallocation but allocate disk space by
+#  posix_fallocate() rather than writing zeros.
+# @full: preallocate all data by writing zeros to device to ensure disk
+#space is really available. @full preallocation also sets up
+#metadata correctly.
+#
+# Since 2.2
+##
+{ 'enum': 'PreallocMode',
+  'data': [ 'off', 'metadata', 'falloc', 'full' ] }
diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out
index 71ca44d..09ca0ae 100644
--- a/tests/qemu-iotests/049.out
+++ b/tests/qemu-iotests/049.out
@@ -179,7 +179,7 @@ qemu-img create -f qcow2 -o preallocation=metadata 
TEST_DIR/t.qcow2 64M
 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off 
cluster_size=65536 preallocation='metadata' lazy_refcounts=off 
 
 qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M
-qemu-img: TEST_DIR/t.qcow2: Invalid preallocation mode: '1234'
+qemu-img: TEST_DIR/t.qcow2: invalid parameter value: 1234
 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off 
cluster_size=65536 preallocation='1234' lazy_refcounts=off 
 
 == Check encryption option ==
-- 
1.9.3




[Qemu-devel] [PATCH v14 2/5] block: don't convert file size to sector size

2014-09-08 Thread Hu Tao
and avoid converting it back later.

Signed-off-by: Hu Tao 
Reviewed-by: Max Reitz 
---
 block/gluster.c   |  9 -
 block/qcow.c  |  8 
 block/qcow2.c | 10 +-
 block/raw-posix.c | 12 ++--
 block/raw-win32.c |  6 +++---
 5 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/block/gluster.c b/block/gluster.c
index 65c7a58..1eb3a8c 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -494,8 +494,8 @@ static int qemu_gluster_create(const char *filename,
 goto out;
 }
 
-total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
-  BDRV_SECTOR_SIZE);
+total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 
 tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
 if (!tmp || !strcmp(tmp, "off")) {
@@ -516,9 +516,8 @@ static int qemu_gluster_create(const char *filename,
 if (!fd) {
 ret = -errno;
 } else {
-if (!glfs_ftruncate(fd, total_size * BDRV_SECTOR_SIZE)) {
-if (prealloc && qemu_gluster_zerofill(fd, 0,
-total_size * BDRV_SECTOR_SIZE)) {
+if (!glfs_ftruncate(fd, total_size)) {
+if (prealloc && qemu_gluster_zerofill(fd, 0, total_size)) {
 ret = -errno;
 }
 } else {
diff --git a/block/qcow.c b/block/qcow.c
index 041af26..a87bd69 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -725,8 +725,8 @@ static int qcow_create(const char *filename, QemuOpts 
*opts, Error **errp)
 BlockDriverState *qcow_bs;
 
 /* Read out options */
-total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
-  BDRV_SECTOR_SIZE);
+total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
 if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
 flags |= BLOCK_FLAG_ENCRYPT;
@@ -754,7 +754,7 @@ static int qcow_create(const char *filename, QemuOpts 
*opts, Error **errp)
 memset(&header, 0, sizeof(header));
 header.magic = cpu_to_be32(QCOW_MAGIC);
 header.version = cpu_to_be32(QCOW_VERSION);
-header.size = cpu_to_be64(total_size * 512);
+header.size = cpu_to_be64(total_size);
 header_size = sizeof(header);
 backing_filename_len = 0;
 if (backing_file) {
@@ -776,7 +776,7 @@ static int qcow_create(const char *filename, QemuOpts 
*opts, Error **errp)
 }
 header_size = (header_size + 7) & ~7;
 shift = header.cluster_bits + header.l2_bits;
-l1_size = ((total_size * 512) + (1LL << shift) - 1) >> shift;
+l1_size = (total_size + (1LL << shift) - 1) >> shift;
 
 header.l1_table_offset = cpu_to_be64(header_size);
 if (flags & BLOCK_FLAG_ENCRYPT) {
diff --git a/block/qcow2.c b/block/qcow2.c
index c8050e5..cf27c3f 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1859,7 +1859,7 @@ static int qcow2_create2(const char *filename, int64_t 
total_size,
 }
 
 /* Okay, now that we have a valid image, let's give it the right size */
-ret = bdrv_truncate(bs, total_size * BDRV_SECTOR_SIZE);
+ret = bdrv_truncate(bs, total_size);
 if (ret < 0) {
 error_setg_errno(errp, -ret, "Could not resize image");
 goto out;
@@ -1912,7 +1912,7 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 char *backing_file = NULL;
 char *backing_fmt = NULL;
 char *buf = NULL;
-uint64_t sectors = 0;
+uint64_t size = 0;
 int flags = 0;
 size_t cluster_size = DEFAULT_CLUSTER_SIZE;
 int prealloc = 0;
@@ -1921,8 +1921,8 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 int ret;
 
 /* Read out options */
-sectors = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
-   BDRV_SECTOR_SIZE);
+size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+BDRV_SECTOR_SIZE);
 backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
 backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
 if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
@@ -1972,7 +1972,7 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 goto finish;
 }
 
-ret = qcow2_create2(filename, sectors, backing_file, backing_fmt, flags,
+ret = qcow2_create2(filename, size, backing_file, backing_fmt, flags,
 cluster_size, prealloc, opts, version, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 9c22e3f..7208c05 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1369,8 +1369,8 @@ static int raw_create(const char 

[Qemu-devel] [PATCH v14 1/5] block: round up file size to nearest sector

2014-09-08 Thread Hu Tao
Signed-off-by: Hu Tao 
Reviewed-by: Kevin Wolf 
Reviewed-by: Eric Blake 
Reviewed-by: Max Reitz 
---
 block/archipelago.c  |  3 ++-
 block/cow.c  |  3 ++-
 block/gluster.c  |  4 +--
 block/iscsi.c|  4 +--
 block/nfs.c  |  3 ++-
 block/qcow.c |  3 ++-
 block/qcow2.c|  3 ++-
 block/qed.c  |  3 ++-
 block/raw-posix.c|  8 +++---
 block/raw-win32.c|  4 +--
 block/rbd.c  |  3 ++-
 block/sheepdog.c |  3 ++-
 block/ssh.c  |  3 ++-
 block/vdi.c  |  3 ++-
 block/vhdx.c |  3 ++-
 block/vmdk.c |  3 ++-
 block/vpc.c  |  3 ++-
 tests/qemu-iotests/104   | 57 
 tests/qemu-iotests/104.out   | 12 +
 tests/qemu-iotests/common.filter | 21 +++
 tests/qemu-iotests/group |  1 +
 21 files changed, 127 insertions(+), 23 deletions(-)
 create mode 100755 tests/qemu-iotests/104
 create mode 100644 tests/qemu-iotests/104.out

diff --git a/block/archipelago.c b/block/archipelago.c
index 22a7daa..06c51f9 100644
--- a/block/archipelago.c
+++ b/block/archipelago.c
@@ -708,7 +708,8 @@ static int qemu_archipelago_create(const char *filename,
 
 parse_filename_opts(filename, errp, &volname, &segment_name, &mport,
 &vport);
-total_size = qemu_opt_get_size_del(options, BLOCK_OPT_SIZE, 0);
+total_size = ROUND_UP(qemu_opt_get_size_del(options, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 
 if (segment_name == NULL) {
 segment_name = g_strdup("archipelago");
diff --git a/block/cow.c b/block/cow.c
index 6ee4833..c3769fe 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -335,7 +335,8 @@ static int cow_create(const char *filename, QemuOpts *opts, 
Error **errp)
 BlockDriverState *cow_bs = NULL;
 
 /* Read out options */
-image_sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
+image_sectors = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 
0),
+ BDRV_SECTOR_SIZE);
 image_filename = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
 
 ret = bdrv_create_file(filename, opts, &local_err);
diff --git a/block/gluster.c b/block/gluster.c
index 1912cf9..65c7a58 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -494,8 +494,8 @@ static int qemu_gluster_create(const char *filename,
 goto out;
 }
 
-total_size =
-qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
+total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 
 tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
 if (!tmp || !strcmp(tmp, "off")) {
diff --git a/block/iscsi.c b/block/iscsi.c
index 3e19202..84bcae8 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1531,8 +1531,8 @@ static int iscsi_create(const char *filename, QemuOpts 
*opts, Error **errp)
 bs = bdrv_new("", &error_abort);
 
 /* Read out options */
-total_size =
-qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
+total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 bs->opaque = g_new0(struct IscsiLun, 1);
 iscsilun = bs->opaque;
 
diff --git a/block/nfs.c b/block/nfs.c
index 194f301..c76e368 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -418,7 +418,8 @@ static int nfs_file_create(const char *url, QemuOpts *opts, 
Error **errp)
 client->aio_context = qemu_get_aio_context();
 
 /* Read out options */
-total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 
 ret = nfs_client_open(client, url, O_CREAT, errp);
 if (ret < 0) {
diff --git a/block/qcow.c b/block/qcow.c
index 67c237f..041af26 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -725,7 +725,8 @@ static int qcow_create(const char *filename, QemuOpts 
*opts, Error **errp)
 BlockDriverState *qcow_bs;
 
 /* Read out options */
-total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
+total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
 if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
 flags |= BLOCK_FLAG_ENCRYPT;
diff --git a/block/qcow2.c b/block/qcow2.c
index f9e045f..c8050e5 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1921,7 +1921,8 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Erro

[Qemu-devel] [PATCH v14 0/5] qcow2, raw: add preallocation=full and preallocation=falloc

2014-09-08 Thread Hu Tao
This series adds two preallocation mode to qcow2 and raw:

Option preallocation=full preallocates disk space for image by writing
zeros to disk, this ensures disk space in any cases.

Option preallocation=falloc preallocates disk space by calling
posix_fallocate(). This is faster than preallocation=full.

Note: there is a false positive reported by checkpatch.pl to patch 1.

changes to v13:

  - rebase (patch 3 in v13 is already in)
  - don't convert file size to sector size in hdev_create(), too (patch 2)
  - reintroduce preallocation=falloc. (patch 3)
  - split the implementation of preallocation=full in v13 into
preallocation=falloc and preallocation=full (patch 4)

changes to v12:

  - remove dependence on minimal_blob_size() (patch 6)
  - remove preallocation=falloc. (patch 4)
  - preallocation=full tries posix_fallocate() first then writing
zeros (patch 5)
  - round up file size for all formats (patch 1)
  - avoid converting file size for more formats (patch 2)

changes to v11:

 - fix test case 049 (patch 4)
 - unsigned nl2e -> uint64_t nl2e (patch 6)
 - use >> instead of / (patch 6)

changes to v10:

  - PreallocMode is moved from file qapi-schema.json to qapi/block-core.json
  - introdues preallocation=falloc, no changes to preallocation=metadata
  - using minimal_blob_size() to calculate metadata size for qcow2
  - indentation fix in file blockdev.c

changes to v9:

 - use ROUND_UP to do round up
 - split the round up into its own patch and add test case
 - new patch rename parse_enum_option to qapi_enum_parse and make it public
 - reuse qapi_enum_parse

changes to v8:

 - round up image file size to nearest sector size
 - dont' blindly lose error info
 - target for 2.1 rather than 2.0
 - and, rebase to latest git tree

changes to v5:

  - add `Since 2.0' to PreallocMode
  - apply total_size change to raw-win32.c as well

changes to v4:

  - fix wrong calculation of qcow2 metadata size in v4
  - remove raw_preallocate2()
  - better error out path in raw_create()
  - fix coding style

changes to v3:

  - remove bdrv_preallocate and make preallocation a
bdrv_create_file option
  - prealloc_mode -> PreallocMode and add it to QAPI
  - fix return value in raw_preallocate2

changes to v2:

  - Fix comments to v2 by Fam.
  - qcow2: first fallocate disk space, then allocate metadata. This avoids
the problem in v2 that bdrv_preallocate may clear all information in
metadata. This does not necessarily map all data clusters sequentially
but does keep information in metadata. Peter, is this acceptable?


Hu Tao (5):
  block: round up file size to nearest sector
  block: don't convert file size to sector size
  qapi: introduce PreallocMode and new PreallocModes full and falloc.
  raw-posix: Add falloc and full preallocation option
  qcow2: Add falloc and full preallocation option

 block/archipelago.c  |   3 +-
 block/cow.c  |   3 +-
 block/gluster.c  |   9 ++--
 block/iscsi.c|   4 +-
 block/nfs.c  |   3 +-
 block/qcow.c |   7 +--
 block/qcow2.c|  80 --
 block/qed.c  |   3 +-
 block/raw-posix.c| 103 ++-
 block/raw-win32.c|   6 +--
 block/rbd.c  |   3 +-
 block/sheepdog.c |   3 +-
 block/ssh.c  |   3 +-
 block/vdi.c  |   3 +-
 block/vhdx.c |   3 +-
 block/vmdk.c |   3 +-
 block/vpc.c  |   3 +-
 qapi/block-core.json |  17 +++
 qemu-doc.texi|  17 +--
 qemu-img.texi|  17 +--
 tests/qemu-iotests/049.out   |   2 +-
 tests/qemu-iotests/082.out   |  54 ++--
 tests/qemu-iotests/104   |  57 ++
 tests/qemu-iotests/104.out   |  12 +
 tests/qemu-iotests/common.filter |  21 
 tests/qemu-iotests/group |   1 +
 26 files changed, 344 insertions(+), 96 deletions(-)
 create mode 100755 tests/qemu-iotests/104
 create mode 100644 tests/qemu-iotests/104.out

-- 
1.9.3




Re: [Qemu-devel] [PATCH v13 6/6] qcow2: Add full preallocation option

2014-09-08 Thread Hu Tao
On Thu, Sep 04, 2014 at 03:09:08PM +0200, Kevin Wolf wrote:
> Am 29.08.2014 um 10:33 hat Hu Tao geschrieben:
> > preallocation=full allocates disk space by fallocating the space if
> > posix_fallocate() is available, otherwise by writing zeros to disk to
> > ensure disk space in any cases.
> > 
> > Signed-off-by: Hu Tao 
> > ---
> >  block/qcow2.c  | 61 
> > +++---
> >  qemu-doc.texi  |  7 +++---
> >  qemu-img.texi  |  7 +++---
> >  tests/qemu-iotests/082.out | 54 
> >  4 files changed, 87 insertions(+), 42 deletions(-)
> 
> > +qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
> > +aligned_total_size + meta_size);
> > +qemu_opt_set(opts, BLOCK_OPT_PREALLOC, 
> > PreallocMode_lookup[prealloc]);
> > +}
> 
> This means that if used with a protocol that doesn't have a
> preallocation option, it gets silently ignored. I'm not completely
> decided yet whether that's a bug or a feature. :-)

We can add code to reject preallocation option if it is determined as a
bug later, but it seems not necessary currently.

Regards,
Hu



Re: [Qemu-devel] [PATCH v13 2/6] block: don't convert file size to sector size

2014-09-05 Thread Hu Tao
On Thu, Sep 04, 2014 at 11:57:58AM +0200, Kevin Wolf wrote:
> Am 29.08.2014 um 10:33 hat Hu Tao geschrieben:
> > and avoid converting it back later.
> > 
> > Signed-off-by: Hu Tao 
> 
> > diff --git a/block/raw-posix.c b/block/raw-posix.c
> > index 9c22e3f..abe0759 100644
> > --- a/block/raw-posix.c
> > +++ b/block/raw-posix.c
> > @@ -1369,8 +1369,8 @@ static int raw_create(const char *filename, QemuOpts 
> > *opts, Error **errp)
> >  strstart(filename, "file:", &filename);
> >  
> >  /* Read out options */
> > -total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 
> > 0),
> > -  BDRV_SECTOR_SIZE);
> > +total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
> > +  BDRV_SECTOR_SIZE);
> >  nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false);
> >  
> >  fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
> > @@ -1394,7 +1394,7 @@ static int raw_create(const char *filename, QemuOpts 
> > *opts, Error **errp)
> >  #endif
> >  }
> >  
> > -if (ftruncate(fd, total_size * BDRV_SECTOR_SIZE) != 0) {
> > +if (ftruncate(fd, total_size) != 0) {
> >  result = -errno;
> >  error_setg_errno(errp, -result, "Could not resize file");
> >  }
> 
> You forgot changing hdev_create() in raw-posix. Doesn't make the patch
> less correct, but you may want to add it for v14.

Thanks, changed it too.

Regards,
Hu

> 
> Kevin



Re: [Qemu-devel] [PATCH 1/2] qemu-iotests: fix filter of encryption option

2014-09-04 Thread Hu Tao
On Fri, Aug 29, 2014 at 05:06:20PM +0100, Stefan Hajnoczi wrote:
> On Thu, Aug 28, 2014 at 04:56:03PM +0800, Hu Tao wrote:
> > We should filter out encryption=on, too.
> > 
> > Signed-off-by: Hu Tao 
> > ---
> >  tests/qemu-iotests/common.filter | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/tests/qemu-iotests/common.filter 
> > b/tests/qemu-iotests/common.filter
> > index 51192c8..362394e 100644
> > --- a/tests/qemu-iotests/common.filter
> > +++ b/tests/qemu-iotests/common.filter
> > @@ -176,7 +176,7 @@ _filter_img_create()
> >  sed -e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
> >  -e "s#$TEST_DIR#TEST_DIR#g" \
> >  -e "s#$IMGFMT#IMGFMT#g" \
> > --e "s# encryption=off##g" \
> > +-e "s# encryption=\\(on\\|off\\)##g" \
> 
> Why?

This is considered a bug of _filter_img_create(). It should have filtered out
driver specific option 'encryption=on', too.

Regards,
Hu



Re: [Qemu-devel] [PATCH v13 5/6] raw-posix: Add full preallocation option

2014-09-04 Thread Hu Tao
On Fri, Aug 29, 2014 at 09:48:01AM +0100, Richard W.M. Jones wrote:
> On Fri, Aug 29, 2014 at 04:33:12PM +0800, Hu Tao wrote:
> > +if (prealloc == PREALLOC_MODE_FULL) {
> > +/* posix_fallocate() doesn't set errno. */
> > +result = -posix_fallocate(fd, 0, total_size);
> > +if (result != 0) {
> 
> Is it better to test:
> 
>   result != ENOSYS && result != EOPNOTSUPP
> 
> here?
> 
> I think this is definitely the right approach.

Hi Kevin,

How do you think this approach?

Regards,
Hu



Re: [Qemu-devel] [PATCH v13 5/6] raw-posix: Add full preallocation option

2014-09-02 Thread Hu Tao
On Tue, Sep 02, 2014 at 11:45:38PM +0200, Max Reitz wrote:
> On 29.08.2014 10:33, Hu Tao wrote:
> >This patch adds a new option preallocation for raw format, and implements
> >full preallocation.
> >
> >Signed-off-by: Hu Tao 
> >---
> >  block/raw-posix.c | 92 
> > +++
> >  qemu-doc.texi |  8 +
> >  qemu-img.texi |  8 +
> >  3 files changed, 88 insertions(+), 20 deletions(-)
> >
> >diff --git a/block/raw-posix.c b/block/raw-posix.c
> >index abe0759..25f66f2 100644
> >--- a/block/raw-posix.c
> >+++ b/block/raw-posix.c
> >@@ -30,6 +30,7 @@
> >  #include "block/thread-pool.h"
> >  #include "qemu/iov.h"
> >  #include "raw-aio.h"
> >+#include "qapi/util.h"
> >  #if defined(__APPLE__) && (__MACH__)
> >  #include 
> >@@ -1365,6 +1366,9 @@ static int raw_create(const char *filename, QemuOpts 
> >*opts, Error **errp)
> >  int result = 0;
> >  int64_t total_size = 0;
> >  bool nocow = false;
> >+PreallocMode prealloc = PREALLOC_MODE_OFF;
> >+char *buf = NULL;
> >+Error *local_err = NULL;
> >  strstart(filename, "file:", &filename);
> >@@ -1372,37 +1376,80 @@ static int raw_create(const char *filename, QemuOpts 
> >*opts, Error **errp)
> >  total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
> >BDRV_SECTOR_SIZE);
> >  nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false);
> >+buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
> >+prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
> >+   PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
> >+   &local_err);
> >+g_free(buf);
> >+if (local_err) {
> >+error_propagate(errp, local_err);
> >+result = -EINVAL;
> >+goto out;
> >+}
> >  fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
> > 0644);
> >  if (fd < 0) {
> >  result = -errno;
> >  error_setg_errno(errp, -result, "Could not create file");
> >-} else {
> >-if (nocow) {
> >+goto out;
> >+}
> >+
> >+if (nocow) {
> >  #ifdef __linux__
> >-/* Set NOCOW flag to solve performance issue on fs like btrfs.
> >- * This is an optimisation. The FS_IOC_SETFLAGS ioctl return 
> >value
> >- * will be ignored since any failure of this operation should 
> >not
> >- * block the left work.
> >- */
> >-int attr;
> >-if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) {
> >-attr |= FS_NOCOW_FL;
> >-ioctl(fd, FS_IOC_SETFLAGS, &attr);
> >-}
> >-#endif
> >+/* Set NOCOW flag to solve performance issue on fs like btrfs.
> >+ * This is an optimisation. The FS_IOC_SETFLAGS ioctl return value
> >+ * will be ignored since any failure of this operation should not
> >+ * block the left work.
> >+ */
> >+int attr;
> >+if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) {
> >+attr |= FS_NOCOW_FL;
> >+ioctl(fd, FS_IOC_SETFLAGS, &attr);
> >  }
> >+#endif
> >+}
> >-if (ftruncate(fd, total_size) != 0) {
> >-result = -errno;
> >-error_setg_errno(errp, -result, "Could not resize file");
> >-}
> >-if (qemu_close(fd) != 0) {
> >-result = -errno;
> >-error_setg_errno(errp, -result, "Could not close the new file");
> >+if (ftruncate(fd, total_size) != 0) {
> >+result = -errno;
> >+error_setg_errno(errp, -result, "Could not resize file");
> >+goto out_close;
> >+}
> >+
> >+if (prealloc == PREALLOC_MODE_FULL) {
> >+/* posix_fallocate() doesn't set errno. */
> >+result = -posix_fallocate(fd, 0, total_size);
> >+if (result != 0) {
> >+buf = g_malloc0(65536);
> >+int64_t num = 0, left = total_size;
> >+
> >+while (left > 0) {
> >+num = MIN(left, 65536);
> >+result = write(fd, buf, num);
> >+if (result < 0) {
> >+result = -errno;
> >

Re: [Qemu-devel] [PATCH v13 4/6] qapi: introduce PreallocMode and a new PreallocMode full.

2014-09-02 Thread Hu Tao
On Tue, Sep 02, 2014 at 03:51:23PM -0600, Eric Blake wrote:
> On 08/29/2014 02:33 AM, Hu Tao wrote:
> > This patch prepares for the subsequent patches.
> > 
> > Signed-off-by: Hu Tao 
> > ---
> >  block/qcow2.c  | 23 +++
> >  qapi/block-core.json   | 16 
> >  tests/qemu-iotests/049.out |  2 +-
> >  3 files changed, 32 insertions(+), 9 deletions(-)
> > 
> 
> > @@ -1958,6 +1958,13 @@ static int qcow2_create(const char *filename, 
> > QemuOpts *opts, Error **errp)
> >  flags |= BLOCK_FLAG_LAZY_REFCOUNTS;
> >  }
> >  
> > +if (prealloc && prealloc != PREALLOC_MODE_METADATA) {

This one reads as 'support PREALLOC_MODE_METADATA' only,

> 
> I find it a bit awkward that you are checking for PREALLOC_MODE_OFF
> implicitly ('prealloc &&') vs. checking for prealloc mode METADATA
> explicitly.  Since there are only three modes, would it be any simpler
> to just have written:
> 
> if (prealloc == PREALLOC_MODE_FULL) {

and this one reads as 'does't support PREALLOC_MODE_FULL'.  Althrough
they are the same, but I'd prefer the former one. Anyway, the check is
removed in patch 6.

Regards,
Hu

> 
> -- 
> Eric Blake   eblake redhat com+1-919-301-3266
> Libvirt virtualization library http://libvirt.org
> 





Re: [Qemu-devel] [PATCH v13 4/6] qapi: introduce PreallocMode and a new PreallocMode full.

2014-09-02 Thread Hu Tao
On Tue, Sep 02, 2014 at 11:32:50PM +0200, Max Reitz wrote:
> On 29.08.2014 10:33, Hu Tao wrote:
> >This patch prepares for the subsequent patches.
> >
> >Signed-off-by: Hu Tao 
> >---
> >  block/qcow2.c  | 23 +++
> >  qapi/block-core.json   | 16 
> >  tests/qemu-iotests/049.out |  2 +-
> >  3 files changed, 32 insertions(+), 9 deletions(-)
> >
> >diff --git a/block/qcow2.c b/block/qcow2.c
> >index cf27c3f..95fb240 100644
> >--- a/block/qcow2.c
> >+++ b/block/qcow2.c
> >@@ -30,6 +30,7 @@
> >  #include "qemu/error-report.h"
> >  #include "qapi/qmp/qerror.h"
> >  #include "qapi/qmp/qbool.h"
> >+#include "qapi/util.h"
> >  #include "trace.h"
> >  #include "qemu/option_int.h"
> >@@ -1738,7 +1739,7 @@ static int preallocate(BlockDriverState *bs)
> >  static int qcow2_create2(const char *filename, int64_t total_size,
> >   const char *backing_file, const char 
> > *backing_format,
> >- int flags, size_t cluster_size, int prealloc,
> >+ int flags, size_t cluster_size, PreallocMode 
> >prealloc,
> >   QemuOpts *opts, int version,
> >   Error **errp)
> >  {
> >@@ -1915,7 +1916,7 @@ static int qcow2_create(const char *filename, QemuOpts 
> >*opts, Error **errp)
> >  uint64_t size = 0;
> >  int flags = 0;
> >  size_t cluster_size = DEFAULT_CLUSTER_SIZE;
> >-int prealloc = 0;
> >+PreallocMode prealloc = PREALLOC_MODE_OFF;
> >  int version = 3;
> >  Error *local_err = NULL;
> >  int ret;
> >@@ -1931,12 +1932,11 @@ static int qcow2_create(const char *filename, 
> >QemuOpts *opts, Error **errp)
> >  cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE,
> >   DEFAULT_CLUSTER_SIZE);
> >  buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
> >-if (!buf || !strcmp(buf, "off")) {
> >-prealloc = 0;
> >-} else if (!strcmp(buf, "metadata")) {
> >-prealloc = 1;
> >-} else {
> >-error_setg(errp, "Invalid preallocation mode: '%s'", buf);
> >+prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
> >+   PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
> >+   &local_err);
> >+if (local_err) {
> >+error_propagate(errp, local_err);
> >  ret = -EINVAL;
> >  goto finish;
> >  }
> >@@ -1958,6 +1958,13 @@ static int qcow2_create(const char *filename, 
> >QemuOpts *opts, Error **errp)
> >  flags |= BLOCK_FLAG_LAZY_REFCOUNTS;
> >  }
> >+if (prealloc && prealloc != PREALLOC_MODE_METADATA) {
> >+ret = -1;
> 
> Since the return value is expected to be -errno, I'd propose "ret =
> -EINVAL;" here. With that fixed (or a good explanation why we want
> -1 here):

Good.

> 
> Reviewed-by: Max Reitz 
> 
> >+error_setg(errp, "Unsupported preallocate mode: %s",
> >+   PreallocMode_lookup[prealloc]);
> >+goto finish;
> >+}
> >+
> >  if (backing_file && prealloc) {
> >  error_setg(errp, "Backing file and preallocation cannot be used at 
> > "
> > "the same time");
> >diff --git a/qapi/block-core.json b/qapi/block-core.json
> >index fb74c56..543b00b 100644
> >--- a/qapi/block-core.json
> >+++ b/qapi/block-core.json
> >@@ -1679,3 +1679,19 @@
> >  'len'   : 'int',
> >  'offset': 'int',
> >  'speed' : 'int' } }
> >+
> >+# @PreallocMode
> >+#
> >+# Preallocation mode of QEMU image file
> >+#
> >+# @off: no preallocation
> >+# @metadata: preallocate only for metadata
> >+# @full: preallocate all data by calling posix_fallocate() if it is
> >+#available, otherwise by writing zeros to device to ensure disk
> >+#space is really available. @full preallocation also sets up
> >+#metadata correctly.
> >+#
> >+# Since 2.2
> >+##
> >+{ 'enum': 'PreallocMode',
> >+  'data': [ 'off', 'metadata', 'full' ] }
> >diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out
> >index 71ca44d..09ca0ae 100644
> >--- a/tests/qemu-iotests/049.out
> >+++ b/tests/qemu-iotests/049.out
> >@@ -179,7 +179,7 @@ qemu-img create -f qcow2 -o preallocation=metadata 
> >TEST_DIR/t.qcow2 64M
> >  Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off 
> > cluster_size=65536 preallocation='metadata' lazy_refcounts=off
> >  qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M
> >-qemu-img: TEST_DIR/t.qcow2: Invalid preallocation mode: '1234'
> >+qemu-img: TEST_DIR/t.qcow2: invalid parameter value: 1234
> >  Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off 
> > cluster_size=65536 preallocation='1234' lazy_refcounts=off
> >  == Check encryption option ==



Re: [Qemu-devel] [PATCH v13 3/6] rename parse_enum_option to qapi_enum_parse and make it public

2014-09-02 Thread Hu Tao
On Tue, Sep 02, 2014 at 11:27:00PM +0200, Max Reitz wrote:
> On 29.08.2014 10:33, Hu Tao wrote:
> >From: Peter Lieven 
> >
> >relaxing the license to LGPLv2+ is intentional.
> >
> >Suggested-by: Markus Armbruster 
> >Signed-off-by: Hu Tao 
> >Signed-off-by: Peter Lieven 
> >Reviewed-by: Eric Blake 
> >Reviewed-by: Benoit Canet 
> >---
> >  blockdev.c  | 30 ++
> >  include/qapi/util.h | 17 +
> >  qapi/Makefile.objs  |  1 +
> >  qapi/qapi-util.c| 34 ++
> >  4 files changed, 58 insertions(+), 24 deletions(-)
> >  create mode 100644 include/qapi/util.h
> >  create mode 100644 qapi/qapi-util.c
> 
> Seems pretty much unchanged (except for the author note), so:

Yes. There was a license discussion, so I just take the latest version
by Peter.

Regards,
Hu

> 
> Reviewed-by: Max Reitz 



Re: [Qemu-devel] [PATCH v13 5/6] raw-posix: Add full preallocation option

2014-09-02 Thread Hu Tao
On Fri, Aug 29, 2014 at 09:48:01AM +0100, Richard W.M. Jones wrote:
> On Fri, Aug 29, 2014 at 04:33:12PM +0800, Hu Tao wrote:
> > +if (prealloc == PREALLOC_MODE_FULL) {
> > +/* posix_fallocate() doesn't set errno. */
> > +result = -posix_fallocate(fd, 0, total_size);
> > +if (result != 0) {
> 
> Is it better to test:
> 
>   result != ENOSYS && result != EOPNOTSUPP
> 
> here?

posix_fallocate() doesn't return ENOSYS or EOPNOTSUPP. All the errors
returned by posix_fallocate() apply to writing zeros, too. that is, if
posix_fallocate() returns an error, we should not do writing zeros,
neither.

I'm wondering what is the right way to test if posix_fallocate() is
supported, something like AC_CHECK_FUNC? how?

Regards,
Hu

> 
> I think this is definitely the right approach.
> 
> Rich.
> 
> 
> -- 
> Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
> Read my programming and virtualization blog: http://rwmj.wordpress.com
> virt-p2v converts physical machines to virtual machines.  Boot with a
> live CD or over the network (PXE) and turn machines into KVM guests.
> http://libguestfs.org/virt-v2v



[Qemu-devel] [PATCH v13 6/6] qcow2: Add full preallocation option

2014-08-29 Thread Hu Tao
preallocation=full allocates disk space by fallocating the space if
posix_fallocate() is available, otherwise by writing zeros to disk to
ensure disk space in any cases.

Signed-off-by: Hu Tao 
---
 block/qcow2.c  | 61 +++---
 qemu-doc.texi  |  7 +++---
 qemu-img.texi  |  7 +++---
 tests/qemu-iotests/082.out | 54 
 4 files changed, 87 insertions(+), 42 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 95fb240..f222fff 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1772,6 +1772,56 @@ static int qcow2_create2(const char *filename, int64_t 
total_size,
 Error *local_err = NULL;
 int ret;
 
+if (prealloc == PREALLOC_MODE_FULL) {
+int64_t meta_size = 0;
+uint64_t nreftablee, nrefblocke, nl1e, nl2e;
+int64_t aligned_total_size = align_offset(total_size, cluster_size);
+
+/* header: 1 cluster */
+meta_size += cluster_size;
+
+/* total size of L2 tables */
+nl2e = aligned_total_size / cluster_size;
+nl2e = align_offset(nl2e, cluster_size / sizeof(uint64_t));
+meta_size += nl2e * sizeof(uint64_t);
+
+/* total size of L1 tables */
+nl1e = nl2e * sizeof(uint64_t) / cluster_size;
+nl1e = align_offset(nl1e, cluster_size / sizeof(uint64_t));
+meta_size += nl1e * sizeof(uint64_t);
+
+/* total size of refcount blocks
+ *
+ * note: every host cluster is reference-counted, including metadata
+ * (even refcount blocks are recursively included).
+ * Let:
+ *   a = total_size (this is the guest disk size)
+ *   m = meta size not including refcount blocks and refcount tables
+ *   c = cluster size
+ *   y1 = number of refcount blocks entries
+ *   y2 = meta size including everything
+ * then,
+ *   y1 = (y2 + a)/c
+ *   y2 = y1 * sizeof(u16) + y1 * sizeof(u16) * sizeof(u64) / c + m
+ * we can get y1:
+ *   y1 = (a + m) / (c - sizeof(u16) - sizeof(u16) * sizeof(u64) / c)
+ */
+nrefblocke = (aligned_total_size + meta_size + cluster_size) /
+(cluster_size - sizeof(uint16_t) -
+ 1.0 * sizeof(uint16_t) * sizeof(uint64_t) / cluster_size);
+nrefblocke = align_offset(nrefblocke, cluster_size / sizeof(uint16_t));
+meta_size += nrefblocke * sizeof(uint16_t);
+
+/* total size of refcount tables */
+nreftablee = nrefblocke * sizeof(uint16_t) / cluster_size;
+nreftablee = align_offset(nreftablee, cluster_size / sizeof(uint64_t));
+meta_size += nreftablee * sizeof(uint64_t);
+
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
+aligned_total_size + meta_size);
+qemu_opt_set(opts, BLOCK_OPT_PREALLOC, PreallocMode_lookup[prealloc]);
+}
+
 ret = bdrv_create_file(filename, opts, &local_err);
 if (ret < 0) {
 error_propagate(errp, local_err);
@@ -1877,7 +1927,7 @@ static int qcow2_create2(const char *filename, int64_t 
total_size,
 }
 
 /* And if we're supposed to preallocate metadata, do that now */
-if (prealloc) {
+if (prealloc != PREALLOC_MODE_OFF) {
 BDRVQcowState *s = bs->opaque;
 qemu_co_mutex_lock(&s->lock);
 ret = preallocate(bs);
@@ -1958,13 +2008,6 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 flags |= BLOCK_FLAG_LAZY_REFCOUNTS;
 }
 
-if (prealloc && prealloc != PREALLOC_MODE_METADATA) {
-ret = -1;
-error_setg(errp, "Unsupported preallocate mode: %s",
-   PreallocMode_lookup[prealloc]);
-goto finish;
-}
-
 if (backing_file && prealloc) {
 error_setg(errp, "Backing file and preallocation cannot be used at "
"the same time");
@@ -2525,7 +2568,7 @@ static QemuOptsList qcow2_create_opts = {
 {
 .name = BLOCK_OPT_PREALLOC,
 .type = QEMU_OPT_STRING,
-.help = "Preallocation mode (allowed values: off, metadata)"
+.help = "Preallocation mode (allowed values: off, metadata, full)"
 },
 {
 .name = BLOCK_OPT_LAZY_REFCOUNTS,
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 2637765..b72ff7c 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -583,9 +583,10 @@ sizes can improve the image file size whereas larger 
cluster sizes generally
 provide better performance.
 
 @item preallocation
-Preallocation mode (allowed values: off, metadata). An image with preallocated
-metadata is initially larger but can improve performance when the image needs
-to grow.
+Preallocation mode (allowed values: @code{off}, @code{metadata}, @code{full}).
+An image with preallocated metadata is initially larger but can improve
+perform

[Qemu-devel] [PATCH v13 5/6] raw-posix: Add full preallocation option

2014-08-29 Thread Hu Tao
This patch adds a new option preallocation for raw format, and implements
full preallocation.

Signed-off-by: Hu Tao 
---
 block/raw-posix.c | 92 +++
 qemu-doc.texi |  8 +
 qemu-img.texi |  8 +
 3 files changed, 88 insertions(+), 20 deletions(-)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index abe0759..25f66f2 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -30,6 +30,7 @@
 #include "block/thread-pool.h"
 #include "qemu/iov.h"
 #include "raw-aio.h"
+#include "qapi/util.h"
 
 #if defined(__APPLE__) && (__MACH__)
 #include 
@@ -1365,6 +1366,9 @@ static int raw_create(const char *filename, QemuOpts 
*opts, Error **errp)
 int result = 0;
 int64_t total_size = 0;
 bool nocow = false;
+PreallocMode prealloc = PREALLOC_MODE_OFF;
+char *buf = NULL;
+Error *local_err = NULL;
 
 strstart(filename, "file:", &filename);
 
@@ -1372,37 +1376,80 @@ static int raw_create(const char *filename, QemuOpts 
*opts, Error **errp)
 total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
   BDRV_SECTOR_SIZE);
 nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false);
+buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
+prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
+   PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
+   &local_err);
+g_free(buf);
+if (local_err) {
+error_propagate(errp, local_err);
+result = -EINVAL;
+goto out;
+}
 
 fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
0644);
 if (fd < 0) {
 result = -errno;
 error_setg_errno(errp, -result, "Could not create file");
-} else {
-if (nocow) {
+goto out;
+}
+
+if (nocow) {
 #ifdef __linux__
-/* Set NOCOW flag to solve performance issue on fs like btrfs.
- * This is an optimisation. The FS_IOC_SETFLAGS ioctl return value
- * will be ignored since any failure of this operation should not
- * block the left work.
- */
-int attr;
-if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) {
-attr |= FS_NOCOW_FL;
-ioctl(fd, FS_IOC_SETFLAGS, &attr);
-}
-#endif
+/* Set NOCOW flag to solve performance issue on fs like btrfs.
+ * This is an optimisation. The FS_IOC_SETFLAGS ioctl return value
+ * will be ignored since any failure of this operation should not
+ * block the left work.
+ */
+int attr;
+if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) {
+attr |= FS_NOCOW_FL;
+ioctl(fd, FS_IOC_SETFLAGS, &attr);
 }
+#endif
+}
 
-if (ftruncate(fd, total_size) != 0) {
-result = -errno;
-error_setg_errno(errp, -result, "Could not resize file");
-}
-if (qemu_close(fd) != 0) {
-result = -errno;
-error_setg_errno(errp, -result, "Could not close the new file");
+if (ftruncate(fd, total_size) != 0) {
+result = -errno;
+error_setg_errno(errp, -result, "Could not resize file");
+goto out_close;
+}
+
+if (prealloc == PREALLOC_MODE_FULL) {
+/* posix_fallocate() doesn't set errno. */
+result = -posix_fallocate(fd, 0, total_size);
+if (result != 0) {
+buf = g_malloc0(65536);
+int64_t num = 0, left = total_size;
+
+while (left > 0) {
+num = MIN(left, 65536);
+result = write(fd, buf, num);
+if (result < 0) {
+result = -errno;
+error_setg_errno(errp, -result,
+ "Could not write to the new file");
+g_free(buf);
+goto out_close;
+}
+left -= num;
+}
+fsync(fd);
+g_free(buf);
 }
+} else if (prealloc != PREALLOC_MODE_OFF) {
+result = -1;
+error_setg(errp, "Unsupported preallocation mode: %s",
+   PreallocMode_lookup[prealloc]);
+}
+
+out_close:
+if (qemu_close(fd) != 0 && result == 0) {
+result = -errno;
+error_setg_errno(errp, -result, "Could not close the new file");
 }
+out:
 return result;
 }
 
@@ -1585,6 +1632,11 @@ static QemuOptsList raw_create_opts = {
 .type = QEMU_OPT_BOOL,
 .help = "Turn off copy-on-write (valid only on btrfs)"
 },
+{
+.name = BLOCK_OPT_PREALLOC,
+.type = QEMU_OPT_STRING,
+.help = "Preallocation mode (allowed values:

[Qemu-devel] [PATCH v13 4/6] qapi: introduce PreallocMode and a new PreallocMode full.

2014-08-29 Thread Hu Tao
This patch prepares for the subsequent patches.

Signed-off-by: Hu Tao 
---
 block/qcow2.c  | 23 +++
 qapi/block-core.json   | 16 
 tests/qemu-iotests/049.out |  2 +-
 3 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index cf27c3f..95fb240 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -30,6 +30,7 @@
 #include "qemu/error-report.h"
 #include "qapi/qmp/qerror.h"
 #include "qapi/qmp/qbool.h"
+#include "qapi/util.h"
 #include "trace.h"
 #include "qemu/option_int.h"
 
@@ -1738,7 +1739,7 @@ static int preallocate(BlockDriverState *bs)
 
 static int qcow2_create2(const char *filename, int64_t total_size,
  const char *backing_file, const char *backing_format,
- int flags, size_t cluster_size, int prealloc,
+ int flags, size_t cluster_size, PreallocMode prealloc,
  QemuOpts *opts, int version,
  Error **errp)
 {
@@ -1915,7 +1916,7 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 uint64_t size = 0;
 int flags = 0;
 size_t cluster_size = DEFAULT_CLUSTER_SIZE;
-int prealloc = 0;
+PreallocMode prealloc = PREALLOC_MODE_OFF;
 int version = 3;
 Error *local_err = NULL;
 int ret;
@@ -1931,12 +1932,11 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE,
  DEFAULT_CLUSTER_SIZE);
 buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
-if (!buf || !strcmp(buf, "off")) {
-prealloc = 0;
-} else if (!strcmp(buf, "metadata")) {
-prealloc = 1;
-} else {
-error_setg(errp, "Invalid preallocation mode: '%s'", buf);
+prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
+   PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
+   &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
 ret = -EINVAL;
 goto finish;
 }
@@ -1958,6 +1958,13 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 flags |= BLOCK_FLAG_LAZY_REFCOUNTS;
 }
 
+if (prealloc && prealloc != PREALLOC_MODE_METADATA) {
+ret = -1;
+error_setg(errp, "Unsupported preallocate mode: %s",
+   PreallocMode_lookup[prealloc]);
+goto finish;
+}
+
 if (backing_file && prealloc) {
 error_setg(errp, "Backing file and preallocation cannot be used at "
"the same time");
diff --git a/qapi/block-core.json b/qapi/block-core.json
index fb74c56..543b00b 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1679,3 +1679,19 @@
 'len'   : 'int',
 'offset': 'int',
 'speed' : 'int' } }
+
+# @PreallocMode
+#
+# Preallocation mode of QEMU image file
+#
+# @off: no preallocation
+# @metadata: preallocate only for metadata
+# @full: preallocate all data by calling posix_fallocate() if it is
+#available, otherwise by writing zeros to device to ensure disk
+#space is really available. @full preallocation also sets up
+#metadata correctly.
+#
+# Since 2.2
+##
+{ 'enum': 'PreallocMode',
+  'data': [ 'off', 'metadata', 'full' ] }
diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out
index 71ca44d..09ca0ae 100644
--- a/tests/qemu-iotests/049.out
+++ b/tests/qemu-iotests/049.out
@@ -179,7 +179,7 @@ qemu-img create -f qcow2 -o preallocation=metadata 
TEST_DIR/t.qcow2 64M
 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off 
cluster_size=65536 preallocation='metadata' lazy_refcounts=off 
 
 qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M
-qemu-img: TEST_DIR/t.qcow2: Invalid preallocation mode: '1234'
+qemu-img: TEST_DIR/t.qcow2: invalid parameter value: 1234
 Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off 
cluster_size=65536 preallocation='1234' lazy_refcounts=off 
 
 == Check encryption option ==
-- 
1.9.3




[Qemu-devel] [PATCH v13 0/6] qcow2, raw: add preallocation=full

2014-08-29 Thread Hu Tao
This series adds preallocation=full to qcow2 and raw:

Option preallocation=full preallocates disk space for image by calling
posix_fallocate() if it's available, otherwise by writing zeros to
disk.

Max, Eric, Fam,

I removed your Reviewed-by line in all patches since they've been
changed. You're welcome to review again!

changes to v12:

- remove dependence on minimal_blob_size() (patch 6)
- remove preallocation=falloc. (patch 4)
- preallocation=full tries posix_fallocate() first then writing
  zeros (patch 5)
- round up file size for all formats (patch 1)
- avoid converting file size for more formats (patch 2)

Hu Tao (5):
  block: round up file size to nearest sector
  block: don't convert file size to sector size
  qapi: introduce PreallocMode and a new PreallocMode full.
  raw-posix: Add full preallocation option
  qcow2: Add full preallocation option

Peter Lieven (1):
  rename parse_enum_option to qapi_enum_parse and make it public

 block/archipelago.c  |   3 +-
 block/cow.c  |   3 +-
 block/gluster.c  |   9 ++--
 block/iscsi.c|   4 +-
 block/nfs.c  |   3 +-
 block/qcow.c |   7 +--
 block/qcow2.c|  79 +--
 block/qed.c  |   3 +-
 block/raw-posix.c| 100 +--
 block/raw-win32.c|   6 +--
 block/rbd.c  |   3 +-
 block/sheepdog.c |   3 +-
 block/ssh.c  |   3 +-
 block/vdi.c  |   3 +-
 block/vhdx.c |   3 +-
 block/vmdk.c |   3 +-
 block/vpc.c  |   3 +-
 blockdev.c   |  30 +++-
 include/qapi/util.h  |  17 +++
 qapi/Makefile.objs   |   1 +
 qapi/block-core.json |  16 +++
 qapi/qapi-util.c |  34 +
 qemu-doc.texi|  15 --
 qemu-img.texi|  15 --
 tests/qemu-iotests/049.out   |   2 +-
 tests/qemu-iotests/082.out   |  54 ++---
 tests/qemu-iotests/104   |  57 ++
 tests/qemu-iotests/104.out   |  12 +
 tests/qemu-iotests/common.filter |  21 
 tests/qemu-iotests/group |   1 +
 30 files changed, 393 insertions(+), 120 deletions(-)
 create mode 100644 include/qapi/util.h
 create mode 100644 qapi/qapi-util.c
 create mode 100755 tests/qemu-iotests/104
 create mode 100644 tests/qemu-iotests/104.out

-- 
1.9.3




[Qemu-devel] [PATCH v13 3/6] rename parse_enum_option to qapi_enum_parse and make it public

2014-08-29 Thread Hu Tao
From: Peter Lieven 

relaxing the license to LGPLv2+ is intentional.

Suggested-by: Markus Armbruster 
Signed-off-by: Hu Tao 
Signed-off-by: Peter Lieven 
Reviewed-by: Eric Blake 
Reviewed-by: Benoit Canet 
---
 blockdev.c  | 30 ++
 include/qapi/util.h | 17 +
 qapi/Makefile.objs  |  1 +
 qapi/qapi-util.c| 34 ++
 4 files changed, 58 insertions(+), 24 deletions(-)
 create mode 100644 include/qapi/util.h
 create mode 100644 qapi/qapi-util.c

diff --git a/blockdev.c b/blockdev.c
index 6a204c6..b2aa7a2 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -39,6 +39,7 @@
 #include "qapi/qmp/types.h"
 #include "qapi-visit.h"
 #include "qapi/qmp-output-visitor.h"
+#include "qapi/util.h"
 #include "sysemu/sysemu.h"
 #include "block/block_int.h"
 #include "qmp-commands.h"
@@ -274,25 +275,6 @@ static int parse_block_error_action(const char *buf, bool 
is_read, Error **errp)
 }
 }
 
-static inline int parse_enum_option(const char *lookup[], const char *buf,
-int max, int def, Error **errp)
-{
-int i;
-
-if (!buf) {
-return def;
-}
-
-for (i = 0; i < max; i++) {
-if (!strcmp(buf, lookup[i])) {
-return i;
-}
-}
-
-error_setg(errp, "invalid parameter value: %s", buf);
-return def;
-}
-
 static bool check_throttle_config(ThrottleConfig *cfg, Error **errp)
 {
 if (throttle_conflicting(cfg)) {
@@ -456,11 +438,11 @@ static DriveInfo *blockdev_init(const char *file, QDict 
*bs_opts,
 }
 
 detect_zeroes =
-parse_enum_option(BlockdevDetectZeroesOptions_lookup,
-  qemu_opt_get(opts, "detect-zeroes"),
-  BLOCKDEV_DETECT_ZEROES_OPTIONS_MAX,
-  BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
-  &error);
+qapi_enum_parse(BlockdevDetectZeroesOptions_lookup,
+qemu_opt_get(opts, "detect-zeroes"),
+BLOCKDEV_DETECT_ZEROES_OPTIONS_MAX,
+BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
+&error);
 if (error) {
 error_propagate(errp, error);
 goto early_err;
diff --git a/include/qapi/util.h b/include/qapi/util.h
new file mode 100644
index 000..de9238b
--- /dev/null
+++ b/include/qapi/util.h
@@ -0,0 +1,17 @@
+/*
+ * QAPI util functions
+ *
+ * Copyright Fujitsu, Inc. 2014
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QAPI_UTIL_H
+#define QAPI_UTIL_H
+
+int qapi_enum_parse(const char *lookup[], const char *buf,
+int max, int def, Error **errp);
+
+#endif
diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs
index d14b769..ffd88a6 100644
--- a/qapi/Makefile.objs
+++ b/qapi/Makefile.objs
@@ -4,3 +4,4 @@ util-obj-y += string-input-visitor.o string-output-visitor.o
 
 util-obj-y += opts-visitor.o
 util-obj-y += qmp-event.o
+util-obj-y += qapi-util.o
diff --git a/qapi/qapi-util.c b/qapi/qapi-util.c
new file mode 100644
index 000..982d4e8
--- /dev/null
+++ b/qapi/qapi-util.c
@@ -0,0 +1,34 @@
+/*
+ * QAPI util functions
+ *
+ * Authors:
+ *  Hu Tao   
+ *  Peter Lieven 
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include "qemu-common.h"
+#include "qapi/error.h"
+#include "qapi/util.h"
+
+int qapi_enum_parse(const char *lookup[], const char *buf,
+int max, int def, Error **errp)
+{
+int i;
+
+if (!buf) {
+return def;
+}
+
+for (i = 0; i < max; i++) {
+if (!strcmp(buf, lookup[i])) {
+return i;
+}
+}
+
+error_setg(errp, "invalid parameter value: %s", buf);
+return def;
+}
-- 
1.9.3




[Qemu-devel] [PATCH v13 1/6] block: round up file size to nearest sector

2014-08-29 Thread Hu Tao
Signed-off-by: Hu Tao 
---
 block/archipelago.c  |  3 ++-
 block/cow.c  |  3 ++-
 block/gluster.c  |  4 +--
 block/iscsi.c|  4 +--
 block/nfs.c  |  3 ++-
 block/qcow.c |  3 ++-
 block/qcow2.c|  3 ++-
 block/qed.c  |  3 ++-
 block/raw-posix.c|  8 +++---
 block/raw-win32.c|  4 +--
 block/rbd.c  |  3 ++-
 block/sheepdog.c |  3 ++-
 block/ssh.c  |  3 ++-
 block/vdi.c  |  3 ++-
 block/vhdx.c |  3 ++-
 block/vmdk.c |  3 ++-
 block/vpc.c  |  3 ++-
 tests/qemu-iotests/104   | 57 
 tests/qemu-iotests/104.out   | 12 +
 tests/qemu-iotests/common.filter | 21 +++
 tests/qemu-iotests/group |  1 +
 21 files changed, 127 insertions(+), 23 deletions(-)
 create mode 100755 tests/qemu-iotests/104
 create mode 100644 tests/qemu-iotests/104.out

diff --git a/block/archipelago.c b/block/archipelago.c
index 34f72dc..a8d06aa 100644
--- a/block/archipelago.c
+++ b/block/archipelago.c
@@ -707,7 +707,8 @@ static int qemu_archipelago_create(const char *filename,
 
 parse_filename_opts(filename, errp, &volname, &segment_name, &mport,
 &vport);
-total_size = qemu_opt_get_size_del(options, BLOCK_OPT_SIZE, 0);
+total_size = ROUND_UP(qemu_opt_get_size_del(options, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 
 if (segment_name == NULL) {
 segment_name = g_strdup("archipelago");
diff --git a/block/cow.c b/block/cow.c
index 6ee4833..c3769fe 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -335,7 +335,8 @@ static int cow_create(const char *filename, QemuOpts *opts, 
Error **errp)
 BlockDriverState *cow_bs = NULL;
 
 /* Read out options */
-image_sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
+image_sectors = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 
0),
+ BDRV_SECTOR_SIZE);
 image_filename = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
 
 ret = bdrv_create_file(filename, opts, &local_err);
diff --git a/block/gluster.c b/block/gluster.c
index 1912cf9..65c7a58 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -494,8 +494,8 @@ static int qemu_gluster_create(const char *filename,
 goto out;
 }
 
-total_size =
-qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
+total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 
 tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
 if (!tmp || !strcmp(tmp, "off")) {
diff --git a/block/iscsi.c b/block/iscsi.c
index 3e19202..84bcae8 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1531,8 +1531,8 @@ static int iscsi_create(const char *filename, QemuOpts 
*opts, Error **errp)
 bs = bdrv_new("", &error_abort);
 
 /* Read out options */
-total_size =
-qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
+total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 bs->opaque = g_new0(struct IscsiLun, 1);
 iscsilun = bs->opaque;
 
diff --git a/block/nfs.c b/block/nfs.c
index 93d87f3..d3ba09e 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -414,7 +414,8 @@ static int nfs_file_create(const char *url, QemuOpts *opts, 
Error **errp)
 client->aio_context = qemu_get_aio_context();
 
 /* Read out options */
-total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 
 ret = nfs_client_open(client, url, O_CREAT, errp);
 if (ret < 0) {
diff --git a/block/qcow.c b/block/qcow.c
index 67c237f..041af26 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -725,7 +725,8 @@ static int qcow_create(const char *filename, QemuOpts 
*opts, Error **errp)
 BlockDriverState *qcow_bs;
 
 /* Read out options */
-total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
+total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
 if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
 flags |= BLOCK_FLAG_ENCRYPT;
diff --git a/block/qcow2.c b/block/qcow2.c
index f9e045f..c8050e5 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1921,7 +1921,8 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 int ret;
 
 /* Read out options */
-sectors = 

[Qemu-devel] [PATCH v13 2/6] block: don't convert file size to sector size

2014-08-29 Thread Hu Tao
and avoid converting it back later.

Signed-off-by: Hu Tao 
---
 block/gluster.c   |  9 -
 block/qcow.c  |  8 
 block/qcow2.c | 10 +-
 block/raw-posix.c |  6 +++---
 block/raw-win32.c |  6 +++---
 5 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/block/gluster.c b/block/gluster.c
index 65c7a58..1eb3a8c 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -494,8 +494,8 @@ static int qemu_gluster_create(const char *filename,
 goto out;
 }
 
-total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
-  BDRV_SECTOR_SIZE);
+total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 
 tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
 if (!tmp || !strcmp(tmp, "off")) {
@@ -516,9 +516,8 @@ static int qemu_gluster_create(const char *filename,
 if (!fd) {
 ret = -errno;
 } else {
-if (!glfs_ftruncate(fd, total_size * BDRV_SECTOR_SIZE)) {
-if (prealloc && qemu_gluster_zerofill(fd, 0,
-total_size * BDRV_SECTOR_SIZE)) {
+if (!glfs_ftruncate(fd, total_size)) {
+if (prealloc && qemu_gluster_zerofill(fd, 0, total_size)) {
 ret = -errno;
 }
 } else {
diff --git a/block/qcow.c b/block/qcow.c
index 041af26..a87bd69 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -725,8 +725,8 @@ static int qcow_create(const char *filename, QemuOpts 
*opts, Error **errp)
 BlockDriverState *qcow_bs;
 
 /* Read out options */
-total_size = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
-  BDRV_SECTOR_SIZE);
+total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+  BDRV_SECTOR_SIZE);
 backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
 if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
 flags |= BLOCK_FLAG_ENCRYPT;
@@ -754,7 +754,7 @@ static int qcow_create(const char *filename, QemuOpts 
*opts, Error **errp)
 memset(&header, 0, sizeof(header));
 header.magic = cpu_to_be32(QCOW_MAGIC);
 header.version = cpu_to_be32(QCOW_VERSION);
-header.size = cpu_to_be64(total_size * 512);
+header.size = cpu_to_be64(total_size);
 header_size = sizeof(header);
 backing_filename_len = 0;
 if (backing_file) {
@@ -776,7 +776,7 @@ static int qcow_create(const char *filename, QemuOpts 
*opts, Error **errp)
 }
 header_size = (header_size + 7) & ~7;
 shift = header.cluster_bits + header.l2_bits;
-l1_size = ((total_size * 512) + (1LL << shift) - 1) >> shift;
+l1_size = (total_size + (1LL << shift) - 1) >> shift;
 
 header.l1_table_offset = cpu_to_be64(header_size);
 if (flags & BLOCK_FLAG_ENCRYPT) {
diff --git a/block/qcow2.c b/block/qcow2.c
index c8050e5..cf27c3f 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1859,7 +1859,7 @@ static int qcow2_create2(const char *filename, int64_t 
total_size,
 }
 
 /* Okay, now that we have a valid image, let's give it the right size */
-ret = bdrv_truncate(bs, total_size * BDRV_SECTOR_SIZE);
+ret = bdrv_truncate(bs, total_size);
 if (ret < 0) {
 error_setg_errno(errp, -ret, "Could not resize image");
 goto out;
@@ -1912,7 +1912,7 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 char *backing_file = NULL;
 char *backing_fmt = NULL;
 char *buf = NULL;
-uint64_t sectors = 0;
+uint64_t size = 0;
 int flags = 0;
 size_t cluster_size = DEFAULT_CLUSTER_SIZE;
 int prealloc = 0;
@@ -1921,8 +1921,8 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 int ret;
 
 /* Read out options */
-sectors = DIV_ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
-   BDRV_SECTOR_SIZE);
+size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+BDRV_SECTOR_SIZE);
 backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
 backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
 if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
@@ -1972,7 +1972,7 @@ static int qcow2_create(const char *filename, QemuOpts 
*opts, Error **errp)
 goto finish;
 }
 
-ret = qcow2_create2(filename, sectors, backing_file, backing_fmt, flags,
+ret = qcow2_create2(filename, size, backing_file, backing_fmt, flags,
 cluster_size, prealloc, opts, version, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 9c22e3f..abe0759 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1369,8 +1369,8 @@ static int raw_create(const char *filename, QemuOpts 
*opts, E

[Qemu-devel] [PATCH 2/2] qemu-iotests: filter out driver-specific option preallocation

2014-08-28 Thread Hu Tao

Signed-off-by: Hu Tao 
---
 tests/qemu-iotests/common.filter | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index 362394e..97d2934 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -189,6 +189,7 @@ _filter_img_create()
 -e "s# block_size=[0-9]\\+##g" \
 -e "s# block_state_zero=\\(on\\|off\\)##g" \
 -e "s# log_size=[0-9]\\+##g" \
+-e "s# preallocation='[^']*'##g" \
 -e "s/archipelago:a/TEST_DIR\//g"
 }
 
-- 
1.8.0




[Qemu-devel] [PATCH 0/2] qemu-iotests: fix two driver-specific option filtering problems

2014-08-28 Thread Hu Tao
See each patch for the details.

Hu Tao (2):
  qemu-iotests: fix filter of encryption option
  qemu-iotests: filter out driver-specific option preallocation

 tests/qemu-iotests/common.filter | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

-- 
1.8.0




[Qemu-devel] [PATCH 1/2] qemu-iotests: fix filter of encryption option

2014-08-28 Thread Hu Tao
We should filter out encryption=on, too.

Signed-off-by: Hu Tao 
---
 tests/qemu-iotests/common.filter | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index 51192c8..362394e 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -176,7 +176,7 @@ _filter_img_create()
 sed -e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
 -e "s#$TEST_DIR#TEST_DIR#g" \
 -e "s#$IMGFMT#IMGFMT#g" \
--e "s# encryption=off##g" \
+-e "s# encryption=\\(on\\|off\\)##g" \
 -e "s# cluster_size=[0-9]\\+##g" \
 -e "s# table_size=[0-9]\\+##g" \
 -e "s# compat='[^']*'##g" \
-- 
1.8.0




Re: [Qemu-devel] [PATCH v12 0/6] qcow2, raw: add preallocation=full and preallocation=falloc

2014-08-27 Thread Hu Tao
On Tue, Aug 26, 2014 at 11:44:26AM +0100, Stefan Hajnoczi wrote:
> On Mon, Aug 25, 2014 at 09:35:15AM +0800, Hu Tao wrote:
> > On Fri, Aug 22, 2014 at 12:54:29PM +0200, Kevin Wolf wrote:
> > > Am 28.07.2014 um 10:48 hat Hu Tao geschrieben:
> > > > ping...
> > > > 
> > > > All the 6 patches have reviewed-by now.
> > > 
> > > Looks mostly good to me, I have only a few minor comments that wouldn't
> > > block inclusion but could be addressed in follow-up patches.
> > > 
> > > However, you have a dependency on a patch series from Max (you use
> > > minimal_blob_size()), which hasn't been reviewed and merged yet, so your
> > > series is blocked on that.
> > > 
> > > If you want to get your series merged quicker, you could replace this
> > > with a rough estimate that excludes the clusters used by refcount table
> > > and blocks. If full preallocation isn't really full, but only
> > > preallocation of 99.9%, that's probably good enough in practice.
> > 
> > How about my calculation in v10?
> > https://lists.nongnu.org/archive/html/qemu-devel/2014-06/msg02844.html
> > 
> > It doesn't depend on minimal_blob_size(). In most cases the calculated
> > size is the same as the size before this patch. I have no test results
> > on hand, but if you need I can do it.
> 
> Kevin is on vacation this week.
> 
> I think the previous calculation could work.
> 
> Stefan

Okay, I'll send v13 patchset implementing preallocation as Rich
suggested for you to review.

Regards,
Hu





Re: [Qemu-devel] [PATCH v7 0/8] memory API improvements and bug fixes for memory backends

2014-08-27 Thread Hu Tao
ping...



Re: [Qemu-devel] [PATCH v12 0/6] qcow2, raw: add preallocation=full and preallocation=falloc

2014-08-25 Thread Hu Tao
On Fri, Aug 22, 2014 at 05:00:08PM +0100, Richard W.M. Jones wrote:
> On Fri, Aug 22, 2014 at 05:53:22PM +0200, Kevin Wolf wrote:
> > Am 22.08.2014 um 17:34 hat Richard W.M. Jones geschrieben:
> > > On Fri, Aug 22, 2014 at 05:22:33PM +0200, Kevin Wolf wrote:
> > > > It's still useful because it happens to reduce the overhead in most
> > > > implementations and it's a relatively quick operation, but the best way
> > > > I know of to actually _fully_ preallocate is still writing zeros. Which
> > > > of the two the user wants, is a decision that qemu can't make for them.
> > > 
> > > This is a difficult situation.  Possibly the choice is between
> > > 
> > >  - efficiently make the file fully allocated, that works in the vast
> > >majority of cases, but don't go crazy (ie. fallocate)
> > > 
> > >  - really really try as hard as possible to make sure that future
> > >allocations will never fail (ie. write random non-zero data to the
> > >file)
> > > 
> > > Note that neither of these is the preallocation=... option as
> > > specified in this patch.
> > 
> > Isn't the first one exactly preallocation=falloc and the second is
> > preallocation=full, except that we're not writing non-zero blocks? (And
> > probably shouldn't, because that would change the content.)
> 
> Well no for a few reasons:
> 
> What is proposed to be called 'preallocation=falloc' should fall back
> to other methods (eg. writing random, writing zeroes).  It should
> also be called something more useful like 'preallocation=best'.

I think you suggested this one. Kevin, how do you think this
implementation?

> 
> What is proposed to be called 'preallocation=full' should not write
> just zeroes.  It needs to write random data since otherwise lower
> layers could discard those writes and that would mean metadata
> allocations could still take time (or fail).  It could also be called
> something more useful, say, 'preallocation=tryveryhard'.
> 
> TBH I think this whole thing is overkill and we should just have a
> preallocation option that works like in libvirt.  Anything else is
> silly [see above] or pushes the problem to upper layers that are in no
> position to make that decision.
> 
> Remember that the upper layer is probably not even running on the same
> machine.  It has no knowledge of the backing LUN.  It doesn't know
> about the hypervisor kernel (ie. if fallocate will fail).
> 
> Rich.
> 
> -- 
> Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
> Read my programming and virtualization blog: http://rwmj.wordpress.com
> virt-p2v converts physical machines to virtual machines.  Boot with a
> live CD or over the network (PXE) and turn machines into KVM guests.
> http://libguestfs.org/virt-v2v



  1   2   3   4   5   6   7   8   9   10   >