qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] spapr NVDIMM: consider 'nvdimm' machine option
@ 2020-08-25 21:57 Daniel Henrique Barboza
  2020-08-25 21:57 ` [PATCH 1/3] ppc/spapr_nvdimm: use g_autofree in spapr_nvdimm_validate_opts() Daniel Henrique Barboza
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Daniel Henrique Barboza @ 2020-08-25 21:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Daniel Henrique Barboza, qemu-ppc, david

This series aims to solve bug [1].

First patch is a trivial cleanup, feel free to squash into
patch 02. Patch 02 attempts a code simplification to put
all NVDIMM related logic in the same function.

Patch 03 is where the actual fix is implemented. My initial
approach here was to make the handling of '-machine nvdimm' for
pSeries similar to how it is handled elsewhere, but I wasn't
able to accomplish that without either (1) breaking up existing
pseries-5.1 guests that didn't care about this option or (2)
make pseries-5.1 and pseries-5.2+ machines to have different
semantics for it.

I ended up doing what I was sure was sensible: if the user puts
'-machine nvdimm=off', we must comply to that.


[1] https://bugzilla.redhat.com/show_bug.cgi?id=1848887

Daniel Henrique Barboza (3):
  ppc/spapr_nvdimm: use g_autofree in spapr_nvdimm_validate_opts()
  spapr, spapr_nvdimm: fold NVDIMM validation in the same place
  ppc/spapr_nvdimm: do not enable support with 'nvdimm=off'

 hw/ppc/spapr.c                | 18 ++++++------------
 hw/ppc/spapr_nvdimm.c         | 31 +++++++++++++++++++++++++++----
 include/hw/ppc/spapr_nvdimm.h |  4 ++--
 3 files changed, 35 insertions(+), 18 deletions(-)

-- 
2.26.2



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] ppc/spapr_nvdimm: use g_autofree in spapr_nvdimm_validate_opts()
  2020-08-25 21:57 [PATCH 0/3] spapr NVDIMM: consider 'nvdimm' machine option Daniel Henrique Barboza
@ 2020-08-25 21:57 ` Daniel Henrique Barboza
  2020-08-25 21:57 ` [PATCH 2/3] spapr, spapr_nvdimm: fold NVDIMM validation in the same place Daniel Henrique Barboza
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Daniel Henrique Barboza @ 2020-08-25 21:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Daniel Henrique Barboza, qemu-ppc, david

Since we're using the string just once, just use g_autofree and
avoid leaking it without calling g_free().

Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
---
 hw/ppc/spapr_nvdimm.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
index 81410aa63f..9a20a65640 100644
--- a/hw/ppc/spapr_nvdimm.c
+++ b/hw/ppc/spapr_nvdimm.c
@@ -33,7 +33,7 @@
 void spapr_nvdimm_validate_opts(NVDIMMDevice *nvdimm, uint64_t size,
                                 Error **errp)
 {
-    char *uuidstr = NULL;
+    g_autofree char *uuidstr = NULL;
     QemuUUID uuid;
     int ret;
 
@@ -54,7 +54,6 @@ void spapr_nvdimm_validate_opts(NVDIMMDevice *nvdimm, uint64_t size,
                                       &error_abort);
     ret = qemu_uuid_parse(uuidstr, &uuid);
     g_assert(!ret);
-    g_free(uuidstr);
 
     if (qemu_uuid_is_null(&uuid)) {
         error_setg(errp, "NVDIMM device requires the uuid to be set");
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] spapr, spapr_nvdimm: fold NVDIMM validation in the same place
  2020-08-25 21:57 [PATCH 0/3] spapr NVDIMM: consider 'nvdimm' machine option Daniel Henrique Barboza
  2020-08-25 21:57 ` [PATCH 1/3] ppc/spapr_nvdimm: use g_autofree in spapr_nvdimm_validate_opts() Daniel Henrique Barboza
