Commit df0acded authored by Igor Mammedov's avatar Igor Mammedov Committed by Michael S. Tsirkin
Browse files

memhp: extend address auto assignment to support gaps



setting gap to TRUE will make sparse DIMM
address auto allocation, leaving gaps between
a new DIMM address and preceeding existing DIMM.

Signed-off-by: default avatarIgor Mammedov <imammedo@redhat.com>
Reviewed-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 8a9b6b37
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1644,7 +1644,8 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
        goto out;
    }

    pc_dimm_memory_plug(dev, &pcms->hotplug_memory, mr, align, &local_err);
    pc_dimm_memory_plug(dev, &pcms->hotplug_memory, mr, align, false,
                        &local_err);
    if (local_err) {
        goto out;
    }
+9 −6
Original line number Diff line number Diff line
@@ -32,7 +32,8 @@ typedef struct pc_dimms_capacity {
} pc_dimms_capacity;

void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
                         MemoryRegion *mr, uint64_t align, Error **errp)
                         MemoryRegion *mr, uint64_t align, bool gap,
                         Error **errp)
{
    int slot;
    MachineState *machine = MACHINE(qdev_get_machine());
@@ -48,7 +49,7 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,

    addr = pc_dimm_get_free_addr(hpms->base,
                                 memory_region_size(&hpms->mr),
                                 !addr ? NULL : &addr, align,
                                 !addr ? NULL : &addr, align, gap,
                                 memory_region_size(mr), &local_err);
    if (local_err) {
        goto out;
@@ -287,8 +288,8 @@ static int pc_dimm_built_list(Object *obj, void *opaque)

uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
                               uint64_t address_space_size,
                               uint64_t *hint, uint64_t align, uint64_t size,
                               Error **errp)
                               uint64_t *hint, uint64_t align, bool gap,
                               uint64_t size, Error **errp)
{
    GSList *list = NULL, *item;
    uint64_t new_addr, ret = 0;
@@ -333,13 +334,15 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
            goto out;
        }

        if (ranges_overlap(dimm->addr, dimm_size, new_addr, size)) {
        if (ranges_overlap(dimm->addr, dimm_size, new_addr,
                           size + (gap ? 1 : 0))) {
            if (hint) {
                DeviceState *d = DEVICE(dimm);
                error_setg(errp, "address range conflicts with '%s'", d->id);
                goto out;
            }
            new_addr = QEMU_ALIGN_UP(dimm->addr + dimm_size, align);
            new_addr = QEMU_ALIGN_UP(dimm->addr + dimm_size + (gap ? 1 : 0),
                                     align);
        }
    }
    ret = new_addr;
+1 −1
Original line number Diff line number Diff line
@@ -2096,7 +2096,7 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
        goto out;
    }

    pc_dimm_memory_plug(dev, &ms->hotplug_memory, mr, align, &local_err);
    pc_dimm_memory_plug(dev, &ms->hotplug_memory, mr, align, false, &local_err);
    if (local_err) {
        goto out;
    }
+4 −3
Original line number Diff line number Diff line
@@ -83,15 +83,16 @@ typedef struct MemoryHotplugState {

uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
                               uint64_t address_space_size,
                               uint64_t *hint, uint64_t align, uint64_t size,
                               Error **errp);
                               uint64_t *hint, uint64_t align, bool gap,
                               uint64_t size, Error **errp);

int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp);

int qmp_pc_dimm_device_list(Object *obj, void *opaque);
uint64_t pc_existing_dimms_capacity(Error **errp);
void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
                         MemoryRegion *mr, uint64_t align, Error **errp);
                         MemoryRegion *mr, uint64_t align, bool gap,
                         Error **errp);
void pc_dimm_memory_unplug(DeviceState *dev, MemoryHotplugState *hpms,
                           MemoryRegion *mr);
#endif