1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <signal.h> 8 #include <getopt.h> 9 #include <string.h> 10 11 #include <rte_lcore.h> 12 #include <rte_power_cpufreq.h> 13 #include <rte_power_guest_channel.h> 14 #include <rte_debug.h> 15 #include <rte_eal.h> 16 #include <rte_log.h> 17 #include <rte_string_fns.h> 18 19 #include "vm_power_cli_guest.h" 20 #include "parse.h" 21 22 static void 23 sig_handler(int signo) 24 { 25 printf("Received signal %d, exiting...\n", signo); 26 unsigned lcore_id; 27 28 RTE_LCORE_FOREACH(lcore_id) { 29 rte_power_exit(lcore_id); 30 } 31 32 } 33 34 #define MAX_HOURS 24 35 36 /* Parse the argument given in the command line of the application */ 37 static int 38 parse_args(int argc, char **argv) 39 { 40 int opt, ret; 41 char **argvopt; 42 int option_index; 43 char *prgname = argv[0]; 44 const struct option lgopts[] = { 45 { "vm-name", required_argument, 0, 'n'}, 46 { "busy-hours", required_argument, 0, 'b'}, 47 { "quiet-hours", required_argument, 0, 'q'}, 48 { "port-list", required_argument, 0, 'p'}, 49 { "vcpu-list", required_argument, 0, 'l'}, 50 { "policy", required_argument, 0, 'o'}, 51 {NULL, 0, 0, 0} 52 }; 53 struct rte_power_channel_packet *policy; 54 unsigned short int hours[MAX_HOURS]; 55 unsigned short int cores[RTE_POWER_MAX_VCPU_PER_VM]; 56 unsigned short int ports[RTE_POWER_MAX_VCPU_PER_VM]; 57 int i, cnt, idx; 58 59 policy = get_policy(); 60 ret = set_policy_defaults(policy); 61 if (ret != 0) { 62 printf("Failed to set policy defaults\n"); 63 return -1; 64 } 65 66 argvopt = argv; 67 68 while ((opt = getopt_long(argc, argvopt, "n:b:q:p:", 69 lgopts, &option_index)) != EOF) { 70 71 switch (opt) { 72 /* portmask */ 73 case 'n': 74 strlcpy(policy->vm_name, optarg, 75 RTE_POWER_VM_MAX_NAME_SZ); 76 printf("Setting VM Name to [%s]\n", policy->vm_name); 77 break; 78 case 'b': 79 case 'q': 80 //printf("***Processing set using [%s]\n", optarg); 81 cnt = parse_set(optarg, hours, MAX_HOURS); 82 if (cnt < 0) { 83 printf("Invalid value passed to quiet/busy hours - [%s]\n", 84 optarg); 85 break; 86 } 87 idx = 0; 88 for (i = 0; i < MAX_HOURS; i++) { 89 if (hours[i]) { 90 if (opt == 'b') { 91 printf("***Busy Hour %d\n", i); 92 policy->timer_policy.busy_hours 93 [idx++] = i; 94 } else { 95 printf("***Quiet Hour %d\n", i); 96 policy->timer_policy.quiet_hours 97 [idx++] = i; 98 } 99 } 100 } 101 break; 102 case 'l': 103 cnt = parse_set(optarg, cores, 104 RTE_POWER_MAX_VCPU_PER_VM); 105 if (cnt < 0) { 106 printf("Invalid value passed to vcpu-list - [%s]\n", 107 optarg); 108 break; 109 } 110 idx = 0; 111 for (i = 0; i < RTE_POWER_MAX_VCPU_PER_VM; i++) { 112 if (cores[i]) { 113 printf("***Using core %d\n", i); 114 policy->vcpu_to_control[idx++] = i; 115 } 116 } 117 policy->num_vcpu = idx; 118 printf("Total cores: %d\n", idx); 119 break; 120 case 'p': 121 cnt = parse_set(optarg, ports, 122 RTE_POWER_MAX_VCPU_PER_VM); 123 if (cnt < 0) { 124 printf("Invalid value passed to port-list - [%s]\n", 125 optarg); 126 break; 127 } 128 idx = 0; 129 for (i = 0; i < RTE_POWER_MAX_VCPU_PER_VM; i++) { 130 if (ports[i]) { 131 printf("***Using port %d\n", i); 132 if (set_policy_mac(i, idx++) != 0) { 133 printf("Cannot set policy MAC"); 134 return -1; 135 } 136 } 137 } 138 policy->nb_mac_to_monitor = idx; 139 printf("Total Ports: %d\n", idx); 140 break; 141 case 'o': 142 if (!strcmp(optarg, "TRAFFIC")) 143 policy->policy_to_use = 144 RTE_POWER_POLICY_TRAFFIC; 145 else if (!strcmp(optarg, "TIME")) 146 policy->policy_to_use = 147 RTE_POWER_POLICY_TIME; 148 else if (!strcmp(optarg, "WORKLOAD")) 149 policy->policy_to_use = 150 RTE_POWER_POLICY_WORKLOAD; 151 else if (!strcmp(optarg, "BRANCH_RATIO")) 152 policy->policy_to_use = 153 RTE_POWER_POLICY_BRANCH_RATIO; 154 else { 155 printf("Invalid policy specified: %s\n", 156 optarg); 157 return -1; 158 } 159 break; 160 /* long options */ 161 162 case 0: 163 break; 164 165 default: 166 return -1; 167 } 168 } 169 170 if (optind >= 0) 171 argv[optind-1] = prgname; 172 173 ret = optind-1; 174 optind = 0; /* reset getopt lib */ 175 return ret; 176 } 177 178 int 179 main(int argc, char **argv) 180 { 181 int ret; 182 unsigned lcore_id; 183 184 ret = rte_eal_init(argc, argv); 185 if (ret < 0) 186 rte_panic("Cannot init EAL\n"); 187 188 signal(SIGINT, sig_handler); 189 signal(SIGTERM, sig_handler); 190 191 argc -= ret; 192 argv += ret; 193 194 /* parse application arguments (after the EAL ones) */ 195 ret = parse_args(argc, argv); 196 if (ret < 0) 197 rte_exit(EXIT_FAILURE, "Invalid arguments\n"); 198 199 rte_power_set_env(PM_ENV_KVM_VM); 200 RTE_LCORE_FOREACH(lcore_id) { 201 rte_power_init(lcore_id); 202 } 203 run_cli(NULL); 204 205 /* clean up the EAL */ 206 rte_eal_cleanup(); 207 208 return 0; 209 } 210