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