[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH 1/4] HVM vcpu add/remove: qemu logic for vcpu add/revmoe



On Fri, 31 May 2013, Anthony PERARD wrote:
> From: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
> 
> -- at qemu side, get vcpu_avail which used for original cpu avail map;
> -- setup gpe ioread/iowrite at qmeu;
> -- setup vcpu add/remove user interface through monitor;
> -- setup SCI logic;
> 
> Signed-off-by: Liu, Jinsong <jinsong.liu@xxxxxxxxx>
> 
> [ PATCH 4/4 ] HVM vcpu add/remove: qemu logic for vcpu add/revmoe
> 
> Port from qemu-xen-traditionnal to qemu-xen.
> 
> Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
> ---
>  hmp-commands.hx |  9 +++++++
>  hw/acpi_piix4.c | 75 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  monitor.c       | 18 ++++++++++++++
>  qemu-options.hx |  3 +++
>  sysemu.h        |  3 +++
>  vl.c            |  6 +++++
>  6 files changed, 113 insertions(+), 1 deletion(-)
> 
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 010b8c9..e92f173 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1581,3 +1581,12 @@ ETEXI
>  STEXI
>  @end table
>  ETEXI
> +
> +HXCOMM TODO doc
> +    {
> +        .name       = "cpu_set",
> +        .args_type  = "cpu_index:i,status:s",
> +        .params     = "cpu [online|offline]",
> +        .help       = "change cpu state",
> +        .mhandler.cmd = do_cpu_set_nr,
> +    },
> diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
> index 519269a..c73dc7c 100644
> --- a/hw/acpi_piix4.c
> +++ b/hw/acpi_piix4.c
> @@ -45,8 +45,11 @@
>  #define PCI_DOWN_BASE 0xae04
>  #define PCI_EJ_BASE 0xae08
>  #define PCI_RMV_BASE 0xae0c
> +/* ioport to monitor cpu add/remove status */
> +#define PROC_BASE 0xaf00
>  
>  #define PIIX4_PCI_HOTPLUG_STATUS 2
> +#define PIIX4_CPU_HOTPLUG_STATUS 4
>  
>  struct pci_status {
>      uint32_t up; /* deprecated, maintained for migration compatibility */
> @@ -77,6 +80,9 @@ typedef struct PIIX4PMState {
>      uint8_t disable_s3;
>      uint8_t disable_s4;
>      uint8_t s4_val;
> +
> +    /* CPU bitmap */
> +    uint8_t cpus_sts[32];
>  } PIIX4PMState;
>  
>  static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s);
> @@ -95,7 +101,7 @@ static void pm_update_sci(PIIX4PMState *s)
>                     ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
>                     ACPI_BITMASK_TIMER_ENABLE)) != 0) ||
>          (((s->ar.gpe.sts[0] & s->ar.gpe.en[0])
> -          & PIIX4_PCI_HOTPLUG_STATUS) != 0);
> +          & (PIIX4_PCI_HOTPLUG_STATUS|PIIX4_CPU_HOTPLUG_STATUS)) != 0);
>  
>      qemu_set_irq(s->irq, sci_level);
>      /* schedule a timer interruption if needed */
> @@ -602,11 +608,48 @@ static uint32_t pcirmv_read(void *opaque, uint32_t addr)
>      return s->pci0_hotplug_enable;
>  }
>  
> +static uint32_t gpe_cpus_readb(void *opaque, uint32_t addr)
> +{
> +    uint32_t val = 0;
> +    PIIX4PMState *g = opaque;
> +
> +    switch (addr) {
> +        case PROC_BASE ... PROC_BASE+31:
> +            val = g->cpus_sts[addr - PROC_BASE];
> +        default:
> +            break;
> +    }
> +
> +    return val;
> +}
> +
> +static void gpe_cpus_writeb(void *opaque, uint32_t addr, uint32_t val)
> +{
> +    switch (addr) {
> +        case PROC_BASE ... PROC_BASE + 31:
> +            /* don't allow to change cpus_sts from inside a guest */
> +            break;
> +        default:
> +            break;
> +    }
> +}
> +
>  static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
>                                  PCIHotplugState state);
>  
> +extern uint64_t vcpu_avail;
> +static PIIX4PMState *acpi_state;
>  static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
>  {
> +    int i = 0, cpus = max_cpus;
> +    char *vcpumap = (char *)&vcpu_avail;
> +
> +    while (cpus > 0) {
> +        s->cpus_sts[i] = vcpumap[i];
> +        i++;
> +        cpus -= 8;
> +    }
> +    acpi_state = s;
>  
>      register_ioport_write(GPE_BASE, GPE_LEN, 1, gpe_writeb, s);
>      register_ioport_read(GPE_BASE, GPE_LEN, 1,  gpe_readb, s);
> @@ -620,6 +663,9 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, 
> PIIX4PMState *s)
>  
>      register_ioport_read(PCI_RMV_BASE, 4, 4,  pcirmv_read, s);
>  
> +    register_ioport_read(PROC_BASE, 32, 1,  gpe_cpus_readb, s);
> +    register_ioport_write(PROC_BASE, 32, 1, gpe_cpus_writeb, s);
> +
>      pci_bus_hotplug(bus, piix4_device_hotplug, &s->dev.qdev);
>  }
>  
> @@ -660,3 +706,30 @@ static int piix4_device_hotplug(DeviceState *qdev, 
> PCIDevice *dev,
>  
>      return 0;
>  }
> +
> +static void enable_processor(PIIX4PMState *g, int cpu)
> +{
> +    g->ar.gpe.sts[0] |= 4;
> +    g->cpus_sts[cpu/8] |= (1 << (cpu%8));
> +}
> +
> +static void disable_processor(PIIX4PMState *g, int cpu)
> +{
> +    g->ar.gpe.sts[0] |= 4;
> +    g->cpus_sts[cpu/8] &= ~(1 << (cpu%8));
> +}
> +
> +void qemu_cpu_add_remove(int cpu, int state)
> +{
> +    if ((cpu <=0) || (cpu >= max_cpus)) {

the original code has cpu < 0

> +        fprintf(stderr, "vcpu out of range, should be [1~%d]\n", max_cpus - 
> 1);
> +        return;
> +    }
> +
> +    if (state)
> +        enable_processor(acpi_state, cpu);
> +    else
> +        disable_processor(acpi_state, cpu);
> +
> +    pm_update_sci(acpi_state);
> +}

