numam-dpdk/app/test/test_power_intel_uncore.c
Tadhg Kearney 60b8a661a9 power: add Intel uncore frequency control
Add API to allow uncore frequency adjustment.

Uncore is a term used by Intel to describe function
of a microprocessor that are closely connected
to the core to achieve high performance.

This is done through manipulating related uncore frequency control
sysfs entries to adjust the minimum and maximum uncore frequency values
and works on Linux for Intel hardware.

Signed-off-by: Tadhg Kearney <tadhg.kearney@intel.com>
Reviewed-by: David Hunt <david.hunt@intel.com>
Acked-by: David Hunt <david.hunt@intel.com>
2022-10-10 14:53:40 +02:00

302 lines
6.5 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2022 Intel Corporation
*/
#include "test.h"
#ifndef RTE_LIB_POWER
static int
test_power_intel_uncore(void)
{
printf("Power management library not supported, skipping test\n");
return TEST_SKIPPED;
}
#else
#include <rte_power_intel_uncore.h>
#include <power_common.h>
#define MAX_UNCORE_FREQS 32
#define VALID_PKG 0
#define VALID_DIE 0
#define INVALID_PKG (rte_power_uncore_get_num_pkgs() + 1)
#define INVALID_DIE (rte_power_uncore_get_num_dies(VALID_PKG) + 1)
#define VALID_INDEX 1
#define INVALID_INDEX (MAX_UNCORE_FREQS + 1)
static int check_power_uncore_init(void)
{
int ret;
/* Test initialisation of uncore configuration*/
ret = rte_power_uncore_init(VALID_PKG, VALID_DIE);
if (ret < 0) {
printf("Cannot initialise uncore power management for pkg %u die %u, this "
"may occur if environment is not configured "
"correctly(APCI cpufreq) or operating in another valid "
"Power management environment\n", VALID_PKG, VALID_DIE);
return -1;
}
/* Unsuccessful Test */
ret = rte_power_uncore_init(INVALID_PKG, INVALID_DIE);
if (ret == 0) {
printf("Unexpectedly was able to initialise uncore power management "
"for pkg %u die %u\n", INVALID_PKG, INVALID_DIE);
return -1;
}
return 0;
}
static int
check_power_get_uncore_freq(void)
{
int ret;
/* Successfully get uncore freq */
ret = rte_power_get_uncore_freq(VALID_PKG, VALID_DIE);
if (ret < 0) {
printf("Failed to get uncore frequency for pkg %u die %u\n",
VALID_PKG, VALID_DIE);
return -1;
}
/* Unsuccessful Test */
ret = rte_power_get_uncore_freq(INVALID_PKG, INVALID_DIE);
if (ret >= 0) {
printf("Unexpectedly got invalid uncore frequency for pkg %u die %u\n",
INVALID_PKG, INVALID_DIE);
return -1;
}
return 0;
}
static int
check_power_set_uncore_freq(void)
{
int ret;
/* Successfully set uncore freq */
ret = rte_power_set_uncore_freq(VALID_PKG, VALID_DIE, VALID_INDEX);
if (ret < 0) {
printf("Failed to set uncore frequency for pkg %u die %u index %u\n",
VALID_PKG, VALID_DIE, VALID_INDEX);
return -1;
}
/* Try to unsuccessfully set invalid uncore freq index */
ret = rte_power_set_uncore_freq(VALID_PKG, VALID_DIE, INVALID_INDEX);
if (ret == 0) {
printf("Unexpectedly set invalid uncore index for pkg %u die %u index %u\n",
VALID_PKG, VALID_DIE, INVALID_INDEX);
return -1;
}
/* Unsuccessful Test */
ret = rte_power_set_uncore_freq(INVALID_PKG, INVALID_DIE, VALID_INDEX);
if (ret == 0) {
printf("Unexpectedly set invalid uncore frequency for pkg %u die %u index %u\n",
INVALID_PKG, INVALID_DIE, VALID_INDEX);
return -1;
}
return 0;
}
static int
check_power_uncore_freq_max(void)
{
int ret;
/* Successfully get max uncore freq */
ret = rte_power_uncore_freq_max(VALID_PKG, VALID_DIE);
if (ret < 0) {
printf("Failed to set max uncore frequency for pkg %u die %u\n",
VALID_PKG, VALID_DIE);
return -1;
}
/* Unsuccessful Test */
ret = rte_power_uncore_freq_max(INVALID_PKG, INVALID_DIE);
if (ret == 0) {
printf("Unexpectedly set invalid max uncore frequency for pkg %u die %u\n",
INVALID_PKG, INVALID_DIE);
return -1;
}
return 0;
}
static int
check_power_uncore_freq_min(void)
{
int ret;
/* Successfully get min uncore freq */
ret = rte_power_uncore_freq_min(VALID_PKG, VALID_DIE);
if (ret < 0) {
printf("Failed to set min uncore frequency for pkg %u die %u\n",
VALID_PKG, VALID_DIE);
return -1;
}
/* Unsuccessful Test */
ret = rte_power_uncore_freq_min(INVALID_PKG, INVALID_DIE);
if (ret == 0) {
printf("Unexpectedly set invalid min uncore frequency for pkg %u die %u\n",
INVALID_PKG, INVALID_DIE);
return -1;
}
return 0;
}
static int
check_power_uncore_get_num_freqs(void)
{
int ret;
/* Successfully get number of uncore freq */
ret = rte_power_uncore_get_num_freqs(VALID_PKG, VALID_DIE);
if (ret < 0) {
printf("Failed to get number of uncore frequencies for pkg %u die %u\n",
VALID_PKG, VALID_DIE);
return -1;
}
/* Unsuccessful Test */
ret = rte_power_uncore_get_num_freqs(INVALID_PKG, INVALID_DIE);
if (ret >= 0) {
printf("Unexpectedly got number of invalid frequencies for pkg %u die %u\n",
INVALID_PKG, INVALID_DIE);
return -1;
}
return 0;
}
static int
check_power_uncore_get_num_pkgs(void)
{
int ret;
/* Successfully get number of uncore pkgs */
ret = rte_power_uncore_get_num_pkgs();
if (ret == 0) {
printf("Failed to get number of uncore pkgs\n");
return -1;
}
return 0;
}
static int
check_power_uncore_get_num_dies(void)
{
int ret;
/* Successfully get number of uncore dies */
ret = rte_power_uncore_get_num_dies(VALID_PKG);
if (ret == 0) {
printf("Failed to get number of uncore dies for pkg %u\n",
VALID_PKG);
return -1;
}
/* Unsuccessful test */
ret = rte_power_uncore_get_num_dies(INVALID_PKG);
if (ret > 0) {
printf("Unexpectedly got number of invalid dies for pkg %u\n",
INVALID_PKG);
return -1;
}
return 0;
}
static int
check_power_uncore_exit(void)
{
int ret;
/* Successfully exit uncore power management */
ret = rte_power_uncore_exit(VALID_PKG, VALID_DIE);
if (ret < 0) {
printf("Failed to exit uncore power management for pkg %u die %u\n",
VALID_PKG, VALID_DIE);
}
/* Unsuccessful Test */
ret = rte_power_uncore_exit(INVALID_PKG, INVALID_DIE);
if (ret == 0) {
printf("Unexpectedly was able to exit uncore power management for pkg %u die %u\n",
INVALID_PKG, INVALID_DIE);
return -1;
}
return 0;
}
static int
test_power_intel_uncore(void)
{
int ret;
ret = rte_power_uncore_get_num_pkgs();
if (ret == 0) {
printf("Uncore frequency management not supported/enabled on this kernel. "
"Please enable CONFIG_INTEL_UNCORE_FREQ_CONTROL if on x86 with linux kernel"
" >= 5.6\n");
return TEST_SKIPPED;
}
ret = check_power_uncore_init();
if (ret < 0)
goto fail_all;
ret = check_power_get_uncore_freq();
if (ret < 0)
goto fail_all;
ret = check_power_set_uncore_freq();
if (ret < 0)
goto fail_all;
ret = check_power_uncore_freq_max();
if (ret < 0)
goto fail_all;
ret = check_power_uncore_freq_min();
if (ret < 0)
goto fail_all;
ret = check_power_uncore_get_num_freqs();
if (ret < 0)
goto fail_all;
ret = check_power_uncore_get_num_pkgs();
if (ret < 0)
goto fail_all;
ret = check_power_uncore_get_num_dies();
if (ret < 0)
goto fail_all;
ret = check_power_uncore_exit();
if (ret < 0)
return -1;
return 0;
fail_all:
rte_power_uncore_exit(VALID_PKG, VALID_DIE);
return -1;
}
#endif
REGISTER_TEST_COMMAND(power_intel_uncore_autotest, test_power_intel_uncore);