mirror of
https://git.proxmox.com/git/qemu-server
synced 2026-01-24 16:55:07 +00:00
add memory_unplug support V2
qemu 2.4 feature changelog: rebase on last git Note that currently linux guest don't support unplug of dimm when it'sused by kernel memory. They are some tunning to do with memory zone movable. http://events.linuxfoundation.org/sites/events/files/lcjp13_chen.pdf Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
This commit is contained in:
parent
a119327929
commit
525814b230
@ -2495,6 +2495,27 @@ sub foreach_dimm {
|
||||
}
|
||||
}
|
||||
|
||||
sub foreach_reverse_dimm {
|
||||
my ($conf, $vmid, $memory, $sockets, $func) = @_;
|
||||
|
||||
my $dimm_id = 253;
|
||||
my $current_size = 4177920;
|
||||
my $dimm_size = 65536;
|
||||
return if $current_size == $memory;
|
||||
|
||||
for (my $j = 0; $j < 8; $j++) {
|
||||
for (my $i = 0; $i < 32; $i++) {
|
||||
my $name = "dimm${dimm_id}";
|
||||
$dimm_id--;
|
||||
my $numanode = $i % $sockets;
|
||||
$current_size -= $dimm_size;
|
||||
&$func($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory);
|
||||
return $current_size if $current_size <= $memory;
|
||||
}
|
||||
$dimm_size /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
sub foreach_drive {
|
||||
my ($conf, $func) = @_;
|
||||
|
||||
@ -3578,33 +3599,77 @@ sub qemu_memory_hotplug {
|
||||
my $dimm_memory = $memory - $static_memory;
|
||||
|
||||
die "memory can't be lower than $static_memory MB" if $value < $static_memory;
|
||||
die "memory unplug is not yet available" if $value < $memory;
|
||||
die "you cannot add more memory than $MAX_MEM MB!\n" if $memory > $MAX_MEM;
|
||||
|
||||
|
||||
my $sockets = 1;
|
||||
$sockets = $conf->{sockets} if $conf->{sockets};
|
||||
|
||||
foreach_dimm($conf, $vmid, $value, $sockets, sub {
|
||||
my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_;
|
||||
if($value > $memory) {
|
||||
|
||||
return if $current_size <= $conf->{memory};
|
||||
foreach_dimm($conf, $vmid, $value, $sockets, sub {
|
||||
my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_;
|
||||
|
||||
eval { vm_mon_cmd($vmid, "object-add", 'qom-type' => "memory-backend-ram", id => "mem-$name", props => { size => int($dimm_size*1024*1024) } ) };
|
||||
if (my $err = $@) {
|
||||
eval { qemu_objectdel($vmid, "mem-$name"); };
|
||||
die $err;
|
||||
}
|
||||
return if $current_size <= $conf->{memory};
|
||||
|
||||
eval { vm_mon_cmd($vmid, "device_add", driver => "pc-dimm", id => "$name", memdev => "mem-$name", node => $numanode) };
|
||||
if (my $err = $@) {
|
||||
eval { qemu_objectdel($vmid, "mem-$name"); };
|
||||
die $err;
|
||||
}
|
||||
#update conf after each succesful module hotplug
|
||||
$conf->{memory} = $current_size;
|
||||
update_config_nolock($vmid, $conf, 1);
|
||||
});
|
||||
eval { vm_mon_cmd($vmid, "object-add", 'qom-type' => "memory-backend-ram", id => "mem-$name", props => { size => int($dimm_size*1024*1024) } ) };
|
||||
if (my $err = $@) {
|
||||
eval { qemu_objectdel($vmid, "mem-$name"); };
|
||||
die $err;
|
||||
}
|
||||
|
||||
eval { vm_mon_cmd($vmid, "device_add", driver => "pc-dimm", id => "$name", memdev => "mem-$name", node => $numanode) };
|
||||
if (my $err = $@) {
|
||||
eval { qemu_objectdel($vmid, "mem-$name"); };
|
||||
die $err;
|
||||
}
|
||||
#update conf after each succesful module hotplug
|
||||
$conf->{memory} = $current_size;
|
||||
update_config_nolock($vmid, $conf, 1);
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
foreach_reverse_dimm($conf, $vmid, $value, $sockets, sub {
|
||||
my ($conf, $vmid, $name, $dimm_size, $numanode, $current_size, $memory) = @_;
|
||||
|
||||
return if $current_size >= $conf->{memory};
|
||||
print "try to unplug memory dimm $name\n";
|
||||
|
||||
my $retry = 0;
|
||||
while (1) {
|
||||
eval { qemu_devicedel($vmid, $name) };
|
||||
sleep 3;
|
||||
my $dimm_list = qemu_dimm_list($vmid);
|
||||
last if !$dimm_list->{$name};
|
||||
raise_param_exc({ $name => "error unplug memory module" }) if $retry > 5;
|
||||
$retry++;
|
||||
}
|
||||
|
||||
#update conf after each succesful module unplug
|
||||
$conf->{memory} = $current_size;
|
||||
|
||||
eval { qemu_objectdel($vmid, "mem-$name"); };
|
||||
update_config_nolock($vmid, $conf, 1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
sub qemu_dimm_list {
|
||||
my ($vmid) = @_;
|
||||
|
||||
my $dimmarray = vm_mon_cmd_nocheck($vmid, "query-memory-devices");
|
||||
my $dimms = {};
|
||||
|
||||
foreach my $dimm (@$dimmarray) {
|
||||
|
||||
$dimms->{$dimm->{data}->{id}}->{id} = $dimm->{data}->{id};
|
||||
$dimms->{$dimm->{data}->{id}}->{node} = $dimm->{data}->{node};
|
||||
$dimms->{$dimm->{data}->{id}}->{addr} = $dimm->{data}->{addr};
|
||||
$dimms->{$dimm->{data}->{id}}->{size} = $dimm->{data}->{size};
|
||||
$dimms->{$dimm->{data}->{id}}->{slot} = $dimm->{data}->{slot};
|
||||
}
|
||||
return $dimms;
|
||||
}
|
||||
|
||||
sub qemu_block_set_io_throttle {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user