xref: /dpdk/examples/vm_power_manager/guest_cli/main.c (revision daa02b5cddbb8e11b31d41e2bf7bb1ae64dcae2f)
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