@ 2020-08-25 21:57 ` Daniel Henrique Barboza
  2020-08-25 21:57 ` [PATCH 3/3] ppc/spapr_nvdimm: do not enable support with 'nvdimm=off' Daniel Henrique Barboza
  2020-08-28 13:17 ` [PATCH 0/3] spapr NVDIMM: consider 'nvdimm' machine option David Gibson
  3 siblings, 0 replies; 5+ messages in thread
From: Daniel Henrique Barboza @ 2020-08-25 21:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Daniel Henrique Barboza, qemu-ppc, david

NVDIMM has different contraints and conditions than the regular
DIMM and we'll need to add at least one more.

Instead of relying on 'if (nvdimm)' conditionals in the body of
spapr_memory_pre_plug(), use the existing spapr_nvdimm_validate_opts()
and put all NVDIMM handling code there. Rename it to
spapr_nvdimm_validate() to reflect that the function is now checking
more than the nvdimm device options. This makes spapr_memory_pre_plug()
a bit easier to follow, and we can tune in NVDIMM parameters
and validation in the same place.

Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
---
 hw/ppc/spapr.c                | 18 ++++++------------
 hw/ppc/spapr_nvdimm.c         | 10 ++++++++--
 include/hw/ppc/spapr_nvdimm.h |  4 ++--
 3 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index dd2fa4826b..b0a04443fb 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3520,7 +3520,6 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
 {
     const SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(hotplug_dev);
     SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
-    const MachineClass *mc = MACHINE_CLASS(smc);
     bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
     PCDIMMDevice *dimm = PC_DIMM(dev);
     Error *local_err = NULL;
@@ -3533,27 +3532,22 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
         return;
     }
 
-    if (is_nvdimm && !mc->nvdimm_supported) {
-        error_setg(errp, "NVDIMM hotplug not supported for this machine");
-        return;
-    }
-
     size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
     }
 
-    if (!is_nvdimm && size % SPAPR_MEMORY_BLOCK_SIZE) {
-        error_setg(errp, "Hotplugged memory size must be a multiple of "
-                   "%" PRIu64 " MB", SPAPR_MEMORY_BLOCK_SIZE / MiB);
-        return;
-    } else if (is_nvdimm) {
-        spapr_nvdimm_validate_opts(NVDIMM(dev), size, &local_err);
+    if (is_nvdimm) {
+        spapr_nvdimm_validate(hotplug_dev, NVDIMM(dev), size, &local_err);
         if (local_err) {
             error_propagate(errp, local_err);
             return;
         }
+    } else if (size % SPAPR_MEMORY_BLOCK_SIZE) {
+        error_setg(errp, "Hotplugged memory size must be a multiple of "
+                   "%" PRIu64 " MB", SPAPR_MEMORY_BLOCK_SIZE / MiB);
+        return;
     }
 
     memdev = object_property_get_link(OBJECT(dimm), PC_DIMM_MEMDEV_PROP,
diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
index 9a20a65640..bc2b65420c 100644
--- a/hw/ppc/spapr_nvdimm.c
+++ b/hw/ppc/spapr_nvdimm.c
@@ -30,13 +30,19 @@
 #include "hw/ppc/fdt.h"
 #include "qemu/range.h"
 
-void spapr_nvdimm_validate_opts(NVDIMMDevice *nvdimm, uint64_t size,
-                                Error **errp)
+void spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
+                           uint64_t size, Error **errp)
 {
+    const MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
     g_autofree char *uuidstr = NULL;
     QemuUUID uuid;
     int ret;
 
+    if (!mc->nvdimm_supported) {
+        error_setg(errp, "NVDIMM hotplug not supported for this machine");
+        return;
+    }
+
     if (object_property_get_int(OBJECT(nvdimm), NVDIMM_LABEL_SIZE_PROP,
                                 &error_abort) == 0) {
         error_setg(errp, "PAPR requires NVDIMM devices to have label-size set");
diff --git a/include/hw/ppc/spapr_nvdimm.h b/include/hw/ppc/spapr_nvdimm.h
index b3330cc485..fd1736634c 100644
--- a/include/hw/ppc/spapr_nvdimm.h
+++ b/include/hw/ppc/spapr_nvdimm.h
@@ -29,8 +29,8 @@ int spapr_pmem_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
                            void *fdt, int *fdt_start_offset, Error **errp);
 int spapr_dt_nvdimm(void *fdt, int parent_offset, NVDIMMDevice *nvdimm);
 void spapr_dt_persistent_memory(void *fdt);
-void spapr_nvdimm_validate_opts(NVDIMMDevice *nvdimm, uint64_t size,
-                                Error **errp);
+void 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);
 
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] ppc/spapr_nvdimm: do not enable support with 'nvdimm=off'
  2020-08-25 21:57 [PATCH 0/3] spapr NVDIMM: consider 'nvdimm' machine option Daniel Henrique Barboza
  2020-08-25 21:57 ` [PATCH 1/3] ppc/spapr_nvdimm: use g_autofree in spapr_nvdimm_validate_opts() Daniel Henrique Barboza
  2020-08-25 21:57 ` [PATCH 2/3] spapr, spapr_nvdimm: fold NVDIMM validation in the same place Daniel Henrique Barboza
@ 2020-08-25 21:57 ` Daniel Henrique Barboza
  2020-08-28 13:17 ` [PATCH 0/3] spapr NVDIMM: consider 'nvdimm' machine option David Gibson
  3 siblings, 0 replies; 5+ messages in thread
From: Daniel Henrique Barboza @ 2020-08-25 21:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Daniel Henrique Barboza, qemu-ppc, david

The NVDIMM support for pSeries was introduced in 5.1, but it
didn't contemplate the 'nvdimm' machine option that other
archs uses. For every other arch, if no '-machine nvdimm(=on)'
is present, it is assumed that the NVDIMM support is disabled.
The user must explictly inform that the machine supports
NVDIMM. For pseries-5.1 the 'nvdimm' option is completely
ignored, and support is always assumed to exist. This
leads to situations where the user is able to set 'nvdimm=off'
but the guest boots up with the NVDIMMs anyway.

Fixing this now, after 5.1 launch, can put the overall NVDIMM
support for pseries in a strange place regarding this 'nvdimm'
machine option. If we force everything to be like other archs,
existing pseries-5.1 guests that didn't use 'nvdimm' to use NVDIMM
devices will break. If we attempt to make the newer pseries
machines (5.2+) behave like everyone else, but keep pseries-5.1
untouched, we'll have consistency problems on machine upgrade
(5.1 will have different default values for NVDIMM support than
5.2).

The common ground here is, if the user sets 'nvdimm=off', we
must comply regardless of being 5.1 or 5.2+. This patch
changes spapr_nvdimm_validate() to verify if the user set
NVDIMM support off in the machine options and, in that
case, error out if we have a NVDIMM device. The default
value for 5.2+ pseries machines will still be 'nvdimm=on'
when there is no 'nvdimm' option declared, just like it is today
with pseries-5.1. In the end we'll have different default
semantics from everyone else in the absence of the 'nvdimm'
machine option, but this boat has sailed.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1848887
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
---
 hw/ppc/spapr_nvdimm.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
index bc2b65420c..95cbc30528 100644
--- a/hw/ppc/spapr_nvdimm.c
+++ b/hw/ppc/spapr_nvdimm.c
@@ -27,13 +27,17 @@
 #include "hw/ppc/spapr_nvdimm.h"
 #include "hw/mem/nvdimm.h"
 #include "qemu/nvdimm-utils.h"
+#include "qemu/option.h"
 #include "hw/ppc/fdt.h"
 #include "qemu/range.h"
+#include "sysemu/sysemu.h"
 
 void spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
                            uint64_t size, Error **errp)
 {
     const MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
+    const MachineState *ms = MACHINE(hotplug_dev);
+    const char *nvdimm_opt = qemu_opt_get(qemu_get_machine_opts(), "nvdimm");
     g_autofree char *uuidstr = NULL;
     QemuUUID uuid;
     int ret;
@@ -43,6 +47,20 @@ void spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
         return;
     }
 
+    /*
+     * NVDIMM support went live in 5.1 without considering that, in
+     * other archs, the user needs to enable NVDIMM support with the
+     * 'nvdimm' machine option and the default behavior is NVDIMM
+     * support disabled. It is too late to roll back to the standard
+     * behavior without breaking 5.1 guests. What we can do is to
+     * ensure that, if the user sets nvdimm=off, we error out
+     * regardless of being 5.1 or newer.
+     */
+    if (!ms->nvdimms_state->is_enabled && nvdimm_opt) {
+        error_setg(errp, "nvdimm device found but 'nvdimm=off' was set");
+        return;
+    }
+
     if (object_property_get_int(OBJECT(nvdimm), NVDIMM_LABEL_SIZE_PROP,
                                 &error_abort) == 0) {
         error_setg(errp, "PAPR requires NVDIMM devices to have label-size set");
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/3] spapr NVDIMM: consider 'nvdimm' machine option
  2020-08-25 21:57 [PATCH 0/3] spapr NVDIMM: consider 'nvdimm' machine option Daniel Henrique Barboza
                   ` (2 preceding siblings ...)
  2020-08-25 21:57 ` [PATCH 3/3] ppc/spapr_nvdimm: do not enable support with 'nvdimm=off' Daniel Henrique Barboza
@ 2020-08-28 13:17 ` David Gibson
  3 siblings, 0 replies; 5+ messages in thread
