Mr.Will Posted October 8, 2022 Author Share Posted October 8, 2022 Thats interesting. I'm literally modifying the qemu file from <?php if (!isset($argv[2]) || $argv[2] != 'start') { exit(0); } to <?php include 'start_stop_vm_script.php'; if (!isset($argv[2]) || $argv[2] != 'start') { exit(0); } I added that PHP file in /usr/local/emhttp/, and basically has something similar to this: if ($argv[1] == 'Windows 10' && $argv[2] == 'prepare' && $argv[3] == 'begin'){ shell_exec('date +"%b %d %H:%M:%S libvirt hook: VM just turned ON. Disabling Nvidia persistence mode on host" >> /var/log/syslog'); shell_exec('kill $(pidof nvidia-persistenced) &'); sleep(2); } Does something similar to detect when it's being turned off. I don't like modifying the qemu hooks file, so I will defenitelly look at your method (it's newer than my script). It's important that we start/kill nvidia-persistenced before anything else in the VM, or it will fail. If qemu.d is called AFTER the VM is already starting/stopping, then it may not be an option. 1 Quote Link to comment
ich777 Posted October 8, 2022 Share Posted October 8, 2022 40 minutes ago, Mr.Will said: With this I managed to get quite some energy savings, from 100W to around 45W. @alturismo posted such a script already on the forums, somewhere… 😅 40 minutes ago, Mr.Will said: I try to start the VM without killing nvidia-persistenced before it just erros out. You can also call nvidia-persistenced once and kill it after a few seconds this should pull down your power draw from the GPU too, even if nvidia-persistenced isn‘t running at all. Of course this is also a workaround. It would be of course a welcome addition but the description has to be cristal clear what his plugin is doing (VFIO, that is not for use in Docker containers and so on). Quote Link to comment
ich777 Posted October 8, 2022 Share Posted October 8, 2022 23 minutes ago, Mr.Will said: Does something similar to detect when it's being turned off. @alturismo has a solution for this I think. Quote Link to comment
SimonF Posted October 8, 2022 Share Posted October 8, 2022 39 minutes ago, Mr.Will said: Thats interesting. I'm literally modifying the qemu file from <?php if (!isset($argv[2]) || $argv[2] != 'start') { exit(0); } to <?php include 'start_stop_vm_script.php'; if (!isset($argv[2]) || $argv[2] != 'start') { exit(0); } I added that PHP file in /usr/local/emhttp/, and basically has something similar to this: if ($argv[1] == 'Windows 10' && $argv[2] == 'prepare' && $argv[3] == 'begin'){ shell_exec('date +"%b %d %H:%M:%S libvirt hook: VM just turned ON. Disabling Nvidia persistence mode on host" >> /var/log/syslog'); shell_exec('kill $(pidof nvidia-persistenced) &'); sleep(2); } Does something similar to detect when it's being turned off. I don't like modifying the qemu hooks file, so I will defenitelly look at your method (it's newer than my script). It's important that we start/kill nvidia-persistenced before anything else in the VM, or it will fail. If qemu.d is called AFTER the VM is already starting/stopping, then it may not be an option. There are stopped status you can use in qemu hooks. #!/usr/bin/env php <?php #begin USB_MANAGER if (\$argv[2] == 'prepare' || \$argv[2] == 'stopped'){ shell_exec("/usr/local/emhttp/plugins/usb_manager/scripts/rc.usb_manager vm_action '{\$argv[1]}' {\$argv[2]} {\$argv[3]} {\$argv[4]} >/dev/null 2>&1 & disown") ; } #end USB_MANAGER ?> Quote Link to comment
Mr.Will Posted October 8, 2022 Author Share Posted October 8, 2022 2 minutes ago, SimonF said: There are stopped status you can use in qemu hooks. #!/usr/bin/env php <?php #begin USB_MANAGER if (\$argv[2] == 'prepare' || \$argv[2] == 'stopped'){ shell_exec("/usr/local/emhttp/plugins/usb_manager/scripts/rc.usb_manager vm_action '{\$argv[1]}' {\$argv[2]} {\$argv[3]} {\$argv[4]} >/dev/null 2>&1 & disown") ; } #end USB_MANAGER ?> I saw that in your own plugin page you posted before (thank you by the way!). Right now I'm doing it like this: if ($argv[1] == 'Windows 10' && $argv[2] == 'release' && $argv[3] == 'end'){ The end result should be the same, right? Ilike your solution for unifying in a single "if" statements. I can try to do that. I will investigate what @ich777 said about running nvidia-persistenced and killing it after a few seconds. I think this could simplify things if we just do that after VM is powered off. However, I think it takes about 15-20" to lower the power usage, so if during that time you try to start your VM it will error out. Am I correct? If so, then turning off persistenced before running the VM is probably a good practice I think Quote Link to comment
SimonF Posted October 8, 2022 Share Posted October 8, 2022 9 minutes ago, Mr.Will said: The end result should be the same, right? Yes Quote Link to comment
ich777 Posted October 8, 2022 Share Posted October 8, 2022 8 minutes ago, Mr.Will said: Am I correct? Yes. Maybe it would be a good thing to use the qemu hooks itself and check in the hooks if a Nvidia GPU is bound to the VM itself and if it is even needed to kill nvidia-persistenced or start it after the VM is ended. 1 Quote Link to comment
alturismo Posted October 8, 2022 Share Posted October 8, 2022 2 hours ago, ich777 said: @alturismo posted such a script already on the forums, somewhere… 😅 @Mr.Will here from the german section with sample's etc ... in terms you need some info's in english let me know, pretty straight forward why i "split" the hooks in sep scrip(s), its not a good idea to modify to much inside the qemu itself, recommended to "outsource" it more info's about it here https://libvirt.org/hooks.html here the post with screens and sample's Quote Link to comment
Mr.Will Posted October 8, 2022 Author Share Posted October 8, 2022 I just tried the propper hooks method (qemu.d/myhook) and it works pretty well. It didn't at first, but I just needed to change the line where I was killing the nvidia-persistenced process. So now all I have to do is create a scheduled task using "User Scripts" plugin that run at boot (first start only) and just create that file. Not sure it is worth creating a plugin for this, since it is pretty straightforward. Almost anyone can do that. My current script code is based on @SimonF's plugin file: #!/bin/bash QEMUDFILE=/etc/libvirt/hooks/qemu.d/vm_nvidia_pers_enabler # Check qemu.d exists if not create. [ ! -d "/etc/libvirt/hooks/qemu.d" ] && mkdir /etc/libvirt/hooks/qemu.d # Create vm_nvidia_pers_enabler File. cat << EOF > $QEMUDFILE #!/usr/bin/env php <?php #begin vm_nvidia_pers_enabler if (\$argv[1] == 'Windows 10' && \$argv[2] == 'prepare' && \$argv[3] == 'begin'){ shell_exec('date +"%b %d %H:%M:%S libvirt hook: VM just turned ON. Disabling Nvidia persistence mode on host" >> /var/log/syslog'); #shell_exec('kill $(pidof nvidia-persistenced) &'); #sleep(1); shell_exec('cpufreq-set -c 1 -g performance'); shell_exec('cpufreq-set -c 7 -g performance'); shell_exec('cpufreq-set -c 2 -g performance'); shell_exec('cpufreq-set -c 8 -g performance'); shell_exec('cpufreq-set -c 3 -g performance'); shell_exec('cpufreq-set -c 9 -g performance'); shell_exec('cpufreq-set -c 4 -g performance'); shell_exec('cpufreq-set -c 10 -g performance'); shell_exec('cpufreq-set -c 5 -g performance'); shell_exec('cpufreq-set -c 11 -g performance'); sleep(1); shell_exec('kill $(pidof nvidia-persistenced) &'); } if (\$argv[1] == 'Windows 10' && \$argv[2] == 'release' && \$argv[3] == 'end'){ shell_exec('date +"%b %d %H:%M:%S libvirt hook: VM just turned off. Enabling Nvidia persistence mode on host" >> /var/log/syslog'); shell_exec('cpufreq-set -c 1 -g powersave'); shell_exec('cpufreq-set -c 7 -g powersave'); shell_exec('cpufreq-set -c 2 -g powersave'); shell_exec('cpufreq-set -c 8 -g powersave'); shell_exec('cpufreq-set -c 3 -g powersave'); shell_exec('cpufreq-set -c 9 -g powersave'); shell_exec('cpufreq-set -c 4 -g powersave'); shell_exec('cpufreq-set -c 10 -g powersave'); shell_exec('cpufreq-set -c 5 -g powersave'); shell_exec('cpufreq-set -c 11 -g powersave'); sleep(2); shell_exec('nvidia-persistenced &'); } #end vm_nvidia_pers_enabler ?> EOF chmod +x $QEMUDFILE Here I'm also changing the CPU core's power state assigned to the VM. Not sure how much I'm saving with that though. Of course, anyone using this will need to change the name of the VM from "Windows 10" to whatever 1 Quote Link to comment
alturismo Posted October 8, 2022 Share Posted October 8, 2022 3 minutes ago, Mr.Will said: Here I'm also changing the CPU core's power state assigned to the VM. Not sure how much I'm saving with that though. Of course, anyone using this will need to change the name of the VM from "Windows 10" to whatever here may a sample howto shorten this a litte (im also setting some different CPU Governor's and Freq's ) #!/bin/bash nvidia-smi -i 1 -pm 1 & sleep 1 #/usr/local/sbin/rc.tweaks set_governor ondemand & bash -c 'for ((i=8;i<10;i++)); do cpufreq-set -c $i -g powersave; done' bash -c 'for ((i=18;i<20;i++)); do cpufreq-set -c $i -g powersave; done' sleep 1 exit 0; #!/bin/bash nvidia-smi -i 1 -pm 0 sleep 1 #/usr/local/sbin/rc.tweaks set_governor ondemand & bash -c 'for ((i=8;i<10;i++)); do cpufreq-set -c $i -g ondemand; done' bash -c 'for ((i=18;i<20;i++)); do cpufreq-set -c $i -g ondemand; done' sleep 1 exit 0; Quote Link to comment
Mr.Will Posted October 8, 2022 Author Share Posted October 8, 2022 5 minutes ago, alturismo said: @Mr.Will here from the german section with sample's etc ... in terms you need some info's in english let me know, pretty straight forward why i "split" the hooks in sep scrip(s), its not a good idea to modify to much inside the qemu itself, recommended to "outsource" it more info's about it here https://libvirt.org/hooks.html here the post with screens and sample's It seems we crossed posts Yes, that's basically what I ended up doing, altough I add the CPU thing and will require a little more cleanup. But other than that I believe it's the same process Quote Link to comment
SimonF Posted October 8, 2022 Share Posted October 8, 2022 13 minutes ago, Mr.Will said: It seems we crossed posts Yes, that's basically what I ended up doing, altough I add the CPU thing and will require a little more cleanup. But other than that I believe it's the same process Sorry if teaching you to suck eggs but just create a simple array and foreach it. $vcpu[] = [ 1,2,3,4,5,7,8,9,10] ; foreach ($vcpus as $vcpu) shell_exec("cpufreq-set -c $vcpu -g powersave"); Quote Link to comment
dlandon Posted October 8, 2022 Share Posted October 8, 2022 With the Tips and Tweaks plugun unstalled, you can use the following command to change the CPU governor: /usr/local/sbin/rc.tweaks set_governor 'governor' Quote Link to comment
ich777 Posted October 8, 2022 Share Posted October 8, 2022 15 minutes ago, SimonF said: Sorry if teaching you to suck eggs but just create a simple array and foreach it. I think there are multiple ways of setting the governor for currently assigned cores to VMs which is either on or off but the proper way should be to read which cores are assigned to the VM from libvirt and change the states only for the assigned cores since those two are trying to accomplish this from what I read here. Quote Link to comment
SimonF Posted October 8, 2022 Share Posted October 8, 2022 12 minutes ago, ich777 said: I think there are multiple ways of setting the governor for currently assigned cores to VMs which is either on or off but the proper way should be to read which cores are assigned to the VM from libvirt and change the states only for the assigned cores since those two are trying to accomplish this from what I read here. Yes looking a way to do that. Quote Link to comment
ich777 Posted October 8, 2022 Share Posted October 8, 2022 36 minutes ago, SimonF said: Yes looking a way to do that. I think @alturismo & @Mr.Will will figure that out... Quote Link to comment
SimonF Posted October 8, 2022 Share Posted October 8, 2022 2 hours ago, Mr.Will said: It seems we crossed posts Yes, that's basically what I ended up doing, altough I add the CPU thing and will require a little more cleanup. But other than that I believe it's the same process #!/usr/bin/php <?php /* Copyright 2022, Simon Fairweather * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation. * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. */ $docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp'; // add translations if (substr($_SERVER['REQUEST_URI'],0,4) != '/VMs') { $_SERVER['REQUEST_URI'] = 'vms'; require_once "$docroot/webGui/include/Translations.php"; } require_once "$docroot/webGui/include/Helpers.php"; require_once "$docroot/webGui/include/Custom.php"; require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php"; $vmname = 'Windows 10' $res = $lv->get_domain_by_name($vmname); $vcpus = $lv->domain_get_vcpu_pins($res) ; This provide an array which you can add to the loop. Array(6) { [0]=> string(1) "2" [1]=> string(1) "3" [2]=> string(1) "6" [3]=> string(1) "7" [4]=> string(2) "12" [5]=> string(2) "13" } Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.