diff mbox

[RFC,v3,21/24] spapr: Initialize hotplug memory address space

Message ID 1429858066-12088-22-git-send-email-bharata@linux.vnet.ibm.com
State New
Headers show

Commit Message

Bharata B Rao April 24, 2015, 6:47 a.m. UTC
Initialize a hotplug memory region under which all the hotplugged
memory is accommodated. Also enable memory hotplug by setting
CONFIG_MEM_HOTPLUG.

Modelled on i386 memory hotplug.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 default-configs/ppc64-softmmu.mak |  1 +
 hw/ppc/spapr.c                    | 38 ++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/spapr.h            | 12 ++++++++++++
 3 files changed, 51 insertions(+)

Comments

David Gibson May 5, 2015, 7:33 a.m. UTC | #1
On Fri, Apr 24, 2015 at 12:17:43PM +0530, Bharata B Rao wrote:
> Initialize a hotplug memory region under which all the hotplugged
> memory is accommodated. Also enable memory hotplug by setting
> CONFIG_MEM_HOTPLUG.
> 
> Modelled on i386 memory hotplug.
> 
> Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>

So, the cpu hotplug stuff has been caught up in these generic level
design discussions.  Could you split out the memory hotplug part of
this series so that we might be able to move forwards with that while
the cpu hotplug discussion continues?

> ---
>  default-configs/ppc64-softmmu.mak |  1 +
>  hw/ppc/spapr.c                    | 38 ++++++++++++++++++++++++++++++++++++++
>  include/hw/ppc/spapr.h            | 12 ++++++++++++
>  3 files changed, 51 insertions(+)
> 
> diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
> index 22ef132..16b3011 100644
> --- a/default-configs/ppc64-softmmu.mak
> +++ b/default-configs/ppc64-softmmu.mak
> @@ -51,3 +51,4 @@ CONFIG_XICS_KVM=$(and $(CONFIG_PSERIES),$(CONFIG_KVM))
>  # For PReP
>  CONFIG_MC146818RTC=y
>  CONFIG_ISA_TESTDEV=y
> +CONFIG_MEM_HOTPLUG=y
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 910a50f..9dc4c36 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -125,6 +125,9 @@ struct sPAPRMachineState {
>  
>      /*< public >*/
>      char *kvm_type;
> +    ram_addr_t hotplug_memory_base;
> +    MemoryRegion hotplug_memory;
> +    bool enforce_aligned_dimm;

As mentioned on the earlier version, on ppc we don't have
compatibility reasons we need to have a mode for unaligned dimms.  Get
rid of this bool and treat it as always on instead.

>  };
>  
>  sPAPREnvironment *spapr;
> @@ -1514,6 +1517,7 @@ static void ppc_spapr_init(MachineState *machine)
>      QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL);
>      int sockets = opts ? qemu_opt_get_number(opts, "sockets", 0) : 0;
>      int cores = (smp_cpus/smp_threads) ? smp_cpus/smp_threads : 1;
> +    sPAPRMachineState *ms = SPAPR_MACHINE(machine);
>  
>      sockets = sockets ? sockets : cores;
>      msi_supported = true;
> @@ -1613,6 +1617,36 @@ static void ppc_spapr_init(MachineState *machine)
>          memory_region_add_subregion(sysmem, 0, rma_region);
>      }
>  
> +    /* initialize hotplug memory address space */
> +    if (machine->ram_size < machine->maxram_size) {
> +        ram_addr_t hotplug_mem_size =
> +            machine->maxram_size - machine->ram_size;
> +
> +        if (machine->ram_slots > SPAPR_MAX_RAM_SLOTS) {
> +            error_report("unsupported amount of memory slots: %"PRIu64,
> +                         machine->ram_slots);
> +            exit(EXIT_FAILURE);
> +        }
> +
> +        ms->hotplug_memory_base = ROUND_UP(machine->ram_size,
> +                                    SPAPR_HOTPLUG_MEM_ALIGN);
> +
> +        if (ms->enforce_aligned_dimm) {
> +            hotplug_mem_size += SPAPR_HOTPLUG_MEM_ALIGN * machine->ram_slots;
> +        }
> +
> +        if ((ms->hotplug_memory_base + hotplug_mem_size) < hotplug_mem_size) {
> +            error_report("unsupported amount of maximum memory: " RAM_ADDR_FMT,
> +                         machine->maxram_size);
> +            exit(EXIT_FAILURE);
> +        }
> +
> +        memory_region_init(&ms->hotplug_memory, OBJECT(ms),
> +                           "hotplug-memory", hotplug_mem_size);
> +        memory_region_add_subregion(sysmem, ms->hotplug_memory_base,
> +                                    &ms->hotplug_memory);
> +    }
> +
>      filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");
>      spapr->rtas_size = get_image_size(filename);
>      spapr->rtas_blob = g_malloc(spapr->rtas_size);
> @@ -1844,11 +1878,15 @@ static void spapr_set_kvm_type(Object *obj, const char *value, Error **errp)
>  
>  static void spapr_machine_initfn(Object *obj)
>  {
> +    sPAPRMachineState *ms = SPAPR_MACHINE(obj);
> +
>      object_property_add_str(obj, "kvm-type",
>                              spapr_get_kvm_type, spapr_set_kvm_type, NULL);
>      object_property_set_description(obj, "kvm-type",
>                                      "Specifies the KVM virtualization mode (HV, PR)",
>                                      NULL);
> +
> +    ms->enforce_aligned_dimm = true;
>  }
>  
>  static void ppc_cpu_do_nmi_on_cpu(void *arg)
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index ecac6e3..53560e9 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -542,6 +542,18 @@ struct sPAPREventLogEntry {
>  
>  #define SPAPR_MEMORY_BLOCK_SIZE (1 << 28) /* 256MB */
>  
> +/*
> + * This defines the maximum number of DIMM slots we can have for sPAPR
> + * guest. This is not defined by sPAPR but we are defining it to 4096 slots
> + * here. With the worst case addition of SPAPR_MEMORY_BLOCK_SIZE
> + * (256MB) memory per slot, we should be able to support 1TB of guest
> + * hotpluggable memory.
> + */
> +#define SPAPR_MAX_RAM_SLOTS     (1ULL << 12)
> +
> +/* 1GB alignment for hotplug memory region */
> +#define SPAPR_HOTPLUG_MEM_ALIGN (1ULL << 30)
> +
>  void spapr_events_init(sPAPREnvironment *spapr);
>  void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq);
>  int spapr_h_cas_compose_response(target_ulong addr, target_ulong size);
Igor Mammedov May 5, 2015, 8:48 a.m. UTC | #2
On Fri, 24 Apr 2015 12:17:43 +0530
Bharata B Rao <bharata@linux.vnet.ibm.com> wrote:

