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
sig_handler(int signo)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
parse_args(int argc,char ** argv)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
main(int argc,char ** argv)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