From: David Gibson @ 2020-08-28 13:17 UTC (permalink / raw)
  To: Daniel Henrique Barboza; +Cc: qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1595 bytes --]

On Tue, Aug 25, 2020 at 06:57:46PM -0300, Daniel Henrique Barboza wrote:
> This series aims to solve bug [1].
> 
> First patch is a trivial cleanup, feel free to squash into
> patch 02. Patch 02 attempts a code simplification to put
> all NVDIMM related logic in the same function.
> 
> Patch 03 is where the actual fix is implemented. My initial
> approach here was to make the handling of '-machine nvdimm' for
> pSeries similar to how it is handled elsewhere, but I wasn't
> able to accomplish that without either (1) breaking up existing
> pseries-5.1 guests that didn't care about this option or (2)
> make pseries-5.1 and pseries-5.2+ machines to have different
> semantics for it.
> 
> I ended up doing what I was sure was sensible: if the user puts
> '-machine nvdimm=off', we must comply to that.

Applied to ppc-for-5.2, thanks.

> 
> 
> [1] https://bugzilla.redhat.com/show_bug.cgi?id=1848887
> 
> Daniel Henrique Barboza (3):
>   ppc/spapr_nvdimm: use g_autofree in spapr_nvdimm_validate_opts()
>   spapr, spapr_nvdimm: fold NVDIMM validation in the same place
>   ppc/spapr_nvdimm: do not enable support with 'nvdimm=off'
> 
>  hw/ppc/spapr.c                | 18 ++++++------------
>  hw/ppc/spapr_nvdimm.c         | 31 +++++++++++++++++++++++++++----
>  include/hw/ppc/spapr_nvdimm.h |  4 ++--
>  3 files changed, 35 insertions(+), 18 deletions(-)
> 

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-08-28 13:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-25 21:57 [PATCH 0/3] spapr NVDIMM: consider 'nvdimm' machine option Daniel Henrique Barboza
2020-08-25 21:57 ` [PATCH 1/3] ppc/spapr_nvdimm: use g_autofree in spapr_nvdimm_validate_opts() Daniel Henrique Barboza
2020-08-25 21:57 ` [PATCH 2/3] spapr, spapr_nvdimm: fold NVDIMM validation in the same place Daniel Henrique Barboza
2020-08-25 21:57 ` [PATCH 3/3] ppc/spapr_nvdimm: do not enable support with 'nvdimm=off' Daniel Henrique Barboza
2020-08-28 13:17 ` [PATCH 0/3] spapr NVDIMM: consider 'nvdimm' machine option David Gibson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).