> Initialize a hotplug memory region under which all the hotplugged
> memory is accommodated. Also enable memory hotplug by setting
> CONFIG_MEM_HOTPLUG.
> 
> Modelled on i386 memory hotplug.
> 
> Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
> ---
>  default-configs/ppc64-softmmu.mak |  1 +
>  hw/ppc/spapr.c                    | 38 ++++++++++++++++++++++++++++++++++++++
>  include/hw/ppc/spapr.h            | 12 ++++++++++++
>  3 files changed, 51 insertions(+)
> 
> diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
> index 22ef132..16b3011 100644
> --- a/default-configs/ppc64-softmmu.mak
> +++ b/default-configs/ppc64-softmmu.mak
> @@ -51,3 +51,4 @@ CONFIG_XICS_KVM=$(and $(CONFIG_PSERIES),$(CONFIG_KVM))
>  # For PReP
>  CONFIG_MC146818RTC=y
>  CONFIG_ISA_TESTDEV=y
> +CONFIG_MEM_HOTPLUG=y
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 910a50f..9dc4c36 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -125,6 +125,9 @@ struct sPAPRMachineState {
>  
>      /*< public >*/
>      char *kvm_type;
> +    ram_addr_t hotplug_memory_base;
> +    MemoryRegion hotplug_memory;
> +    bool enforce_aligned_dimm;
>  };
>  
>  sPAPREnvironment *spapr;
> @@ -1514,6 +1517,7 @@ static void ppc_spapr_init(MachineState *machine)
>      QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL);
>      int sockets = opts ? qemu_opt_get_number(opts, "sockets", 0) : 0;
>      int cores = (smp_cpus/smp_threads) ? smp_cpus/smp_threads : 1;
> +    sPAPRMachineState *ms = SPAPR_MACHINE(machine);
>  
>      sockets = sockets ? sockets : cores;
>      msi_supported = true;
> @@ -1613,6 +1617,36 @@ static void ppc_spapr_init(MachineState *machine)
>          memory_region_add_subregion(sysmem, 0, rma_region);
>      }
>  
> +    /* initialize hotplug memory address space */
> +    if (machine->ram_size < machine->maxram_size) {
> +        ram_addr_t hotplug_mem_size =
> +            machine->maxram_size - machine->ram_size;
> +
> +        if (machine->ram_slots > SPAPR_MAX_RAM_SLOTS) {
> +            error_report("unsupported amount of memory slots: %"PRIu64,
> +                         machine->ram_slots);
> +            exit(EXIT_FAILURE);
> +        }
> +
> +        ms->hotplug_memory_base = ROUND_UP(machine->ram_size,
> +                                    SPAPR_HOTPLUG_MEM_ALIGN);
> +
> +        if (ms->enforce_aligned_dimm) {
> +            hotplug_mem_size += SPAPR_HOTPLUG_MEM_ALIGN * machine->ram_slots;
> +        }
> +
> +        if ((ms->hotplug_memory_base + hotplug_mem_size) < hotplug_mem_size) {
> +            error_report("unsupported amount of maximum memory: " RAM_ADDR_FMT,
> +                         machine->maxram_size);
> +            exit(EXIT_FAILURE);
> +        }
> +
> +        memory_region_init(&ms->hotplug_memory, OBJECT(ms),
> +                           "hotplug-memory", hotplug_mem_size);
> +        memory_region_add_subregion(sysmem, ms->hotplug_memory_base,
> +                                    &ms->hotplug_memory);
> +    }
> +
>      filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");
>      spapr->rtas_size = get_image_size(filename);
>      spapr->rtas_blob = g_malloc(spapr->rtas_size);
> @@ -1844,11 +1878,15 @@ static void spapr_set_kvm_type(Object *obj, const char *value, Error **errp)
>  
>  static void spapr_machine_initfn(Object *obj)
>  {
> +    sPAPRMachineState *ms = SPAPR_MACHINE(obj);
> +
>      object_property_add_str(obj, "kvm-type",
>                              spapr_get_kvm_type, spapr_set_kvm_type, NULL);
>      object_property_set_description(obj, "kvm-type",
>                                      "Specifies the KVM virtualization mode (HV, PR)",
>                                      NULL);
> +
> +    ms->enforce_aligned_dimm = true;
>  }
>  
>  static void ppc_cpu_do_nmi_on_cpu(void *arg)
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index ecac6e3..53560e9 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -542,6 +542,18 @@ struct sPAPREventLogEntry {
>  
>  #define SPAPR_MEMORY_BLOCK_SIZE (1 << 28) /* 256MB */
>  
> +/*
> + * This defines the maximum number of DIMM slots we can have for sPAPR
> + * guest. This is not defined by sPAPR but we are defining it to 4096 slots
> + * here. With the worst case addition of SPAPR_MEMORY_BLOCK_SIZE
> + * (256MB) memory per slot, we should be able to support 1TB of guest
> + * hotpluggable memory.
> + */
> +#define SPAPR_MAX_RAM_SLOTS     (1ULL << 12)
why not write 4096 instead of (1ULL << 12), much easier to read.

BTW:
KVM supports upto 509 memory slots including slots consumed by
initial memory.

> +
> +/* 1GB alignment for hotplug memory region */
> +#define SPAPR_HOTPLUG_MEM_ALIGN (1ULL << 30)
> +
>  void spapr_events_init(sPAPREnvironment *spapr);
>  void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq);
>  int spapr_h_cas_compose_response(target_ulong addr, target_ulong size);
Bharata B Rao May 6, 2015, 7:58 a.m. UTC | #3
On Tue, May 05, 2015 at 05:33:33PM +1000, David Gibson wrote:
> On Fri, Apr 24, 2015 at 12:17:43PM +0530, Bharata B Rao wrote:
> > Initialize a hotplug memory region under which all the hotplugged
> > memory is accommodated. Also enable memory hotplug by setting
> > CONFIG_MEM_HOTPLUG.
> > 
> > Modelled on i386 memory hotplug.
> > 
> > Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
> 
> So, the cpu hotplug stuff has been caught up in these generic level
> design discussions.  Could you split out the memory hotplug part of
> this series so that we might be able to move forwards with that while
> the cpu hotplug discussion continues?

