[pve-devel] [PATCH] add memory_unplug support

Alexandre DERUMIER aderumier at odiso.com
Tue Jul 28 07:39:50 CEST 2015


Now that we have qemu 2.4,
I think we can apply this patch ?


----- Mail original -----
De: "aderumier" <aderumier at odiso.com>
À: "pve-devel" <pve-devel at pve.proxmox.com>
Cc: "aderumier" <aderumier at odiso.com>
Envoyé: Mercredi 1 Juillet 2015 17:37:23
Objet: [PATCH] add memory_unplug support

qemu 2.4 feature 

Signed-off-by: Alexandre Derumier <aderumier at odiso.com> 
--- 
PVE/QemuServer.pm | 101 ++++++++++++++++++++++++++++++++++++++++++++---------- 
1 file changed, 83 insertions(+), 18 deletions(-) 

diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm 
index f035b67..36bed4a 100644 
--- a/PVE/QemuServer.pm 
+++ b/PVE/QemuServer.pm 
@@ -2607,6 +2607,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, $vmid, $func) = @_; 

@@ -3693,33 +3714,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 { 
-- 
2.1.4 




More information about the pve-devel mailing list