qemu-arm
[Top][All Lists]
Advanced

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

Re: [Qemu-arm] [Qemu-devel] [RFC PATCH 3/4] hw/arm/virt: Enable pc-dimm


From: Auger Eric
Subject: Re: [Qemu-arm] [Qemu-devel] [RFC PATCH 3/4] hw/arm/virt: Enable pc-dimm hotplug support
Date: Thu, 28 Feb 2019 10:57:41 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.4.0

Hi Igor,

On 2/27/19 6:14 PM, Igor Mammedov wrote:
> On Mon, 28 Jan 2019 11:05:45 +0000
> Shameer Kolothum <address@hidden> wrote:
> 
>> pc-dimm memory hotplug is enabled using GPIO(Pin 2) based ACPI
>> event. Hot removal functionality is not yet supported.
>>
>> Signed-off-by: Shameer Kolothum <address@hidden>
>> ---
>>  hw/arm/virt.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>>  1 file changed, 55 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
>> index 884960d..cf64554 100644
>> --- a/hw/arm/virt.c
>> +++ b/hw/arm/virt.c
>> @@ -62,6 +62,7 @@
>>  #include "hw/mem/pc-dimm.h"
>>  #include "hw/mem/nvdimm.h"
>>  #include "hw/acpi/acpi.h"
>> +#include "hw/acpi/pc-hotplug.h"
>>  
>>  #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
>>      static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
>> @@ -1651,7 +1652,14 @@ static void machvirt_init(MachineState *machine)
>>          nvdimm_init_acpi_state(acpi_nvdimm_state, sysmem,
>>                                 vms->fw_cfg, OBJECT(vms));
>>      }
>> +    if (vms->acpi_memhp_state.is_enabled) {
>> +        MemHotplugState *state =  &vms->acpi_memhp_state;
>> +        hwaddr base;
>>  
>> +        state->hw_reduced_acpi = true;
>> +        base = vms->memmap[VIRT_ACPI_IO].base + ACPI_MEMORY_HOTPLUG_BASE;
>> +        acpi_memory_hotplug_init(sysmem, OBJECT(vms), state, base);
>> +    }
> this hunk should be a part of 'acpi' device that owns respective interrupts 
> and mmio regions.
> (something like we do in x86)
> In this case I'd suggest to make 'base' its property and the board will set 
> it during
> device creation.
> 
>>      vms->bootinfo.ram_size = machine->ram_size;
>>      vms->bootinfo.kernel_filename = machine->kernel_filename;
>>      vms->bootinfo.kernel_cmdline = machine->kernel_cmdline;
>> @@ -1819,6 +1827,20 @@ static void virt_set_nvdimm_persistence(Object *obj, 
>> const char *value,
>>      nvdimm_state->persistence_string = g_strdup(value);
>>  }
>>  
>> +static bool virt_get_memhp_support(Object *obj, Error **errp)
>> +{
>> +    VirtMachineState *vms = VIRT_MACHINE(obj);
>> +
>> +    return vms->acpi_memhp_state.is_enabled;
>> +}
>> +
>> +static void virt_set_memhp_support(Object *obj, bool value, Error **errp)
>> +{
>> +    VirtMachineState *vms = VIRT_MACHINE(obj);
>> +
>> +    vms->acpi_memhp_state.is_enabled = value;
>> +}
>> +
>>  static CpuInstanceProperties
>>  virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
>>  {
>> @@ -1863,8 +1885,8 @@ static void virt_memory_pre_plug(HotplugHandler 
>> *hotplug_dev, DeviceState *dev,
>>      const bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
>>      VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
>>  
>> -    if (dev->hotplugged) {
>> -        error_setg(errp, "memory hotplug is not supported");
>> +    if (dev->hotplugged && is_nvdimm) {
>> +        error_setg(errp, "nvdimm hotplug is not supported");
>>      }
>>  
>>      if (is_nvdimm && !vms->acpi_nvdimm_state.is_enabled) {
>> @@ -1875,6 +1897,22 @@ static void virt_memory_pre_plug(HotplugHandler 
>> *hotplug_dev, DeviceState *dev,
>>      pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev), NULL, errp);
>>  }
>>  
>> +static void virt_memhp_send_event(HotplugHandler *hotplug_dev, DeviceState 
>> *dev,
>> +                                  Error **errp)
>> +{
>> +    DeviceState *gpio_dev;
>> +    VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
>> +
>> +    gpio_dev = virt_get_gpio_dev(GPIO_PCDIMM);
>> +    if (!gpio_dev) {
>> +        error_setg(errp, "No dev interface to send hotplug event");
>                              ^^^^^^ confusing
>> +        return;
>> +    }
>> +    acpi_memory_plug_cb(hotplug_dev, &vms->acpi_memhp_state,
>> +                        dev, errp);
>> +    qemu_set_irq(qdev_get_gpio_in(gpio_dev, 0), 1);
>> +}
>> +
>>  static void virt_memory_plug(HotplugHandler *hotplug_dev,
>>                               DeviceState *dev, Error **errp)
>>  {
>> @@ -1891,6 +1929,10 @@ static void virt_memory_plug(HotplugHandler 
>> *hotplug_dev,
>>          nvdimm_plug(&vms->acpi_nvdimm_state);
>>      }
>>  
>> +    if (dev->hotplugged && !is_nvdimm) {
>> +        virt_memhp_send_event(hotplug_dev, dev, errp);
> ...
>   acpi_memory_plug_cb();
>   hotplug_handler_plug(HOTPLUG_HANDLER(pcms->gpio_dev), dev, &error_abort);
>   ^^^^ forward snd process hotplug notification event in gpio_dev,
>        machine should not care about which and how to deal with random IRQs
> 
>> +    }
>> +
>>  out:
>>      error_propagate(errp, local_err);
>>  }
>> @@ -1898,6 +1940,11 @@ out:
>>  static void virt_memory_unplug(HotplugHandler *hotplug_dev,
>>                                 DeviceState *dev, Error **errp)
>>  {
>> +    if (dev->hotplugged) {
>> +        error_setg(errp, "memory hot unplug is not supported");
>> +        return;
>> +    }
> what if unplug is called on cold-plugged device?
> 
> Better way to disable mgmt initiated unplug is to forbid it in 
> unplug_request()
> For guest initiated one ('unplug' handler), the best we can do is log error
> and ignore it (provided guest won't get in confused). it's also possible 
> to hide _EJ method and then it would be even fine to abort if it gets here,
> since guest is not supposed to interface with MMIO interface without using 
> AML.
I don't understand the guest initiated unplug handling. How does it
differ from x86 handling as we are using the same dynamic methods?

Besides In ARM case I checked
/sys/devices/system/memory/memoryX/removable state for cold-plugged and
hot-plugged DIMMs and it is equal to 0. I don't know if it is a
limitation of the guest or a bug in our ACPI description somewhere. I
would not be surprised if hot-unplug is not supported at kernel leve
though.

Thanks

Eric
> 
>> +
>>      pc_dimm_unplug(PC_DIMM(dev), MACHINE(hotplug_dev));
>>      object_unparent(OBJECT(dev));
>>  }
>> @@ -2085,6 +2132,12 @@ static void virt_instance_init(Object *obj)
>>                                      "Set NVDIMM persistence"
>>                                      "Valid values are cpu and mem-ctrl", 
>> NULL);
>>  
>> +    vms->acpi_memhp_state.is_enabled = true;
>> +    object_property_add_bool(obj, "memory-hotplug-support",
>> +                             virt_get_memhp_support,
>> +                             virt_set_memhp_support,
>> +                             NULL);
>> +
>>      vms->irqmap = a15irqmap;
>>  }
>>  
> 



reply via email to

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