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 { }, 23 }; 24 25 static void print_wrong_arg_exit(void) 26 { 27 printf(_("invalid or unknown argument\n")); 28 exit(EXIT_FAILURE); 29 } 30 31 int cmd_set(int argc, char **argv) 32 { 33 extern char *optarg; 34 extern int optind, opterr, optopt; 35 unsigned int cpu; 36 struct utsname uts; 37 38 union { 39 struct { 40 int perf_bias:1; 41 int epp:1; 42 }; 43 int params; 44 } params; 45 int perf_bias = 0; 46 int ret = 0; 47 char epp[30]; 48 49 ret = uname(&uts); 50 if (!ret && (!strcmp(uts.machine, "ppc64le") || 51 !strcmp(uts.machine, "ppc64"))) { 52 fprintf(stderr, _("Subcommand not supported on POWER.\n")); 53 return ret; 54 } 55 56 setlocale(LC_ALL, ""); 57 textdomain(PACKAGE); 58 59 params.params = 0; 60 /* parameter parsing */ 61 while ((ret = getopt_long(argc, argv, "b:e:", 62 set_opts, NULL)) != -1) { 63 switch (ret) { 64 case 'b': 65 if (params.perf_bias) 66 print_wrong_arg_exit(); 67 perf_bias = atoi(optarg); 68 if (perf_bias < 0 || perf_bias > 15) { 69 printf(_("--perf-bias param out " 70 "of range [0-%d]\n"), 15); 71 print_wrong_arg_exit(); 72 } 73 params.perf_bias = 1; 74 break; 75 case 'e': 76 if (params.epp) 77 print_wrong_arg_exit(); 78 if (sscanf(optarg, "%29s", epp) != 1) { 79 print_wrong_arg_exit(); 80 return -EINVAL; 81 } 82 params.epp = 1; 83 break; 84 default: 85 print_wrong_arg_exit(); 86 } 87 } 88 89 if (!params.params) 90 print_wrong_arg_exit(); 91 92 /* Default is: set all CPUs */ 93 if (bitmask_isallclear(cpus_chosen)) 94 bitmask_setall(cpus_chosen); 95 96 /* loop over CPUs */ 97 for (cpu = bitmask_first(cpus_chosen); 98 cpu <= bitmask_last(cpus_chosen); cpu++) { 99 100 if (!bitmask_isbitset(cpus_chosen, cpu)) 101 continue; 102 103 if (sysfs_is_cpu_online(cpu) != 1){ 104 fprintf(stderr, _("Cannot set values on CPU %d:"), cpu); 105 fprintf(stderr, _(" *is offline\n")); 106 continue; 107 } 108 109 if (params.perf_bias) { 110 ret = cpupower_intel_set_perf_bias(cpu, perf_bias); 111 if (ret) { 112 fprintf(stderr, _("Error setting perf-bias " 113 "value on CPU %d\n"), cpu); 114 break; 115 } 116 } 117 118 if (params.epp) { 119 ret = cpupower_set_epp(cpu, epp); 120 if (ret) { 121 fprintf(stderr, 122 "Error setting epp value on CPU %d\n", cpu); 123 break; 124 } 125 } 126 } 127 return ret; 128 } 129