examples/vm_power: add core list parameter
Add in the '-l' command line parameter (also --core-list) So the user can now pass --corelist=4,6,8-10 and it will expand out to 4,6,8,9,10 using the parse function provided in parse.c (parse_set). This list of cores is then used to enable out-of-band monitoring to scale up and down these cores based on the ratio of branch hits versus branch misses. The ratio will be low when a poll loop is spinning with no packets being received, so the frequency will be scaled down. Also , as part of this change, we introduce a core_info struct which keeps information on each core in the system, and whether we're doing out of band monitoring on them. Signed-off-by: David Hunt <david.hunt@intel.com> Acked-by: Radu Nicolau <radu.nicolau@intel.com>
This commit is contained in:
parent
ace158c4a8
commit
99a968fac0
@ -19,7 +19,7 @@ APP = vm_power_mgr
|
|||||||
|
|
||||||
# all source are stored in SRCS-y
|
# all source are stored in SRCS-y
|
||||||
SRCS-y := main.c vm_power_cli.c power_manager.c channel_manager.c
|
SRCS-y := main.c vm_power_cli.c power_manager.c channel_manager.c
|
||||||
SRCS-y += channel_monitor.c
|
SRCS-y += channel_monitor.c parse.c
|
||||||
|
|
||||||
CFLAGS += -O3 -I$(RTE_SDK)/lib/librte_power/
|
CFLAGS += -O3 -I$(RTE_SDK)/lib/librte_power/
|
||||||
CFLAGS += $(WERROR_FLAGS)
|
CFLAGS += $(WERROR_FLAGS)
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "channel_monitor.h"
|
#include "channel_monitor.h"
|
||||||
#include "power_manager.h"
|
#include "power_manager.h"
|
||||||
#include "vm_power_cli.h"
|
#include "vm_power_cli.h"
|
||||||
|
#include "parse.h"
|
||||||
#include <rte_pmd_ixgbe.h>
|
#include <rte_pmd_ixgbe.h>
|
||||||
#include <rte_pmd_i40e.h>
|
#include <rte_pmd_i40e.h>
|
||||||
#include <rte_pmd_bnxt.h>
|
#include <rte_pmd_bnxt.h>
|
||||||
@ -133,18 +134,22 @@ parse_portmask(const char *portmask)
|
|||||||
static int
|
static int
|
||||||
parse_args(int argc, char **argv)
|
parse_args(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int opt, ret;
|
int opt, ret, cnt, i;
|
||||||
char **argvopt;
|
char **argvopt;
|
||||||
|
uint16_t *oob_enable;
|
||||||
int option_index;
|
int option_index;
|
||||||
char *prgname = argv[0];
|
char *prgname = argv[0];
|
||||||
|
struct core_info *ci;
|
||||||
static struct option lgopts[] = {
|
static struct option lgopts[] = {
|
||||||
{ "mac-updating", no_argument, 0, 1},
|
{ "mac-updating", no_argument, 0, 1},
|
||||||
{ "no-mac-updating", no_argument, 0, 0},
|
{ "no-mac-updating", no_argument, 0, 0},
|
||||||
|
{ "core-list", optional_argument, 0, 'l'},
|
||||||
{NULL, 0, 0, 0}
|
{NULL, 0, 0, 0}
|
||||||
};
|
};
|
||||||
argvopt = argv;
|
argvopt = argv;
|
||||||
|
ci = get_core_info();
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argvopt, "p:q:T:",
|
while ((opt = getopt_long(argc, argvopt, "l:p:q:T:",
|
||||||
lgopts, &option_index)) != EOF) {
|
lgopts, &option_index)) != EOF) {
|
||||||
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
@ -156,6 +161,27 @@ parse_args(int argc, char **argv)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
oob_enable = malloc(ci->core_count * sizeof(uint16_t));
|
||||||
|
if (oob_enable == NULL) {
|
||||||
|
printf("Error - Unable to allocate memory\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
cnt = parse_set(optarg, oob_enable, ci->core_count);
|
||||||
|
if (cnt < 0) {
|
||||||
|
printf("Invalid core-list - [%s]\n",
|
||||||
|
optarg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (i = 0; i < ci->core_count; i++) {
|
||||||
|
if (oob_enable[i]) {
|
||||||
|
printf("***Using core %d\n", i);
|
||||||
|
ci->cd[i].oob_enabled = 1;
|
||||||
|
ci->cd[i].global_enabled_cpus = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(oob_enable);
|
||||||
|
break;
|
||||||
/* long options */
|
/* long options */
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
@ -261,6 +287,10 @@ main(int argc, char **argv)
|
|||||||
uint16_t portid;
|
uint16_t portid;
|
||||||
|
|
||||||
|
|
||||||
|
ret = core_info_init();
|
||||||
|
if (ret < 0)
|
||||||
|
rte_panic("Cannot allocate core info\n");
|
||||||
|
|
||||||
ret = rte_eal_init(argc, argv);
|
ret = rte_eal_init(argc, argv);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
rte_panic("Cannot init EAL\n");
|
rte_panic("Cannot init EAL\n");
|
||||||
|
81
examples/vm_power_manager/parse.c
Normal file
81
examples/vm_power_manager/parse.c
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
* Copyright(c) 2010-2014 Intel Corporation.
|
||||||
|
* Copyright(c) 2014 6WIND S.A.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <rte_log.h>
|
||||||
|
#include "parse.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse elem, the elem could be single number/range or group
|
||||||
|
* 1) A single number elem, it's just a simple digit. e.g. 9
|
||||||
|
* 2) A single range elem, two digits with a '-' between. e.g. 2-6
|
||||||
|
* 3) A group elem, combines multiple 1) or 2) e.g 0,2-4,6
|
||||||
|
* Within group, '-' used for a range separator;
|
||||||
|
* ',' used for a single number.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
parse_set(const char *input, uint16_t set[], unsigned int num)
|
||||||
|
{
|
||||||
|
unsigned int idx;
|
||||||
|
const char *str = input;
|
||||||
|
char *end = NULL;
|
||||||
|
unsigned int min, max;
|
||||||
|
|
||||||
|
memset(set, 0, num * sizeof(uint16_t));
|
||||||
|
|
||||||
|
while (isblank(*str))
|
||||||
|
str++;
|
||||||
|
|
||||||
|
/* only digit or left bracket is qualify for start point */
|
||||||
|
if (!isdigit(*str) || *str == '\0')
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
while (isblank(*str))
|
||||||
|
str++;
|
||||||
|
if (*str == '\0')
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
min = num;
|
||||||
|
do {
|
||||||
|
|
||||||
|
/* go ahead to the first digit */
|
||||||
|
while (isblank(*str))
|
||||||
|
str++;
|
||||||
|
if (!isdigit(*str))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* get the digit value */
|
||||||
|
errno = 0;
|
||||||
|
idx = strtoul(str, &end, 10);
|
||||||
|
if (errno || end == NULL || idx >= num)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* go ahead to separator '-' and ',' */
|
||||||
|
while (isblank(*end))
|
||||||
|
end++;
|
||||||
|
if (*end == '-') {
|
||||||
|
if (min == num)
|
||||||
|
min = idx;
|
||||||
|
else /* avoid continuous '-' */
|
||||||
|
return -1;
|
||||||
|
} else if ((*end == ',') || (*end == '\0')) {
|
||||||
|
max = idx;
|
||||||
|
|
||||||
|
if (min == num)
|
||||||
|
min = idx;
|
||||||
|
|
||||||
|
for (idx = RTE_MIN(min, max);
|
||||||
|
idx <= RTE_MAX(min, max); idx++) {
|
||||||
|
set[idx] = 1;
|
||||||
|
}
|
||||||
|
min = num;
|
||||||
|
} else
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
str = end + 1;
|
||||||
|
} while (*end != '\0');
|
||||||
|
|
||||||
|
return str - input;
|
||||||
|
}
|
20
examples/vm_power_manager/parse.h
Normal file
20
examples/vm_power_manager/parse.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
* Copyright(c) 2018 Intel Corporation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PARSE_H_
|
||||||
|
#define PARSE_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
parse_set(const char *, uint16_t [], unsigned int);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* PARSE_H_ */
|
@ -12,6 +12,7 @@
|
|||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <rte_log.h>
|
#include <rte_log.h>
|
||||||
@ -54,6 +55,7 @@ struct freq_info {
|
|||||||
|
|
||||||
static struct freq_info global_core_freq_info[POWER_MGR_MAX_CPUS];
|
static struct freq_info global_core_freq_info[POWER_MGR_MAX_CPUS];
|
||||||
|
|
||||||
|
struct core_info ci;
|
||||||
static uint64_t global_enabled_cpus;
|
static uint64_t global_enabled_cpus;
|
||||||
|
|
||||||
#define SYSFS_CPU_PATH "/sys/devices/system/cpu/cpu%u/topology/core_id"
|
#define SYSFS_CPU_PATH "/sys/devices/system/cpu/cpu%u/topology/core_id"
|
||||||
@ -76,6 +78,35 @@ set_host_cpus_mask(void)
|
|||||||
return num_cpus;
|
return num_cpus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct core_info *
|
||||||
|
get_core_info(void)
|
||||||
|
{
|
||||||
|
return &ci;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
core_info_init(void)
|
||||||
|
{
|
||||||
|
struct core_info *ci;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ci = get_core_info();
|
||||||
|
|
||||||
|
ci->core_count = get_nprocs_conf();
|
||||||
|
ci->cd = malloc(ci->core_count * sizeof(struct core_details));
|
||||||
|
if (!ci->cd) {
|
||||||
|
RTE_LOG(ERR, POWER_MANAGER, "Failed to allocate memory for core info.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for (i = 0; i < ci->core_count; i++) {
|
||||||
|
ci->cd[i].global_enabled_cpus = 1;
|
||||||
|
ci->cd[i].oob_enabled = 0;
|
||||||
|
ci->cd[i].msr_fd = 0;
|
||||||
|
}
|
||||||
|
printf("%d cores in system\n", ci->core_count);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
power_manager_init(void)
|
power_manager_init(void)
|
||||||
{
|
{
|
||||||
|
@ -8,6 +8,26 @@
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
struct core_details {
|
||||||
|
uint64_t last_branches;
|
||||||
|
uint64_t last_branch_misses;
|
||||||
|
uint16_t global_enabled_cpus;
|
||||||
|
uint16_t oob_enabled;
|
||||||
|
int msr_fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct core_info {
|
||||||
|
uint16_t core_count;
|
||||||
|
struct core_details *cd;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct core_info *
|
||||||
|
get_core_info(void);
|
||||||
|
|
||||||
|
int
|
||||||
|
core_info_init(void);
|
||||||
|
|
||||||
|
#define RTE_LOGTYPE_POWER_MANAGER RTE_LOGTYPE_USER1
|
||||||
|
|
||||||
/* Maximum number of CPUS to manage */
|
/* Maximum number of CPUS to manage */
|
||||||
#define POWER_MGR_MAX_CPUS 64
|
#define POWER_MGR_MAX_CPUS 64
|
||||||
|
Loading…
x
Reference in New Issue
Block a user