Yes, in fact I too was planning to split memory and push it separately.

> 
> > ---
> >  default-configs/ppc64-softmmu.mak |  1 +
> >  hw/ppc/spapr.c                    | 38 ++++++++++++++++++++++++++++++++++++++
> >  include/hw/ppc/spapr.h            | 12 ++++++++++++
> >  3 files changed, 51 insertions(+)
> > 
> > diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
> > index 22ef132..16b3011 100644
> > --- a/default-configs/ppc64-softmmu.mak
> > +++ b/default-configs/ppc64-softmmu.mak
> > @@ -51,3 +51,4 @@ CONFIG_XICS_KVM=$(and $(CONFIG_PSERIES),$(CONFIG_KVM))
> >  # For PReP
> >  CONFIG_MC146818RTC=y
> >  CONFIG_ISA_TESTDEV=y
> > +CONFIG_MEM_HOTPLUG=y
> > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > index 910a50f..9dc4c36 100644
> > --- a/hw/ppc/spapr.c
> > +++ b/hw/ppc/spapr.c
> > @@ -125,6 +125,9 @@ struct sPAPRMachineState {
> >  
> >      /*< public >*/
> >      char *kvm_type;
> > +    ram_addr_t hotplug_memory_base;
> > +    MemoryRegion hotplug_memory;
> > +    bool enforce_aligned_dimm;
> 
> As mentioned on the earlier version, on ppc we don't have
> compatibility reasons we need to have a mode for unaligned dimms.  Get
> rid of this bool and treat it as always on instead.

ok.

Regards,
Bharata.
Bharata B Rao May 6, 2015, 8:23 a.m. UTC | #4
On Tue, May 05, 2015 at 10:48:50AM +0200, Igor Mammedov wrote:
> On Fri, 24 Apr 2015 12:17:43 +0530
> Bharata B Rao <bharata@linux.vnet.ibm.com> wrote:
> 
> > Initialize a hotplug memory region under which all the hotplugged
> > memory is accommodated. Also enable memory hotplug by setting
> > CONFIG_MEM_HOTPLUG.
> > 
> > Modelled on i386 memory hotplug.
> > 
> > Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
> > ---
> >  default-configs/ppc64-softmmu.mak |  1 +
> >  hw/ppc/spapr.c                    | 38 ++++++++++++++++++++++++++++++++++++++
> >  include/hw/ppc/spapr.h            | 12 ++++++++++++
> >  3 files changed, 51 insertions(+)
> > 
> > diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
> > index 22ef132..16b3011 100644
> > --- a/default-configs/ppc64-softmmu.mak
> > +++ b/default-configs/ppc64-softmmu.mak
> > @@ -51,3 +51,4 @@ CONFIG_XICS_KVM=$(and $(CONFIG_PSERIES),$(CONFIG_KVM))
> >  # For PReP
> >  CONFIG_MC146818RTC=y
> >  CONFIG_ISA_TESTDEV=y
> > +CONFIG_MEM_HOTPLUG=y
> > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > index 910a50f..9dc4c36 100644
> > --- a/hw/ppc/spapr.c
> > +++ b/hw/ppc/spapr.c
> > @@ -125,6 +125,9 @@ struct sPAPRMachineState {
> >  
> >      /*< public >*/
> >      char *kvm_type;
> > +    ram_addr_t hotplug_memory_base;
> > +    MemoryRegion hotplug_memory;
> > +    bool enforce_aligned_dimm;
> >  };
> >  
> >  sPAPREnvironment *spapr;
> > @@ -1514,6 +1517,7 @@ static void ppc_spapr_init(MachineState *machine)
> >      QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL);
> >      int sockets = opts ? qemu_opt_get_number(opts, "sockets", 0) : 0;
> >      int cores = (smp_cpus/smp_threads) ? smp_cpus/smp_threads : 1;
> > +    sPAPRMachineState *ms = SPAPR_MACHINE(machine);
> >  
> >      sockets = sockets ? sockets : cores;
> >      msi_supported = true;
> > @@ -1613,6 +1617,36 @@ static void ppc_spapr_init(MachineState *machine)
> >          memory_region_add_subregion(sysmem, 0, rma_region);
> >      }
> >  
> > +    /* initialize hotplug memory address space */
> > +    if (machine->ram_size < machine->maxram_size) {
> > +        ram_addr_t hotplug_mem_size =
> > +            machine->maxram_size - machine->ram_size;
> > +
> > +        if (machine->ram_slots > SPAPR_MAX_RAM_SLOTS) {
> > +            error_report("unsupported amount of memory slots: %"PRIu64,
> > +                         machine->ram_slots);
> > +            exit(EXIT_FAILURE);
> > +        }
> > +
> > +        ms->hotplug_memory_base = ROUND_UP(machine->ram_size,
> > +                                    SPAPR_HOTPLUG_MEM_ALIGN);
> > +
> > +        if (ms->enforce_aligned_dimm) {
> > +            hotplug_mem_size += SPAPR_HOTPLUG_MEM_ALIGN * machine->ram_slots;
> > +        }
> > +
> > +        if ((ms->hotplug_memory_base + hotplug_mem_size) < hotplug_mem_size) {
> > +            error_report("unsupported amount of maximum memory: " RAM_ADDR_FMT,
> > +                         machine->maxram_size);
> > +            exit(EXIT_FAILURE);
> > +        }
> > +
> > +        memory_region_init(&ms->hotplug_memory, OBJECT(ms),
> > +                           "hotplug-memory", hotplug_mem_size);
> > +        memory_region_add_subregion(sysmem, ms->hotplug_memory_base,
> > +                                    &ms->hotplug_memory);
> > +    }
> > +
> >      filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");
> >      spapr->rtas_size = get_image_size(filename);
> >      spapr->rtas_blob = g_malloc(spapr->rtas_size);
> > @@ -1844,11 +1878,15 @@ static void spapr_set_kvm_type(Object *obj, const char *value, Error **errp)
> >  
> >  static void spapr_machine_initfn(Object *obj)
> >  {
> > +    sPAPRMachineState *ms = SPAPR_MACHINE(obj);
> > +
> >      object_property_add_str(obj, "kvm-type",
> >                              spapr_get_kvm_type, spapr_set_kvm_type, NULL);
> >      object_property_set_description(obj, "kvm-type",
> >                                      "Specifies the KVM virtualization mode (HV, PR)",
> >                                      NULL);
> > +
> > +    ms->enforce_aligned_dimm = true;
> >  }
> >  
> >  static void ppc_cpu_do_nmi_on_cpu(void *arg)
> > diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> > index ecac6e3..53560e9 100644
> > --- a/include/hw/ppc/spapr.h
> > +++ b/include/hw/ppc/spapr.h
> > @@ -542,6 +542,18 @@ struct sPAPREventLogEntry {
> >  
> >  #define SPAPR_MEMORY_BLOCK_SIZE (1 << 28) /* 256MB */
> >  
> > +/*
> > + * This defines the maximum number of DIMM slots we can have for sPAPR
> > + * guest. This is not defined by sPAPR but we are defining it to 4096 slots
> > + * here. With the worst case addition of SPAPR_MEMORY_BLOCK_SIZE
> > + * (256MB) memory per slot, we should be able to support 1TB of guest
> > + * hotpluggable memory.
> > + */
> > +#define SPAPR_MAX_RAM_SLOTS     (1ULL << 12)
> why not write 4096 instead of (1ULL << 12), much easier to read.

Sure.

> 
> BTW:
> KVM supports upto 509 memory slots including slots consumed by
> initial memory.

I see that PowerPC defaults to 32 slots. So having 4096 slots is really
pointless then ? So to ensure more hot-pluggable memory space is available
should I be increasing the size of the minimum pluggable memory in a
dimm slot (as defined by SPAPR_MEMORY_BLOCK_SIZE above) ?

Regards,
Bharata.
David Gibson May 7, 2015, 1:12 a.m. UTC | #5
On Wed, May 06, 2015 at 01:53:05PM +0530, Bharata B Rao wrote:
> On Tue, May 05, 2015 at 10:48:50AM +0200, Igor Mammedov wrote:
> > On Fri, 24 Apr 2015 12:17:43 +0530
> > Bharata B Rao <bharata@linux.vnet.ibm.com> wrote:
> > 
> > > Initialize a hotplug memory region under which all the hotplugged
> > > memory is accommodated. Also enable memory hotplug by setting
> > > CONFIG_MEM_HOTPLUG.
> > > 
> > > Modelled on i386 memory hotplug.
> > > 
> > > Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
> > > ---
> > >  default-configs/ppc64-softmmu.mak |  1 +
> > >  hw/ppc/spapr.c                    | 38 ++++++++++++++++++++++++++++++++++++++
> > >  include/hw/ppc/spapr.h            | 12 ++++++++++++
> > >  3 files changed, 51 insertions(+)
> > > 
> > > diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
> > > index 22ef132..16b3011 100644
> > > --- a/default-configs/ppc64-softmmu.mak
> > > +++ b/default-configs/ppc64-softmmu.mak
> > > @@ -51,3 +51,4 @@ CONFIG_XICS_KVM=$(and $(CONFIG_PSERIES),$(CONFIG_KVM))
> > >  # For PReP
> > >  CONFIG_MC146818RTC=y
> > >  CONFIG_ISA_TESTDEV=y
> > > +CONFIG_MEM_HOTPLUG=y
> > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > > index 910a50f..9dc4c36 100644
> > > --- a/hw/ppc/spapr.c
> > > +++ b/hw/ppc/spapr.c
> > > @@ -125,6 +125,9 @@ struct sPAPRMachineState {
> > >  
> > >      /*< public >*/
> > >      char *kvm_type;
> > > +    ram_addr_t hotplug_memory_base;
> > > +    MemoryRegion hotplug_memory;
> > > +    bool enforce_aligned_dimm;
> > >  };
> > >  
> > >  sPAPREnvironment *spapr;
> > > @@ -1514,6 +1517,7 @@ static void ppc_spapr_init(MachineState *machine)
> > >      QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL);
> > >      int sockets = opts ? qemu_opt_get_number(opts, "sockets", 0) : 0;
> > >      int cores = (smp_cpus/smp_threads) ? smp_cpus/smp_threads : 1;
> > > +    sPAPRMachineState *ms = SPAPR_MACHINE(machine);
> > >  
> > >      sockets = sockets ? sockets : cores;
> > >      msi_supported = true;
> > > @@ -1613,6 +1617,36 @@ static void ppc_spapr_init(MachineState *machine)
> > >          memory_region_add_subregion(sysmem, 0, rma_region);
> > >      }
> > >  
> > > +    /* initialize hotplug memory address space */
> > > +    if (machine->ram_size < machine->maxram_size) {
> > > +        ram_addr_t hotplug_mem_size =
> > > +            machine->maxram_size - machine->ram_size;
> > > +
> > > +        if (machine->ram_slots > SPAPR_MAX_RAM_SLOTS) {
> > > +            error_report("unsupported amount of memory slots: %"PRIu64,
> > > +                         machine->ram_slots);
> > > +            exit(EXIT_FAILURE);
> > > +        }
> > > +
> > > +        ms->hotplug_memory_base = ROUND_UP(machine->ram_size,
> > > +                                    SPAPR_HOTPLUG_MEM_ALIGN);
> > > +
> > > +        if (ms->enforce_aligned_dimm) {
> > > +            hotplug_mem_size += SPAPR_HOTPLUG_MEM_ALIGN * machine->ram_slots;
> > > +        }
> > > +
> > > +        if ((ms->hotplug_memory_base + hotplug_mem_size) < hotplug_mem_size) {
> > > +            error_report("unsupported amount of maximum memory: " RAM_ADDR_FMT,
> > > +                         machine->maxram_size);
> > > +            exit(EXIT_FAILURE);
> > > +        }
> > > +
> > > +        memory_region_init(&ms->hotplug_memory, OBJECT(ms),
> > > +                           "hotplug-memory", hotplug_mem_size);
> > > +        memory_region_add_subregion(sysmem, ms->hotplug_memory_base,
> > > +                                    &ms->hotplug_memory);
> > > +    }
> > > +
> > >      filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");
> > >      spapr->rtas_size = get_image_size(filename);
> > >      spapr->rtas_blob = g_malloc(spapr->rtas_size);
> > > @@ -1844,11 +1878,15 @@ static void spapr_set_kvm_type(Object *obj, const char *value, Error **errp)
> > >  
> > >  static void spapr_machine_initfn(Object *obj)
> > >  {
> > > +    sPAPRMachineState *ms = SPAPR_MACHINE(obj);
> > > +
> > >      object_property_add_str(obj, "kvm-type",
> > >                              spapr_get_kvm_type, spapr_set_kvm_type, NULL);
> > >      object_property_set_description(obj, "kvm-type",
> > >                                      "Specifies the KVM virtualization mode (HV, PR)",
> > >                                      NULL);
> > > +
> > > +    ms->enforce_aligned_dimm = true;
> > >  }
> > >  
> > >  static void ppc_cpu_do_nmi_on_cpu(void *arg)
> > > diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> > > index ecac6e3..53560e9 100644
> > > --- a/include/hw/ppc/spapr.h
> > > +++ b/include/hw/ppc/spapr.h
> > > @@ -542,6 +542,18 @@ struct sPAPREventLogEntry {
> > >  
> > >  #define SPAPR_MEMORY_BLOCK_SIZE (1 << 28) /* 256MB */
> > >  
> > > +/*
> > > + * This defines the maximum number of DIMM slots we can have for sPAPR
> > > + * guest. This is not defined by sPAPR but we are defining it to 4096 slots
> > > + * here. With the worst case addition of SPAPR_MEMORY_BLOCK_SIZE
> > > + * (256MB) memory per slot, we should be able to support 1TB of guest
> > > + * hotpluggable memory.
> > > + */
> > > +#define SPAPR_MAX_RAM_SLOTS     (1ULL << 12)
> > why not write 4096 instead of (1ULL << 12), much easier to read.
> 
> Sure.
> 
> > 
> > BTW:
> > KVM supports upto 509 memory slots including slots consumed by
> > initial memory.
> 
> I see that PowerPC defaults to 32 slots. So having 4096 slots is really
> pointless then ? So to ensure more hot-pluggable memory space is available
> should I be increasing the size of the minimum pluggable memory in a
> dimm slot (as defined by SPAPR_MEMORY_BLOCK_SIZE above) ?

That seems a bit nasty, since then the granularity of adding blocks
will be enormous for small guests as well.

Is it possible to increase the maximum size of a single DIMM, but not
the minimum?  That way you can still do small inserts for small
guests.  To get the full RAM for big guests youd have to insert big
chunks though, due to the limited number of slots.
Bharata B Rao May 7, 2015, 5:01 a.m. UTC | #6
On Thu, May 07, 2015 at 11:12:36AM +1000, David Gibson wrote:
> On Wed, May 06, 2015 at 01:53:05PM +0530, Bharata B Rao wrote:
> > On Tue, May 05, 2015 at 10:48:50AM +0200, Igor Mammedov wrote:
> > > On Fri, 24 Apr 2015 12:17:43 +0530
> > > Bharata B Rao <bharata@linux.vnet.ibm.com> wrote:
<snip>
> > > 
> > > > Initialize a hotplug memory region under which all the hotplugged
> > > > memory is accommodated. Also enable memory hotplug by setting
> > > > CONFIG_MEM_HOTPLUG.
> > > > 
> > > >  }
> > > >  
> > > >  static void ppc_cpu_do_nmi_on_cpu(void *arg)
> > > > diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> > > > index ecac6e3..53560e9 100644
> > > > --- a/include/hw/ppc/spapr.h
> > > > +++ b/include/hw/ppc/spapr.h
> > > > @@ -542,6 +542,18 @@ struct sPAPREventLogEntry {
> > > >  
> > > >  #define SPAPR_MEMORY_BLOCK_SIZE (1 << 28) /* 256MB */
> > > >  
> > > > +/*
> > > > + * This defines the maximum number of DIMM slots we can have for sPAPR
> > > > + * guest. This is not defined by sPAPR but we are defining it to 4096 slots
> > > > + * here. With the worst case addition of SPAPR_MEMORY_BLOCK_SIZE
> > > > + * (256MB) memory per slot, we should be able to support 1TB of guest
> > > > + * hotpluggable memory.
> > > > + */
> > > > +#define SPAPR_MAX_RAM_SLOTS     (1ULL << 12)
> > > why not write 4096 instead of (1ULL << 12), much easier to read.
> > 
> > Sure.
> > 
> > > 
> > > BTW:
> > > KVM supports upto 509 memory slots including slots consumed by
> > > initial memory.
> > 
> > I see that PowerPC defaults to 32 slots. So having 4096 slots is really
> > pointless then ? So to ensure more hot-pluggable memory space is available
> > should I be increasing the size of the minimum pluggable memory in a
> > dimm slot (as defined by SPAPR_MEMORY_BLOCK_SIZE above) ?
> 
> That seems a bit nasty, since then the granularity of adding blocks
> will be enormous for small guests as well.
> 
> Is it possible to increase the maximum size of a single DIMM, but not
> the minimum?  That way you can still do small inserts for small
> guests.  To get the full RAM for big guests youd have to insert big
> chunks though, due to the limited number of slots.

The maximum memory that can be plugged into a slot is not limited iiuc,
so smaller and bigger guests can use memory sizes appropriate for them.
Only the minimum size is restricted to SPAPR_MEMORY_BLOCK_SIZE (256M).

So I guess I should just stick to 32 slots here for PowerPC memory
hotplug implementation.

Regards,
Bharata.
diff mbox

Patch

diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
index 22ef132..16b3011 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -51,3 +51,4 @@  CONFIG_XICS_KVM=$(and $(CONFIG_PSERIES),$(CONFIG_KVM))
 # For PReP
 CONFIG_MC146818RTC=y
 CONFIG_ISA_TESTDEV=y
+CONFIG_MEM_HOTPLUG=y
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 910a50f..9dc4c36 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -125,6 +125,9 @@  struct sPAPRMachineState {
 
     /*< public >*/
     char *kvm_type;
+    ram_addr_t hotplug_memory_base;
+    MemoryRegion hotplug_memory;
+    bool enforce_aligned_dimm;
 };
 
 sPAPREnvironment *spapr;
@@ -1514,6 +1517,7 @@  static void ppc_spapr_init(MachineState *machine)
     QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL);
     int sockets = opts ? qemu_opt_get_number(opts, "sockets", 0) : 0;
     int cores = (smp_cpus/smp_threads) ? smp_cpus/smp_threads : 1;
