13998e2a0SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 23998e2a0SBruce Richardson * Copyright(c) 2010-2014 Intel Corporation 3f5e5c334SAlan Carew */ 4f5e5c334SAlan Carew 5f5e5c334SAlan Carew #include <stdio.h> 6f5e5c334SAlan Carew #include <stdlib.h> 7f5e5c334SAlan Carew #include <signal.h> 859287933SDavid Hunt #include <getopt.h> 959287933SDavid Hunt #include <string.h> 10f5e5c334SAlan Carew 11f5e5c334SAlan Carew #include <rte_lcore.h> 12f5e5c334SAlan Carew #include <rte_power.h> 13f5e5c334SAlan Carew #include <rte_debug.h> 1459287933SDavid Hunt #include <rte_eal.h> 1559287933SDavid Hunt #include <rte_log.h> 16*30a1de10SSean Morrissey #include <rte_string_fns.h> 17f5e5c334SAlan Carew 18f5e5c334SAlan Carew #include "vm_power_cli_guest.h" 1959287933SDavid Hunt #include "parse.h" 20f5e5c334SAlan Carew 21f5e5c334SAlan Carew static void 22f5e5c334SAlan Carew sig_handler(int signo) 23f5e5c334SAlan Carew { 24f5e5c334SAlan Carew printf("Received signal %d, exiting...\n", signo); 25f5e5c334SAlan Carew unsigned lcore_id; 26f5e5c334SAlan Carew 27f5e5c334SAlan Carew RTE_LCORE_FOREACH(lcore_id) { 28f5e5c334SAlan Carew rte_power_exit(lcore_id); 29f5e5c334SAlan Carew } 30f5e5c334SAlan Carew 31f5e5c334SAlan Carew } 32f5e5c334SAlan Carew 3359287933SDavid Hunt #define MAX_HOURS 24 3459287933SDavid Hunt 3559287933SDavid Hunt /* Parse the argument given in the command line of the application */ 3659287933SDavid Hunt static int 3759287933SDavid Hunt parse_args(int argc, char **argv) 3859287933SDavid Hunt { 3959287933SDavid Hunt int opt, ret; 4059287933SDavid Hunt char **argvopt; 4159287933SDavid Hunt int option_index; 4259287933SDavid Hunt char *prgname = argv[0]; 4359287933SDavid Hunt const struct option lgopts[] = { 4459287933SDavid Hunt { "vm-name", required_argument, 0, 'n'}, 4559287933SDavid Hunt { "busy-hours", required_argument, 0, 'b'}, 4659287933SDavid Hunt { "quiet-hours", required_argument, 0, 'q'}, 4759287933SDavid Hunt { "port-list", required_argument, 0, 'p'}, 4859287933SDavid Hunt { "vcpu-list", required_argument, 0, 'l'}, 4959287933SDavid Hunt { "policy", required_argument, 0, 'o'}, 5059287933SDavid Hunt {NULL, 0, 0, 0} 5159287933SDavid Hunt }; 52bd5b6720SBruce Richardson struct rte_power_channel_packet *policy; 5359287933SDavid Hunt unsigned short int hours[MAX_HOURS]; 5438d232b9SBruce Richardson unsigned short int cores[RTE_POWER_MAX_VCPU_PER_VM]; 5538d232b9SBruce Richardson unsigned short int ports[RTE_POWER_MAX_VCPU_PER_VM]; 5659287933SDavid Hunt int i, cnt, idx; 5759287933SDavid Hunt 5859287933SDavid Hunt policy = get_policy(); 5970febdcfSIgor Romanov ret = set_policy_defaults(policy); 6070febdcfSIgor Romanov if (ret != 0) { 6170febdcfSIgor Romanov printf("Failed to set policy defaults\n"); 6270febdcfSIgor Romanov return -1; 6370febdcfSIgor Romanov } 6459287933SDavid Hunt 6559287933SDavid Hunt argvopt = argv; 6659287933SDavid Hunt 6759287933SDavid Hunt while ((opt = getopt_long(argc, argvopt, "n:b:q:p:", 6859287933SDavid Hunt lgopts, &option_index)) != EOF) { 6959287933SDavid Hunt 7059287933SDavid Hunt switch (opt) { 7159287933SDavid Hunt /* portmask */ 7259287933SDavid Hunt case 'n': 7338d232b9SBruce Richardson strlcpy(policy->vm_name, optarg, 7438d232b9SBruce Richardson RTE_POWER_VM_MAX_NAME_SZ); 7559287933SDavid Hunt printf("Setting VM Name to [%s]\n", policy->vm_name); 7659287933SDavid Hunt break; 7759287933SDavid Hunt case 'b': 7859287933SDavid Hunt case 'q': 7959287933SDavid Hunt //printf("***Processing set using [%s]\n", optarg); 8059287933SDavid Hunt cnt = parse_set(optarg, hours, MAX_HOURS); 8159287933SDavid Hunt if (cnt < 0) { 8259287933SDavid Hunt printf("Invalid value passed to quiet/busy hours - [%s]\n", 8359287933SDavid Hunt optarg); 8459287933SDavid Hunt break; 8559287933SDavid Hunt } 8659287933SDavid Hunt idx = 0; 8759287933SDavid Hunt for (i = 0; i < MAX_HOURS; i++) { 8859287933SDavid Hunt if (hours[i]) { 8959287933SDavid Hunt if (opt == 'b') { 9059287933SDavid Hunt printf("***Busy Hour %d\n", i); 9159287933SDavid Hunt policy->timer_policy.busy_hours 9259287933SDavid Hunt [idx++] = i; 9359287933SDavid Hunt } else { 9459287933SDavid Hunt printf("***Quiet Hour %d\n", i); 9559287933SDavid Hunt policy->timer_policy.quiet_hours 9659287933SDavid Hunt [idx++] = i; 9759287933SDavid Hunt } 9859287933SDavid Hunt } 9959287933SDavid Hunt } 10059287933SDavid Hunt break; 10159287933SDavid Hunt case 'l': 10238d232b9SBruce Richardson cnt = parse_set(optarg, cores, 10338d232b9SBruce Richardson RTE_POWER_MAX_VCPU_PER_VM); 10459287933SDavid Hunt if (cnt < 0) { 10559287933SDavid Hunt printf("Invalid value passed to vcpu-list - [%s]\n", 10659287933SDavid Hunt optarg); 10759287933SDavid Hunt break; 10859287933SDavid Hunt } 10959287933SDavid Hunt idx = 0; 11038d232b9SBruce Richardson for (i = 0; i < RTE_POWER_MAX_VCPU_PER_VM; i++) { 11159287933SDavid Hunt if (cores[i]) { 11259287933SDavid Hunt printf("***Using core %d\n", i); 11359287933SDavid Hunt policy->vcpu_to_control[idx++] = i; 11459287933SDavid Hunt } 11559287933SDavid Hunt } 11659287933SDavid Hunt policy->num_vcpu = idx; 11759287933SDavid Hunt printf("Total cores: %d\n", idx); 11859287933SDavid Hunt break; 11959287933SDavid Hunt case 'p': 12038d232b9SBruce Richardson cnt = parse_set(optarg, ports, 12138d232b9SBruce Richardson RTE_POWER_MAX_VCPU_PER_VM); 12259287933SDavid Hunt if (cnt < 0) { 12359287933SDavid Hunt printf("Invalid value passed to port-list - [%s]\n", 12459287933SDavid Hunt optarg); 12559287933SDavid Hunt break; 12659287933SDavid Hunt } 12759287933SDavid Hunt idx = 0; 12838d232b9SBruce Richardson for (i = 0; i < RTE_POWER_MAX_VCPU_PER_VM; i++) { 12959287933SDavid Hunt if (ports[i]) { 13059287933SDavid Hunt printf("***Using port %d\n", i); 13170febdcfSIgor Romanov if (set_policy_mac(i, idx++) != 0) { 13270febdcfSIgor Romanov printf("Cannot set policy MAC"); 13370febdcfSIgor Romanov return -1; 13470febdcfSIgor Romanov } 13559287933SDavid Hunt } 13659287933SDavid Hunt } 13759287933SDavid Hunt policy->nb_mac_to_monitor = idx; 13859287933SDavid Hunt printf("Total Ports: %d\n", idx); 13959287933SDavid Hunt break; 14059287933SDavid Hunt case 'o': 14159287933SDavid Hunt if (!strcmp(optarg, "TRAFFIC")) 14238d232b9SBruce Richardson policy->policy_to_use = 14338d232b9SBruce Richardson RTE_POWER_POLICY_TRAFFIC; 14459287933SDavid Hunt else if (!strcmp(optarg, "TIME")) 14538d232b9SBruce Richardson policy->policy_to_use = 14638d232b9SBruce Richardson RTE_POWER_POLICY_TIME; 14759287933SDavid Hunt else if (!strcmp(optarg, "WORKLOAD")) 14838d232b9SBruce Richardson policy->policy_to_use = 14938d232b9SBruce Richardson RTE_POWER_POLICY_WORKLOAD; 15059287933SDavid Hunt else if (!strcmp(optarg, "BRANCH_RATIO")) 15138d232b9SBruce Richardson policy->policy_to_use = 15238d232b9SBruce Richardson RTE_POWER_POLICY_BRANCH_RATIO; 15359287933SDavid Hunt else { 15459287933SDavid Hunt printf("Invalid policy specified: %s\n", 15559287933SDavid Hunt optarg); 15659287933SDavid Hunt return -1; 15759287933SDavid Hunt } 15859287933SDavid Hunt break; 15959287933SDavid Hunt /* long options */ 16059287933SDavid Hunt 16159287933SDavid Hunt case 0: 16259287933SDavid Hunt break; 16359287933SDavid Hunt 16459287933SDavid Hunt default: 16559287933SDavid Hunt return -1; 16659287933SDavid Hunt } 16759287933SDavid Hunt } 16859287933SDavid Hunt 16959287933SDavid Hunt if (optind >= 0) 17059287933SDavid Hunt argv[optind-1] = prgname; 17159287933SDavid Hunt 17259287933SDavid Hunt ret = optind-1; 17359287933SDavid Hunt optind = 0; /* reset getopt lib */ 17459287933SDavid Hunt return ret; 17559287933SDavid Hunt } 17659287933SDavid Hunt 177f5e5c334SAlan Carew int 17898a16481SDavid Marchand main(int argc, char **argv) 179f5e5c334SAlan Carew { 180f5e5c334SAlan Carew int ret; 181f5e5c334SAlan Carew unsigned lcore_id; 182f5e5c334SAlan Carew 183f5e5c334SAlan Carew ret = rte_eal_init(argc, argv); 184f5e5c334SAlan Carew if (ret < 0) 185f5e5c334SAlan Carew rte_panic("Cannot init EAL\n"); 186f5e5c334SAlan Carew 187f5e5c334SAlan Carew signal(SIGINT, sig_handler); 188f5e5c334SAlan Carew signal(SIGTERM, sig_handler); 189f5e5c334SAlan Carew 19059287933SDavid Hunt argc -= ret; 19159287933SDavid Hunt argv += ret; 19259287933SDavid Hunt 19359287933SDavid Hunt /* parse application arguments (after the EAL ones) */ 19459287933SDavid Hunt ret = parse_args(argc, argv); 19559287933SDavid Hunt if (ret < 0) 19659287933SDavid Hunt rte_exit(EXIT_FAILURE, "Invalid arguments\n"); 19759287933SDavid Hunt 198f5e5c334SAlan Carew rte_power_set_env(PM_ENV_KVM_VM); 199f5e5c334SAlan Carew RTE_LCORE_FOREACH(lcore_id) { 200f5e5c334SAlan Carew rte_power_init(lcore_id); 201f5e5c334SAlan Carew } 202f5e5c334SAlan Carew run_cli(NULL); 203f5e5c334SAlan Carew 20410aa3757SChengchang Tang /* clean up the EAL */ 20510aa3757SChengchang Tang rte_eal_cleanup(); 20610aa3757SChengchang Tang 207f5e5c334SAlan Carew return 0; 208f5e5c334SAlan Carew } 209