[Qemu-devel] [PATCH v4 11/12] nvdimm: make get_memory_region() perform checks and initialization

David Hildenbrand posted 12 patches 7 years, 7 months ago
There is a newer version of this series
[Qemu-devel] [PATCH v4 11/12] nvdimm: make get_memory_region() perform checks and initialization
Posted by David Hildenbrand 7 years, 7 months ago
We might get a call to get_memory_region() before the device has been
realized. We should return a consistent value, as the return value
will e.g. later on be used in the pre_plug handler.

To avoid duplicating too much code, factor the initialization and checks
out into a helper function.

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
 hw/mem/nvdimm.c | 46 +++++++++++++++++++++++++++++++++++++---------
 1 file changed, 37 insertions(+), 9 deletions(-)

diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c
index db7d8c3050..bba98e57e1 100644
--- a/hw/mem/nvdimm.c
+++ b/hw/mem/nvdimm.c
@@ -71,20 +71,24 @@ static void nvdimm_init(Object *obj)
                         NULL, NULL);
 }
 
-static MemoryRegion *nvdimm_get_memory_region(PCDIMMDevice *dimm, Error **errp)
+static void nvdimm_prepare_memory_region(NVDIMMDevice *nvdimm, Error **errp)
 {
-    NVDIMMDevice *nvdimm = NVDIMM(dimm);
+    PCDIMMDevice *dimm = PC_DIMM(nvdimm);
+    uint64_t align, pmem_size, size;
+    MemoryRegion *mr;
 
-    return nvdimm->nvdimm_mr;
-}
+    if (nvdimm->nvdimm_mr) {
+        return;
+    }
 
-static void nvdimm_realize(PCDIMMDevice *dimm, Error **errp)
-{
-    MemoryRegion *mr = host_memory_backend_get_memory(dimm->hostmem);
-    NVDIMMDevice *nvdimm = NVDIMM(dimm);
-    uint64_t align, pmem_size, size = memory_region_size(mr);
+    if (!dimm->hostmem) {
+        error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property must be set");
+        return;
+    }
 
+    mr = host_memory_backend_get_memory(dimm->hostmem);
     align = memory_region_get_alignment(mr);
+    size = memory_region_size(mr);
 
     pmem_size = size - nvdimm->label_size;
     nvdimm->label_data = memory_region_get_ram_ptr(mr) + pmem_size;
@@ -108,6 +112,30 @@ static void nvdimm_realize(PCDIMMDevice *dimm, Error **errp)
     nvdimm->nvdimm_mr->align = align;
 }
 
