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