Unraid power usage higher than Windows


Mr.Will

Recommended Posts

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.

  • Like 1
Link to comment
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).

Link to comment
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

?>

Link to comment
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

Link to comment
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.

  • Like 1
Link to comment
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

 

Link to comment

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

  • Like 1
Link to comment
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;

 

Link to comment
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

Link to comment
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");

Link to comment
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.

Link to comment
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. :)

Link to comment
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"
}

 

Link to comment

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.