+static MemoryRegion *nvdimm_get_memory_region(PCDIMMDevice *dimm, Error **errp)
+{
+    NVDIMMDevice *nvdimm = NVDIMM(dimm);
+    Error *local_err = NULL;
+
+    if (!nvdimm->nvdimm_mr) {
+        nvdimm_prepare_memory_region(nvdimm, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return NULL;
+        }
+    }
+    return nvdimm->nvdimm_mr;
+}
+
+static void nvdimm_realize(PCDIMMDevice *dimm, Error **errp)
+{
+    NVDIMMDevice *nvdimm = NVDIMM(dimm);
+
+    if (!nvdimm->nvdimm_mr) {
+        nvdimm_prepare_memory_region(nvdimm, errp);
+    }
+}
+
 /*
  * the caller should check the input parameters before calling
  * label read/write functions.
-- 
2.17.1


Re: [Qemu-devel] [PATCH v4 11/12] nvdimm: make get_memory_region() perform checks and initialization
Posted by David Gibson 7 years, 7 months ago
On Mon, Jun 18, 2018 at 04:25:35PM +0200, David Hildenbrand wrote:
> We might get a call to get_memory_region() before the device has been
> realized. We should return a consistent value, as the return value
> will e.g. later on be used in the pre_plug handler.
> 
> To avoid duplicating too much code, factor the initialization and checks
> out into a helper function.
> 
> Reviewed-by: Igor Mammedov <imammedo@redhat.com>
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  hw/mem/nvdimm.c | 46 +++++++++++++++++++++++++++++++++++++---------
>  1 file changed, 37 insertions(+), 9 deletions(-)
> 
> diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c
> index db7d8c3050..bba98e57e1 100644
> --- a/hw/mem/nvdimm.c
> +++ b/hw/mem/nvdimm.c
> @@ -71,20 +71,24 @@ static void nvdimm_init(Object *obj)
>                          NULL, NULL);
>  }
>  
> -static MemoryRegion *nvdimm_get_memory_region(PCDIMMDevice *dimm, Error **errp)
> +static void nvdimm_prepare_memory_region(NVDIMMDevice *nvdimm, Error **errp)
>  {
> -    NVDIMMDevice *nvdimm = NVDIMM(dimm);
> +    PCDIMMDevice *dimm = PC_DIMM(nvdimm);
> +    uint64_t align, pmem_size, size;
> +    MemoryRegion *mr;
>  
> -    return nvdimm->nvdimm_mr;
> -}
> +    if (nvdimm->nvdimm_mr) {
> +        return;
> +    }
>  
> -static void nvdimm_realize(PCDIMMDevice *dimm, Error **errp)
> -{
> -    MemoryRegion *mr = host_memory_backend_get_memory(dimm->hostmem);
> -    NVDIMMDevice *nvdimm = NVDIMM(dimm);
> -    uint64_t align, pmem_size, size = memory_region_size(mr);
> +    if (!dimm->hostmem) {
> +        error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property must be set");
> +        return;
> +    }
>  
> +    mr = host_memory_backend_get_memory(dimm->hostmem);
>      align = memory_region_get_alignment(mr);
> +    size = memory_region_size(mr);
>  
>      pmem_size = size - nvdimm->label_size;
>      nvdimm->label_data = memory_region_get_ram_ptr(mr) + pmem_size;
> @@ -108,6 +112,30 @@ static void nvdimm_realize(PCDIMMDevice *dimm, Error **errp)
>      nvdimm->nvdimm_mr->align = align;
>  }
>  
> +static MemoryRegion *nvdimm_get_memory_region(PCDIMMDevice *dimm, Error **errp)
> +{
> +    NVDIMMDevice *nvdimm = NVDIMM(dimm);
> +    Error *local_err = NULL;
> +
> +    if (!nvdimm->nvdimm_mr) {

nvdimm_prepare..() already checks this internally, so you could just
call it internally.  Nonetheless

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> +        nvdimm_prepare_memory_region(nvdimm, &local_err);
> +        if (local_err) {
> +            error_propagate(errp, local_err);
> +            return NULL;
> +        }
> +    }
> +    return nvdimm->nvdimm_mr;
> +}
> +
> +static void nvdimm_realize(PCDIMMDevice *dimm, Error **errp)
> +{
> +    NVDIMMDevice *nvdimm = NVDIMM(dimm);
> +
> +    if (!nvdimm->nvdimm_mr) {
> +        nvdimm_prepare_memory_region(nvdimm, errp);
> +    }
> +}
> +
>  /*
>   * the caller should check the input parameters before calling
>   * label read/write functions.

-- 
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
Re: [Qemu-devel] [PATCH v4 11/12] nvdimm: make get_memory_region() perform checks and initialization
Posted by David Hildenbrand 7 years, 7 months ago
On 19.06.2018 02:12, David Gibson wrote:
> On Mon, Jun 18, 2018 at 04:25:35PM +0200, David Hildenbrand wrote:
>> We might get a call to get_memory_region() before the device has been
>> realized. We should return a consistent value, as the return value
>> will e.g. later on be used in the pre_plug handler.
>>
>> To avoid duplicating too much code, factor the initialization and checks
>> out into a helper function.
>>
>> Reviewed-by: Igor Mammedov <imammedo@redhat.com>
>> Signed-off-by: David Hildenbrand <david@redhat.com>
>> ---
>>  hw/mem/nvdimm.c | 46 +++++++++++++++++++++++++++++++++++++---------
>>  1 file changed, 37 insertions(+), 9 deletions(-)
>>
>> diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c
>> index db7d8c3050..bba98e57e1 100644
>> --- a/hw/mem/nvdimm.c
>> +++ b/hw/mem/nvdimm.c
>> @@ -71,20 +71,24 @@ static void nvdimm_init(Object *obj)
>>                          NULL, NULL);
>>  }
>>  
>> -static MemoryRegion *nvdimm_get_memory_region(PCDIMMDevice *dimm, Error **errp)
>> +static void nvdimm_prepare_memory_region(NVDIMMDevice *nvdimm, Error **errp)
>>  {
>> -    NVDIMMDevice *nvdimm = NVDIMM(dimm);
>> +    PCDIMMDevice *dimm = PC_DIMM(nvdimm);
>> +    uint64_t align, pmem_size, size;
>> +    MemoryRegion *mr;
>>  
>> -    return nvdimm->nvdimm_mr;
>> -}
>> +    if (nvdimm->nvdimm_mr) {
>> +        return;
>> +    }
>>  
>> -static void nvdimm_realize(PCDIMMDevice *dimm, Error **errp)
>> -{
>> -    MemoryRegion *mr = host_memory_backend_get_memory(dimm->hostmem);
>> -    NVDIMMDevice *nvdimm = NVDIMM(dimm);
>> -    uint64_t align, pmem_size, size = memory_region_size(mr);
>> +    if (!dimm->hostmem) {
>> +        error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property must be set");
>> +        return;
>> +    }
>>  
>> +    mr = host_memory_backend_get_memory(dimm->hostmem);
>>      align = memory_region_get_alignment(mr);
>> +    size = memory_region_size(mr);
>>  
>>      pmem_size = size - nvdimm->label_size;
>>      nvdimm->label_data = memory_region_get_ram_ptr(mr) + pmem_size;
>> @@ -108,6 +112,30 @@ static void nvdimm_realize(PCDIMMDevice *dimm, Error **errp)
>>      nvdimm->nvdimm_mr->align = align;
>>  }
>>  
>> +static MemoryRegion *nvdimm_get_memory_region(PCDIMMDevice *dimm, Error **errp)
>> +{
>> +    NVDIMMDevice *nvdimm = NVDIMM(dimm);
>> +    Error *local_err = NULL;
>> +
>> +    if (!nvdimm->nvdimm_mr) {
> 
> nvdimm_prepare..() already checks this internally, so you could just
> call it internally.  Nonetheless
> 

I'll just turn this into an assert as I'll resend. Thanks!

-- 

Thanks,

David / dhildenb