3.1. Managing CPU Resources

You can manage the following CPU resource parameters for virtual machines and containers:

  • CPU units for virtual machines and containers
  • CPU affinity for virtual machines and containers
  • CPU limits for virtual machines and containers
  • NUMA nodes for virtual machines and containers
  • CPU hotplug for virtual machines
  • CPU topology for virtual machines

Detailed information on these parameters is given in the following sections.

3.1.1. Configuring CPU Units

CPU units define how much CPU time one virtual machine or container can receive in comparison with the other virtual machines and containers on the hardware node if all the CPUs of the hardware node are fully used. For example, if the container MyCT and the virtual machine MyVM are set to receive 1000 CPU units each and the container MyCT2 is configured to get 2000 CPU units, the container MyCT2 will get twice as much CPU time as the container MyCT or the virtual machine MyVM if all the CPUs of the Node are completely loaded.

By default, each virtual machine and container on the Node gets 1000 CPU units. You can configure the default setting using the prlctl set command. For example, you can run the following commands to allocate 2000 CPU units to the container MyCT and the virtual machine MyVM:

# prlctl set MyCT --cpuunits 2000
# prlctl set MyVM --cpuunits 2000

3.1.2. Configuring CPU Affinity for Virtual Machines and Containers

If your physical server has several CPUs installed, you can bind a virtual machine or container to specific CPUs so that only these CPUs are used to handle the processes running in the virtual machine or container. The feature of binding certain processes to certain CPUs is known as CPU affinity.

By default, any newly created virtual machine or container can consume the CPU time of all processors installed on the physical server. To bind a virtual machine or container to specific CPUs, you can use the --cpumask option of the prlctl set command. Assuming that your physical server has 8 CPUs, you can make the processes in the virtual machine MyVM and the container MyCT run on CPUs 0, 1, 3, 4, 5, and 6 by running the following commands:

# prlctl set MyVM --cpumask 0,1,3,4-6
# prlctl set MyCT --cpumask 0,1,3,4-6

You can specify the CPU affinity mask—that is, the processors to bind to virtual machines and containers—as separate CPU index numbers (0,1,3) or as CPU ranges (4-6). If you are setting the CPU affinity mask for a running virtual machine or container, the changes are applied on the fly.

To undo the changes made to the virtual machine MyVM and the container MyCT and set their processes to run on all available CPUs on the server, run these commands:

# prlctl set MyVM --cpumask all
# prlctl set MyCT --cpumask all

3.1.3. Configuring CPU Limits for Virtual Machines and Containers

A CPU limit indicates the maximum CPU power a virtual machine or container may get for its running processes. The container is not allowed to exceed the specified limit even if the server has enough free CPU power. By default, the CPU limit parameter is disabled for all newly created virtual machines and containers. This means that any application in any virtual machine or container can use all the free CPU power of the server.

Note

You can change which virtual machine threads—both service and activity or only activity—are limited by the parameters described below. To do this, enter the prlsrvctl set --vm-cpulimit-type <full|guest> command and restart running virtual machines for the changes to take effect.

To set a CPU limit for a virtual machine or container, you can use one of these options: --cpulimit, --cpus. Both options are described below in detail.

3.1.3.1. Using –cpulimit to Set CPU Limits

As a rule, you set a CPU limit for a virtual machine or container by using the prlctl set --cpulimit command. In the following example, the container MyCT is set to receive no more than 25% of the server CPU time even if the CPUs on the server are not fully loaded:

# prlctl set MyCT --cpulimit 25

This command sets the CPU limit for the container MyCT to 25% of the total CPU power of the server. The total CPU power of a server in per cent is calculated by multiplying the number of logical CPU cores installed on the server by 100%. So if a server has 2 logical CPU cores, 2 GHz each, the total CPU power will equal 200% and the limit for the container MyCT will be set to 500 MHz.

For example, on a hardware node with 2 logical CPU cores, 3 GHz each, the container MyCT will be able to get 25% of 6 GHz, that is, 750 MHz. To ensure that the container MyCT always has the same CPU limit on all servers, irrespective of their total CPU power, you can set the CPU limits in megahertz (MHz). For example, to make the container MyCT consume no more than 500 MHz on any hardware node, run the following command:

# prlctl set MyCT --cpulimit 500m

Note

For more information on setting CPU limits for virtual machines and containers, see also CPU Limit Specifics.

3.1.3.2. Using –cpus to Set CPU Limits

Another way of setting a CPU limit for a virtual machine or container is to use the prlctl set --cpus command. In this case, you can specify how many logical CPU cores per CPU socket the virtual machine or container may use. For example, as containers have only one CPU socket (for details, see Configuring CPU Topology for Virtual Machines), you can allow the container MyCT to use only 2 cores by running this command:

# prlctl set MyCT --cpus 2

To make sure that the CPU limit has been successfully set, you check /proc/cpuinfo in the container. For example:

# prlctl exec MyCT cat /proc/cpuinfo | grep "cpu cores"
cpu cores       : 2

3.1.3.3. Using –cpulimit and –cpus Simultaneously

If you use both --cpulimit and --cpus to set the CPU limit for a virtual machine or container, the smallest limit applies. For example, running the following commands on a server with 4 CPUs, 2 GHz each, will set the limit for the container MyCT to 2 GHz:

# prlctl set MyCT --cpus 2
# prlctl set MyCT --cpulimit 2000m

3.1.3.4. CPU Limit Specifics

Internally, Virtuozzo sets the CPU limit for virtual machines and containers in percent. On multi-core systems, each logical CPU core is considered to have the CPU power of 100%. So if a server has 4 CPU cores, the total CPU power of the server equals 400%.

