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