+    sPAPRMachineState *ms = SPAPR_MACHINE(machine);
 
     sockets = sockets ? sockets : cores;
     msi_supported = true;
@@ -1613,6 +1617,36 @@  static void ppc_spapr_init(MachineState *machine)
         memory_region_add_subregion(sysmem, 0, rma_region);
     }
 
+    /* initialize hotplug memory address space */
+    if (machine->ram_size < machine->maxram_size) {
+        ram_addr_t hotplug_mem_size =
+            machine->maxram_size - machine->ram_size;
+
+        if (machine->ram_slots > SPAPR_MAX_RAM_SLOTS) {
+            error_report("unsupported amount of memory slots: %"PRIu64,
+                         machine->ram_slots);
+            exit(EXIT_FAILURE);
+        }
+
+        ms->hotplug_memory_base = ROUND_UP(machine->ram_size,
+                                    SPAPR_HOTPLUG_MEM_ALIGN);
+
+        if (ms->enforce_aligned_dimm) {
+            hotplug_mem_size += SPAPR_HOTPLUG_MEM_ALIGN * machine->ram_slots;
+        }
+
+        if ((ms->hotplug_memory_base + hotplug_mem_size) < hotplug_mem_size) {
+            error_report("unsupported amount of maximum memory: " RAM_ADDR_FMT,
+                         machine->maxram_size);
+            exit(EXIT_FAILURE);
+        }
+
+        memory_region_init(&ms->hotplug_memory, OBJECT(ms),
+                           "hotplug-memory", hotplug_mem_size);
+        memory_region_add_subregion(sysmem, ms->hotplug_memory_base,
+                                    &ms->hotplug_memory);
+    }
+
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");
     spapr->rtas_size = get_image_size(filename);
     spapr->rtas_blob = g_malloc(spapr->rtas_size);