You can also set a CPU limit in megahertz (MHz). If you specify the limit in MHz, Virtuozzo uses the following formula to convert the CPU power of the server from MHz into percent: CPULIMIT_% = 100% * CPULIMIT_MHz / CPUFREQ, where

  • CPULIMIT_% is the total CPU power of the server in percent.
  • CPULIMIT_MHz is the total CPU power of the server in megahertz.
  • CPUFREQ is the CPU frequency of one core on the server.

When setting CPU limits, note the following:

  • Make sure that the CPU limit you plan to set for a virtual machine or container does not exceed the total CPU power of the server. So if a server has 4 CPUs, 1000 MHz each, do not set the CPU limit to more than 4000 MHz.
  • The processes running in a virtual machine or container are scheduled for execution on all server CPUs in equal shares. For example, if a server has 4 CPUs, 1000 MHz each, and you set the CPU limit for a virtual machine or container to 2000 MHz, the virtual machine or container will consume 500 MHz from each CPU.
  • All running virtual machines and containers on a server cannot simultaneously consume more CPU power than is physically available on the node. In other words, if the total CPU power of the server is 4000 MHz, the running virtual machines and containers on this server will not be able to consume more than 4000 MHz, irrespective of their CPU limits. It is, however, perfectly normal that the overall CPU limit of all virtual machines and containers exceeds the Node total CPU power because most of the time virtual machines and containers consume only part of the CPU power assigned to them.

3.1.4. Binding CPUs to NUMA Nodes

On systems with a NUMA (Non-Uniform Memory Access) architecture, you can configure virtual machines and containers to use CPUs from specific NUMA nodes only. Consider the following example:

  • Your physical server has 8 CPUs installed.
  • The CPUs are divided into 2 NUMA nodes: NUMA node 0 and NUMA node 1. Each NUMA node has 4 CPUs.
  • You want the processes in the container MyCT to be executed on the processors from NUMA node 1.

To set the container MyCT to use the processors from NUMA node 1, run the following command:

# prlctl set MyCT --nodemask 1

To check that the container MyCT is now bound to NUMA node 1, use this command:

# prlctl list -i MyCT | grep nodemask
  cpu cpus=unlimited VT-x hotplug accl=high mode=32 cpuunits=1000 ioprio=4 nodemask=1

To unbind the container MyCT from NUMA node 1, execute this command:

# prlctl set MyCT --nodemask all

Now the container MyCT should be able to use all CPUs on the server again.

Note

For more information on NUMA, visit http://lse.sourceforge.net/numa.

3.1.5. Enabling CPU Hotplug for Virtual Machines

If a guest operating system supports the CPU hotplug functionality, you can enable this functionality for the virtual machine. Once the CPU hotplug functionality is turned on, you can increase the number of CPUs available to your virtual machines even if they are running.

Currently, the following systems come with the CPU hotplug support:

  • Linux operating systems based on the RHEL 5 kernel and higher (Red Hat Linux Enterprise 5, CentOS 5, and so on)
  • x64 version of Windows Server 2008 R2 (Datacenter Edition)
  • x64 version of Windows Server 2012 (Standard and Datacenter Edition)
  • x64 version of Windows Server 2008 (Standard Edition)
  • x64 version of Windows Server 2008 (Enterprise Edition)
  • x64 version of Windows Server 2008 (Datacenter Edition)

By default, the CPU hotplug support is disabled for all newly created virtual machines. To enable this functionality, you can use the --cpu-hotplug option of the prlctl set command. For example, to enable the CPU hotplug support in the virtual machine MyVM that runs one of the supported operating systems, stop the virtual machine MyVM and run this command:

# prlctl set MyVM --cpu-hotplug on
set cpu hotplug: 1
The VM has been successfully configured.

Once the functionality is enabled, you can increase the number of CPUs in the virtual machine MyVM even it is running. Assuming that your physical server has 4 CPUs installed and the processes in the virtual machine MyVM are set to be executed on two CPUs, you can run the following command to assign 3 CPUs to the virtual machine:

# prlctl set MyVM --cpus 3
set cpus(4): 3
The VM has been successfully configured.

To disable the CPU hotplug support in the virtual machine MyVM, use this command:

# prlctl set MyVM --cpu-hotplug off
set cpu hotplug: 0
The VM has been successfully configured.

The changes will come into effect on the next virtual machine start.

3.1.6. Configuring CPU Topology for Virtual Machines

In the current version of Virtuozzo, you can specify CPU topology for virtual machines, i.e. the number of CPU sockets and CPU cores per socket. This can be efficient, for example, if you use a guest operating system that supports a specific number of CPU sockets (e.g., limited by a license). In such a case, you can set the VM to use as many CPU cores as allowed by the guest OS and achieve near-native guest OS performance. The overall number of CPU cores available to a virtual machine is calculated by multiplying the number of CPU sockets by the number of CPU cores per socket. It can be no greater than the number of CPU cores on the host physical server.

By default, a virtual machine is created with one CPU socket and two CPU cores.

Note

In turn, a container has only one CPU socket, and this parameter cannot be changed.

You can change the number of CPU sockets and CPU cores per socket of a virtual machine using the --cpu-sockets and --cpus options of the prlctl set command. For example, if your physical server has 4 CPU cores, you can allow the virtual machine MyVM to use 2 CPU sockets and 2 CPU cores per socket by running the following command:

# prlctl set MyVM --cpu-sockets 2 --cpus 2

If a virtual machine is running, the changes will take effect after it is restarted.

To check the current CPU topology of a VM, run the following command:

# prlctl list MyVM -i | grep "cpu"
cpu sockets=2 cpus=2 cores=2 <...>