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