@@ -1844,11 +1878,15 @@  static void spapr_set_kvm_type(Object *obj, const char *value, Error **errp)
 
 static void spapr_machine_initfn(Object *obj)
 {
+    sPAPRMachineState *ms = SPAPR_MACHINE(obj);
+
     object_property_add_str(obj, "kvm-type",
                             spapr_get_kvm_type, spapr_set_kvm_type, NULL);
     object_property_set_description(obj, "kvm-type",
                                     "Specifies the KVM virtualization mode (HV, PR)",
                                     NULL);
+
+    ms->enforce_aligned_dimm = true;
 }
 
 static void ppc_cpu_do_nmi_on_cpu(void *arg)
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index ecac6e3..53560e9 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -542,6 +542,18 @@  struct sPAPREventLogEntry {
 
 #define SPAPR_MEMORY_BLOCK_SIZE (1 << 28) /* 256MB */
 
+/*
+ * This defines the maximum number of DIMM slots we can have for sPAPR
+ * guest. This is not defined by sPAPR but we are defining it to 4096 slots
+ * here. With the worst case addition of SPAPR_MEMORY_BLOCK_SIZE
+ * (256MB) memory per slot, we should be able to support 1TB of guest
+ * hotpluggable memory.
+ */
+#define SPAPR_MAX_RAM_SLOTS     (1ULL << 12)
+
+/* 1GB alignment for hotplug memory region */
+#define SPAPR_HOTPLUG_MEM_ALIGN (1ULL << 30)
+
 void spapr_events_init(sPAPREnvironment *spapr);
 void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq);
 int spapr_h_cas_compose_response(target_ulong addr, target_ulong size);