xref: /linux/tools/power/cpupower/utils/cpupower-set.c (revision 9e4e86a604dfd06402933467578c4b79f5412b2c)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *  (C) 2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
4  */
5 
6 
7 #include <unistd.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <errno.h>
11 #include <string.h>
12 #include <getopt.h>
13 #include <sys/utsname.h>
14 
15 #include "helpers/helpers.h"
16 #include "helpers/sysfs.h"
17 #include "helpers/bitmask.h"
18 
19 static struct option set_opts[] = {
20 	{"perf-bias", required_argument, NULL, 'b'},
21 	{"epp", required_argument, NULL, 'e'},
22 	{"amd-pstate-mode", required_argument, NULL, 'm'},
23 	{"turbo-boost", required_argument, NULL, 't'},
24 	{"boost", required_argument, NULL, 't'},
25 	{ },
26 };
27 
print_wrong_arg_exit(void)28 static void print_wrong_arg_exit(void)
29 {
30 	printf(_("invalid or unknown argument\n"));
31 	exit(EXIT_FAILURE);
32 }
33 
cmd_set(int argc,char ** argv)34 int cmd_set(int argc, char **argv)
35 {
36 	unsigned int cpu;
37 	struct utsname uts;
38 
39 	union {
40 		struct {
41 			int perf_bias:1;
42 			int epp:1;
43 			int mode:1;
44 			int turbo_boost:1;
45 		};
46 		int params;
47 	} params;
48 	int perf_bias = 0, turbo_boost = 1;
49 	int ret = 0;
50 	char epp[30], mode[20];
51 
52 	ret = uname(&uts);
53 	if (!ret && (!strcmp(uts.machine, "ppc64le") ||
54 		     !strcmp(uts.machine, "ppc64"))) {
55 		fprintf(stderr, _("Subcommand not supported on POWER.\n"));
56 		return ret;
57 	}
58 
59 	setlocale(LC_ALL, "");
60 	textdomain(PACKAGE);
61 
62 	params.params = 0;
63 	/* parameter parsing */
64 	while ((ret = getopt_long(argc, argv, "b:e:m:t:",
65 				  set_opts, NULL)) != -1) {
66 		switch (ret) {
67 		case 'b':
68 			if (params.perf_bias)
69 				print_wrong_arg_exit();
70 			perf_bias = atoi(optarg);
71 			if (perf_bias < 0 || perf_bias > 15) {
72 				printf(_("--perf-bias param out "
73 					 "of range [0-%d]\n"), 15);
74 				print_wrong_arg_exit();
75 			}
76 			params.perf_bias = 1;
77 			break;
78 		case 'e':
79 			if (params.epp)
80 				print_wrong_arg_exit();
81 			if (sscanf(optarg, "%29s", epp) != 1) {
82 				print_wrong_arg_exit();
83 				return -EINVAL;
84 			}
85 			params.epp = 1;
86 			break;
87 		case 'm':
88 			if (cpupower_cpu_info.vendor != X86_VENDOR_AMD)
89 				print_wrong_arg_exit();
90 			if (params.mode)
91 				print_wrong_arg_exit();
92 			if (sscanf(optarg, "%19s", mode) != 1) {
93 				print_wrong_arg_exit();
94 				return -EINVAL;
95 			}
96 			params.mode = 1;
97 			break;
98 		case 't':
99 			if (params.turbo_boost)
100 				print_wrong_arg_exit();
101 			turbo_boost = atoi(optarg);
102 			if (turbo_boost < 0 || turbo_boost > 1) {
103 				printf("--turbo-boost param out of range [0-1]\n");
104 				print_wrong_arg_exit();
105 			}
106 			params.turbo_boost = 1;
107 			break;
108 
109 
110 		default:
111 			print_wrong_arg_exit();
112 		}
113 	}
114 
115 	if (!params.params)
116 		print_wrong_arg_exit();
117 
118 	if (params.mode) {
119 		ret = cpupower_set_amd_pstate_mode(mode);
120 		if (ret)
121 			fprintf(stderr, "Error setting mode\n");
122 	}
123 
124 	if (params.turbo_boost) {
125 		if (cpupower_cpu_info.vendor == X86_VENDOR_INTEL)
126 			ret = cpupower_set_intel_turbo_boost(turbo_boost);
127 		else
128 			ret = cpupower_set_generic_turbo_boost(turbo_boost);
129 
130 		if (ret)
131 			fprintf(stderr, "Error setting turbo-boost\n");
132 	}
133 
134 	/* Default is: set all CPUs */
135 	if (bitmask_isallclear(cpus_chosen))
136 		bitmask_setall(cpus_chosen);
137 
138 	/* loop over CPUs */
139 	for (cpu = bitmask_first(cpus_chosen);
140 	     cpu <= bitmask_last(cpus_chosen); cpu++) {
141 
142 		if (!bitmask_isbitset(cpus_chosen, cpu))
143 			continue;
144 
145 		if (sysfs_is_cpu_online(cpu) != 1){
146 			fprintf(stderr, _("Cannot set values on CPU %d:"), cpu);
147 			fprintf(stderr, _(" *is offline\n"));
148 			continue;
149 		}
150 
151 		if (params.perf_bias) {
152 			ret = cpupower_intel_set_perf_bias(cpu, perf_bias);
153 			if (ret) {
154 				fprintf(stderr, _("Error setting perf-bias "
155 						  "value on CPU %d\n"), cpu);
156 				break;
157 			}
158 		}
159 
160 		if (params.epp) {
161 			ret = cpupower_set_epp(cpu, epp);
162 			if (ret) {
163 				fprintf(stderr,
164 					"Error setting epp value on CPU %d\n", cpu);
165 				break;
166 			}
167 		}
168 
169 	}
170 	return ret;
171 }
172