mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 16:12:59 +02:00
linux-cpupower-6.15-rc1
Fixes lib version-ing, memory leaks in error legs, removes hard-coded values, and implements CPU physical core querying. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEPZKym/RZuOCGeA/kCwJExA0NQxwFAmfPGr8ACgkQCwJExA0N QxwMHA//YsbRMQtDFWaP71HyF0S2L9W/ZxGz5r/VL73Sz8HQ0yciA4+3GpHMUsrJ 5Dez9NwDNLmzNFq7aVZN8IGGsBJ7+Q+ok9idzFVmBAt6ufhR4p+l2QqN1G8dQEvM ++Cj/eWx3S4t1su8XpEW2cJXEbQV8uvyWWmyViSpuvEAIXVd82M43mP7qO66w8EC hie0wOIok2NdW+cuXuwBoMDgN5gPun9gePRPgK0rJK03Rir2deaI4cAjcoJG811c cg1IgsO6eieSDbZ+siX/OmpYGvJ7CVOu1dYBqvqLj9Q1ivts8HYyuQrBmScGIG4a yAap9m2KzJGuSQKGy/8Drf+pJ2IBMDR3Xwkk+zyS8V91M0bOWiw/cQLQ4j1eJoh0 RbSHc3vHRB3QJks4V3Tf+80EbNYdwl1Fqwj8YxzYGEfyM4pt8aJbm3EzUVGAOhkp nU00Zcx3tLrNxuS1x5NgCZSUJv1y8hxOete3btBU4eduFCmnqXO7XPmn4HzelE/T Wl4FSpz1dt+bhDu03I9RriipAR2G+6GiYrYdH7+zkuX8cHeCjn73XKQrfS3MQNjP ZnUQFzAgEQs5JqCDuRa3Z22ekP1MoDDUWkyJ5tJPP+HfDIymZimm8UX3An4+FUtp xSgHtjA+PMtuc4xQX7MAzrGOXX/Ayle571tGhM7Lqzum+SgqohE= =xM94 -----END PGP SIGNATURE----- Merge tag 'linux-cpupower-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux Merge cpupower utility updates for 6.15-rc1 from Shuah Khan: "Fixes lib version-ing, memory leaks in error legs, removes hard-coded values, and implements CPU physical core querying." * tag 'linux-cpupower-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux: cpupower: Make lib versioning scheme more obvious and fix version link cpupower: Implement CPU physical core querying pm: cpupower: remove hard-coded topology depth values pm: cpupower: Fix cmd_monitor() error legs to free cpu_topology cpupower: monitor: Exit with error status if execvp() fail pm: cpupower: bench: Prevent NULL dereference on malloc failure
This commit is contained in:
commit
80f0f07946
|
|
@ -52,8 +52,11 @@ DESTDIR ?=
|
|||
# and _should_ modify the PACKAGE_BUGREPORT definition
|
||||
|
||||
VERSION:= $(shell ./utils/version-gen.sh)
|
||||
LIB_MAJ= 0.0.1
|
||||
LIB_MIN= 1
|
||||
LIB_FIX= 1
|
||||
LIB_MIN= 0
|
||||
LIB_MAJ= 1
|
||||
LIB_VER= $(LIB_MAJ).$(LIB_MIN).$(LIB_FIX)
|
||||
|
||||
|
||||
PACKAGE = cpupower
|
||||
PACKAGE_BUGREPORT = linux-pm@vger.kernel.org
|
||||
|
|
@ -200,14 +203,14 @@ $(OUTPUT)lib/%.o: $(LIB_SRC) $(LIB_HEADERS)
|
|||
$(ECHO) " CC " $@
|
||||
$(QUIET) $(CC) $(CFLAGS) -fPIC -o $@ -c lib/$*.c
|
||||
|
||||
$(OUTPUT)libcpupower.so.$(LIB_MAJ): $(LIB_OBJS)
|
||||
$(OUTPUT)libcpupower.so.$(LIB_VER): $(LIB_OBJS)
|
||||
$(ECHO) " LD " $@
|
||||
$(QUIET) $(CC) -shared $(CFLAGS) $(LDFLAGS) -o $@ \
|
||||
-Wl,-soname,libcpupower.so.$(LIB_MIN) $(LIB_OBJS)
|
||||
-Wl,-soname,libcpupower.so.$(LIB_MAJ) $(LIB_OBJS)
|
||||
@ln -sf $(@F) $(OUTPUT)libcpupower.so
|
||||
@ln -sf $(@F) $(OUTPUT)libcpupower.so.$(LIB_MIN)
|
||||
@ln -sf $(@F) $(OUTPUT)libcpupower.so.$(LIB_MAJ)
|
||||
|
||||
libcpupower: $(OUTPUT)libcpupower.so.$(LIB_MAJ)
|
||||
libcpupower: $(OUTPUT)libcpupower.so.$(LIB_VER)
|
||||
|
||||
# Let all .o files depend on its .c file and all headers
|
||||
# Might be worth to put this into utils/Makefile at some point of time
|
||||
|
|
@ -217,7 +220,7 @@ $(OUTPUT)%.o: %.c
|
|||
$(ECHO) " CC " $@
|
||||
$(QUIET) $(CC) $(CFLAGS) -I./lib -I ./utils -o $@ -c $*.c
|
||||
|
||||
$(OUTPUT)cpupower: $(UTIL_OBJS) $(OUTPUT)libcpupower.so.$(LIB_MAJ)
|
||||
$(OUTPUT)cpupower: $(UTIL_OBJS) $(OUTPUT)libcpupower.so.$(LIB_VER)
|
||||
$(ECHO) " CC " $@
|
||||
ifeq ($(strip $(STATIC)),true)
|
||||
$(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lrt -lpci -L$(OUTPUT) -o $@
|
||||
|
|
@ -262,7 +265,7 @@ update-po: $(OUTPUT)po/$(PACKAGE).pot
|
|||
done;
|
||||
endif
|
||||
|
||||
compile-bench: $(OUTPUT)libcpupower.so.$(LIB_MAJ)
|
||||
compile-bench: $(OUTPUT)libcpupower.so.$(LIB_VER)
|
||||
@V=$(V) confdir=$(confdir) $(MAKE) -C bench O=$(OUTPUT)
|
||||
|
||||
# we compile into subdirectories. if the target directory is not the
|
||||
|
|
|
|||
|
|
@ -121,6 +121,10 @@ FILE *prepare_output(const char *dirname)
|
|||
struct config *prepare_default_config()
|
||||
{
|
||||
struct config *config = malloc(sizeof(struct config));
|
||||
if (!config) {
|
||||
perror("malloc");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dprintf("loading defaults\n");
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cpupower.h"
|
||||
#include "cpupower_intern.h"
|
||||
|
|
@ -150,15 +151,25 @@ static int __compare(const void *t1, const void *t2)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __compare_core_cpu_list(const void *t1, const void *t2)
|
||||
{
|
||||
struct cpuid_core_info *top1 = (struct cpuid_core_info *)t1;
|
||||
struct cpuid_core_info *top2 = (struct cpuid_core_info *)t2;
|
||||
|
||||
return strcmp(top1->core_cpu_list, top2->core_cpu_list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns amount of cpus, negative on error, cpu_top must be
|
||||
* passed to cpu_topology_release to free resources
|
||||
*
|
||||
* Array is sorted after ->pkg, ->core, then ->cpu
|
||||
* Array is sorted after ->cpu_smt_list ->pkg, ->core
|
||||
*/
|
||||
int get_cpu_topology(struct cpupower_topology *cpu_top)
|
||||
{
|
||||
int cpu, last_pkg, cpus = sysconf(_SC_NPROCESSORS_CONF);
|
||||
char path[SYSFS_PATH_MAX];
|
||||
char *last_cpu_list;
|
||||
|
||||
cpu_top->core_info = malloc(sizeof(struct cpuid_core_info) * cpus);
|
||||
if (cpu_top->core_info == NULL)
|
||||
|
|
@ -183,6 +194,34 @@ int get_cpu_topology(struct cpupower_topology *cpu_top)
|
|||
cpu_top->core_info[cpu].core = -1;
|
||||
continue;
|
||||
}
|
||||
if (cpu_top->core_info[cpu].core == -1) {
|
||||
strncpy(cpu_top->core_info[cpu].core_cpu_list, "-1", CPULIST_BUFFER);
|
||||
continue;
|
||||
}
|
||||
snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/topology/%s",
|
||||
cpu, "core_cpus_list");
|
||||
if (cpupower_read_sysfs(
|
||||
path,
|
||||
cpu_top->core_info[cpu].core_cpu_list,
|
||||
CPULIST_BUFFER) < 1) {
|
||||
printf("Warning CPU%u has a 0 size core_cpus_list string", cpu);
|
||||
}
|
||||
}
|
||||
|
||||
/* Count the number of distinct cpu lists to get the physical core
|
||||
* count.
|
||||
*/
|
||||
qsort(cpu_top->core_info, cpus, sizeof(struct cpuid_core_info),
|
||||
__compare_core_cpu_list);
|
||||
|
||||
last_cpu_list = cpu_top->core_info[0].core_cpu_list;
|
||||
cpu_top->cores = 1;
|
||||
for (cpu = 1; cpu < cpus; cpu++) {
|
||||
if (strcmp(cpu_top->core_info[cpu].core_cpu_list, last_cpu_list) != 0 &&
|
||||
cpu_top->core_info[cpu].pkg != -1) {
|
||||
last_cpu_list = cpu_top->core_info[cpu].core_cpu_list;
|
||||
cpu_top->cores++;
|
||||
}
|
||||
}
|
||||
|
||||
qsort(cpu_top->core_info, cpus, sizeof(struct cpuid_core_info),
|
||||
|
|
@ -203,13 +242,6 @@ int get_cpu_topology(struct cpupower_topology *cpu_top)
|
|||
if (!(cpu_top->core_info[0].pkg == -1))
|
||||
cpu_top->pkgs++;
|
||||
|
||||
/* Intel's cores count is not consecutively numbered, there may
|
||||
* be a core_id of 3, but none of 2. Assume there always is 0
|
||||
* Get amount of cores by counting duplicates in a package
|
||||
for (cpu = 0; cpu_top->core_info[cpu].pkg = 0 && cpu < cpus; cpu++) {
|
||||
if (cpu_top->core_info[cpu].core == 0)
|
||||
cpu_top->cores++;
|
||||
*/
|
||||
return cpus;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
#ifndef __CPUPOWER_CPUPOWER_H__
|
||||
#define __CPUPOWER_CPUPOWER_H__
|
||||
|
||||
#define CPULIST_BUFFER 5
|
||||
|
||||
struct cpupower_topology {
|
||||
/* Amount of CPU cores, packages and threads per core in the system */
|
||||
unsigned int cores;
|
||||
|
|
@ -16,6 +18,7 @@ struct cpuid_core_info {
|
|||
int pkg;
|
||||
int core;
|
||||
int cpu;
|
||||
char core_cpu_list[CPULIST_BUFFER];
|
||||
|
||||
/* flags */
|
||||
unsigned int is_online:1;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -91,7 +92,11 @@ int fill_string_with_spaces(char *s, int n)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_COL_WIDTH 6
|
||||
#define MAX_COL_WIDTH 6
|
||||
#define TOPOLOGY_DEPTH_PKG 3
|
||||
#define TOPOLOGY_DEPTH_CORE 2
|
||||
#define TOPOLOGY_DEPTH_CPU 1
|
||||
|
||||
void print_header(int topology_depth)
|
||||
{
|
||||
int unsigned mon;
|
||||
|
|
@ -113,12 +118,19 @@ void print_header(int topology_depth)
|
|||
}
|
||||
printf("\n");
|
||||
|
||||
if (topology_depth > 2)
|
||||
switch (topology_depth) {
|
||||
case TOPOLOGY_DEPTH_PKG:
|
||||
printf(" PKG|");
|
||||
if (topology_depth > 1)
|
||||
break;
|
||||
case TOPOLOGY_DEPTH_CORE:
|
||||
printf("CORE|");
|
||||
if (topology_depth > 0)
|
||||
break;
|
||||
case TOPOLOGY_DEPTH_CPU:
|
||||
printf(" CPU|");
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
for (mon = 0; mon < avail_monitors; mon++) {
|
||||
if (mon != 0)
|
||||
|
|
@ -152,12 +164,19 @@ void print_results(int topology_depth, int cpu)
|
|||
cpu_top.core_info[cpu].pkg == -1)
|
||||
return;
|
||||
|
||||
if (topology_depth > 2)
|
||||
switch (topology_depth) {
|
||||
case TOPOLOGY_DEPTH_PKG:
|
||||
printf("%4d|", cpu_top.core_info[cpu].pkg);
|
||||
if (topology_depth > 1)
|
||||
break;
|
||||
case TOPOLOGY_DEPTH_CORE:
|
||||
printf("%4d|", cpu_top.core_info[cpu].core);
|
||||
if (topology_depth > 0)
|
||||
break;
|
||||
case TOPOLOGY_DEPTH_CPU:
|
||||
printf("%4d|", cpu_top.core_info[cpu].cpu);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
for (mon = 0; mon < avail_monitors; mon++) {
|
||||
if (mon != 0)
|
||||
|
|
@ -294,7 +313,10 @@ int fork_it(char **argv)
|
|||
|
||||
if (!child_pid) {
|
||||
/* child */
|
||||
execvp(argv[0], argv);
|
||||
if (execvp(argv[0], argv) == -1) {
|
||||
printf("Invalid monitor command %s\n", argv[0]);
|
||||
exit(errno);
|
||||
}
|
||||
} else {
|
||||
/* parent */
|
||||
if (child_pid == -1) {
|
||||
|
|
@ -423,11 +445,13 @@ int cmd_monitor(int argc, char **argv)
|
|||
|
||||
if (avail_monitors == 0) {
|
||||
printf(_("No HW Cstate monitors found\n"));
|
||||
cpu_topology_release(cpu_top);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mode == list) {
|
||||
list_monitors();
|
||||
cpu_topology_release(cpu_top);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
@ -448,15 +472,15 @@ int cmd_monitor(int argc, char **argv)
|
|||
/* ToDo: Topology parsing needs fixing first to do
|
||||
this more generically */
|
||||
if (cpu_top.pkgs > 1)
|
||||
print_header(3);
|
||||
print_header(TOPOLOGY_DEPTH_PKG);
|
||||
else
|
||||
print_header(1);
|
||||
print_header(TOPOLOGY_DEPTH_CPU);
|
||||
|
||||
for (cpu = 0; cpu < cpu_count; cpu++) {
|
||||
if (cpu_top.pkgs > 1)
|
||||
print_results(3, cpu);
|
||||
print_results(TOPOLOGY_DEPTH_PKG, cpu);
|
||||
else
|
||||
print_results(1, cpu);
|
||||
print_results(TOPOLOGY_DEPTH_CPU, cpu);
|
||||
}
|
||||
|
||||
for (num = 0; num < avail_monitors; num++) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user