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