[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 10/27] dimm: add busy slot check and slot auto-alloc
From: |
Igor Mammedov |
Subject: |
[Qemu-devel] [PATCH 10/27] dimm: add busy slot check and slot auto-allocation |
Date: |
Thu, 21 Nov 2013 03:38:31 +0100 |
- if slot property is not specified on -device/device_add command,
treat default value as request for assigning DimmDevice to
the first free slot.
- if slot is provided with -device/device_add command, attempt to
use it or fail command if it's already occupied.
Signed-off-by: Igor Mammedov <address@hidden>
---
v2:
s/dc/dbc/
---
hw/mem/dimm.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++-
include/hw/mem/dimm.h | 4 +++
2 files changed, 54 insertions(+), 1 deletions(-)
diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index b3d6fda..8837ffe 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -21,6 +21,7 @@
#include "hw/mem/dimm.h"
#include "qemu/config-file.h"
#include "qapi/visitor.h"
+#include "qemu/bitmap.h"
static void dimm_bus_initfn(Object *obj)
{
@@ -28,6 +29,45 @@ static void dimm_bus_initfn(Object *obj)
b->allow_hotplug = true;
}
+
+static int dimm_bus_slot2bitmap(DeviceState *dev, void *opaque)
+{
+ unsigned long *bitmap = opaque;
+ BusClass *bc = BUS_GET_CLASS(qdev_get_parent_bus(dev));
+ DimmDevice *d = DIMM(dev);
+
+ if (dev->realized) { /* count only realized DIMMs */
+ g_assert(d->slot < bc->max_dev);
+ set_bit(d->slot, bitmap);
+ }
+ return 0;
+}
+
+static int dimm_bus_get_free_slot(DimmBus *bus, const int *hint, Error **errp)
+{
+ BusClass *bc = BUS_GET_CLASS(bus);
+ unsigned long *bitmap = bitmap_new(bc->max_dev);
+ int slot = 0;
+
+ qbus_walk_children(BUS(bus), dimm_bus_slot2bitmap, NULL, bitmap);
+
+ /* check if requested slot is not occupied */
+ if (hint) {
+ if (!test_bit(*hint, bitmap)) {
+ slot = *hint;
+ } else {
+ error_setg(errp, "slot %d is busy", *hint);
+ }
+ goto out;
+ }
+
+ /* search for free slot */
+ slot = find_first_zero_bit(bitmap, bc->max_dev);
+out:
+ g_free(bitmap);
+ return slot;
+}
+
static void dimm_bus_register_memory(DimmBus *bus, DimmDevice *dimm,
Error **errp)
{
@@ -43,6 +83,7 @@ static void dimm_bus_class_init(ObjectClass *oc, void *data)
bc->max_dev = qemu_opt_get_number(opts, "slots", 0);
dbc->register_memory = dimm_bus_register_memory;
+ dbc->get_free_slot = dimm_bus_get_free_slot;
}
static const TypeInfo dimm_bus_info = {
@@ -57,7 +98,7 @@ static const TypeInfo dimm_bus_info = {
static Property dimm_properties[] = {
DEFINE_PROP_UINT64("start", DimmDevice, start, 0),
DEFINE_PROP_UINT32("node", DimmDevice, node, 0),
- DEFINE_PROP_INT32("slot", DimmDevice, slot, 0),
+ DEFINE_PROP_INT32("slot", DimmDevice, slot, -1),
DEFINE_PROP_END_OF_LIST(),
};
@@ -132,6 +173,7 @@ static void dimm_realize(DeviceState *dev, Error **errp)
DimmBus *bus = DIMM_BUS(qdev_get_parent_bus(dev));
BusClass *bc = BUS_GET_CLASS(bus);
DimmBusClass *dbc = DIMM_BUS_GET_CLASS(bus);
+ int *slot_hint;
if (!dimm->mr) {
error_setg(errp, "'memdev' property is not set");
@@ -147,6 +189,13 @@ static void dimm_realize(DeviceState *dev, Error **errp)
error_setg(errp, "maximum allowed slot is: %d", bc->max_dev - 1);
return;
}
+ g_assert(dbc->get_free_slot);
+ slot_hint = dimm->slot < 0 ? NULL : &dimm->slot;
+ dimm->slot = dbc->get_free_slot(bus, slot_hint, errp);
+ if (error_is_set(errp)) {
+ return;
+ }
+
g_assert(dbc->register_memory);
dbc->register_memory(bus, dimm, errp);
diff --git a/include/hw/mem/dimm.h b/include/hw/mem/dimm.h
index ae9ad2e..963b26d 100644
--- a/include/hw/mem/dimm.h
+++ b/include/hw/mem/dimm.h
@@ -75,11 +75,15 @@ typedef struct DimmBus {
/**
* DimmBusClass:
* @parent_class: opaque parent class container
+ * @get_free_slot: returns a not occupied slot number. If @hint is provided,
+ * it tries to return slot specified by @hint if it's not busy or returns
+ * error in @errp.
* @register_memory: map @DimmDevice into hot-plugable address space
*/
typedef struct DimmBusClass {
BusClass parent_class;
+ int (*get_free_slot)(DimmBus *bus, const int *hint, Error **errp);
void (*register_memory)(DimmBus *bus, DimmDevice *dimm, Error **errp);
} DimmBusClass;
--
1.7.1
- Re: [Qemu-devel] [PATCH 02/27] rename pci_hotplug_fn to hotplug_fn and make it available for other devices, (continued)
- [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor, Igor Mammedov, 2013/11/20
- [Qemu-devel] [PATCH 06/27] get reference to /backend container via qemu_get_backend(), Igor Mammedov, 2013/11/20
- [Qemu-devel] [PATCH 07/27] add memdev backend infrastructure, Igor Mammedov, 2013/11/20
- [Qemu-devel] [PATCH 08/27] dimm: implement dimm device abstraction, Igor Mammedov, 2013/11/20
- [Qemu-devel] [PATCH 09/27] dimm: map DimmDevice into DimBus provided address space, Igor Mammedov, 2013/11/20
- [Qemu-devel] [PATCH 10/27] dimm: add busy slot check and slot auto-allocation,
Igor Mammedov <=
- [Qemu-devel] [PATCH 11/27] dimm: add busy address check and address auto-allocation, Igor Mammedov, 2013/11/20
- [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation, Igor Mammedov, 2013/11/20
- Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation, Michael S. Tsirkin, 2013/11/21
- Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation, Igor Mammedov, 2013/11/21
- Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation, Michael S. Tsirkin, 2013/11/21
- Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation, Igor Mammedov, 2013/11/22
- Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation, Michael S. Tsirkin, 2013/11/24
- Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation, Markus Armbruster, 2013/11/25
- Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation, Paolo Bonzini, 2013/11/25
- Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation, Igor Mammedov, 2013/11/25