This is also different, the code we have on qemu-xen-unstable is:

if (gpe_state.gpe0_en[0] & 4) {
        qemu_set_irq(sci_irq, 1);
        qemu_set_irq(sci_irq, 0);
}

what's the reason for the change?


If possible, it would be better to port a QMP command for vcpu hotplug
to avoid compatibility problems, so I would get rid of the code below


> diff --git a/monitor.c b/monitor.c
> index c0e32d6..564373c 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -2421,6 +2421,24 @@ int monitor_handle_fd_param(Monitor *mon, const char 
> *fdname)
>      return fd;
>  }
>  
> +static void do_cpu_set_nr(Monitor *mon, const QDict *qdict)
> +{
> +    int cpu_index = qdict_get_int(qdict, "cpu_index");
> +    const char *status = qdict_get_str(qdict, "status");
> +    int state;
> +
> +    if (!strcmp(status, "online")) {
> +        state = 1;
> +    } else if (!strcmp(status, "offline")) {
> +        state = 0;
> +    } else {
> +        monitor_printf(mon, "invalid status: %s\n", status);
> +        return;
> +    }
> +
> +    qemu_cpu_add_remove(cpu_index, state);
> +}
> +
>  /* mon_cmds and info_cmds would be sorted at runtime */
>  static mon_cmd_t mon_cmds[] = {
>  #include "hmp-commands.h"
> diff --git a/qemu-options.hx b/qemu-options.hx
> index de43b1b..0ba668f 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -94,6 +94,9 @@ given, the total number of CPUs @var{n} can be omitted. 
> @var{maxcpus}
>  specifies the maximum number of hotpluggable CPUs.
>  ETEXI
>  
> +DEF("vcpu_avail", HAS_ARG, QEMU_OPTION_vcpu_avail,
> +    "-vcpu_avail bitmap\n", QEMU_ARCH_ALL)
> +
>  DEF("numa", HAS_ARG, QEMU_OPTION_numa,
>      "-numa node[,mem=size][,cpus=cpu[-cpu]][,nodeid=node]\n", QEMU_ARCH_ALL)
>  STEXI
> diff --git a/sysemu.h b/sysemu.h
> index f5ac664..ed7b264 100644
> --- a/sysemu.h
> +++ b/sysemu.h
> @@ -149,6 +149,9 @@ int pci_drive_hot_add(Monitor *mon, const QDict *qdict,
>                        DriveInfo *dinfo, int type);
>  void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict);
>  
> +/* cpu hotplug */
> +void qemu_cpu_add_remove(int cpu, int state);
> +
>  /* generic hotplug */
>  void drive_hot_add(Monitor *mon, const QDict *qdict);
>  
> diff --git a/vl.c b/vl.c
> index a3ab384..27ae6c1 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -207,6 +207,7 @@ int win2k_install_hack = 0;
>  int singlestep = 0;
>  int smp_cpus = 1;
>  int max_cpus = 0;
> +uint64_t vcpu_avail = 1;
>  int smp_cores = 1;
>  int smp_threads = 1;
>  #ifdef CONFIG_VNC
> @@ -3302,6 +3303,11 @@ int main(int argc, char **argv, char **envp)
>                      exit(1);
>                  }
>                  break;
> +            case QEMU_OPTION_vcpu_avail:
> +                vcpu_avail = atol(optarg);
> +                fprintf(stderr, "qemu: the avail cpu bitmap is %lx\n",
> +                        vcpu_avail);
> +                break;
>           case QEMU_OPTION_vnc:
>  #ifdef CONFIG_VNC
>                  display_remote++;

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.