Add new command line arguments to the guest app to make testing and validation of the policy usage easier. These arguments are mainly around setting up the power management policy that is sent from the guest vm to to the vm_power_manager in the host New command line parameters: -n or --vm-name sets the name of the vm to be used by the host OS. -b or --busy-hours sets the list of hours that are predicted to be busy -q or --quiet-hours sets the list of hours that are predicted to be quiet -l or --vcpu-list sets the list of vcpus to monitor -p or --port-list sets the list of posts to monitor when using a workload policy. -o or --policy sets the default policy type TIME WORKLOAD TRAFFIC BRANCH_RATIO The format of the hours or list paramers is a comma-separated list of integers, which can take the form of a. x e.g. --vcpu-list=1 b. x,y e.g. --quiet-hours=3,4 c. x-y e.g. --busy-hours=9-12 d. combination of above (e.g. --busy-hours=4,5-7,9) Signed-off-by: David Hunt <david.hunt@intel.com> Acked-by: Radu Nicolau <radu.nicolau@intel.com>
191 lines
4.0 KiB
C
191 lines
4.0 KiB
C
/* SPDX-License-Identifier: BSD-3-Clause
|
|
* Copyright(c) 2010-2014 Intel Corporation
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <signal.h>
|
|
#include <getopt.h>
|
|
#include <string.h>
|
|
|
|
#include <rte_lcore.h>
|
|
#include <rte_power.h>
|
|
#include <rte_debug.h>
|
|
#include <rte_eal.h>
|
|
#include <rte_log.h>
|
|
|
|
#include "vm_power_cli_guest.h"
|
|
#include "parse.h"
|
|
|
|
static void
|
|
sig_handler(int signo)
|
|
{
|
|
printf("Received signal %d, exiting...\n", signo);
|
|
unsigned lcore_id;
|
|
|
|
RTE_LCORE_FOREACH(lcore_id) {
|
|
rte_power_exit(lcore_id);
|
|
}
|
|
|
|
}
|
|
|
|
#define MAX_HOURS 24
|
|
|
|
/* Parse the argument given in the command line of the application */
|
|
static int
|
|
parse_args(int argc, char **argv)
|
|
{
|
|
int opt, ret;
|
|
char **argvopt;
|
|
int option_index;
|
|
char *prgname = argv[0];
|
|
const struct option lgopts[] = {
|
|
{ "vm-name", required_argument, 0, 'n'},
|
|
{ "busy-hours", required_argument, 0, 'b'},
|
|
{ "quiet-hours", required_argument, 0, 'q'},
|
|
{ "port-list", required_argument, 0, 'p'},
|
|
{ "vcpu-list", required_argument, 0, 'l'},
|
|
{ "policy", required_argument, 0, 'o'},
|
|
{NULL, 0, 0, 0}
|
|
};
|
|
struct channel_packet *policy;
|
|
unsigned short int hours[MAX_HOURS];
|
|
unsigned short int cores[MAX_VCPU_PER_VM];
|
|
unsigned short int ports[MAX_VCPU_PER_VM];
|
|
int i, cnt, idx;
|
|
|
|
policy = get_policy();
|
|
set_policy_defaults(policy);
|
|
|
|
argvopt = argv;
|
|
|
|
while ((opt = getopt_long(argc, argvopt, "n:b:q:p:",
|
|
lgopts, &option_index)) != EOF) {
|
|
|
|
switch (opt) {
|
|
/* portmask */
|
|
case 'n':
|
|
strcpy(policy->vm_name, optarg);
|
|
printf("Setting VM Name to [%s]\n", policy->vm_name);
|
|
break;
|
|
case 'b':
|
|
case 'q':
|
|
//printf("***Processing set using [%s]\n", optarg);
|
|
cnt = parse_set(optarg, hours, MAX_HOURS);
|
|
if (cnt < 0) {
|
|
printf("Invalid value passed to quiet/busy hours - [%s]\n",
|
|
optarg);
|
|
break;
|
|
}
|
|
idx = 0;
|
|
for (i = 0; i < MAX_HOURS; i++) {
|
|
if (hours[i]) {
|
|
if (opt == 'b') {
|
|
printf("***Busy Hour %d\n", i);
|
|
policy->timer_policy.busy_hours
|
|
[idx++] = i;
|
|
} else {
|
|
printf("***Quiet Hour %d\n", i);
|
|
policy->timer_policy.quiet_hours
|
|
[idx++] = i;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 'l':
|
|
cnt = parse_set(optarg, cores, MAX_VCPU_PER_VM);
|
|
if (cnt < 0) {
|
|
printf("Invalid value passed to vcpu-list - [%s]\n",
|
|
optarg);
|
|
break;
|
|
}
|
|
idx = 0;
|
|
for (i = 0; i < MAX_VCPU_PER_VM; i++) {
|
|
if (cores[i]) {
|
|
printf("***Using core %d\n", i);
|
|
policy->vcpu_to_control[idx++] = i;
|
|
}
|
|
}
|
|
policy->num_vcpu = idx;
|
|
printf("Total cores: %d\n", idx);
|
|
break;
|
|
case 'p':
|
|
cnt = parse_set(optarg, ports, MAX_VCPU_PER_VM);
|
|
if (cnt < 0) {
|
|
printf("Invalid value passed to port-list - [%s]\n",
|
|
optarg);
|
|
break;
|
|
}
|
|
idx = 0;
|
|
for (i = 0; i < MAX_VCPU_PER_VM; i++) {
|
|
if (ports[i]) {
|
|
printf("***Using port %d\n", i);
|
|
set_policy_mac(i, idx++);
|
|
}
|
|
}
|
|
policy->nb_mac_to_monitor = idx;
|
|
printf("Total Ports: %d\n", idx);
|
|
break;
|
|
case 'o':
|
|
if (!strcmp(optarg, "TRAFFIC"))
|
|
policy->policy_to_use = TRAFFIC;
|
|
else if (!strcmp(optarg, "TIME"))
|
|
policy->policy_to_use = TIME;
|
|
else if (!strcmp(optarg, "WORKLOAD"))
|
|
policy->policy_to_use = WORKLOAD;
|
|
else if (!strcmp(optarg, "BRANCH_RATIO"))
|
|
policy->policy_to_use = BRANCH_RATIO;
|
|
else {
|
|
printf("Invalid policy specified: %s\n",
|
|
optarg);
|
|
return -1;
|
|
}
|
|
break;
|
|
/* long options */
|
|
|
|
case 0:
|
|
break;
|
|
|
|
default:
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if (optind >= 0)
|
|
argv[optind-1] = prgname;
|
|
|
|
ret = optind-1;
|
|
optind = 0; /* reset getopt lib */
|
|
return ret;
|
|
}
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
int ret;
|
|
unsigned lcore_id;
|
|
|
|
ret = rte_eal_init(argc, argv);
|
|
if (ret < 0)
|
|
rte_panic("Cannot init EAL\n");
|
|
|
|
signal(SIGINT, sig_handler);
|
|
signal(SIGTERM, sig_handler);
|
|
|
|
argc -= ret;
|
|
argv += ret;
|
|
|
|
/* parse application arguments (after the EAL ones) */
|
|
ret = parse_args(argc, argv);
|
|
if (ret < 0)
|
|
rte_exit(EXIT_FAILURE, "Invalid arguments\n");
|
|
|
|
rte_power_set_env(PM_ENV_KVM_VM);
|
|
RTE_LCORE_FOREACH(lcore_id) {
|
|
rte_power_init(lcore_id);
|
|
}
|
|
run_cli(NULL);
|
|
|
|
return 0;
|
|
}
|