From ce316b5118c732c5fef23d7763b8c01054bfcdfa Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Mon, 12 Oct 2020 12:15:21 +0200 Subject: spapr: Move spapr_create_nvdimm_dr_connectors() to core machine code The spapr_create_nvdimm_dr_connectors() function doesn't need to access any internal details of the sPAPR NVDIMM implementation. Also, pretty much like for the LMBs, only spapr_machine_init() is responsible for the creation of DR connectors for NVDIMMs. Make this clear by making this function static in hw/ppc/spapr.c. Signed-off-by: Greg Kurz Message-Id: <160249772183.757627.7396780936543977766.stgit@bahia.lan> Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- include/hw/ppc/spapr_nvdimm.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/hw/ppc/spapr_nvdimm.h b/include/hw/ppc/spapr_nvdimm.h index b834d82f55..490b19a009 100644 --- a/include/hw/ppc/spapr_nvdimm.h +++ b/include/hw/ppc/spapr_nvdimm.h @@ -31,6 +31,5 @@ void spapr_dt_persistent_memory(SpaprMachineState *spapr, void *fdt); bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm, uint64_t size, Error **errp); void spapr_add_nvdimm(DeviceState *dev, uint64_t slot, Error **errp); -void spapr_create_nvdimm_dr_connectors(SpaprMachineState *spapr); #endif -- cgit v1.2.3-55-g7522 From 84fd54961933a324e99bb52d0cc1de0ac9b7780e Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Mon, 19 Oct 2020 10:48:04 +0200 Subject: pc-dimm: Drop @errp argument of pc_dimm_plug() pc_dimm_plug() doesn't use it. It only aborts on error. Drop @errp and adapt the callers accordingly. [dwg: Removed unused label to fix compile] Signed-off-by: Greg Kurz Message-Id: <160309728447.2739814.12831204841251148202.stgit@bahia.lan> Reviewed-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Igor Mammedov Signed-off-by: David Gibson --- hw/arm/virt.c | 9 +-------- hw/i386/pc.c | 8 +------- hw/mem/pc-dimm.c | 2 +- hw/ppc/spapr.c | 6 +----- include/hw/mem/pc-dimm.h | 2 +- 5 files changed, 5 insertions(+), 22 deletions(-) (limited to 'include') diff --git a/hw/arm/virt.c b/hw/arm/virt.c index e465a988d6..27dbeb549e 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -2261,12 +2261,8 @@ static void virt_memory_plug(HotplugHandler *hotplug_dev, VirtMachineState *vms = VIRT_MACHINE(hotplug_dev); MachineState *ms = MACHINE(hotplug_dev); bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM); - Error *local_err = NULL; - pc_dimm_plug(PC_DIMM(dev), MACHINE(vms), &local_err); - if (local_err) { - goto out; - } + pc_dimm_plug(PC_DIMM(dev), MACHINE(vms)); if (is_nvdimm) { nvdimm_plug(ms->nvdimms_state); @@ -2274,9 +2270,6 @@ static void virt_memory_plug(HotplugHandler *hotplug_dev, hotplug_handler_plug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &error_abort); - -out: - error_propagate(errp, local_err); } static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev, diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 4e323755d0..0d9bd7d635 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1265,24 +1265,18 @@ static void pc_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, static void pc_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - Error *local_err = NULL; PCMachineState *pcms = PC_MACHINE(hotplug_dev); X86MachineState *x86ms = X86_MACHINE(hotplug_dev); MachineState *ms = MACHINE(hotplug_dev); bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM); - pc_dimm_plug(PC_DIMM(dev), MACHINE(pcms), &local_err); - if (local_err) { - goto out; - } + pc_dimm_plug(PC_DIMM(dev), MACHINE(pcms)); if (is_nvdimm) { nvdimm_plug(ms->nvdimms_state); } hotplug_handler_plug(x86ms->acpi_dev, dev, &error_abort); -out: - error_propagate(errp, local_err); } static void pc_memory_unplug_request(HotplugHandler *hotplug_dev, diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index c30351070b..2ffc986734 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -64,7 +64,7 @@ void pc_dimm_pre_plug(PCDIMMDevice *dimm, MachineState *machine, errp); } -void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine, Error **errp) +void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine) { PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); MemoryRegion *vmstate_mr = ddc->get_vmstate_memory_region(dimm, diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index ee716a12af..05abf6cc57 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3438,10 +3438,7 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev, size = memory_device_get_region_size(MEMORY_DEVICE(dev), &error_abort); - pc_dimm_plug(dimm, MACHINE(ms), &local_err); - if (local_err) { - goto out; - } + pc_dimm_plug(dimm, MACHINE(ms)); if (!is_nvdimm) { addr = object_property_get_uint(OBJECT(dimm), @@ -3469,7 +3466,6 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev, out_unplug: pc_dimm_unplug(dimm, MACHINE(ms)); -out: error_propagate(errp, local_err); } diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h index aec9527fdd..3d3db82641 100644 --- a/include/hw/mem/pc-dimm.h +++ b/include/hw/mem/pc-dimm.h @@ -72,6 +72,6 @@ struct PCDIMMDeviceClass { void pc_dimm_pre_plug(PCDIMMDevice *dimm, MachineState *machine, const uint64_t *legacy_align, Error **errp); -void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine, Error **errp); +void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine); void pc_dimm_unplug(PCDIMMDevice *dimm, MachineState *machine); #endif -- cgit v1.2.3-55-g7522 From 6e837f98ba03bab8008b7c1a6c125298ce41de7a Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Mon, 19 Oct 2020 10:49:01 +0200 Subject: spapr: Simplify error handling in spapr_memory_plug() As recommended in "qapi/error.h", add a bool return value to spapr_add_lmbs() and spapr_add_nvdimm(), and use them instead of local_err in spapr_memory_plug(). This allows to get rid of the error propagation overhead. Signed-off-by: Greg Kurz Message-Id: <160309734178.2739814.3488437759887793902.stgit@bahia.lan> Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/ppc/spapr.c | 22 ++++++++++------------ hw/ppc/spapr_nvdimm.c | 5 +++-- include/hw/ppc/spapr_nvdimm.h | 2 +- 3 files changed, 14 insertions(+), 15 deletions(-) (limited to 'include') diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index a5aef7a6ff..0cc19b5863 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3382,7 +3382,7 @@ int spapr_lmb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr, return 0; } -static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size, +static bool spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size, bool dedicated_hp_event_source, Error **errp) { SpaprDrc *drc; @@ -3403,7 +3403,7 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size, addr / SPAPR_MEMORY_BLOCK_SIZE); spapr_drc_detach(drc); } - return; + return false; } if (!hotplugged) { spapr_drc_reset(drc); @@ -3425,12 +3425,12 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size, nr_lmbs); } } + return true; } static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - Error *local_err = NULL; SpaprMachineState *ms = SPAPR_MACHINE(hotplug_dev); PCDIMMDevice *dimm = PC_DIMM(dev); uint64_t size, addr; @@ -3444,26 +3444,24 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev, if (!is_nvdimm) { addr = object_property_get_uint(OBJECT(dimm), PC_DIMM_ADDR_PROP, &error_abort); - spapr_add_lmbs(dev, addr, size, - spapr_ovec_test(ms->ov5_cas, OV5_HP_EVT), - &local_err); + if (!spapr_add_lmbs(dev, addr, size, + spapr_ovec_test(ms->ov5_cas, OV5_HP_EVT), errp)) { + goto out_unplug; + } } else { slot = object_property_get_int(OBJECT(dimm), PC_DIMM_SLOT_PROP, &error_abort); /* We should have valid slot number at this point */ g_assert(slot >= 0); - spapr_add_nvdimm(dev, slot, &local_err); - } - - if (local_err) { - goto out_unplug; + if (!spapr_add_nvdimm(dev, slot, errp)) { + goto out_unplug; + } } return; out_unplug: pc_dimm_unplug(dimm, MACHINE(ms)); - error_propagate(errp, local_err); } static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c index 9e3d94071f..a833a63b5e 100644 --- a/hw/ppc/spapr_nvdimm.c +++ b/hw/ppc/spapr_nvdimm.c @@ -89,7 +89,7 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm, } -void spapr_add_nvdimm(DeviceState *dev, uint64_t slot, Error **errp) +bool spapr_add_nvdimm(DeviceState *dev, uint64_t slot, Error **errp) { SpaprDrc *drc; bool hotplugged = spapr_drc_hotplugged(dev); @@ -98,12 +98,13 @@ void spapr_add_nvdimm(DeviceState *dev, uint64_t slot, Error **errp) g_assert(drc); if (!spapr_drc_attach(drc, dev, errp)) { - return; + return false; } if (hotplugged) { spapr_hotplug_req_add_by_index(drc); } + return true; } static int spapr_dt_nvdimm(SpaprMachineState *spapr, void *fdt, diff --git a/include/hw/ppc/spapr_nvdimm.h b/include/hw/ppc/spapr_nvdimm.h index 490b19a009..344582d2f5 100644 --- a/include/hw/ppc/spapr_nvdimm.h +++ b/include/hw/ppc/spapr_nvdimm.h @@ -30,6 +30,6 @@ int spapr_pmem_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr, void spapr_dt_persistent_memory(SpaprMachineState *spapr, void *fdt); bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm, uint64_t size, Error **errp); -void spapr_add_nvdimm(DeviceState *dev, uint64_t slot, Error **errp); +bool spapr_add_nvdimm(DeviceState *dev, uint64_t slot, Error **errp); #endif -- cgit v1.2.3-55-g7522 From a4e3a7c02bec45b1054c5e4fe3234519498fb55a Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Mon, 26 Oct 2020 13:40:54 +0100 Subject: spapr: Improve spapr_reallocate_hpt() error reporting spapr_reallocate_hpt() has three users, two of which pass &error_fatal and the third one, htab_load(), passes &local_err, uses it to detect failures and simply propagates -EINVAL up to vmstate_load(), which will cause QEMU to exit. It is thus confusing that spapr_reallocate_hpt() doesn't return right away when an error is detected in some cases. Also, the comment suggesting that the caller is welcome to try to carry on seems like a remnant in this respect. This can be improved: - change spapr_reallocate_hpt() to always report a negative errno on failure, either as reported by KVM or -ENOSPC if the HPT is smaller than what was asked, - use that to detect failures in htab_load() which is preferred over checking &local_err, - propagate this negative errno to vmstate_load() because it is more accurate than propagating -EINVAL for all possible errors. [dwg: Fix compile error due to omitted prelim patch] Signed-off-by: Greg Kurz Message-Id: <160371605460.305923.5890143959901241157.stgit@bahia.lan> Signed-off-by: David Gibson --- hw/ppc/spapr.c | 20 +++++++++++--------- include/hw/ppc/spapr.h | 3 +-- 2 files changed, 12 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index ec2536dba1..227075103e 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1483,8 +1483,7 @@ void spapr_free_hpt(SpaprMachineState *spapr) close_htab_fd(spapr); } -void spapr_reallocate_hpt(SpaprMachineState *spapr, int shift, - Error **errp) +int spapr_reallocate_hpt(SpaprMachineState *spapr, int shift, Error **errp) { ERRP_GUARD(); long rc; @@ -1496,7 +1495,7 @@ void spapr_reallocate_hpt(SpaprMachineState *spapr, int shift, if (rc == -EOPNOTSUPP) { error_setg(errp, "HPT not supported in nested guests"); - return; + return -EOPNOTSUPP; } if (rc < 0) { @@ -1504,8 +1503,7 @@ void spapr_reallocate_hpt(SpaprMachineState *spapr, int shift, error_setg_errno(errp, errno, "Failed to allocate KVM HPT of order %d", shift); error_append_hint(errp, "Try smaller maxmem?\n"); - /* This is almost certainly fatal, but if the caller really - * wants to carry on with shift == 0, it's welcome to try */ + return -errno; } else if (rc > 0) { /* kernel-side HPT allocated */ if (rc != shift) { @@ -1513,6 +1511,7 @@ void spapr_reallocate_hpt(SpaprMachineState *spapr, int shift, "Requested order %d HPT, but kernel allocated order %ld", shift, rc); error_append_hint(errp, "Try smaller maxmem?\n"); + return -ENOSPC; } spapr->htab_shift = shift; @@ -1526,7 +1525,7 @@ void spapr_reallocate_hpt(SpaprMachineState *spapr, int shift, if (!spapr->htab) { error_setg_errno(errp, errno, "Could not allocate HPT of order %d", shift); - return; + return -ENOMEM; } memset(spapr->htab, 0, size); @@ -1539,6 +1538,7 @@ void spapr_reallocate_hpt(SpaprMachineState *spapr, int shift, /* We're setting up a hash table, so that means we're not radix */ spapr->patb_entry = 0; spapr_set_all_lpcrs(0, LPCR_HR | LPCR_UPRT); + return 0; } void spapr_setup_hpt(SpaprMachineState *spapr) @@ -2292,11 +2292,13 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id) } if (section_hdr) { + int ret; + /* First section gives the htab size */ - spapr_reallocate_hpt(spapr, section_hdr, &local_err); - if (local_err) { + ret = spapr_reallocate_hpt(spapr, section_hdr, &local_err); + if (ret < 0) { error_report_err(local_err); - return -EINVAL; + return ret; } return 0; } diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index bb47896f17..2e89e36cfb 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -846,8 +846,7 @@ void spapr_hotplug_req_add_by_count_indexed(SpaprDrcType drc_type, void spapr_hotplug_req_remove_by_count_indexed(SpaprDrcType drc_type, uint32_t count, uint32_t index); int spapr_hpt_shift_for_ramsize(uint64_t ramsize); -void spapr_reallocate_hpt(SpaprMachineState *spapr, int shift, - Error **errp); +int spapr_reallocate_hpt(SpaprMachineState *spapr, int shift, Error **errp); void spapr_clear_pending_events(SpaprMachineState *spapr); void spapr_clear_pending_hotplug_events(SpaprMachineState *spapr); int spapr_max_server_number(SpaprMachineState *spapr); -- cgit v1.2.3-55-g7522