-.. BSD LICENSE
- Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
- * Neither the name of Intel Corporation nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2010-2014 Intel Corporation.
VM Power Management Application
===============================
The Virtual Machine Power Management solution shows an example of
how a DPDK application can indicate its processing requirements using VM local
-only information(vCPU/lcore) to a Host based Monitor which is responsible
+only information(vCPU/lcore, etc.) to a Host based Monitor which is responsible
for accepting requests for frequency changes for a vCPU, translating the vCPU
to a pCPU via libvirt and affecting the change in frequency.
to the librte_power ACPI cpufreq sysfs based library.
The Host Application relies on both qemu-kvm and libvirt to function.
+ This monitoring application is responsible for:
+
+ - Accepting requests from client applications: Client applications can
+ request frequency changes for a vCPU, translating
+ the vCPU to a pCPU via libvirt and affecting the change in frequency.
+
+ - Accepting policies from client applications: Client application can
+ send a policy to the host application. The
+ host application will then apply the rules of the policy independent
+ of the application. For example, the policy can contain time-of-day
+ information for busy/quiet periods, and the host application can scale
+ up/down the relevant cores when required. See the details of the guest
+ application below for more information on setting the policy values.
+
+ - Out-of-band monitoring of workloads via cores hardware event counters:
+ The host application can manage power for an application in a virtualised
+ OR non-virtualised environment by looking at the event counters of the
+ cores and taking action based on the branch hit/miss ratio. See the host
+ application '--core-list' command line parameter below.
+
#. librte_power for Virtual Machines
Using an alternate implementation for the librte_power API, requests for
the APCI cpufreq sysfs interface used on the host.
The l3fwd-power application will use this implementation when deployed on a VM
- (see Chapter 11 "L3 Forwarding with Power Management Application").
+ (see :doc:`l3_forward_power_man`).
+
+.. _figure_vm_power_mgr_highlevel:
-.. _figure_24:
+.. figure:: img/vm_power_mgr_highlevel.*
-**Figure 24. Highlevel Solution**
+ Highlevel Solution
-|vm_power_mgr_highlevel|
Overview
--------
Upon receiving a request, the host translates the vCPU to a pCPU via
the libvirt API before forwarding to the host librte_power.
-.. _figure_25:
+.. _figure_vm_power_mgr_vm_request_seq:
-**Figure 25. VM request to scale frequency**
+.. figure:: img/vm_power_mgr_vm_request_seq.*
+
+ VM request to scale frequency
-|vm_power_mgr_vm_request_seq|
Performance Considerations
~~~~~~~~~~~~~~~~~~~~~~~~~~
The Host OS must also have the *apci_cpufreq* module installed, in some cases
the *intel_pstate* driver may be the default Power Management environment.
To enable *acpi_cpufreq* and disable *intel_pstate*, add the following
-to the grub linux command line:
+to the grub Linux command line:
.. code-block:: console
</controller>
<channel type='unix'>
<source mode='bind' path='/tmp/powermonitor/{vm_name}.{channel_num}'/>
- <target type='virtio' name='virtio.serial.port.poweragent.{vm_channel_num}/>
+ <target type='virtio' name='virtio.serial.port.poweragent.{vm_channel_num}'/>
<address type='virtio-serial' controller='0' bus='0' port='{N}'/>
</channel>
Compiling
~~~~~~~~~
-#. export RTE_SDK=/path/to/rte_sdk
-#. cd ${RTE_SDK}/examples/vm_power_manager
-#. make
+For information on compiling DPDK and the sample applications
+see :doc:`compiling`.
+
+The application is located in the ``vm_power_manager`` sub-directory.
+
+To build just the ``vm_power_manager`` application using ``make``:
+
+.. code-block:: console
+
+ export RTE_SDK=/path/to/rte_sdk
+ export RTE_TARGET=build
+ cd ${RTE_SDK}/examples/vm_power_manager/
+ make
+
+The resulting binary will be ${RTE_SDK}/build/examples/vm_power_manager
+
+To build just the ``vm_power_manager`` application using ``meson/ninja``:
+
+.. code-block:: console
+
+ export RTE_SDK=/path/to/rte_sdk
+ cd ${RTE_SDK}
+ meson build
+ cd build
+ ninja
+ meson configure -Dexamples=vm_power_manager
+ ninja
+
+The resulting binary will be ${RTE_SDK}/build/examples/dpdk-vm_power_manager
Running
~~~~~~~
.. code-block:: console
- ./build/vm_power_mgr -c 0x3 -n 4
+ ./build/vm_power_mgr -l 0-1 -n 4
-After successful initialisation the user is presented with VM Power Manager CLI:
+After successful initialization the user is presented with VM Power Manager CLI:
.. code-block:: console
set_cpu_freq {core_num} up|down|min|max
+There are also some command line parameters for enabling the out-of-band
+monitoring of branch ratio on cores doing busy polling via PMDs.
+
+ .. code-block:: console
+
+ --core-list {list of cores}
+
+ When this parameter is used, the list of cores specified will monitor the ratio
+ between branch hits and branch misses. A tightly polling PMD thread will have a
+ very low branch ratio, so the core frequency will be scaled down to the minimim
+ allowed value. When packets are received, the code path will alter, causing the
+ branch ratio to increase. When the ratio goes above the ratio threshold, the
+ core frequency will be scaled up to the maximum allowed value.
+
+ .. code-block:: console
+
+ --branch-ratio {ratio}
+
+ The branch ratio is a floating point number that specifies the threshold at which
+ to scale up or down for the given workload. The default branch ratio is 0.01,
+ and will need to be adjusted for different workloads.
+
+
+
+JSON API
+~~~~~~~~
+
+In addition to the command line interface for host command and a virtio-serial
+interface for VM power policies, there is also a JSON interface through which
+power commands and policies can be sent. This functionality adds a dependency
+on the Jansson library, and the Jansson development package must be installed
+on the system before the JSON parsing functionality is included in the app.
+This is achieved by:
+
+ .. code-block:: javascript
+
+ apt-get install libjansson-dev
+
+The command and package name may be different depending on your operating
+system. It's worth noting that the app will successfully build without this
+package present, but a warning is shown during compilation, and the JSON
+parsing functionality will not be present in the app.
+
+Sending a command or policy to the power manager application is achieved by
+simply opening a fifo file, writing a JSON string to that fifo, and closing
+the file.
+
+The fifo is at /tmp/powermonitor/fifo
+
+The jason string can be a policy or instruction, and takes the following
+format:
+
+ .. code-block:: javascript
+
+ {"packet_type": {
+ "pair_1": value,
+ "pair_2": value
+ }}
+
+The 'packet_type' header can contain one of two values, depending on
+whether a policy or power command is being sent. The two possible values are
+"policy" and "instruction", and the expected name-value pairs is different
+depending on which type is being sent.
+
+The pairs are the format of standard JSON name-value pairs. The value type
+varies between the different name/value pairs, and may be integers, strings,
+arrays, etc. Examples of policies follow later in this document. The allowed
+names and value types are as follows:
+
+
+:Pair Name: "name"
+:Description: Name of the VM or Host. Allows the parser to associate the
+ policy with the relevant VM or Host OS.
+:Type: string
+:Values: any valid string
+:Required: yes
+:Example:
+
+ .. code-block:: javascript
+
+ "name", "ubuntu2"
+
+
+:Pair Name: "command"
+:Description: The type of packet we're sending to the power manager. We can be
+ creating or destroying a policy, or sending a direct command to adjust
+ the frequency of a core, similar to the command line interface.
+:Type: string
+:Values:
+
+ :CREATE: used when creating a new policy,
+ :DESTROY: used when removing a policy,
+ :POWER: used when sending an immediate command, max, min, etc.
+:Required: yes
+:Example:
+
+ .. code-block:: javascript
+
+ "command", "CREATE"
+
+
+:Pair Name: "policy_type"
+:Description: Type of policy to apply. Please see vm_power_manager documentation
+ for more information on the types of policies that may be used.
+:Type: string
+:Values:
+
+ :TIME: Time-of-day policy. Frequencies of the relevant cores are
+ scaled up/down depending on busy and quiet hours.
+ :TRAFFIC: This policy takes statistics from the NIC and scales up
+ and down accordingly.
+ :WORKLOAD: This policy looks at how heavily loaded the cores are,
+ and scales up and down accordingly.
+ :BRANCH_RATIO: This out-of-band policy can look at the ratio between
+ branch hits and misses on a core, and is useful for detecting
+ how much packet processing a core is doing.
+:Required: only for CREATE/DESTROY command
+:Example:
+
+ .. code-block:: javascript
+
+ "policy_type", "TIME"
+
+:Pair Name: "busy_hours"
+:Description: The hours of the day in which we scale up the cores for busy
+ times.
+:Type: array of integers
+:Values: array with list of hour numbers, (0-23)
+:Required: only for TIME policy
+:Example:
+
+ .. code-block:: javascript
+
+ "busy_hours":[ 17, 18, 19, 20, 21, 22, 23 ]
+
+:Pair Name: "quiet_hours"
+:Description: The hours of the day in which we scale down the cores for quiet
+ times.
+:Type: array of integers
+:Values: array with list of hour numbers, (0-23)
+:Required: only for TIME policy
+:Example:
+
+ .. code-block:: javascript
+
+ "quiet_hours":[ 2, 3, 4, 5, 6 ]
+
+:Pair Name: "avg_packet_thresh"
+:Description: Threshold below which the frequency will be set to min for
+ the TRAFFIC policy. If the traffic rate is above this and below max, the
+ frequency will be set to medium.
+:Type: integer
+:Values: The number of packets below which the TRAFFIC policy applies the
+ minimum frequency, or medium frequency if between avg and max thresholds.
+:Required: only for TRAFFIC policy
+:Example:
+
+ .. code-block:: javascript
+
+ "avg_packet_thresh": 100000
+
+:Pair Name: "max_packet_thresh"
+:Description: Threshold above which the frequency will be set to max for
+ the TRAFFIC policy
+:Type: integer
+:Values: The number of packets per interval above which the TRAFFIC policy
+ applies the maximum frequency
+:Required: only for TRAFFIC policy
+:Example:
+
+ .. code-block:: javascript
+
+ "max_packet_thresh": 500000
+
+:Pair Name: "core_list"
+:Description: The cores to which to apply the policy.
+:Type: array of integers
+:Values: array with list of virtual CPUs.
+:Required: only policy CREATE/DESTROY
+:Example:
+
+ .. code-block:: javascript
+
+ "core_list":[ 10, 11 ]
+
+:Pair Name: "workload"
+:Description: When our policy is of type WORKLOAD, we need to specify how
+ heavy our workload is.
+:Type: string
+:Values:
+
+ :HIGH: For cores running workloads that require high frequencies
+ :MEDIUM: For cores running workloads that require medium frequencies
+ :LOW: For cores running workloads that require low frequencies
+:Required: only for WORKLOAD policy types
+:Example:
+
+ .. code-block:: javascript
+
+ "workload", "MEDIUM"
+
+:Pair Name: "mac_list"
+:Description: When our policy is of type TRAFFIC, we need to specify the
+ MAC addresses that the host needs to monitor
+:Type: string
+:Values: array with a list of mac address strings.
+:Required: only for TRAFFIC policy types
+:Example:
+
+ .. code-block:: javascript
+
+ "mac_list":[ "de:ad:be:ef:01:01", "de:ad:be:ef:01:02" ]
+
+:Pair Name: "unit"
+:Description: the type of power operation to apply in the command
+:Type: string
+:Values:
+
+ :SCALE_MAX: Scale frequency of this core to maximum
+ :SCALE_MIN: Scale frequency of this core to minimum
+ :SCALE_UP: Scale up frequency of this core
+ :SCALE_DOWN: Scale down frequency of this core
+ :ENABLE_TURBO: Enable Turbo Boost for this core
+ :DISABLE_TURBO: Disable Turbo Boost for this core
+:Required: only for POWER instruction
+:Example:
+
+ .. code-block:: javascript
+
+ "unit", "SCALE_MAX"
+
+:Pair Name: "resource_id"
+:Description: The core to which to apply the power command.
+:Type: integer
+:Values: valid core id for VM or host OS.
+:Required: only POWER instruction
+:Example:
+
+ .. code-block:: javascript
+
+ "resource_id": 10
+
+JSON API Examples
+~~~~~~~~~~~~~~~~~
+
+Profile create example:
+
+ .. code-block:: javascript
+
+ {"policy": {
+ "name": "ubuntu",
+ "command": "create",
+ "policy_type": "TIME",
+ "busy_hours":[ 17, 18, 19, 20, 21, 22, 23 ],
+ "quiet_hours":[ 2, 3, 4, 5, 6 ],
+ "core_list":[ 11 ]
+ }}
+
+Profile destroy example:
+
+ .. code-block:: javascript
+
+ {"profile": {
+ "name": "ubuntu",
+ "command": "destroy",
+ }}
+
+Power command example:
+
+ .. code-block:: javascript
+
+ {"command": {
+ "name": "ubuntu",
+ "unit": "SCALE_MAX",
+ "resource_id": 10
+ }}
+
+To send a JSON string to the Power Manager application, simply paste the
+example JSON string into a text file and cat it into the fifo:
+
+ .. code-block:: console
+
+ cat file.json >/tmp/powermonitor/fifo
+
+The console of the Power Manager application should indicate the command that
+was just received via the fifo.
+
Compiling and Running the Guest Applications
--------------------------------------------
-For compiling and running l3fwd-power, see Chapter 11 "L3 Forwarding with Power Management Application".
+l3fwd-power is one sample application that can be used with vm_power_manager.
A guest CLI is also provided for validating the setup.
For both l3fwd-power and guest CLI, the channels for the VM must be monitored by the
-host application using the *add_channels* command on the host.
+host application using the *add_channels* command on the host. This typically uses
+the following commands in the host application:
+
+.. code-block:: console
+
+ vm_power> add_vm vmname
+ vm_power> add_channels vmname all
+ vm_power> set_channel_status vmname all enabled
+ vm_power> show_vm vmname
+
Compiling
~~~~~~~~~
-#. export RTE_SDK=/path/to/rte_sdk
-#. cd ${RTE_SDK}/examples/vm_power_manager/guest_cli
-#. make
+For information on compiling DPDK and the sample applications
+see :doc:`compiling`.
+
+For compiling and running l3fwd-power, see :doc:`l3_forward_power_man`.
+
+The application is located in the ``guest_cli`` sub-directory under ``vm_power_manager``.
+
+To build just the ``guest_vm_power_manager`` application using ``make``:
+
+.. code-block:: console
+
+ export RTE_SDK=/path/to/rte_sdk
+ export RTE_TARGET=build
+ cd ${RTE_SDK}/examples/vm_power_manager/guest_cli/
+ make
+
+The resulting binary will be ${RTE_SDK}/build/examples/guest_cli
+
+To build just the ``vm_power_manager`` application using ``meson/ninja``:
+
+.. code-block:: console
+
+ export RTE_SDK=/path/to/rte_sdk
+ cd ${RTE_SDK}
+ meson build
+ cd build
+ ninja
+ meson configure -Dexamples=vm_power_manager/guest_cli
+ ninja
+
+The resulting binary will be ${RTE_SDK}/build/examples/guest_cli
Running
~~~~~~~
-The application does not have any specific command line options other than *EAL*:
+The standard *EAL* command line parameters are required:
.. code-block:: console
- ./build/vm_power_mgr [EAL options]
+ ./build/guest_vm_power_mgr [EAL options] -- [guest options]
-The application for example purposes uses a channel for each lcore enabled,
-for example to run on cores 0,1,2,3 on a system with 4 memory channels:
+The guest example uses a channel for each lcore enabled. For example,
+to run on cores 0,1,2,3:
.. code-block:: console
- ./build/guest_vm_power_mgr -c 0xf -n 4
+ ./build/guest_vm_power_mgr -l 0-3
+
+Optionally, there is a list of command line parameter should the user wish to send a power
+policy down to the host application. These parameters are as follows:
+
+ .. code-block:: console
+
+ --vm-name {name of guest vm}
+
+ This parameter allows the user to change the Virtual Machine name passed down to the
+ host application via the power policy. The default is "ubuntu2"
+
+ .. code-block:: console
+
+ --vcpu-list {list vm cores}
+
+ A comma-separated list of cores in the VM that the user wants the host application to
+ monitor. The list of cores in any vm starts at zero, and these are mapped to the
+ physical cores by the host application once the policy is passed down.
+ Valid syntax includes individial cores '2,3,4', or a range of cores '2-4', or a
+ combination of both '1,3,5-7'
+
+ .. code-block:: console
+
+ --busy-hours {list of busy hours}
+
+ A comma-separated list of hours within which to set the core frequency to maximum.
+ Valid syntax includes individial hours '2,3,4', or a range of hours '2-4', or a
+ combination of both '1,3,5-7'. Valid hours are 0 to 23.
+
+ .. code-block:: console
+
+ --quiet-hours {list of quiet hours}
+
+ A comma-separated list of hours within which to set the core frequency to minimum.
+ Valid syntax includes individial hours '2,3,4', or a range of hours '2-4', or a
+ combination of both '1,3,5-7'. Valid hours are 0 to 23.
+
+ .. code-block:: console
+
+ --policy {policy type}
+ The type of policy. This can be one of the following values:
+ TRAFFIC - based on incoming traffic rates on the NIC.
+ TIME - busy/quiet hours policy.
+ BRANCH_RATIO - uses branch ratio counters to determine core busyness.
+ Not all parameters are needed for all policy types. For example, BRANCH_RATIO
+ only needs the vcpu-list parameter, not any of the hours.
-After successful initialisation the user is presented with VM Power Manager Guest CLI:
+
+After successful initialization the user is presented with VM Power Manager Guest CLI:
.. code-block:: console
set_cpu_freq {core_num} up|down|min|max
-.. |vm_power_mgr_highlevel| image:: img/vm_power_mgr_highlevel.svg
+To start the application and configure the power policy, and send it to the host:
+
+.. code-block:: console
+
+ ./build/guest_vm_power_mgr -l 0-3 -n 4 -- --vm-name=ubuntu --policy=BRANCH_RATIO --vcpu-list=2-4
+
+Once the VM Power Manager Guest CLI appears, issuing the 'send_policy now' command
+will send the policy to the host:
+
+.. code-block:: console
+
+ send_policy now
+
+Once the policy is sent to the host, the host application takes over the power monitoring
+of the specified cores in the policy.
-.. |vm_power_mgr_vm_request_seq| image:: img/vm_power_mgr_vm_request_seq.svg