* [Qemu-devel] [PATCH v7 0/4] s390: Support for Hotplug of Standby Memory
@ 2014-07-30 18:15 Matthew Rosato
2014-07-30 18:15 ` [Qemu-devel] [PATCH v7 1/4] sclp-s390: Add device to manage s390 memory hotplug Matthew Rosato
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Matthew Rosato @ 2014-07-30 18:15 UTC (permalink / raw)
To: qemu-devel
Cc: agraf, borntraeger, aliguori, imammedo, cornelia.huck, pbonzini, rth
This patchset adds support in s390 for a pool of standby memory,
which can be set online/offline by the guest (ie, via chmem).
The standby pool of memory is allocated as the difference between
the initial memory setting and the maxmem setting.
As part of this work, additional results are provided for the
Read SCP Information SCLP, and new implentation is added for the
Read Storage Element Information, Attach Storage Element,
Assign Storage and Unassign Storage SCLPs, which enables the s390
guest to manipulate the standby memory pool.
This patchset is based on work originally done by Jeng-Fang (Nick)
Wang.
Sample qemu command snippet:
qemu -machine s390-ccw-virtio -m 1024M,maxmem=2048M,slots=32 -enable-kvm
This will allocate 1024M of active memory, and another 1024M
of standby memory. Example output from s390-tools lsmem:
=============================================================================
0x0000000000000000-0x000000000fffffff 256 online no 0-127
0x0000000010000000-0x000000001fffffff 256 online yes 128-255
0x0000000020000000-0x000000003fffffff 512 online no 256-511
0x0000000040000000-0x000000007fffffff 1024 offline - 512-1023
Memory device size : 2 MB
Memory block size : 256 MB
Total online memory : 1024 MB
Total offline memory: 1024 MB
The guest can dynamically enable part or all of the standby pool
via the s390-tools chmem, for example:
chmem -e 512M
And can attempt to dynamically disable:
chmem -d 512M
Changes for v7:
* Added patch to enforce the same memory alignments in s390-virtio.c,
so that shared code (like sclp) doesn't need to be dual paths.
Changes for v6:
* Fix in sclp.h - DeviceState parent --> SysBusDevice parent
in struct sclpMemoryHotplugDev.
* Fix in assign_storage - int this_subregion_size, should
be uint64_t.
* Added information on how to test in the cover letter.
Changes for v5:
* Since ACPI memory hotplug is now in, removed Igor's patches
from this set.
* Updated sclp.c to use object_resolve_path() instead of
object_property_find().
Matthew Rosato (4):
sclp-s390: Add device to manage s390 memory hotplug
virtio-ccw: Include standby memory when calculating storage increment
s390-virtio: Apply same memory boundaries as virtio-ccw
sclp-s390: Add memory hotplug SCLPs
hw/s390x/s390-virtio-ccw.c | 46 +++++--
hw/s390x/s390-virtio.c | 15 ++-
hw/s390x/sclp.c | 289 +++++++++++++++++++++++++++++++++++++++++++-
include/hw/s390x/sclp.h | 20 +++
qemu-options.hx | 3 +-
target-s390x/cpu.h | 18 +++
target-s390x/kvm.c | 5 +
7 files changed, 375 insertions(+), 21 deletions(-)
--
1.7.9.5
^ permalink raw reply [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v7 1/4] sclp-s390: Add device to manage s390 memory hotplug
2014-07-30 18:15 [Qemu-devel] [PATCH v7 0/4] s390: Support for Hotplug of Standby Memory Matthew Rosato
@ 2014-07-30 18:15 ` Matthew Rosato
2014-07-30 18:15 ` [Qemu-devel] [PATCH v7 2/4] virtio-ccw: Include standby memory when calculating storage increment Matthew Rosato
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Matthew Rosato @ 2014-07-30 18:15 UTC (permalink / raw)
To: qemu-devel
Cc: agraf, borntraeger, aliguori, imammedo, cornelia.huck, pbonzini, rth
Add sclpMemoryHotplugDev to contain associated data structures, etc.
Signed-off-by: Matthew Rosato <mjrosato@linux.vnet.ibm.com>
---
hw/s390x/sclp.c | 30 ++++++++++++++++++++++++++++++
include/hw/s390x/sclp.h | 20 ++++++++++++++++++++
2 files changed, 50 insertions(+)
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index d8ddf35..769d7c3 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -183,3 +183,33 @@ void s390_sclp_init(void)
OBJECT(dev), NULL);
qdev_init_nofail(dev);
}
+
+sclpMemoryHotplugDev *init_sclp_memory_hotplug_dev(void)
+{
+ DeviceState *dev;
+ dev = qdev_create(NULL, TYPE_SCLP_MEMORY_HOTPLUG_DEV);
+ object_property_add_child(qdev_get_machine(),
+ TYPE_SCLP_MEMORY_HOTPLUG_DEV,
+ OBJECT(dev), NULL);
+ qdev_init_nofail(dev);
+ return SCLP_MEMORY_HOTPLUG_DEV(object_resolve_path(
+ TYPE_SCLP_MEMORY_HOTPLUG_DEV, NULL));
+}
+
+sclpMemoryHotplugDev *get_sclp_memory_hotplug_dev(void)
+{
+ return SCLP_MEMORY_HOTPLUG_DEV(object_resolve_path(
+ TYPE_SCLP_MEMORY_HOTPLUG_DEV, NULL));
+}
+
+static TypeInfo sclp_memory_hotplug_dev_info = {
+ .name = TYPE_SCLP_MEMORY_HOTPLUG_DEV,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(sclpMemoryHotplugDev),
+};
+
+static void register_types(void)
+{
+ type_register_static(&sclp_memory_hotplug_dev_info);
+}
+type_init(register_types);
diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h
index 7ef1622..5c43574 100644
--- a/include/hw/s390x/sclp.h
+++ b/include/hw/s390x/sclp.h
@@ -37,6 +37,7 @@
#define SCLP_STARTING_SUBINCREMENT_ID 0x10001
#define SCLP_INCREMENT_UNIT 0x10000
#define MAX_AVAIL_SLOTS 32
+#define MAX_STORAGE_INCREMENTS 1020
/* CPU hotplug SCLP codes */
#define SCLP_HAS_CPU_INFO 0x0C00000000000000ULL
@@ -156,6 +157,23 @@ typedef struct SCCB {
char data[SCCB_DATA_LEN];
} QEMU_PACKED SCCB;
+typedef struct sclpMemoryHotplugDev sclpMemoryHotplugDev;
+
+#define TYPE_SCLP_MEMORY_HOTPLUG_DEV "sclp-memory-hotplug-dev"
+#define SCLP_MEMORY_HOTPLUG_DEV(obj) \
+ OBJECT_CHECK(sclpMemoryHotplugDev, (obj), TYPE_SCLP_MEMORY_HOTPLUG_DEV)
+
+struct sclpMemoryHotplugDev {
+ SysBusDevice parent;
+ ram_addr_t standby_mem_size;
+ ram_addr_t padded_ram_size;
+ ram_addr_t pad_size;
+ ram_addr_t standby_subregion_size;
+ ram_addr_t rzm;
+ int increment_size;
+ char *standby_state_map;
+};
+
static inline int sccb_data_len(SCCB *sccb)
{
return be16_to_cpu(sccb->h.length) - sizeof(sccb->h);
@@ -163,6 +181,8 @@ static inline int sccb_data_len(SCCB *sccb)
void s390_sclp_init(void);
+sclpMemoryHotplugDev *init_sclp_memory_hotplug_dev(void);
+sclpMemoryHotplugDev *get_sclp_memory_hotplug_dev(void);
void sclp_service_interrupt(uint32_t sccb);
void raise_irq_cpu_hotplug(void);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v7 2/4] virtio-ccw: Include standby memory when calculating storage increment
2014-07-30 18:15 [Qemu-devel] [PATCH v7 0/4] s390: Support for Hotplug of Standby Memory Matthew Rosato
2014-07-30 18:15 ` [Qemu-devel] [PATCH v7 1/4] sclp-s390: Add device to manage s390 memory hotplug Matthew Rosato
@ 2014-07-30 18:15 ` Matthew Rosato
2014-07-30 18:15 ` [Qemu-devel] [PATCH v7 3/4] s390-virtio: Apply same memory boundaries as virtio-ccw Matthew Rosato
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Matthew Rosato @ 2014-07-30 18:15 UTC (permalink / raw)
To: qemu-devel
Cc: agraf, borntraeger, aliguori, imammedo, cornelia.huck, pbonzini, rth
When determining the memory increment size, use the maxmem size if
it was specified.
Signed-off-by: Matthew Rosato <mjrosato@linux.vnet.ibm.com>
---
hw/s390x/s390-virtio-ccw.c | 46 ++++++++++++++++++++++++++++++++++++--------
qemu-options.hx | 3 ++-
target-s390x/cpu.h | 3 +++
3 files changed, 43 insertions(+), 9 deletions(-)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 42f5cec..e736b24 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -17,6 +17,7 @@
#include "ioinst.h"
#include "css.h"
#include "virtio-ccw.h"
+#include "qemu/config-file.h"
void io_subsystem_reset(void)
{
@@ -84,17 +85,35 @@ static void ccw_init(MachineState *machine)
ram_addr_t my_ram_size = machine->ram_size;
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);
- int shift = 0;
+ sclpMemoryHotplugDev *mhd = init_sclp_memory_hotplug_dev();
uint8_t *storage_keys;
int ret;
VirtualCssBus *css_bus;
-
- /* s390x ram size detection needs a 16bit multiplier + an increment. So
- guests > 64GB can be specified in 2MB steps etc. */
- while ((my_ram_size >> (20 + shift)) > 65535) {
- shift++;
+ QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory"), NULL);
+ ram_addr_t pad_size = 0;
+ ram_addr_t maxmem = qemu_opt_get_size(opts, "maxmem", my_ram_size);
+ ram_addr_t standby_mem_size = maxmem - my_ram_size;
+
+ /* The storage increment size is a multiple of 1M and is a power of 2.
+ * The number of storage increments must be MAX_STORAGE_INCREMENTS or fewer.
+ * The variable 'mhd->increment_size' is an exponent of 2 that can be
+ * used to calculate the size (in bytes) of an increment. */
+ mhd->increment_size = 20;
+ while ((my_ram_size >> mhd->increment_size) > MAX_STORAGE_INCREMENTS) {
+ mhd->increment_size++;
+ }
+ while ((standby_mem_size >> mhd->increment_size) > MAX_STORAGE_INCREMENTS) {
+ mhd->increment_size++;
}
- my_ram_size = my_ram_size >> (20 + shift) << (20 + shift);
+
+ /* The core and standby memory areas need to be aligned with
+ * the increment size. In effect, this can cause the
+ * user-specified memory size to be rounded down to align
+ * with the nearest increment boundary. */
+ standby_mem_size = standby_mem_size >> mhd->increment_size
+ << mhd->increment_size;
+ my_ram_size = my_ram_size >> mhd->increment_size
+ << mhd->increment_size;
/* let's propagate the changed ram size into the global variable. */
ram_size = my_ram_size;
@@ -109,11 +128,22 @@ static void ccw_init(MachineState *machine)
/* register hypercalls */
virtio_ccw_register_hcalls();
- /* allocate RAM */
+ /* allocate RAM for core */
memory_region_init_ram(ram, NULL, "s390.ram", my_ram_size);
vmstate_register_ram_global(ram);
memory_region_add_subregion(sysmem, 0, ram);
+ /* If the size of ram is not on a MEM_SECTION_SIZE boundary,
+ calculate the pad size necessary to force this boundary. */
+ if (standby_mem_size) {
+ if (my_ram_size % MEM_SECTION_SIZE) {
+ pad_size = MEM_SECTION_SIZE - my_ram_size % MEM_SECTION_SIZE;
+ }
+ my_ram_size += standby_mem_size + pad_size;
+ mhd->pad_size = pad_size;
+ mhd->standby_mem_size = standby_mem_size;
+ }
+
/* allocate storage keys */
storage_keys = g_malloc0(my_ram_size / TARGET_PAGE_SIZE);
diff --git a/qemu-options.hx b/qemu-options.hx
index 1549625..ab69efd 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -225,7 +225,8 @@ DEF("m", HAS_ARG, QEMU_OPTION_m,
" size: initial amount of guest memory (default: "
stringify(DEFAULT_RAM_SIZE) "MiB)\n"
" slots: number of hotplug slots (default: none)\n"
- " maxmem: maximum amount of guest memory (default: none)\n",
+ " maxmem: maximum amount of guest memory (default: none)\n"
+ "NOTE: Some architectures might enforce a specific granularity\n",
QEMU_ARCH_ALL)
STEXI
@item -m [size=]@var{megs}
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index b13761d..ba0e4b4 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -1045,6 +1045,9 @@ static inline void cpu_inject_crw_mchk(S390CPU *cpu)
cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
}
+/* from s390-virtio-ccw */
+#define MEM_SECTION_SIZE 0x10000000UL
+
/* fpu_helper.c */
uint32_t set_cc_nz_f32(float32 v);
uint32_t set_cc_nz_f64(float64 v);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v7 3/4] s390-virtio: Apply same memory boundaries as virtio-ccw
2014-07-30 18:15 [Qemu-devel] [PATCH v7 0/4] s390: Support for Hotplug of Standby Memory Matthew Rosato
2014-07-30 18:15 ` [Qemu-devel] [PATCH v7 1/4] sclp-s390: Add device to manage s390 memory hotplug Matthew Rosato
2014-07-30 18:15 ` [Qemu-devel] [PATCH v7 2/4] virtio-ccw: Include standby memory when calculating storage increment Matthew Rosato
@ 2014-07-30 18:15 ` Matthew Rosato
2014-07-30 18:15 ` [Qemu-devel] [PATCH v7 4/4] sclp-s390: Add memory hotplug SCLPs Matthew Rosato
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Matthew Rosato @ 2014-07-30 18:15 UTC (permalink / raw)
To: qemu-devel
Cc: agraf, borntraeger, aliguori, imammedo, cornelia.huck, pbonzini, rth
Although s390-virtio won't support memory hotplug, it should
enforce the same memory boundaries so that it can use shared codepaths
(like read_SCP_info).
Signed-off-by: Matthew Rosato <mjrosato@linux.vnet.ibm.com>
---
hw/s390x/s390-virtio.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index 93c7ace..857f8d3 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -229,18 +229,21 @@ static void s390_init(MachineState *machine)
ram_addr_t my_ram_size = machine->ram_size;
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);
- int shift = 0;
+ int increment_size = 20;
uint8_t *storage_keys;
void *virtio_region;
hwaddr virtio_region_len;
hwaddr virtio_region_start;
- /* s390x ram size detection needs a 16bit multiplier + an increment. So
- guests > 64GB can be specified in 2MB steps etc. */
- while ((my_ram_size >> (20 + shift)) > 65535) {
- shift++;
+ /*
+ * The storage increment size is a multiple of 1M and is a power of 2.
+ * The number of storage increments must be MAX_STORAGE_INCREMENTS or
+ * fewer.
+ */
+ while ((my_ram_size >> increment_size) > MAX_STORAGE_INCREMENTS) {
+ increment_size++;
}
- my_ram_size = my_ram_size >> (20 + shift) << (20 + shift);
+ my_ram_size = my_ram_size >> increment_size << increment_size;
/* let's propagate the changed ram size into the global variable. */
ram_size = my_ram_size;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v7 4/4] sclp-s390: Add memory hotplug SCLPs
2014-07-30 18:15 [Qemu-devel] [PATCH v7 0/4] s390: Support for Hotplug of Standby Memory Matthew Rosato
` (2 preceding siblings ...)
2014-07-30 18:15 ` [Qemu-devel] [PATCH v7 3/4] s390-virtio: Apply same memory boundaries as virtio-ccw Matthew Rosato
@ 2014-07-30 18:15 ` Matthew Rosato
2014-08-27 13:22 ` [Qemu-devel] [PATCH v7 0/4] s390: Support for Hotplug of Standby Memory Matthew Rosato
2014-08-28 7:27 ` Christian Borntraeger
5 siblings, 0 replies; 7+ messages in thread
From: Matthew Rosato @ 2014-07-30 18:15 UTC (permalink / raw)
To: qemu-devel
Cc: agraf, borntraeger, aliguori, imammedo, cornelia.huck, pbonzini, rth
Add memory information to read SCP info and add handlers for
Read Storage Element Information, Attach Storage Element,
Assign Storage and Unassign Storage.
Signed-off-by: Matthew Rosato <mjrosato@linux.vnet.ibm.com>
---
hw/s390x/sclp.c | 259 ++++++++++++++++++++++++++++++++++++++++++++++++++--
target-s390x/cpu.h | 15 +++
target-s390x/kvm.c | 5 +
3 files changed, 273 insertions(+), 6 deletions(-)
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 769d7c3..936b189 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -16,7 +16,8 @@
#include "sysemu/kvm.h"
#include "exec/memory.h"
#include "sysemu/sysemu.h"
-
+#include "exec/address-spaces.h"
+#include "qemu/config-file.h"
#include "hw/s390x/sclp.h"
#include "hw/s390x/event-facility.h"
@@ -33,10 +34,19 @@ static inline SCLPEventFacility *get_event_facility(void)
static void read_SCP_info(SCCB *sccb)
{
ReadInfo *read_info = (ReadInfo *) sccb;
+ sclpMemoryHotplugDev *mhd = get_sclp_memory_hotplug_dev();
CPUState *cpu;
- int shift = 0;
int cpu_count = 0;
int i = 0;
+ int increment_size = 20;
+ int rnsize, rnmax;
+ QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory"), NULL);
+ int slots = qemu_opt_get_number(opts, "slots", 0);
+ int max_avail_slots = s390_get_memslot_count(kvm_state);
+
+ if (slots > max_avail_slots) {
+ slots = max_avail_slots;
+ }
CPU_FOREACH(cpu) {
cpu_count++;
@@ -54,14 +64,235 @@ static void read_SCP_info(SCCB *sccb)
read_info->facilities = cpu_to_be64(SCLP_HAS_CPU_INFO);
- while ((ram_size >> (20 + shift)) > 65535) {
- shift++;
+ /*
+ * The storage increment size is a multiple of 1M and is a power of 2.
+ * The number of storage increments must be MAX_STORAGE_INCREMENTS or fewer.
+ */
+ while ((ram_size >> increment_size) > MAX_STORAGE_INCREMENTS) {
+ increment_size++;
+ }
+ rnmax = ram_size >> increment_size;
+
+ /* Memory Hotplug is only supported for the ccw machine type */
+ if (mhd) {
+ while ((mhd->standby_mem_size >> increment_size) >
+ MAX_STORAGE_INCREMENTS) {
+ increment_size++;
+ }
+ assert(increment_size == mhd->increment_size);
+
+ mhd->standby_subregion_size = MEM_SECTION_SIZE;
+ /* Deduct the memory slot already used for core */
+ if (slots > 0) {
+ while ((mhd->standby_subregion_size * (slots - 1)
+ < mhd->standby_mem_size)) {
+ mhd->standby_subregion_size = mhd->standby_subregion_size << 1;
+ }
+ }
+ /*
+ * Initialize mapping of guest standby memory sections indicating which
+ * are and are not online. Assume all standby memory begins offline.
+ */
+ if (mhd->standby_state_map == 0) {
+ if (mhd->standby_mem_size % mhd->standby_subregion_size) {
+ mhd->standby_state_map = g_malloc0((mhd->standby_mem_size /
+ mhd->standby_subregion_size + 1) *
+ (mhd->standby_subregion_size /
+ MEM_SECTION_SIZE));
+ } else {
+ mhd->standby_state_map = g_malloc0(mhd->standby_mem_size /
+ MEM_SECTION_SIZE);
+ }
+ }
+ mhd->padded_ram_size = ram_size + mhd->pad_size;
+ mhd->rzm = 1 << mhd->increment_size;
+ rnmax = ((ram_size + mhd->standby_mem_size + mhd->pad_size)
+ >> mhd->increment_size);
+
+ read_info->facilities |= cpu_to_be64(SCLP_FC_ASSIGN_ATTACH_READ_STOR);
+ }
+
+ rnsize = 1 << (increment_size - 20);
+ if (rnsize <= 128) {
+ read_info->rnsize = rnsize;
+ } else {
+ read_info->rnsize = 0;
+ read_info->rnsize2 = cpu_to_be32(rnsize);
}
- read_info->rnmax = cpu_to_be16(ram_size >> (20 + shift));
- read_info->rnsize = 1 << shift;
+
+ if (rnmax < 0x10000) {
+ read_info->rnmax = cpu_to_be16(rnmax);
+ } else {
+ read_info->rnmax = cpu_to_be16(0);
+ read_info->rnmax2 = cpu_to_be64(rnmax);
+ }
+
sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION);
}
+static void read_storage_element0_info(SCCB *sccb)
+{
+ int i, assigned;
+ int subincrement_id = SCLP_STARTING_SUBINCREMENT_ID;
+ ReadStorageElementInfo *storage_info = (ReadStorageElementInfo *) sccb;
+ sclpMemoryHotplugDev *mhd = get_sclp_memory_hotplug_dev();
+
+ assert(mhd);
+
+ if ((ram_size >> mhd->increment_size) >= 0x10000) {
+ sccb->h.response_code = cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
+ return;
+ }
+
+ /* Return information regarding core memory */
+ storage_info->max_id = cpu_to_be16(mhd->standby_mem_size ? 1 : 0);
+ assigned = ram_size >> mhd->increment_size;
+ storage_info->assigned = cpu_to_be16(assigned);
+
+ for (i = 0; i < assigned; i++) {
+ storage_info->entries[i] = cpu_to_be32(subincrement_id);
+ subincrement_id += SCLP_INCREMENT_UNIT;
+ }
+ sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION);
+}
+
+static void read_storage_element1_info(SCCB *sccb)
+{
+ ReadStorageElementInfo *storage_info = (ReadStorageElementInfo *) sccb;
+ sclpMemoryHotplugDev *mhd = get_sclp_memory_hotplug_dev();
+
+ assert(mhd);
+
+ if ((mhd->standby_mem_size >> mhd->increment_size) >= 0x10000) {
+ sccb->h.response_code = cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
+ return;
+ }
+
+ /* Return information regarding standby memory */
+ storage_info->max_id = cpu_to_be16(mhd->standby_mem_size ? 1 : 0);
+ storage_info->assigned = cpu_to_be16(mhd->standby_mem_size >>
+ mhd->increment_size);
+ storage_info->standby = cpu_to_be16(mhd->standby_mem_size >>
+ mhd->increment_size);
+ sccb->h.response_code = cpu_to_be16(SCLP_RC_STANDBY_READ_COMPLETION);
+}
+
+static void attach_storage_element(SCCB *sccb, uint16_t element)
+{
+ int i, assigned, subincrement_id;
+ AttachStorageElement *attach_info = (AttachStorageElement *) sccb;
+ sclpMemoryHotplugDev *mhd = get_sclp_memory_hotplug_dev();
+
+ assert(mhd);
+
+ if (element != 1) {
+ sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
+ return;
+ }
+
+ assigned = mhd->standby_mem_size >> mhd->increment_size;
+ attach_info->assigned = cpu_to_be16(assigned);
+ subincrement_id = ((ram_size >> mhd->increment_size) << 16)
+ + SCLP_STARTING_SUBINCREMENT_ID;
+ for (i = 0; i < assigned; i++) {
+ attach_info->entries[i] = cpu_to_be32(subincrement_id);
+ subincrement_id += SCLP_INCREMENT_UNIT;
+ }
+ sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_COMPLETION);
+}
+
+static void assign_storage(SCCB *sccb)
+{
+ MemoryRegion *mr = NULL;
+ uint64_t this_subregion_size;
+ AssignStorage *assign_info = (AssignStorage *) sccb;
+ sclpMemoryHotplugDev *mhd = get_sclp_memory_hotplug_dev();
+ assert(mhd);
+ ram_addr_t assign_addr = (assign_info->rn - 1) * mhd->rzm;
+ MemoryRegion *sysmem = get_system_memory();
+
+ if ((assign_addr % MEM_SECTION_SIZE == 0) &&
+ (assign_addr >= mhd->padded_ram_size)) {
+ /* Re-use existing memory region if found */
+ mr = memory_region_find(sysmem, assign_addr, 1).mr;
+ if (!mr) {
+
+ MemoryRegion *standby_ram = g_new(MemoryRegion, 1);
+
+ /* offset to align to standby_subregion_size for allocation */
+ ram_addr_t offset = assign_addr -
+ (assign_addr - mhd->padded_ram_size)
+ % mhd->standby_subregion_size;
+
+ /* strlen("standby.ram") + 4 (Max of KVM_MEMORY_SLOTS) + NULL */
+ char id[16];
+ snprintf(id, 16, "standby.ram%d",
+ (int)((offset - mhd->padded_ram_size) /
+ mhd->standby_subregion_size) + 1);
+
+ /* Allocate a subregion of the calculated standby_subregion_size */
+ if (offset + mhd->standby_subregion_size >
+ mhd->padded_ram_size + mhd->standby_mem_size) {
+ this_subregion_size = mhd->padded_ram_size +
+ mhd->standby_mem_size - offset;
+ } else {
+ this_subregion_size = mhd->standby_subregion_size;
+ }
+
+ memory_region_init_ram(standby_ram, NULL, id, this_subregion_size);
+ vmstate_register_ram_global(standby_ram);
+ memory_region_add_subregion(sysmem, offset, standby_ram);
+ }
+ /* The specified subregion is no longer in standby */
+ mhd->standby_state_map[(assign_addr - mhd->padded_ram_size)
+ / MEM_SECTION_SIZE] = 1;
+ }
+ sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_COMPLETION);
+}
+
+static void unassign_storage(SCCB *sccb)
+{
+ MemoryRegion *mr = NULL;
+ AssignStorage *assign_info = (AssignStorage *) sccb;
+ sclpMemoryHotplugDev *mhd = get_sclp_memory_hotplug_dev();
+ assert(mhd);
+ ram_addr_t unassign_addr = (assign_info->rn - 1) * mhd->rzm;
+ MemoryRegion *sysmem = get_system_memory();
+
+ /* if the addr is a multiple of 256 MB */
+ if ((unassign_addr % MEM_SECTION_SIZE == 0) &&
+ (unassign_addr >= mhd->padded_ram_size)) {
+ mhd->standby_state_map[(unassign_addr -
+ mhd->padded_ram_size) / MEM_SECTION_SIZE] = 0;
+
+ /* find the specified memory region and destroy it */
+ mr = memory_region_find(sysmem, unassign_addr, 1).mr;
+ if (mr) {
+ int i;
+ int is_removable = 1;
+ ram_addr_t map_offset = (unassign_addr - mhd->padded_ram_size -
+ (unassign_addr - mhd->padded_ram_size)
+ % mhd->standby_subregion_size);
+ /* Mark all affected subregions as 'standby' once again */
+ for (i = 0;
+ i < (mhd->standby_subregion_size / MEM_SECTION_SIZE);
+ i++) {
+
+ if (mhd->standby_state_map[i + map_offset / MEM_SECTION_SIZE]) {
+ is_removable = 0;
+ break;
+ }
+ }
+ if (is_removable) {
+ memory_region_del_subregion(sysmem, mr);
+ memory_region_destroy(mr);
+ g_free(mr);
+ }
+ }
+ }
+ sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_COMPLETION);
+}
+
/* Provide information about the CPU */
static void sclp_read_cpu_info(SCCB *sccb)
{
@@ -103,6 +334,22 @@ static void sclp_execute(SCCB *sccb, uint32_t code)
case SCLP_CMDW_READ_CPU_INFO:
sclp_read_cpu_info(sccb);
break;
+ case SCLP_READ_STORAGE_ELEMENT_INFO:
+ if (code & 0xff00) {
+ read_storage_element1_info(sccb);
+ } else {
+ read_storage_element0_info(sccb);
+ }
+ break;
+ case SCLP_ATTACH_STORAGE_ELEMENT:
+ attach_storage_element(sccb, (code & 0xff00) >> 8);
+ break;
+ case SCLP_ASSIGN_STORAGE:
+ assign_storage(sccb);
+ break;
+ case SCLP_UNASSIGN_STORAGE:
+ unassign_storage(sccb);
+ break;
default:
efc->command_handler(ef, sccb, code);
break;
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index ba0e4b4..1c1681c 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -1047,6 +1047,7 @@ static inline void cpu_inject_crw_mchk(S390CPU *cpu)
/* from s390-virtio-ccw */
#define MEM_SECTION_SIZE 0x10000000UL
+#define MAX_AVAIL_SLOTS 32
/* fpu_helper.c */
uint32_t set_cc_nz_f32(float32 v);
@@ -1070,6 +1071,7 @@ void kvm_s390_enable_css_support(S390CPU *cpu);
int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch,
int vq, bool assign);
int kvm_s390_cpu_restart(S390CPU *cpu);
+int kvm_s390_get_memslot_count(KVMState *s);
void kvm_s390_clear_cmma_callback(void *opaque);
#else
static inline void kvm_s390_io_interrupt(uint16_t subchannel_id,
@@ -1097,6 +1099,10 @@ static inline int kvm_s390_cpu_restart(S390CPU *cpu)
static inline void kvm_s390_clear_cmma_callback(void *opaque)
{
}
+static inline int kvm_s390_get_memslot_count(KVMState *s)
+{
+ return MAX_AVAIL_SLOTS;
+}
#endif
static inline void cmma_reset(S390CPU *cpu)
@@ -1115,6 +1121,15 @@ static inline int s390_cpu_restart(S390CPU *cpu)
return -ENOSYS;
}
+static inline int s390_get_memslot_count(KVMState *s)
+{
+ if (kvm_enabled()) {
+ return kvm_s390_get_memslot_count(s);
+ } else {
+ return MAX_AVAIL_SLOTS;
+ }
+}
+
void s390_io_interrupt(uint16_t subchannel_id, uint16_t subchannel_nr,
uint32_t io_int_parm, uint32_t io_int_word);
void s390_crw_mchk(void);
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index a32d91a..9f2b586 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -1306,3 +1306,8 @@ int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch,
}
return kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick);
}
+
+int kvm_s390_get_memslot_count(KVMState *s)
+{
+ return kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
+}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v7 0/4] s390: Support for Hotplug of Standby Memory
2014-07-30 18:15 [Qemu-devel] [PATCH v7 0/4] s390: Support for Hotplug of Standby Memory Matthew Rosato
` (3 preceding siblings ...)
2014-07-30 18:15 ` [Qemu-devel] [PATCH v7 4/4] sclp-s390: Add memory hotplug SCLPs Matthew Rosato
@ 2014-08-27 13:22 ` Matthew Rosato
2014-08-28 7:27 ` Christian Borntraeger
5 siblings, 0 replies; 7+ messages in thread
From: Matthew Rosato @ 2014-08-27 13:22 UTC (permalink / raw)
To: qemu-devel
Cc: agraf, borntraeger, aliguori, imammedo, cornelia.huck, pbonzini, rth
On 07/30/2014 02:15 PM, Matthew Rosato wrote:
> This patchset adds support in s390 for a pool of standby memory,
> which can be set online/offline by the guest (ie, via chmem).
> The standby pool of memory is allocated as the difference between
> the initial memory setting and the maxmem setting.
> As part of this work, additional results are provided for the
> Read SCP Information SCLP, and new implentation is added for the
> Read Storage Element Information, Attach Storage Element,
> Assign Storage and Unassign Storage SCLPs, which enables the s390
> guest to manipulate the standby memory pool.
>
> This patchset is based on work originally done by Jeng-Fang (Nick)
> Wang.
>
> Sample qemu command snippet:
>
> qemu -machine s390-ccw-virtio -m 1024M,maxmem=2048M,slots=32 -enable-kvm
>
> This will allocate 1024M of active memory, and another 1024M
> of standby memory. Example output from s390-tools lsmem:
> =============================================================================
> 0x0000000000000000-0x000000000fffffff 256 online no 0-127
> 0x0000000010000000-0x000000001fffffff 256 online yes 128-255
> 0x0000000020000000-0x000000003fffffff 512 online no 256-511
> 0x0000000040000000-0x000000007fffffff 1024 offline - 512-1023
>
> Memory device size : 2 MB
> Memory block size : 256 MB
> Total online memory : 1024 MB
> Total offline memory: 1024 MB
>
>
> The guest can dynamically enable part or all of the standby pool
> via the s390-tools chmem, for example:
>
> chmem -e 512M
>
> And can attempt to dynamically disable:
>
> chmem -d 512M
>
> Changes for v7:
> * Added patch to enforce the same memory alignments in s390-virtio.c,
> so that shared code (like sclp) doesn't need to be dual paths.
Ping...
>
> Changes for v6:
> * Fix in sclp.h - DeviceState parent --> SysBusDevice parent
> in struct sclpMemoryHotplugDev.
> * Fix in assign_storage - int this_subregion_size, should
> be uint64_t.
> * Added information on how to test in the cover letter.
>
> Changes for v5:
> * Since ACPI memory hotplug is now in, removed Igor's patches
> from this set.
> * Updated sclp.c to use object_resolve_path() instead of
> object_property_find().
>
> Matthew Rosato (4):
> sclp-s390: Add device to manage s390 memory hotplug
> virtio-ccw: Include standby memory when calculating storage increment
> s390-virtio: Apply same memory boundaries as virtio-ccw
> sclp-s390: Add memory hotplug SCLPs
>
> hw/s390x/s390-virtio-ccw.c | 46 +++++--
> hw/s390x/s390-virtio.c | 15 ++-
> hw/s390x/sclp.c | 289 +++++++++++++++++++++++++++++++++++++++++++-
> include/hw/s390x/sclp.h | 20 +++
> qemu-options.hx | 3 +-
> target-s390x/cpu.h | 18 +++
> target-s390x/kvm.c | 5 +
> 7 files changed, 375 insertions(+), 21 deletions(-)
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v7 0/4] s390: Support for Hotplug of Standby Memory
2014-07-30 18:15 [Qemu-devel] [PATCH v7 0/4] s390: Support for Hotplug of Standby Memory Matthew Rosato
` (4 preceding siblings ...)
2014-08-27 13:22 ` [Qemu-devel] [PATCH v7 0/4] s390: Support for Hotplug of Standby Memory Matthew Rosato
@ 2014-08-28 7:27 ` Christian Borntraeger
5 siblings, 0 replies; 7+ messages in thread
From: Christian Borntraeger @ 2014-08-28 7:27 UTC (permalink / raw)
To: Matthew Rosato, qemu-devel
Cc: agraf, aliguori, imammedo, cornelia.huck, pbonzini, rth
On 30/07/14 20:15, Matthew Rosato wrote:
> This patchset adds support in s390 for a pool of standby memory,
> which can be set online/offline by the guest (ie, via chmem).
> The standby pool of memory is allocated as the difference between
> the initial memory setting and the maxmem setting.
> As part of this work, additional results are provided for the
> Read SCP Information SCLP, and new implentation is added for the
> Read Storage Element Information, Attach Storage Element,
> Assign Storage and Unassign Storage SCLPs, which enables the s390
> guest to manipulate the standby memory pool.
>
> This patchset is based on work originally done by Jeng-Fang (Nick)
> Wang.
Can you respin against latest upstream.
commit d8d95814609e89e5438a3318a647ec322fc4ff16
memory: convert memory_region_destroy to object_unparent
and followon now cause:
CC s390x-softmmu/trace/generated-helpers.o
qemu/hw/s390x/sclp.c: In function ‘unassign_storage’:
qemu/hw/s390x/sclp.c:288:17: error: implicit declaration of function ‘memory_region_destroy’ [-Werror=implicit-function-declaration]
qemu/hw/s390x/sclp.c:288:17: error: nested extern declaration of ‘memory_region_destroy’ [-Werror=nested-externs]
cc1: all warnings being treated as errors
>
> Sample qemu command snippet:
>
> qemu -machine s390-ccw-virtio -m 1024M,maxmem=2048M,slots=32 -enable-kvm
>
> This will allocate 1024M of active memory, and another 1024M
> of standby memory. Example output from s390-tools lsmem:
> =============================================================================
> 0x0000000000000000-0x000000000fffffff 256 online no 0-127
> 0x0000000010000000-0x000000001fffffff 256 online yes 128-255
> 0x0000000020000000-0x000000003fffffff 512 online no 256-511
> 0x0000000040000000-0x000000007fffffff 1024 offline - 512-1023
>
> Memory device size : 2 MB
> Memory block size : 256 MB
> Total online memory : 1024 MB
> Total offline memory: 1024 MB
>
>
> The guest can dynamically enable part or all of the standby pool
> via the s390-tools chmem, for example:
>
> chmem -e 512M
>
> And can attempt to dynamically disable:
>
> chmem -d 512M
>
> Changes for v7:
> * Added patch to enforce the same memory alignments in s390-virtio.c,
> so that shared code (like sclp) doesn't need to be dual paths.
>
> Changes for v6:
> * Fix in sclp.h - DeviceState parent --> SysBusDevice parent
> in struct sclpMemoryHotplugDev.
> * Fix in assign_storage - int this_subregion_size, should
> be uint64_t.
> * Added information on how to test in the cover letter.
>
> Changes for v5:
> * Since ACPI memory hotplug is now in, removed Igor's patches
> from this set.
> * Updated sclp.c to use object_resolve_path() instead of
> object_property_find().
>
> Matthew Rosato (4):
> sclp-s390: Add device to manage s390 memory hotplug
> virtio-ccw: Include standby memory when calculating storage increment
> s390-virtio: Apply same memory boundaries as virtio-ccw
> sclp-s390: Add memory hotplug SCLPs
>
> hw/s390x/s390-virtio-ccw.c | 46 +++++--
> hw/s390x/s390-virtio.c | 15 ++-
> hw/s390x/sclp.c | 289 +++++++++++++++++++++++++++++++++++++++++++-
> include/hw/s390x/sclp.h | 20 +++
> qemu-options.hx | 3 +-
> target-s390x/cpu.h | 18 +++
> target-s390x/kvm.c | 5 +
> 7 files changed, 375 insertions(+), 21 deletions(-)
>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2014-08-28 7:27 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-30 18:15 [Qemu-devel] [PATCH v7 0/4] s390: Support for Hotplug of Standby Memory Matthew Rosato
2014-07-30 18:15 ` [Qemu-devel] [PATCH v7 1/4] sclp-s390: Add device to manage s390 memory hotplug Matthew Rosato
2014-07-30 18:15 ` [Qemu-devel] [PATCH v7 2/4] virtio-ccw: Include standby memory when calculating storage increment Matthew Rosato
2014-07-30 18:15 ` [Qemu-devel] [PATCH v7 3/4] s390-virtio: Apply same memory boundaries as virtio-ccw Matthew Rosato
2014-07-30 18:15 ` [Qemu-devel] [PATCH v7 4/4] sclp-s390: Add memory hotplug SCLPs Matthew Rosato
2014-08-27 13:22 ` [Qemu-devel] [PATCH v7 0/4] s390: Support for Hotplug of Standby Memory Matthew Rosato
2014-08-28 7:27 ` Christian Borntraeger
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.