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> 12f30a1bbdSSivaprasad Tummala #include <rte_power_cpufreq.h> 13*b462f273SDavid Marchand #include <rte_power_guest_channel.h> 14f5e5c334SAlan Carew #include <rte_debug.h> 1559287933SDavid Hunt #include <rte_eal.h> 1659287933SDavid Hunt #include <rte_log.h> 1730a1de10SSean Morrissey #include <rte_string_fns.h> 18f5e5c334SAlan Carew 19f5e5c334SAlan Carew #include "vm_power_cli_guest.h" 2059287933SDavid Hunt #include "parse.h" 21f5e5c334SAlan Carew 22f5e5c334SAlan Carew static void 23f5e5c334SAlan Carew sig_handler(int signo) 24f5e5c334SAlan Carew { 25f5e5c334SAlan Carew printf("Received signal %d, exiting...\n", signo); 26f5e5c334SAlan Carew unsigned lcore_id; 27f5e5c334SAlan Carew 28f5e5c334SAlan Carew RTE_LCORE_FOREACH(lcore_id) { 29f5e5c334SAlan Carew rte_power_exit(lcore_id); 30f5e5c334SAlan Carew } 31f5e5c334SAlan Carew 32f5e5c334SAlan Carew } 33f5e5c334SAlan Carew 3459287933SDavid Hunt #define MAX_HOURS 24 3559287933SDavid Hunt 3659287933SDavid Hunt /* Parse the argument given in the command line of the application */ 3759287933SDavid Hunt static int 3859287933SDavid Hunt parse_args(int argc, char **argv) 3959287933SDavid Hunt { 4059287933SDavid Hunt int opt, ret; 4159287933SDavid Hunt char **argvopt; 4259287933SDavid Hunt int option_index; 4359287933SDavid Hunt char *prgname = argv[0]; 4459287933SDavid Hunt const struct option lgopts[] = { 4559287933SDavid Hunt { "vm-name", required_argument, 0, 'n'}, 4659287933SDavid Hunt { "busy-hours", required_argument, 0, 'b'}, 4759287933SDavid Hunt { "quiet-hours", required_argument, 0, 'q'}, 4859287933SDavid Hunt { "port-list", required_argument, 0, 'p'}, 4959287933SDavid Hunt { "vcpu-list", required_argument, 0, 'l'}, 5059287933SDavid Hunt { "policy", required_argument, 0, 'o'}, 5159287933SDavid Hunt {NULL, 0, 0, 0} 5259287933SDavid Hunt }; 53bd5b6720SBruce Richardson struct rte_power_channel_packet *policy; 5459287933SDavid Hunt unsigned short int hours[MAX_HOURS]; 5538d232b9SBruce Richardson unsigned short int cores[RTE_POWER_MAX_VCPU_PER_VM]; 5638d232b9SBruce Richardson unsigned short int ports[RTE_POWER_MAX_VCPU_PER_VM]; 5759287933SDavid Hunt int i, cnt, idx; 5859287933SDavid Hunt 5959287933SDavid Hunt policy = get_policy(); 6070febdcfSIgor Romanov ret = set_policy_defaults(policy); 6170febdcfSIgor Romanov if (ret != 0) { 6270febdcfSIgor Romanov printf("Failed to set policy defaults\n"); 6370febdcfSIgor Romanov return -1; 6470febdcfSIgor Romanov } 6559287933SDavid Hunt 6659287933SDavid Hunt argvopt = argv; 6759287933SDavid Hunt 6859287933SDavid Hunt while ((opt = getopt_long(argc, argvopt, "n:b:q:p:", 6959287933SDavid Hunt lgopts, &option_index)) != EOF) { 7059287933SDavid Hunt 7159287933SDavid Hunt switch (opt) { 7259287933SDavid Hunt /* portmask */ 7359287933SDavid Hunt case 'n': 7438d232b9SBruce Richardson strlcpy(policy->vm_name, optarg, 7538d232b9SBruce Richardson RTE_POWER_VM_MAX_NAME_SZ); 7659287933SDavid Hunt printf("Setting VM Name to [%s]\n", policy->vm_name); 7759287933SDavid Hunt break; 7859287933SDavid Hunt case 'b': 7959287933SDavid Hunt case 'q': 8059287933SDavid Hunt //printf("***Processing set using [%s]\n", optarg); 8159287933SDavid Hunt cnt = parse_set(optarg, hours, MAX_HOURS); 8259287933SDavid Hunt if (cnt < 0) { 8359287933SDavid Hunt printf("Invalid value passed to quiet/busy hours - [%s]\n", 8459287933SDavid Hunt optarg); 8559287933SDavid Hunt break; 8659287933SDavid Hunt } 8759287933SDavid Hunt idx = 0; 8859287933SDavid Hunt for (i = 0; i < MAX_HOURS; i++) { 8959287933SDavid Hunt if (hours[i]) { 9059287933SDavid Hunt if (opt == 'b') { 9159287933SDavid Hunt printf("***Busy Hour %d\n", i); 9259287933SDavid Hunt policy->timer_policy.busy_hours 9359287933SDavid Hunt [idx++] = i; 9459287933SDavid Hunt } else { 9559287933SDavid Hunt printf("***Quiet Hour %d\n", i); 9659287933SDavid Hunt policy->timer_policy.quiet_hours 9759287933SDavid Hunt [idx++] = i; 9859287933SDavid Hunt } 9959287933SDavid Hunt } 10059287933SDavid Hunt } 10159287933SDavid Hunt break; 10259287933SDavid Hunt case 'l': 10338d232b9SBruce Richardson cnt = parse_set(optarg, cores, 10438d232b9SBruce Richardson RTE_POWER_MAX_VCPU_PER_VM); 10559287933SDavid Hunt if (cnt < 0) { 10659287933SDavid Hunt printf("Invalid value passed to vcpu-list - [%s]\n", 10759287933SDavid Hunt optarg); 10859287933SDavid Hunt break; 10959287933SDavid Hunt } 11059287933SDavid Hunt idx = 0; 11138d232b9SBruce Richardson for (i = 0; i < RTE_POWER_MAX_VCPU_PER_VM; i++) { 11259287933SDavid Hunt if (cores[i]) { 11359287933SDavid Hunt printf("***Using core %d\n", i); 11459287933SDavid Hunt policy->vcpu_to_control[idx++] = i; 11559287933SDavid Hunt } 11659287933SDavid Hunt } 11759287933SDavid Hunt policy->num_vcpu = idx; 11859287933SDavid Hunt printf("Total cores: %d\n", idx); 11959287933SDavid Hunt break; 12059287933SDavid Hunt case 'p': 12138d232b9SBruce Richardson cnt = parse_set(optarg, ports, 12238d232b9SBruce Richardson RTE_POWER_MAX_VCPU_PER_VM); 12359287933SDavid Hunt if (cnt < 0) { 12459287933SDavid Hunt printf("Invalid value passed to port-list - [%s]\n", 12559287933SDavid Hunt optarg); 12659287933SDavid Hunt break; 12759287933SDavid Hunt } 12859287933SDavid Hunt idx = 0; 12938d232b9SBruce Richardson for (i = 0; i < RTE_POWER_MAX_VCPU_PER_VM; i++) { 13059287933SDavid Hunt if (ports[i]) { 13159287933SDavid Hunt printf("***Using port %d\n", i); 13270febdcfSIgor Romanov if (set_policy_mac(i, idx++) != 0) { 13370febdcfSIgor Romanov printf("Cannot set policy MAC"); 13470febdcfSIgor Romanov return -1; 13570febdcfSIgor Romanov } 13659287933SDavid Hunt } 13759287933SDavid Hunt } 13859287933SDavid Hunt policy->nb_mac_to_monitor = idx; 13959287933SDavid Hunt printf("Total Ports: %d\n", idx); 14059287933SDavid Hunt break; 14159287933SDavid Hunt case 'o': 14259287933SDavid Hunt if (!strcmp(optarg, "TRAFFIC")) 14338d232b9SBruce Richardson policy->policy_to_use = 14438d232b9SBruce Richardson RTE_POWER_POLICY_TRAFFIC; 14559287933SDavid Hunt else if (!strcmp(optarg, "TIME")) 14638d232b9SBruce Richardson policy->policy_to_use = 14738d232b9SBruce Richardson RTE_POWER_POLICY_TIME; 14859287933SDavid Hunt else if (!strcmp(optarg, "WORKLOAD")) 14938d232b9SBruce Richardson policy->policy_to_use = 15038d232b9SBruce Richardson RTE_POWER_POLICY_WORKLOAD; 15159287933SDavid Hunt else if (!strcmp(optarg, "BRANCH_RATIO")) 15238d232b9SBruce Richardson policy->policy_to_use = 15338d232b9SBruce Richardson RTE_POWER_POLICY_BRANCH_RATIO; 15459287933SDavid Hunt else { 15559287933SDavid Hunt printf("Invalid policy specified: %s\n", 15659287933SDavid Hunt optarg); 15759287933SDavid Hunt return -1; 15859287933SDavid Hunt } 15959287933SDavid Hunt break; 16059287933SDavid Hunt /* long options */ 16159287933SDavid Hunt 16259287933SDavid Hunt case 0: 16359287933SDavid Hunt break; 16459287933SDavid Hunt 16559287933SDavid Hunt default: 16659287933SDavid Hunt return -1; 16759287933SDavid Hunt } 16859287933SDavid Hunt } 16959287933SDavid Hunt 17059287933SDavid Hunt if (optind >= 0) 17159287933SDavid Hunt argv[optind-1] = prgname; 17259287933SDavid Hunt 17359287933SDavid Hunt ret = optind-1; 17459287933SDavid Hunt optind = 0; /* reset getopt lib */ 17559287933SDavid Hunt return ret; 17659287933SDavid Hunt } 17759287933SDavid Hunt 178f5e5c334SAlan Carew int 17998a16481SDavid Marchand main(int argc, char **argv) 180f5e5c334SAlan Carew { 181f5e5c334SAlan Carew int ret; 182f5e5c334SAlan Carew unsigned lcore_id; 183f5e5c334SAlan Carew 184f5e5c334SAlan Carew ret = rte_eal_init(argc, argv); 185f5e5c334SAlan Carew if (ret < 0) 186f5e5c334SAlan Carew rte_panic("Cannot init EAL\n"); 187f5e5c334SAlan Carew 188f5e5c334SAlan Carew signal(SIGINT, sig_handler); 189f5e5c334SAlan Carew signal(SIGTERM, sig_handler); 190f5e5c334SAlan Carew 19159287933SDavid Hunt argc -= ret; 19259287933SDavid Hunt argv += ret; 19359287933SDavid Hunt 19459287933SDavid Hunt /* parse application arguments (after the EAL ones) */ 19559287933SDavid Hunt ret = parse_args(argc, argv); 19659287933SDavid Hunt if (ret < 0) 19759287933SDavid Hunt rte_exit(EXIT_FAILURE, "Invalid arguments\n"); 19859287933SDavid Hunt 199f5e5c334SAlan Carew rte_power_set_env(PM_ENV_KVM_VM); 200f5e5c334SAlan Carew RTE_LCORE_FOREACH(lcore_id) { 201f5e5c334SAlan Carew rte_power_init(lcore_id); 202f5e5c334SAlan Carew } 203f5e5c334SAlan Carew run_cli(NULL); 204f5e5c334SAlan Carew 20510aa3757SChengchang Tang /* clean up the EAL */ 20610aa3757SChengchang Tang rte_eal_cleanup(); 20710aa3757SChengchang Tang 208f5e5c334SAlan Carew return 0; 209f5e5c334SAlan Carew } 210