xref: /dpdk/examples/vm_power_manager/guest_cli/main.c (revision b462f2737eb08b07b84da4204fbd1c9b9ba00b2d)
13998e2a0SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
23998e2a0SBruce Richardson  * Copyright(c) 2010-2014 Intel Corporation
3f5e5c334SAlan Carew  */
4f5e5c334SAlan Carew 
5f5e5c334SAlan Carew #include <stdio.h>
6f5e5c334SAlan Carew #include <stdlib.h>
7f5e5c334SAlan Carew #include <signal.h>
859287933SDavid Hunt #include <getopt.h>
959287933SDavid Hunt #include <string.h>
10f5e5c334SAlan Carew 
11f5e5c334SAlan Carew #include <rte_lcore.h>
12f30a1bbdSSivaprasad Tummala #include <rte_power_cpufreq.h>
13*b462f273SDavid Marchand #include <rte_power_guest_channel.h>
14f5e5c334SAlan Carew #include <rte_debug.h>
1559287933SDavid Hunt #include <rte_eal.h>
1659287933SDavid Hunt #include <rte_log.h>
1730a1de10SSean Morrissey #include <rte_string_fns.h>
18f5e5c334SAlan Carew 
19f5e5c334SAlan Carew #include "vm_power_cli_guest.h"
2059287933SDavid Hunt #include "parse.h"
21f5e5c334SAlan Carew 
22f5e5c334SAlan Carew static void
23f5e5c334SAlan Carew sig_handler(int signo)
24f5e5c334SAlan Carew {
25f5e5c334SAlan Carew 	printf("Received signal %d, exiting...\n", signo);
26f5e5c334SAlan Carew 	unsigned lcore_id;
27f5e5c334SAlan Carew 
28f5e5c334SAlan Carew 	RTE_LCORE_FOREACH(lcore_id) {
29f5e5c334SAlan Carew 		rte_power_exit(lcore_id);
30f5e5c334SAlan Carew 	}
31f5e5c334SAlan Carew 
32f5e5c334SAlan Carew }
33f5e5c334SAlan Carew 
3459287933SDavid Hunt #define MAX_HOURS 24
3559287933SDavid Hunt 
3659287933SDavid Hunt /* Parse the argument given in the command line of the application */
3759287933SDavid Hunt static int
3859287933SDavid Hunt parse_args(int argc, char **argv)
3959287933SDavid Hunt {
4059287933SDavid Hunt 	int opt, ret;
4159287933SDavid Hunt 	char **argvopt;
4259287933SDavid Hunt 	int option_index;
4359287933SDavid Hunt 	char *prgname = argv[0];
4459287933SDavid Hunt 	const struct option lgopts[] = {
4559287933SDavid Hunt 		{ "vm-name", required_argument, 0, 'n'},
4659287933SDavid Hunt 		{ "busy-hours", required_argument, 0, 'b'},
4759287933SDavid Hunt 		{ "quiet-hours", required_argument, 0, 'q'},
4859287933SDavid Hunt 		{ "port-list", required_argument, 0, 'p'},
4959287933SDavid Hunt 		{ "vcpu-list", required_argument, 0, 'l'},
5059287933SDavid Hunt 		{ "policy", required_argument, 0, 'o'},
5159287933SDavid Hunt 		{NULL, 0, 0, 0}
5259287933SDavid Hunt 	};
53bd5b6720SBruce Richardson 	struct rte_power_channel_packet *policy;
5459287933SDavid Hunt 	unsigned short int hours[MAX_HOURS];
5538d232b9SBruce Richardson 	unsigned short int cores[RTE_POWER_MAX_VCPU_PER_VM];
5638d232b9SBruce Richardson 	unsigned short int ports[RTE_POWER_MAX_VCPU_PER_VM];
5759287933SDavid Hunt 	int i, cnt, idx;
5859287933SDavid Hunt 
5959287933SDavid Hunt 	policy = get_policy();
6070febdcfSIgor Romanov 	ret = set_policy_defaults(policy);
6170febdcfSIgor Romanov 	if (ret != 0) {
6270febdcfSIgor Romanov 		printf("Failed to set policy defaults\n");
6370febdcfSIgor Romanov 		return -1;
6470febdcfSIgor Romanov 	}
6559287933SDavid Hunt 
6659287933SDavid Hunt 	argvopt = argv;
6759287933SDavid Hunt 
6859287933SDavid Hunt 	while ((opt = getopt_long(argc, argvopt, "n:b:q:p:",
6959287933SDavid Hunt 				  lgopts, &option_index)) != EOF) {
7059287933SDavid Hunt 
7159287933SDavid Hunt 		switch (opt) {
7259287933SDavid Hunt 		/* portmask */
7359287933SDavid Hunt 		case 'n':
7438d232b9SBruce Richardson 			strlcpy(policy->vm_name, optarg,
7538d232b9SBruce Richardson 					RTE_POWER_VM_MAX_NAME_SZ);
7659287933SDavid Hunt 			printf("Setting VM Name to [%s]\n", policy->vm_name);
7759287933SDavid Hunt 			break;
7859287933SDavid Hunt 		case 'b':
7959287933SDavid Hunt 		case 'q':
8059287933SDavid Hunt 			//printf("***Processing set using [%s]\n", optarg);
8159287933SDavid Hunt 			cnt = parse_set(optarg, hours, MAX_HOURS);
8259287933SDavid Hunt 			if (cnt < 0) {
8359287933SDavid Hunt 				printf("Invalid value passed to quiet/busy hours - [%s]\n",
8459287933SDavid Hunt 						optarg);
8559287933SDavid Hunt 				break;
8659287933SDavid Hunt 			}
8759287933SDavid Hunt 			idx = 0;
8859287933SDavid Hunt 			for (i = 0; i < MAX_HOURS; i++) {
8959287933SDavid Hunt 				if (hours[i]) {
9059287933SDavid Hunt 					if (opt == 'b') {
9159287933SDavid Hunt 						printf("***Busy Hour %d\n", i);
9259287933SDavid Hunt 						policy->timer_policy.busy_hours
9359287933SDavid Hunt 							[idx++] = i;
9459287933SDavid Hunt 					} else {
9559287933SDavid Hunt 						printf("***Quiet Hour %d\n", i);
9659287933SDavid Hunt 						policy->timer_policy.quiet_hours
9759287933SDavid Hunt 							[idx++] = i;
9859287933SDavid Hunt 					}
9959287933SDavid Hunt 				}
10059287933SDavid Hunt 			}
10159287933SDavid Hunt 			break;
10259287933SDavid Hunt 		case 'l':
10338d232b9SBruce Richardson 			cnt = parse_set(optarg, cores,
10438d232b9SBruce Richardson 					RTE_POWER_MAX_VCPU_PER_VM);
10559287933SDavid Hunt 			if (cnt < 0) {
10659287933SDavid Hunt 				printf("Invalid value passed to vcpu-list - [%s]\n",
10759287933SDavid Hunt 						optarg);
10859287933SDavid Hunt 				break;
10959287933SDavid Hunt 			}
11059287933SDavid Hunt 			idx = 0;
11138d232b9SBruce Richardson 			for (i = 0; i < RTE_POWER_MAX_VCPU_PER_VM; i++) {
11259287933SDavid Hunt 				if (cores[i]) {
11359287933SDavid Hunt 					printf("***Using core %d\n", i);
11459287933SDavid Hunt 					policy->vcpu_to_control[idx++] = i;
11559287933SDavid Hunt 				}
11659287933SDavid Hunt 			}
11759287933SDavid Hunt 			policy->num_vcpu = idx;
11859287933SDavid Hunt 			printf("Total cores: %d\n", idx);
11959287933SDavid Hunt 			break;
12059287933SDavid Hunt 		case 'p':
12138d232b9SBruce Richardson 			cnt = parse_set(optarg, ports,
12238d232b9SBruce Richardson 					RTE_POWER_MAX_VCPU_PER_VM);
12359287933SDavid Hunt 			if (cnt < 0) {
12459287933SDavid Hunt 				printf("Invalid value passed to port-list - [%s]\n",
12559287933SDavid Hunt 						optarg);
12659287933SDavid Hunt 				break;
12759287933SDavid Hunt 			}
12859287933SDavid Hunt 			idx = 0;
12938d232b9SBruce Richardson 			for (i = 0; i < RTE_POWER_MAX_VCPU_PER_VM; i++) {
13059287933SDavid Hunt 				if (ports[i]) {
13159287933SDavid Hunt 					printf("***Using port %d\n", i);
13270febdcfSIgor Romanov 					if (set_policy_mac(i, idx++) != 0) {
13370febdcfSIgor Romanov 						printf("Cannot set policy MAC");
13470febdcfSIgor Romanov 						return -1;
13570febdcfSIgor Romanov 					}
13659287933SDavid Hunt 				}
13759287933SDavid Hunt 			}
13859287933SDavid Hunt 			policy->nb_mac_to_monitor = idx;
13959287933SDavid Hunt 			printf("Total Ports: %d\n", idx);
14059287933SDavid Hunt 			break;
14159287933SDavid Hunt 		case 'o':
14259287933SDavid Hunt 			if (!strcmp(optarg, "TRAFFIC"))
14338d232b9SBruce Richardson 				policy->policy_to_use =
14438d232b9SBruce Richardson 						RTE_POWER_POLICY_TRAFFIC;
14559287933SDavid Hunt 			else if (!strcmp(optarg, "TIME"))
14638d232b9SBruce Richardson 				policy->policy_to_use =
14738d232b9SBruce Richardson 						RTE_POWER_POLICY_TIME;
14859287933SDavid Hunt 			else if (!strcmp(optarg, "WORKLOAD"))
14938d232b9SBruce Richardson 				policy->policy_to_use =
15038d232b9SBruce Richardson 						RTE_POWER_POLICY_WORKLOAD;
15159287933SDavid Hunt 			else if (!strcmp(optarg, "BRANCH_RATIO"))
15238d232b9SBruce Richardson 				policy->policy_to_use =
15338d232b9SBruce Richardson 						RTE_POWER_POLICY_BRANCH_RATIO;
15459287933SDavid Hunt 			else {
15559287933SDavid Hunt 				printf("Invalid policy specified: %s\n",
15659287933SDavid Hunt 						optarg);
15759287933SDavid Hunt 				return -1;
15859287933SDavid Hunt 			}
15959287933SDavid Hunt 			break;
16059287933SDavid Hunt 		/* long options */
16159287933SDavid Hunt 
16259287933SDavid Hunt 		case 0:
16359287933SDavid Hunt 			break;
16459287933SDavid Hunt 
16559287933SDavid Hunt 		default:
16659287933SDavid Hunt 			return -1;
16759287933SDavid Hunt 		}
16859287933SDavid Hunt 	}
16959287933SDavid Hunt 
17059287933SDavid Hunt 	if (optind >= 0)
17159287933SDavid Hunt 		argv[optind-1] = prgname;
17259287933SDavid Hunt 
17359287933SDavid Hunt 	ret = optind-1;
17459287933SDavid Hunt 	optind = 0; /* reset getopt lib */
17559287933SDavid Hunt 	return ret;
17659287933SDavid Hunt }
17759287933SDavid Hunt 
178f5e5c334SAlan Carew int
17998a16481SDavid Marchand main(int argc, char **argv)
180f5e5c334SAlan Carew {
181f5e5c334SAlan Carew 	int ret;
182f5e5c334SAlan Carew 	unsigned lcore_id;
183f5e5c334SAlan Carew 
184f5e5c334SAlan Carew 	ret = rte_eal_init(argc, argv);
185f5e5c334SAlan Carew 	if (ret < 0)
186f5e5c334SAlan Carew 		rte_panic("Cannot init EAL\n");
187f5e5c334SAlan Carew 
188f5e5c334SAlan Carew 	signal(SIGINT, sig_handler);
189f5e5c334SAlan Carew 	signal(SIGTERM, sig_handler);
190f5e5c334SAlan Carew 
19159287933SDavid Hunt 	argc -= ret;
19259287933SDavid Hunt 	argv += ret;
19359287933SDavid Hunt 
19459287933SDavid Hunt 	/* parse application arguments (after the EAL ones) */
19559287933SDavid Hunt 	ret = parse_args(argc, argv);
19659287933SDavid Hunt 	if (ret < 0)
19759287933SDavid Hunt 		rte_exit(EXIT_FAILURE, "Invalid arguments\n");
19859287933SDavid Hunt 
199f5e5c334SAlan Carew 	rte_power_set_env(PM_ENV_KVM_VM);
200f5e5c334SAlan Carew 	RTE_LCORE_FOREACH(lcore_id) {
201f5e5c334SAlan Carew 		rte_power_init(lcore_id);
202f5e5c334SAlan Carew 	}
203f5e5c334SAlan Carew 	run_cli(NULL);
204f5e5c334SAlan Carew 
20510aa3757SChengchang Tang 	/* clean up the EAL */
20610aa3757SChengchang Tang 	rte_eal_cleanup();
20710aa3757SChengchang Tang 
208f5e5c334SAlan Carew 	return 0;
209f5e5c334SAlan Carew }
210