Commit 2e30baad authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branches 'acpi-tools' and 'pm-tools'

* acpi-tools:
  ACPI / tools: Introduce ec_access.c - tool to access the EC

* pm-tools:
  cpupower: Remove mc and smt power aware scheduler info/settings
  cpupower: cpupower info -b should return 0 on success, not the perf bias value
  cpupower: If root, try to load msr driver on x86 if /dev/cpu/0/msr is not available
  cpupower: Install recently added cpupower-idle-{set, info} manpages
  cpupower: Introduce idle state disable-by-latency and enable-all
  cpupower: Remove all manpages on make uninstall
  cpupower: Remove dead link to homepage, and update the targets built.
  cpupower: Rename cpufrequtils -> cpupower, and libcpufreq -> libcpupower.
  PM / tools: cpupower: add option to display values without round offs
  tools / power: turbostat: Drop temperature checks
...@@ -19,6 +19,8 @@ OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd) ...@@ -19,6 +19,8 @@ OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd)
$(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist)) $(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist))
endif endif
SUBDIRS = tools/ec
# --- CONFIGURATION BEGIN --- # --- CONFIGURATION BEGIN ---
# Set the following to `true' to make a unstripped, unoptimized # Set the following to `true' to make a unstripped, unoptimized
......
ec_access: ec_access.o
$(ECHO) " LD " $@
$(QUIET) $(LD) $(CFLAGS) $(LDFLAGS) $< -o $@
$(QUIET) $(STRIPCMD) $@
%.o: %.c
$(ECHO) " CC " $@
$(QUIET) $(CC) -c $(CFLAGS) -o $@ $<
all: ec_access
install:
$(INSTALL) -d $(DESTDIR)${sbindir}
$(INSTALL_PROGRAM) ec_access $(DESTDIR)${sbindir}
uninstall:
- rm -f $(DESTDIR)${sbindir}/ec_access
clean:
-rm -f $(OUTPUT)ec_access
.PHONY: all install uninstall
/*
* ec_access.c
*
* Copyright (C) 2010 SUSE Linux Products GmbH
* Author:
* Thomas Renninger <trenn@suse.de>
*
* This work is licensed under the terms of the GNU GPL, version 2.
*/
#include <fcntl.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <unistd.h>
#include <getopt.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#define EC_SPACE_SIZE 256
#define SYSFS_PATH "/sys/kernel/debug/ec/ec0/io"
/* TBD/Enhancements:
- Provide param for accessing different ECs (not supported by kernel yet)
*/
static int read_mode = -1;
static int sleep_time;
static int write_byte_offset = -1;
static int read_byte_offset = -1;
static uint8_t write_value = -1;
void usage(char progname[], int exit_status)
{
printf("Usage:\n");
printf("1) %s -r [-s sleep]\n", basename(progname));
printf("2) %s -b byte_offset\n", basename(progname));
printf("3) %s -w byte_offset -v value\n\n", basename(progname));
puts("\t-r [-s sleep] : Dump EC registers");
puts("\t If sleep is given, sleep x seconds,");
puts("\t re-read EC registers and show changes");
puts("\t-b offset : Read value at byte_offset (in hex)");
puts("\t-w offset -v value : Write value at byte_offset");
puts("\t-h : Print this help\n\n");
puts("Offsets and values are in hexadecimal number sytem.");
puts("The offset and value must be between 0 and 0xff.");
exit(exit_status);
}
void parse_opts(int argc, char *argv[])
{
int c;
while ((c = getopt(argc, argv, "rs:b:w:v:h")) != -1) {
switch (c) {
case 'r':
if (read_mode != -1)
usage(argv[0], EXIT_FAILURE);
read_mode = 1;
break;
case 's':
if (read_mode != -1 && read_mode != 1)
usage(argv[0], EXIT_FAILURE);
sleep_time = atoi(optarg);
if (sleep_time <= 0) {
sleep_time = 0;
usage(argv[0], EXIT_FAILURE);
printf("Bad sleep time: %s\n", optarg);
}
break;
case 'b':
if (read_mode != -1)
usage(argv[0], EXIT_FAILURE);
read_mode = 1;
read_byte_offset = strtoul(optarg, NULL, 16);
break;
case 'w':
if (read_mode != -1)
usage(argv[0], EXIT_FAILURE);
read_mode = 0;
write_byte_offset = strtoul(optarg, NULL, 16);
break;
case 'v':
write_value = strtoul(optarg, NULL, 16);
break;
case 'h':
usage(argv[0], EXIT_SUCCESS);
default:
fprintf(stderr, "Unknown option!\n");
usage(argv[0], EXIT_FAILURE);
}
}
if (read_mode == 0) {
if (write_byte_offset < 0 ||
write_byte_offset >= EC_SPACE_SIZE) {
fprintf(stderr, "Wrong byte offset 0x%.2x, valid: "
"[0-0x%.2x]\n",
write_byte_offset, EC_SPACE_SIZE - 1);
usage(argv[0], EXIT_FAILURE);
}
if (write_value < 0 ||
write_value >= 255) {
fprintf(stderr, "Wrong byte offset 0x%.2x, valid:"
"[0-0xff]\n", write_byte_offset);
usage(argv[0], EXIT_FAILURE);
}
}
if (read_mode == 1 && read_byte_offset != -1) {
if (read_byte_offset < -1 ||
read_byte_offset >= EC_SPACE_SIZE) {
fprintf(stderr, "Wrong byte offset 0x%.2x, valid: "
"[0-0x%.2x]\n",
read_byte_offset, EC_SPACE_SIZE - 1);
usage(argv[0], EXIT_FAILURE);
}
}
/* Add additional parameter checks here */
}
void dump_ec(int fd)
{
char buf[EC_SPACE_SIZE];
char buf2[EC_SPACE_SIZE];
int byte_off, bytes_read;
bytes_read = read(fd, buf, EC_SPACE_SIZE);
if (bytes_read == -1)
err(EXIT_FAILURE, "Could not read from %s\n", SYSFS_PATH);
if (bytes_read != EC_SPACE_SIZE)
fprintf(stderr, "Could only read %d bytes\n", bytes_read);
printf(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
for (byte_off = 0; byte_off < bytes_read; byte_off++) {
if ((byte_off % 16) == 0)
printf("\n%.2X: ", byte_off);
printf(" %.2x ", (uint8_t)buf[byte_off]);
}
printf("\n");
if (!sleep_time)
return;
printf("\n");
lseek(fd, 0, SEEK_SET);
sleep(sleep_time);
bytes_read = read(fd, buf2, EC_SPACE_SIZE);
if (bytes_read == -1)
err(EXIT_FAILURE, "Could not read from %s\n", SYSFS_PATH);
if (bytes_read != EC_SPACE_SIZE)
fprintf(stderr, "Could only read %d bytes\n", bytes_read);
printf(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
for (byte_off = 0; byte_off < bytes_read; byte_off++) {
if ((byte_off % 16) == 0)
printf("\n%.2X: ", byte_off);
if (buf[byte_off] == buf2[byte_off])
printf(" %.2x ", (uint8_t)buf2[byte_off]);
else
printf("*%.2x ", (uint8_t)buf2[byte_off]);
}
printf("\n");
}
void read_ec_val(int fd, int byte_offset)
{
uint8_t buf;
int error;
error = lseek(fd, byte_offset, SEEK_SET);
if (error != byte_offset)
err(EXIT_FAILURE, "Cannot set offset to 0x%.2x", byte_offset);
error = read(fd, &buf, 1);
if (error != 1)
err(EXIT_FAILURE, "Could not read byte 0x%.2x from %s\n",
byte_offset, SYSFS_PATH);
printf("0x%.2x\n", buf);
return;
}
void write_ec_val(int fd, int byte_offset, uint8_t value)
{
int error;
error = lseek(fd, byte_offset, SEEK_SET);
if (error != byte_offset)
err(EXIT_FAILURE, "Cannot set offset to 0x%.2x", byte_offset);
error = write(fd, &value, 1);
if (error != 1)
err(EXIT_FAILURE, "Cannot write value 0x%.2x to offset 0x%.2x",
value, byte_offset);
}
int main(int argc, char *argv[])
{
int file_mode = O_RDONLY;
int fd;
parse_opts(argc, argv);
if (read_mode == 0)
file_mode = O_WRONLY;
else if (read_mode == 1)
file_mode = O_RDONLY;
else
usage(argv[0], EXIT_FAILURE);
fd = open(SYSFS_PATH, file_mode);
if (fd == -1)
err(EXIT_FAILURE, "%s", SYSFS_PATH);
if (read_mode)
if (read_byte_offset == -1)
dump_ec(fd);
else if (read_byte_offset < 0 ||
read_byte_offset >= EC_SPACE_SIZE)
usage(argv[0], EXIT_FAILURE);
else
read_ec_val(fd, read_byte_offset);
else
write_ec_val(fd, write_byte_offset, write_value);
close(fd);
exit(EXIT_SUCCESS);
}
...@@ -274,6 +274,8 @@ install-man: ...@@ -274,6 +274,8 @@ install-man:
$(INSTALL_DATA) -D man/cpupower.1 $(DESTDIR)${mandir}/man1/cpupower.1 $(INSTALL_DATA) -D man/cpupower.1 $(DESTDIR)${mandir}/man1/cpupower.1
$(INSTALL_DATA) -D man/cpupower-frequency-set.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-set.1 $(INSTALL_DATA) -D man/cpupower-frequency-set.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-set.1
$(INSTALL_DATA) -D man/cpupower-frequency-info.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-info.1 $(INSTALL_DATA) -D man/cpupower-frequency-info.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-info.1
$(INSTALL_DATA) -D man/cpupower-idle-set.1 $(DESTDIR)${mandir}/man1/cpupower-idle-set.1
$(INSTALL_DATA) -D man/cpupower-idle-info.1 $(DESTDIR)${mandir}/man1/cpupower-idle-info.1
$(INSTALL_DATA) -D man/cpupower-set.1 $(DESTDIR)${mandir}/man1/cpupower-set.1 $(INSTALL_DATA) -D man/cpupower-set.1 $(DESTDIR)${mandir}/man1/cpupower-set.1
$(INSTALL_DATA) -D man/cpupower-info.1 $(DESTDIR)${mandir}/man1/cpupower-info.1 $(INSTALL_DATA) -D man/cpupower-info.1 $(DESTDIR)${mandir}/man1/cpupower-info.1
$(INSTALL_DATA) -D man/cpupower-monitor.1 $(DESTDIR)${mandir}/man1/cpupower-monitor.1 $(INSTALL_DATA) -D man/cpupower-monitor.1 $(DESTDIR)${mandir}/man1/cpupower-monitor.1
...@@ -295,8 +297,12 @@ uninstall: ...@@ -295,8 +297,12 @@ uninstall:
- rm -f $(DESTDIR)${libdir}/libcpupower.* - rm -f $(DESTDIR)${libdir}/libcpupower.*
- rm -f $(DESTDIR)${includedir}/cpufreq.h - rm -f $(DESTDIR)${includedir}/cpufreq.h
- rm -f $(DESTDIR)${bindir}/utils/cpupower - rm -f $(DESTDIR)${bindir}/utils/cpupower
- rm -f $(DESTDIR)${mandir}/man1/cpufreq-set.1 - rm -f $(DESTDIR)${mandir}/man1/cpupower.1
- rm -f $(DESTDIR)${mandir}/man1/cpufreq-info.1 - rm -f $(DESTDIR)${mandir}/man1/cpupower-frequency-set.1
- rm -f $(DESTDIR)${mandir}/man1/cpupower-frequency-info.1
- rm -f $(DESTDIR)${mandir}/man1/cpupower-set.1
- rm -f $(DESTDIR)${mandir}/man1/cpupower-info.1
- rm -f $(DESTDIR)${mandir}/man1/cpupower-monitor.1
- for HLANG in $(LANGUAGES); do \ - for HLANG in $(LANGUAGES); do \
rm -f $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \ rm -f $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \
done; done;
......
The cpufrequtils package (homepage: The cpupower package consists of the following elements:
http://www.kernel.org/pub/linux/utils/kernel/cpufreq/cpufrequtils.html )
consists of the following elements:
requirements requirements
------------ ------------
...@@ -11,10 +9,10 @@ providing cpuid.h is needed. ...@@ -11,10 +9,10 @@ providing cpuid.h is needed.
For both it's not explicitly checked for (yet). For both it's not explicitly checked for (yet).
libcpufreq libcpupower
---------- ----------
"libcpufreq" is a library which offers a unified access method for userspace "libcpupower" is a library which offers a unified access method for userspace
tools and programs to the cpufreq core and drivers in the Linux kernel. This tools and programs to the cpufreq core and drivers in the Linux kernel. This
allows for code reduction in userspace tools, a clean implementation of allows for code reduction in userspace tools, a clean implementation of
the interaction to the cpufreq core, and support for both the sysfs and proc the interaction to the cpufreq core, and support for both the sysfs and proc
...@@ -28,22 +26,22 @@ make ...@@ -28,22 +26,22 @@ make
su su
make install make install
should suffice on most systems. It builds default libcpufreq, should suffice on most systems. It builds libcpupower to put in
cpufreq-set and cpufreq-info files and installs them in /usr/lib and /usr/lib; cpupower, cpufreq-bench_plot.sh to put in /usr/bin; and
/usr/bin, respectively. If you want to set up the paths differently and/or cpufreq-bench to put in /usr/sbin. If you want to set up the paths
want to configure the package to your specific needs, you need to open differently and/or want to configure the package to your specific
"Makefile" with an editor of your choice and edit the block marked needs, you need to open "Makefile" with an editor of your choice and
CONFIGURATION. edit the block marked CONFIGURATION.
THANKS THANKS
------ ------
Many thanks to Mattia Dongili who wrote the autotoolization and Many thanks to Mattia Dongili who wrote the autotoolization and
libtoolization, the manpages and the italian language file for cpufrequtils; libtoolization, the manpages and the italian language file for cpupower;
to Dave Jones for his feedback and his dump_psb tool; to Bruno Ducrot for his to Dave Jones for his feedback and his dump_psb tool; to Bruno Ducrot for his
powernow-k8-decode and intel_gsic tools as well as the french language file; powernow-k8-decode and intel_gsic tools as well as the french language file;
and to various others commenting on the previous (pre-)releases of and to various others commenting on the previous (pre-)releases of
cpufrequtils. cpupower.
Dominik Brodowski Dominik Brodowski
...@@ -3,7 +3,6 @@ ToDos sorted by priority: ...@@ -3,7 +3,6 @@ ToDos sorted by priority:
- Use bitmask functions to parse CPU topology more robust - Use bitmask functions to parse CPU topology more robust
(current implementation has issues on AMD) (current implementation has issues on AMD)
- Try to read out boost states and frequencies on Intel - Try to read out boost states and frequencies on Intel
- Adjust README
- Somewhere saw the ability to read power consumption of - Somewhere saw the ability to read power consumption of
RAM from HW on Intel SandyBridge -> another monitor? RAM from HW on Intel SandyBridge -> another monitor?
- Add another c1e debug idle monitor - Add another c1e debug idle monitor
......
...@@ -50,6 +50,9 @@ Prints out information like provided by the /proc/cpufreq interface in 2.4. and ...@@ -50,6 +50,9 @@ Prints out information like provided by the /proc/cpufreq interface in 2.4. and
\fB\-m\fR \fB\-\-human\fR \fB\-m\fR \fB\-\-human\fR
human\-readable output for the \-f, \-w, \-s and \-y parameters. human\-readable output for the \-f, \-w, \-s and \-y parameters.
.TP .TP
\fB\-n\fR \fB\-\-no-rounding\fR
Output frequencies and latencies without rounding off values.
.TP
.SH "REMARKS" .SH "REMARKS"
.LP .LP
By default only values of core zero are displayed. How to display settings of By default only values of core zero are displayed. How to display settings of
......
...@@ -13,11 +13,17 @@ sleep states. This can be handy for power vs performance tuning. ...@@ -13,11 +13,17 @@ sleep states. This can be handy for power vs performance tuning.
.SH "OPTIONS" .SH "OPTIONS"
.LP .LP
.TP .TP
\fB\-d\fR \fB\-\-disable\fR \fB\-d\fR \fB\-\-disable\fR <STATE_NO>
Disable a specific processor sleep state. Disable a specific processor sleep state.
.TP .TP
\fB\-e\fR \fB\-\-enable\fR \fB\-e\fR \fB\-\-enable\fR <STATE_NO>
Enable a specific processor sleep state. Enable a specific processor sleep state.
.TP
\fB\-D\fR \fB\-\-disable-by-latency\fR <LATENCY>
Disable all idle states with a equal or higher latency than <LATENCY>
.TP
\fB\-E\fR \fB\-\-enable-all\fR
Enable all idle states if not enabled already.
.SH "REMARKS" .SH "REMARKS"
.LP .LP
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
cpupower\-info \- Shows processor power related kernel or hardware configurations cpupower\-info \- Shows processor power related kernel or hardware configurations
.SH SYNOPSIS .SH SYNOPSIS
.ft B .ft B
.B cpupower info [ \-b ] [ \-s ] [ \-m ] .B cpupower info [ \-b ]
.SH DESCRIPTION .SH DESCRIPTION
\fBcpupower info \fP shows kernel configurations or processor hardware \fBcpupower info \fP shows kernel configurations or processor hardware
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
cpupower\-set \- Set processor power related kernel or hardware configurations cpupower\-set \- Set processor power related kernel or hardware configurations
.SH SYNOPSIS .SH SYNOPSIS
.ft B .ft B
.B cpupower set [ \-b VAL ] [ \-s VAL ] [ \-m VAL ] .B cpupower set [ \-b VAL ]
.SH DESCRIPTION .SH DESCRIPTION
...@@ -55,35 +55,6 @@ Use \fBcpupower -c all info -b\fP to verify. ...@@ -55,35 +55,6 @@ Use \fBcpupower -c all info -b\fP to verify.
This options needs the msr kernel driver (CONFIG_X86_MSR) loaded. This options needs the msr kernel driver (CONFIG_X86_MSR) loaded.
.RE .RE
.PP
\-\-sched\-mc, \-m [ VAL ]
.RE
\-\-sched\-smt, \-s [ VAL ]
.RS 4
\-\-sched\-mc utilizes cores in one processor package/socket first before
processes are scheduled to other processor packages/sockets.
\-\-sched\-smt utilizes thread siblings of one processor core first before
processes are scheduled to other cores.
The impact on power consumption and performance (positiv or negativ) heavily
depends on processor support for deep sleep states, frequency scaling and
frequency boost modes and their dependencies between other thread siblings
and processor cores.
Taken over from kernel documentation:
Adjust the kernel's multi-core scheduler support.
Possible values are:
.RS 2
0 - No power saving load balance (default value)
1 - Fill one thread/core/package first for long running threads
2 - Also bias task wakeups to semi-idle cpu package for power
savings
.RE
.SH "SEE ALSO" .SH "SEE ALSO"
cpupower-info(1), cpupower-monitor(1), powertop(1) cpupower-info(1), cpupower-monitor(1), powertop(1)
......
...@@ -82,29 +82,42 @@ static void proc_cpufreq_output(void) ...@@ -82,29 +82,42 @@ static void proc_cpufreq_output(void)
} }
} }
static int no_rounding;
static void print_speed(unsigned long speed) static void print_speed(unsigned long speed)
{ {
unsigned long tmp; unsigned long tmp;
if (speed > 1000000) { if (no_rounding) {
tmp = speed % 10000; if (speed > 1000000)
if (tmp >= 5000) printf("%u.%06u GHz", ((unsigned int) speed/1000000),
speed += 10000; ((unsigned int) speed%1000000));
printf("%u.%02u GHz", ((unsigned int) speed/1000000), else if (speed > 100000)
((unsigned int) (speed%1000000)/10000)); printf("%u MHz", (unsigned int) speed);
} else if (speed > 100000) { else if (speed > 1000)
tmp = speed % 1000; printf("%u.%03u MHz", ((unsigned int) speed/1000),
if (tmp >= 500) (unsigned int) (speed%1000));
speed += 1000; else
printf("%u MHz", ((unsigned int) speed / 1000)); printf("%lu kHz", speed);
} else if (speed > 1000) { } else {
tmp = speed % 100; if (speed > 1000000) {
if (tmp >= 50) tmp = speed%10000;
speed += 100; if (tmp >= 5000)
printf("%u.%01u MHz", ((unsigned int) speed/1000), speed += 10000;
((unsigned int) (speed%1000)/100)); printf("%u.%02u GHz", ((unsigned int) speed/1000000),
} else ((unsigned int) (speed%1000000)/10000));
printf("%lu kHz", speed); } else if (speed > 100000) {
tmp = speed%1000;
if (tmp >= 500)
speed += 1000;
printf("%u MHz", ((unsigned int) speed/1000));
} else if (speed > 1000) {
tmp = speed%100;
if (tmp >= 50)
speed += 100;
printf("%u.%01u MHz", ((unsigned int) speed/1000),
((unsigned int) (speed%1000)/100));
}
}
return; return;
} }
...@@ -113,26 +126,38 @@ static void print_duration(unsigned long duration) ...@@ -113,26 +126,38 @@ static void print_duration(unsigned long duration)
{ {
unsigned long tmp; unsigned long tmp;
if (duration > 1000000) { if (no_rounding) {
tmp = duration % 10000; if (duration > 1000000)
if (tmp >= 5000) printf("%u.%06u ms", ((unsigned int) duration/1000000),
duration += 10000; ((unsigned int) duration%1000000));
printf("%u.%02u ms", ((unsigned int) duration/1000000), else if (duration > 100000)
((unsigned int) (duration%1000000)/10000)); printf("%u us", ((unsigned int) duration/1000));
} else if (duration > 100000) { else if (duration > 1000)
tmp = duration % 1000; printf("%u.%03u us", ((unsigned int) duration/1000),
if (tmp >= 500) ((unsigned int) duration%1000));
duration += 1000; else
printf("%u us", ((unsigned int) duration / 1000)); printf("%lu ns", duration);
} else if (duration > 1000) { } else {
tmp = duration % 100; if (duration > 1000000) {
if (tmp >= 50) tmp = duration%10000;
duration += 100; if (tmp >= 5000)
printf("%u.%01u us", ((unsigned int) duration/1000), duration += 10000;
((unsigned int) (duration%1000)/100)); printf("%u.%02u ms", ((unsigned int) duration/1000000),
} else ((unsigned int) (duration%1000000)/10000));
printf("%lu ns", duration); } else if (duration > 100000) {
tmp = duration%1000;
if (tmp >= 500)
duration += 1000;
printf("%u us", ((unsigned int) duration / 1000));
} else if (duration > 1000) {
tmp = duration%100;
if (tmp >= 50)
duration += 100;
printf("%u.%01u us", ((unsigned int) duration/1000),
((unsigned int) (duration%1000)/100));
} else
printf("%lu ns", duration);
}
return; return;
} }
...@@ -525,6 +550,7 @@ static struct option info_opts[] = { ...@@ -525,6 +550,7 @@ static struct option info_opts[] = {
{ .name = "latency", .has_arg = no_argument, .flag = NULL, .val = 'y'}, { .name = "latency", .has_arg = no_argument, .flag = NULL, .val = 'y'},
{ .name = "proc", .has_arg = no_argument, .flag = NULL, .val = 'o'}, { .name = "proc", .has_arg = no_argument, .flag = NULL, .val = 'o'},
{ .name = "human", .has_arg = no_argument, .flag = NULL, .val = 'm'}, { .name = "human", .has_arg = no_argument, .flag = NULL, .val = 'm'},
{ .name = "no-rounding", .has_arg = no_argument, .flag = NULL, .val = 'n'},
{ }, { },
}; };
...@@ -538,7 +564,8 @@ int cmd_freq_info(int argc, char **argv) ...@@ -538,7 +564,8 @@ int cmd_freq_info(int argc, char **argv)
int output_param = 0; int output_param = 0;
do { do {
ret = getopt_long(argc, argv, "oefwldpgrasmyb", info_opts, NULL); ret = getopt_long(argc, argv, "oefwldpgrasmybn", info_opts,
NULL);
switch (ret) { switch (ret) {
case '?': case '?':
output_param = '?'; output_param = '?';
...@@ -575,6 +602,9 @@ int cmd_freq_info(int argc, char **argv) ...@@ -575,6 +602,9 @@ int cmd_freq_info(int argc, char **argv)
} }
human = 1; human = 1;
break; break;
case 'n':
no_rounding = 1;
break;
default: default:
fprintf(stderr, "invalid or unknown argument\n"); fprintf(stderr, "invalid or unknown argument\n");
return EXIT_FAILURE; return EXIT_FAILURE;
......
...@@ -13,8 +13,14 @@ ...@@ -13,8 +13,14 @@
#include "helpers/sysfs.h" #include "helpers/sysfs.h"
static struct option info_opts[] = { static struct option info_opts[] = {
{ .name = "disable", .has_arg = required_argument, .flag = NULL, .val = 'd'}, { .name = "disable",
{ .name = "enable", .has_arg = required_argument, .flag = NULL, .val = 'e'}, .has_arg = required_argument, .flag = NULL, .val = 'd'},
{ .name = "enable",
.has_arg = required_argument, .flag = NULL, .val = 'e'},
{ .name = "disable-by-latency",
.has_arg = required_argument, .flag = NULL, .val = 'D'},
{ .name = "enable-all",
.has_arg = no_argument, .flag = NULL, .val = 'E'},
{ }, { },
}; };
...@@ -23,11 +29,13 @@ int cmd_idle_set(int argc, char **argv) ...@@ -23,11 +29,13 @@ int cmd_idle_set(int argc, char **argv)
{ {
extern char *optarg; extern char *optarg;
extern int optind, opterr, optopt; extern int optind, opterr, optopt;
int ret = 0, cont = 1, param = 0, idlestate = 0; int ret = 0, cont = 1, param = 0, disabled;
unsigned int cpu = 0; unsigned long long latency = 0, state_latency;
unsigned int cpu = 0, idlestate = 0, idlestates = 0;
char *endptr;
do { do {
ret = getopt_long(argc, argv, "d:e:", info_opts, NULL); ret = getopt_long(argc, argv, "d:e:ED:", info_opts, NULL);
if (ret == -1) if (ret == -1)
break; break;
switch (ret) { switch (ret) {
...@@ -53,6 +61,27 @@ int cmd_idle_set(int argc, char **argv) ...@@ -53,6 +61,27 @@ int cmd_idle_set(int argc, char **argv)
param = ret; param = ret;
idlestate = atoi(optarg); idlestate = atoi(optarg);
break; break;
case 'D':
if (param) {
param = -1;
cont = 0;
break;
}
param = ret;
latency = strtoull(optarg, &endptr, 10);
if (*endptr != '\0') {
printf(_("Bad latency value: %s\n"), optarg);
exit(EXIT_FAILURE);
}
break;
case 'E':
if (param) {
param = -1;
cont = 0;
break;
}
param = ret;
break;
case -1: case -1:
cont = 0; cont = 0;
break; break;
...@@ -79,8 +108,14 @@ int cmd_idle_set(int argc, char **argv) ...@@ -79,8 +108,14 @@ int cmd_idle_set(int argc, char **argv)
if (!bitmask_isbitset(cpus_chosen, cpu)) if (!bitmask_isbitset(cpus_chosen, cpu))
continue; continue;
switch (param) { if (sysfs_is_cpu_online(cpu) != 1)
continue;
idlestates = sysfs_get_idlestate_count(cpu);
if (idlestates <= 0)
continue;
switch (param) {
case 'd': case 'd':
ret = sysfs_idlestate_disable(cpu, idlestate, 1); ret = sysfs_idlestate_disable(cpu, idlestate, 1);
if (ret == 0) if (ret == 0)
...@@ -107,6 +142,34 @@ int cmd_idle_set(int argc, char **argv) ...@@ -107,6 +142,34 @@ int cmd_idle_set(int argc, char **argv)
printf(_("Idlestate %u not enabled on CPU %u\n"), printf(_("Idlestate %u not enabled on CPU %u\n"),
idlestate, cpu); idlestate, cpu);
break; break;
case 'D':
for (idlestate = 0; idlestate < idlestates; idlestate++) {
disabled = sysfs_is_idlestate_disabled
(cpu, idlestate);
state_latency = sysfs_get_idlestate_latency
(cpu, idlestate);
printf("CPU: %u - idlestate %u - state_latency: %llu - latency: %llu\n",
cpu, idlestate, state_latency, latency);
if (disabled == 1 || latency > state_latency)
continue;
ret = sysfs_idlestate_disable
(cpu, idlestate, 1);
if (ret == 0)
printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu);
}
break;
case 'E':
for (idlestate = 0; idlestate < idlestates; idlestate++) {
disabled = sysfs_is_idlestate_disabled
(cpu, idlestate);
if (disabled == 1) {
ret = sysfs_idlestate_disable
(cpu, idlestate, 0);
if (ret == 0)
printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu);
}
}
break;
default: default:
/* Not reachable with proper args checking */ /* Not reachable with proper args checking */
printf(_("Invalid or unknown argument\n")); printf(_("Invalid or unknown argument\n"));
......
...@@ -18,8 +18,6 @@ ...@@ -18,8 +18,6 @@
static struct option set_opts[] = { static struct option set_opts[] = {
{ .name = "perf-bias", .has_arg = optional_argument, .flag = NULL, .val = 'b'}, { .name = "perf-bias", .has_arg = optional_argument, .flag = NULL, .val = 'b'},
{ .name = "sched-mc", .has_arg = optional_argument, .flag = NULL, .val = 'm'},
{ .name = "sched-smt", .has_arg = optional_argument, .flag = NULL, .val = 's'},
{ }, { },
}; };
...@@ -37,8 +35,6 @@ int cmd_info(int argc, char **argv) ...@@ -37,8 +35,6 @@ int cmd_info(int argc, char **argv)
union { union {
struct { struct {
int sched_mc:1;
int sched_smt:1;
int perf_bias:1; int perf_bias:1;
}; };
int params; int params;
...@@ -49,23 +45,13 @@ int cmd_info(int argc, char **argv) ...@@ -49,23 +45,13 @@ int cmd_info(int argc, char **argv)
textdomain(PACKAGE); textdomain(PACKAGE);
/* parameter parsing */ /* parameter parsing */
while ((ret = getopt_long(argc, argv, "msb", set_opts, NULL)) != -1) { while ((ret = getopt_long(argc, argv, "b", set_opts, NULL)) != -1) {
switch (ret) { switch (ret) {
case 'b': case 'b':
if (params.perf_bias) if (params.perf_bias)
print_wrong_arg_exit(); print_wrong_arg_exit();
params.perf_bias = 1; params.perf_bias = 1;
break; break;
case 'm':
if (params.sched_mc)
print_wrong_arg_exit();
params.sched_mc = 1;
break;
case 's':
if (params.sched_smt)
print_wrong_arg_exit();
params.sched_smt = 1;
break;
default: default:
print_wrong_arg_exit(); print_wrong_arg_exit();
} }
...@@ -78,25 +64,6 @@ int cmd_info(int argc, char **argv) ...@@ -78,25 +64,6 @@ int cmd_info(int argc, char **argv)
if (bitmask_isallclear(cpus_chosen)) if (bitmask_isallclear(cpus_chosen))
bitmask_setbit(cpus_chosen, 0); bitmask_setbit(cpus_chosen, 0);
if (params.sched_mc) {
ret = sysfs_get_sched("mc");
printf(_("System's multi core scheduler setting: "));
if (ret < 0)
/* if sysfs file is missing it's: errno == ENOENT */
printf(_("not supported\n"));
else
printf("%d\n", ret);
}
if (params.sched_smt) {
ret = sysfs_get_sched("smt");
printf(_("System's thread sibling scheduler setting: "));
if (ret < 0)
/* if sysfs file is missing it's: errno == ENOENT */
printf(_("not supported\n"));
else
printf("%d\n", ret);
}
/* Add more per cpu options here */ /* Add more per cpu options here */
if (!params.perf_bias) if (!params.perf_bias)
return ret; return ret;
...@@ -125,11 +92,12 @@ int cmd_info(int argc, char **argv) ...@@ -125,11 +92,12 @@ int cmd_info(int argc, char **argv)
if (params.perf_bias) { if (params.perf_bias) {
ret = msr_intel_get_perf_bias(cpu); ret = msr_intel_get_perf_bias(cpu);
if (ret < 0) { if (ret < 0) {
printf(_("Could not read perf-bias value\n")); fprintf(stderr,
break; _("Could not read perf-bias value[%d]\n"), ret);
exit(EXIT_FAILURE);
} else } else
printf(_("perf-bias: %d\n"), ret); printf(_("perf-bias: %d\n"), ret);
} }
} }
return ret; return 0;
} }
...@@ -19,8 +19,6 @@ ...@@ -19,8 +19,6 @@
static struct option set_opts[] = { static struct option set_opts[] = {
{ .name = "perf-bias", .has_arg = required_argument, .flag = NULL, .val = 'b'}, { .name = "perf-bias", .has_arg = required_argument, .flag = NULL, .val = 'b'},
{ .name = "sched-mc", .has_arg = required_argument, .flag = NULL, .val = 'm'},
{ .name = "sched-smt", .has_arg = required_argument, .flag = NULL, .val = 's'},
{ }, { },
}; };
...@@ -38,13 +36,11 @@ int cmd_set(int argc, char **argv) ...@@ -38,13 +36,11 @@ int cmd_set(int argc, char **argv)
union { union {
struct { struct {
int sched_mc:1;
int sched_smt:1;
int perf_bias:1; int perf_bias:1;
}; };
int params; int params;
} params; } params;
int sched_mc = 0, sched_smt = 0, perf_bias = 0; int perf_bias = 0;
int ret = 0; int ret = 0;
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
...@@ -52,7 +48,7 @@ int cmd_set(int argc, char **argv) ...@@ -52,7 +48,7 @@ int cmd_set(int argc, char **argv)
params.params = 0; params.params = 0;
/* parameter parsing */ /* parameter parsing */
while ((ret = getopt_long(argc, argv, "m:s:b:", while ((ret = getopt_long(argc, argv, "b:",
set_opts, NULL)) != -1) { set_opts, NULL)) != -1) {
switch (ret) { switch (ret) {
case 'b': case 'b':
...@@ -66,28 +62,6 @@ int cmd_set(int argc, char **argv) ...@@ -66,28 +62,6 @@ int cmd_set(int argc, char **argv)
} }
params.perf_bias = 1; params.perf_bias = 1;
break; break;
case 'm':
if (params.sched_mc)
print_wrong_arg_exit();
sched_mc = atoi(optarg);
if (sched_mc < 0 || sched_mc > 2) {
printf(_("--sched-mc param out "
"of range [0-%d]\n"), 2);
print_wrong_arg_exit();
}
params.sched_mc = 1;
break;
case 's':
if (params.sched_smt)
print_wrong_arg_exit();
sched_smt = atoi(optarg);
if (sched_smt < 0 || sched_smt > 2) {
printf(_("--sched-smt param out "
"of range [0-%d]\n"), 2);
print_wrong_arg_exit();
}
params.sched_smt = 1;
break;
default: default:
print_wrong_arg_exit(); print_wrong_arg_exit();
} }
...@@ -96,19 +70,6 @@ int cmd_set(int argc, char **argv) ...@@ -96,19 +70,6 @@ int cmd_set(int argc, char **argv)
if (!params.params) if (!params.params)
print_wrong_arg_exit(); print_wrong_arg_exit();
if (params.sched_mc) {
ret = sysfs_set_sched("mc", sched_mc);
if (ret)
fprintf(stderr, _("Error setting sched-mc %s\n"),
(ret == -ENODEV) ? "not supported" : "");
}
if (params.sched_smt) {
ret = sysfs_set_sched("smt", sched_smt);
if (ret)
fprintf(stderr, _("Error setting sched-smt %s\n"),
(ret == -ENODEV) ? "not supported" : "");
}
/* Default is: set all CPUs */ /* Default is: set all CPUs */
if (bitmask_isallclear(cpus_chosen)) if (bitmask_isallclear(cpus_chosen))
bitmask_setall(cpus_chosen); bitmask_setall(cpus_chosen);
......
...@@ -12,6 +12,9 @@ ...@@ -12,6 +12,9 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include "builtin.h" #include "builtin.h"
#include "helpers/helpers.h" #include "helpers/helpers.h"
...@@ -169,6 +172,8 @@ int main(int argc, const char *argv[]) ...@@ -169,6 +172,8 @@ int main(int argc, const char *argv[])
{ {
const char *cmd; const char *cmd;
unsigned int i, ret; unsigned int i, ret;
struct stat statbuf;
struct utsname uts;
cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF)); cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
...@@ -195,6 +200,15 @@ int main(int argc, const char *argv[]) ...@@ -195,6 +200,15 @@ int main(int argc, const char *argv[])
get_cpu_info(0, &cpupower_cpu_info); get_cpu_info(0, &cpupower_cpu_info);
run_as_root = !getuid(); run_as_root = !getuid();
if (run_as_root) {
ret = uname(&uts);
if (!ret && !strcmp(uts.machine, "x86_64") &&
stat("/dev/cpu/0/msr", &statbuf) != 0) {
if (system("modprobe msr") == -1)
fprintf(stderr, _("MSR access not available.\n"));
}
}
for (i = 0; i < ARRAY_SIZE(commands); i++) { for (i = 0; i < ARRAY_SIZE(commands); i++) {
struct cmd_struct *p = commands + i; struct cmd_struct *p = commands + i;
......
...@@ -1971,13 +1971,13 @@ int set_temperature_target(struct thread_data *t, struct core_data *c, struct pk ...@@ -1971,13 +1971,13 @@ int set_temperature_target(struct thread_data *t, struct core_data *c, struct pk
if (get_msr(0, MSR_IA32_TEMPERATURE_TARGET, &msr)) if (get_msr(0, MSR_IA32_TEMPERATURE_TARGET, &msr))
goto guess; goto guess;
target_c_local = (msr >> 16) & 0x7F; target_c_local = (msr >> 16) & 0xFF;
if (verbose) if (verbose)
fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n", fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
cpu, msr, target_c_local); cpu, msr, target_c_local);
if (target_c_local < 85 || target_c_local > 127) if (!target_c_local)
goto guess; goto guess;
tcc_activation_temp = target_c_local; tcc_activation_temp = target_c_local;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment