qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-ppc] [PATCH v2 1/3] pc-dimm: factor out MemoryDevice interface


From: David Hildenbrand
Subject: Re: [Qemu-ppc] [PATCH v2 1/3] pc-dimm: factor out MemoryDevice interface
Date: Fri, 13 Apr 2018 08:36:30 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0

On 13.04.2018 05:25, David Gibson wrote:
> On Thu, Apr 12, 2018 at 04:36:33PM +0200, David Hildenbrand wrote:
>> On the qmp level, we already have the concept of memory devices:
>>     "query-memory-devices"
>> Right now, we only support NVDIMM and PCDIMM.
>>
>> We want to map other devices later into the address space of the guest.
>> Such device could e.g. be virtio devices. These devices will have a
>> guest memory range assigned but won't be exposed via e.g. ACPI. We want
>> to make them look like memory device, but not glued to pc-dimm.
>>
>> Especially, it will not always be possible to have TYPE_PC_DIMM as a parent
>> class (e.g. virtio devices). Let's use an interface instead. As a first
>> part, convert handling of
>> - qmp_pc_dimm_device_list
>> - get_plugged_memory_size
>> to our new model. plug/unplug stuff etc. will follow later.
>>
>> A memory device will have to provide the following functions:
>> - get_addr(): Necessary, as the property "addr" can e.g. not be used for
>>               virtio devices (already defined).
> 
> Is the assumption here that a memory device has a fixed RAM address
> (GPA) from when it is realized?  It seems to me plausible that you
> could have a memory device that has a specific size, but has a BAR of
> some sort that's programmed by the guest as part of the "plug"
> process.

Yes, the assumption is that the
a) address in physical memory
b) region size

Are defined at realize time. Which holds true for DIMM/NVDIMM and will
hold true for the two virtio device types we have in mind
(virtio-mem/virtio-pmem).

Both basically allow to find free address ranges.

> 
>> - get_plugged_size(): The amount this device offers to the guest as of
>>                       now.
>> - get_region_size(): Because this can later on be bigger than the
>>                      plugged size.
>> - fill_device_info(): Fill MemoryDeviceInfo, e.g. for qmp.
>>
>> Signed-off-by: David Hildenbrand <address@hidden>
>> ---
>>  hw/i386/acpi-build.c                         |   3 +-
>>  hw/mem/Makefile.objs                         |   1 +
>>  hw/mem/memory-device.c                       | 119 
>> +++++++++++++++++++++++++++
>>  hw/mem/pc-dimm.c                             | 119 
>> ++++++++++++++-------------
>>  hw/ppc/spapr.c                               |   3 +-
>>  hw/ppc/spapr_hcall.c                         |   1 +
>>  include/hw/mem/memory-device.h               |  44 ++++++++++
>>  include/hw/mem/pc-dimm.h                     |   2 -
>>  numa.c                                       |   3 +-
>>  qmp.c                                        |   4 +-
>>  stubs/Makefile.objs                          |   2 +-
>>  stubs/{qmp_pc_dimm.c => qmp_memory_device.c} |   4 +-
>>  12 files changed, 239 insertions(+), 66 deletions(-)
>>  create mode 100644 hw/mem/memory-device.c
>>  create mode 100644 include/hw/mem/memory-device.h
>>  rename stubs/{qmp_pc_dimm.c => qmp_memory_device.c} (61%)
>>
>> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
>> index 3cf2a1679c..ca3645d57b 100644
>> --- a/hw/i386/acpi-build.c
>> +++ b/hw/i386/acpi-build.c
>> @@ -46,6 +46,7 @@
>>  #include "hw/acpi/vmgenid.h"
>>  #include "sysemu/tpm_backend.h"
>>  #include "hw/timer/mc146818rtc_regs.h"
>> +#include "hw/mem/memory-device.h"
>>  #include "sysemu/numa.h"
>>  
>>  /* Supported chipsets: */
>> @@ -2253,7 +2254,7 @@ build_tpm2(GArray *table_data, BIOSLinker *linker, 
>> GArray *tcpalog)
>>  static void build_srat_hotpluggable_memory(GArray *table_data, uint64_t 
>> base,
>>                                             uint64_t len, int default_node)
>>  {
>> -    MemoryDeviceInfoList *info_list = qmp_pc_dimm_device_list();
>> +    MemoryDeviceInfoList *info_list = qmp_memory_device_list();
>>      MemoryDeviceInfoList *info;
>>      MemoryDeviceInfo *mi;
>>      PCDIMMDeviceInfo *di;
>> diff --git a/hw/mem/Makefile.objs b/hw/mem/Makefile.objs
>> index f12f8b97a2..10be4df2a2 100644
>> --- a/hw/mem/Makefile.objs
>> +++ b/hw/mem/Makefile.objs
>> @@ -1,2 +1,3 @@
>>  common-obj-$(CONFIG_MEM_HOTPLUG) += pc-dimm.o
>> +common-obj-$(CONFIG_MEM_HOTPLUG) += memory-device.o
>>  common-obj-$(CONFIG_NVDIMM) += nvdimm.o
>> diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c
>> new file mode 100644
>> index 0000000000..0e0d6b539a
>> --- /dev/null
>> +++ b/hw/mem/memory-device.c
>> @@ -0,0 +1,119 @@
>> +/*
>> + * Memory Device Interface
>> + *
>> + * Copyright ProfitBricks GmbH 2012
>> + * Copyright (C) 2014 Red Hat Inc
>> + * Copyright (c) 2018 Red Hat Inc
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
>> + * See the COPYING file in the top-level directory.
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "hw/mem/memory-device.h"
>> +#include "hw/qdev.h"
>> +#include "qapi/error.h"
>> +#include "hw/boards.h"
>> +#include "qemu/range.h"
>> +
>> +static gint memory_device_addr_sort(gconstpointer a, gconstpointer b)
>> +{
>> +    MemoryDeviceState *md_a = MEMORY_DEVICE(a);
>> +    MemoryDeviceState *md_b = MEMORY_DEVICE(b);
>> +    MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(a);
> 
> AFAICT from the code below, the two devices don't necessarily have to
> have the same class, so I think you need to get the class pointers for
> each of them separately.  (Or if they do have to be the same by
> design, I think there should at least be an assert).

Haven't considered that, my assumption was that any memory device class
would be sufficient to find/use the pointer (as that layout should not
change). But I might be wrong, so I'll lookup both pointers, thanks!

> 
>> +    const uint64_t addr_a = mdc->get_addr(md_a);
>> +    const uint64_t addr_b = mdc->get_addr(md_b);
>> +
>> +    if (addr_a > addr_b) {
>> +        return 1;
>> +    } else if (addr_a < addr_b) {
>> +        return -1;
>> +    }
>> +    return 0;
>> +}


-- 

Thanks,

David / dhildenb



reply via email to

[Prev in Thread] Current Thread [Next in Thread]