Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f053a56 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'pm-sleep' and 'pm-tools'

* pm-sleep:
  PM / sleep: Add support for read-only sysfs attributes

* pm-tools:
  cpupower: fix how "cpupower frequency-info" interprets latency
  cpupower: rework the "cpupower frequency-info" command
  cpupower: Do not analyse offlined cpus
  cpupower: Provide STATIC variable in Makefile for debug builds
  cpupower: Fix precedence issue
Loading
Loading
Loading
Loading
+2 −15
Original line number Diff line number Diff line
@@ -280,13 +280,7 @@ static ssize_t pm_wakeup_irq_show(struct kobject *kobj,
	return pm_wakeup_irq ? sprintf(buf, "%u\n", pm_wakeup_irq) : -ENODATA;
}

static ssize_t pm_wakeup_irq_store(struct kobject *kobj,
					struct kobj_attribute *attr,
					const char *buf, size_t n)
{
	return -EINVAL;
}
power_attr(pm_wakeup_irq);
power_attr_ro(pm_wakeup_irq);

#else /* !CONFIG_PM_SLEEP_DEBUG */
static inline void pm_print_times_init(void) {}
@@ -564,14 +558,7 @@ static ssize_t pm_trace_dev_match_show(struct kobject *kobj,
	return show_trace_dev_match(buf, PAGE_SIZE);
}

static ssize_t
pm_trace_dev_match_store(struct kobject *kobj, struct kobj_attribute *attr,
			 const char *buf, size_t n)
{
	return -EINVAL;
}

power_attr(pm_trace_dev_match);
power_attr_ro(pm_trace_dev_match);

#endif /* CONFIG_PM_TRACE */

+9 −0
Original line number Diff line number Diff line
@@ -77,6 +77,15 @@ static struct kobj_attribute _name##_attr = { \
	.store	= _name##_store,		\
}

#define power_attr_ro(_name) \
static struct kobj_attribute _name##_attr = {	\
	.attr	= {				\
		.name = __stringify(_name),	\
		.mode = S_IRUGO,		\
	},					\
	.show	= _name##_show,			\
}

/* Preferred image size in bytes (default 500 MB) */
extern unsigned long image_size;
/* Size of memory reserved for drivers (default SPARE_PAGES x PAGE_SIZE) */
+19 −0
Original line number Diff line number Diff line
@@ -47,6 +47,11 @@ NLS ?= true
# cpufreq-bench benchmarking tool
CPUFREQ_BENCH ?= true

# Do not build libraries, but build the code in statically
# Libraries are still built, otherwise the Makefile code would
# be rather ugly.
export STATIC ?= false

# Prefix to the directories we're installing to
DESTDIR ?=

@@ -161,6 +166,12 @@ ifeq ($(strip $(CPUFREQ_BENCH)),true)
	COMPILE_BENCH += compile-bench
endif

ifeq ($(strip $(STATIC)),true)
        UTIL_OBJS += $(LIB_OBJS)
        UTIL_HEADERS += $(LIB_HEADERS)
        UTIL_SRC += $(LIB_SRC)
endif

CFLAGS += $(WARNINGS)

ifeq ($(strip $(V)),false)
@@ -209,7 +220,11 @@ $(OUTPUT)%.o: %.c

$(OUTPUT)cpupower: $(UTIL_OBJS) $(OUTPUT)libcpupower.so.$(LIB_MAJ)
	$(ECHO) "  CC      " $@
ifeq ($(strip $(STATIC)),true)
	$(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lrt -lpci -L$(OUTPUT) -o $@
else
	$(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lcpupower -lrt -lpci -L$(OUTPUT) -o $@
endif
	$(QUIET) $(STRIPCMD) $@

$(OUTPUT)po/$(PACKAGE).pot: $(UTIL_SRC)
@@ -291,7 +306,11 @@ install-bench:
	@#DESTDIR must be set from outside to survive
	@sbindir=$(sbindir) bindir=$(bindir) docdir=$(docdir) confdir=$(confdir) $(MAKE) -C bench O=$(OUTPUT) install

ifeq ($(strip $(STATIC)),true)
install: all install-tools install-man $(INSTALL_NLS) $(INSTALL_BENCH)
else
install: all install-lib install-tools install-man $(INSTALL_NLS) $(INSTALL_BENCH)
endif

uninstall:
	- rm -f $(DESTDIR)${libdir}/libcpupower.*
+7 −1
Original line number Diff line number Diff line
@@ -5,9 +5,15 @@ ifneq ($(O),)
endif
endif

ifeq ($(strip $(STATIC)),true)
LIBS = -L../ -L$(OUTPUT) -lm
OBJS = $(OUTPUT)main.o $(OUTPUT)parse.o $(OUTPUT)system.o $(OUTPUT)benchmark.o \
       $(OUTPUT)../lib/cpufreq.o $(OUTPUT)../lib/sysfs.o
else
LIBS = -L../ -L$(OUTPUT) -lm -lcpupower

OBJS = $(OUTPUT)main.o $(OUTPUT)parse.o $(OUTPUT)system.o $(OUTPUT)benchmark.o
endif

CFLAGS += -D_GNU_SOURCE -I../lib -DDEFAULT_CONFIG_FILE=\"$(confdir)/cpufreq-bench.conf\"

$(OUTPUT)%.o : %.c
+96 −150
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <getopt.h>

#include "cpufreq.h"
#include "helpers/sysfs.h"
#include "helpers/helpers.h"
#include "helpers/bitmask.h"

@@ -244,149 +245,21 @@ static int get_boost_mode(unsigned int cpu)
	return 0;
}

static void debug_output_one(unsigned int cpu)
{
	char *driver;
	struct cpufreq_affected_cpus *cpus;
	struct cpufreq_available_frequencies *freqs;
	unsigned long min, max, freq_kernel, freq_hardware;
	unsigned long total_trans, latency;
	unsigned long long total_time;
	struct cpufreq_policy *policy;
	struct cpufreq_available_governors *governors;
	struct cpufreq_stats *stats;

	if (cpufreq_cpu_exists(cpu))
		return;

	freq_kernel = cpufreq_get_freq_kernel(cpu);
	freq_hardware = cpufreq_get_freq_hardware(cpu);

	driver = cpufreq_get_driver(cpu);
	if (!driver) {
		printf(_("  no or unknown cpufreq driver is active on this CPU\n"));
	} else {
		printf(_("  driver: %s\n"), driver);
		cpufreq_put_driver(driver);
	}

	cpus = cpufreq_get_related_cpus(cpu);
	if (cpus) {
		printf(_("  CPUs which run at the same hardware frequency: "));
		while (cpus->next) {
			printf("%d ", cpus->cpu);
			cpus = cpus->next;
		}
		printf("%d\n", cpus->cpu);
		cpufreq_put_related_cpus(cpus);
	}

	cpus = cpufreq_get_affected_cpus(cpu);
	if (cpus) {
		printf(_("  CPUs which need to have their frequency coordinated by software: "));
		while (cpus->next) {
			printf("%d ", cpus->cpu);
			cpus = cpus->next;
		}
		printf("%d\n", cpus->cpu);
		cpufreq_put_affected_cpus(cpus);
	}

	latency = cpufreq_get_transition_latency(cpu);
	if (latency) {
		printf(_("  maximum transition latency: "));
		print_duration(latency);
		printf(".\n");
	}

	if (!(cpufreq_get_hardware_limits(cpu, &min, &max))) {
		printf(_("  hardware limits: "));
		print_speed(min);
		printf(" - ");
		print_speed(max);
		printf("\n");
	}

	freqs = cpufreq_get_available_frequencies(cpu);
	if (freqs) {
		printf(_("  available frequency steps: "));
		while (freqs->next) {
			print_speed(freqs->frequency);
			printf(", ");
			freqs = freqs->next;
		}
		print_speed(freqs->frequency);
		printf("\n");
		cpufreq_put_available_frequencies(freqs);
	}

	governors = cpufreq_get_available_governors(cpu);
	if (governors) {
		printf(_("  available cpufreq governors: "));
		while (governors->next) {
			printf("%s, ", governors->governor);
			governors = governors->next;
		}
		printf("%s\n", governors->governor);
		cpufreq_put_available_governors(governors);
	}

	policy = cpufreq_get_policy(cpu);
	if (policy) {
		printf(_("  current policy: frequency should be within "));
		print_speed(policy->min);
		printf(_(" and "));
		print_speed(policy->max);

		printf(".\n                  ");
		printf(_("The governor \"%s\" may"
		       " decide which speed to use\n                  within this range.\n"),
		       policy->governor);
		cpufreq_put_policy(policy);
	}

	if (freq_kernel || freq_hardware) {
		printf(_("  current CPU frequency is "));
		if (freq_hardware) {
			print_speed(freq_hardware);
			printf(_(" (asserted by call to hardware)"));
		} else
			print_speed(freq_kernel);
		printf(".\n");
	}
	stats = cpufreq_get_stats(cpu, &total_time);
	if (stats) {
		printf(_("  cpufreq stats: "));
		while (stats) {
			print_speed(stats->frequency);
			printf(":%.2f%%", (100.0 * stats->time_in_state) / total_time);
			stats = stats->next;
			if (stats)
				printf(", ");
		}
		cpufreq_put_stats(stats);
		total_trans = cpufreq_get_transitions(cpu);
		if (total_trans)
			printf("  (%lu)\n", total_trans);
		else
			printf("\n");
	}
	get_boost_mode(cpu);

}

/* --freq / -f */

static int get_freq_kernel(unsigned int cpu, unsigned int human)
{
	unsigned long freq = cpufreq_get_freq_kernel(cpu);
	if (!freq)
	printf(_("  current CPU frequency: "));
	if (!freq) {
		printf(_(" Unable to call to kernel\n"));
		return -EINVAL;
	}
	if (human) {
		print_speed(freq);
		printf("\n");
	} else
		printf("%lu\n", freq);
		printf("%lu", freq);
	printf(_(" (asserted by call to kernel)\n"));
	return 0;
}

@@ -396,13 +269,16 @@ static int get_freq_kernel(unsigned int cpu, unsigned int human)
static int get_freq_hardware(unsigned int cpu, unsigned int human)
{
	unsigned long freq = cpufreq_get_freq_hardware(cpu);
	if (!freq)
	printf(_("  current CPU frequency: "));
	if (!freq) {
		printf("Unable to call hardware\n");
		return -EINVAL;
	}
	if (human) {
		print_speed(freq);
		printf("\n");
	} else
		printf("%lu\n", freq);
		printf("%lu", freq);
	printf(_(" (asserted by call to hardware)\n"));
	return 0;
}

@@ -411,9 +287,17 @@ static int get_freq_hardware(unsigned int cpu, unsigned int human)
static int get_hardware_limits(unsigned int cpu)
{
	unsigned long min, max;
	if (cpufreq_get_hardware_limits(cpu, &min, &max))

	printf(_("  hardware limits: "));
	if (cpufreq_get_hardware_limits(cpu, &min, &max)) {
		printf(_("Not Available\n"));
		return -EINVAL;
	printf("%lu %lu\n", min, max);
	}

	print_speed(min);
	printf(" - ");
	print_speed(max);
	printf("\n");
	return 0;
}

@@ -422,9 +306,11 @@ static int get_hardware_limits(unsigned int cpu)
static int get_driver(unsigned int cpu)
{
	char *driver = cpufreq_get_driver(cpu);
	if (!driver)
	if (!driver) {
		printf(_("  no or unknown cpufreq driver is active on this CPU\n"));
		return -EINVAL;
	printf("%s\n", driver);
	}
	printf("  driver: %s\n", driver);
	cpufreq_put_driver(driver);
	return 0;
}
@@ -434,9 +320,19 @@ static int get_driver(unsigned int cpu)
static int get_policy(unsigned int cpu)
{
	struct cpufreq_policy *policy = cpufreq_get_policy(cpu);
	if (!policy)
	if (!policy) {
		printf(_("  Unable to determine current policy\n"));
		return -EINVAL;
	printf("%lu %lu %s\n", policy->min, policy->max, policy->governor);
	}
	printf(_("  current policy: frequency should be within "));
	print_speed(policy->min);
	printf(_(" and "));
	print_speed(policy->max);

	printf(".\n                  ");
	printf(_("The governor \"%s\" may decide which speed to use\n"
	       "                  within this range.\n"),
	       policy->governor);
	cpufreq_put_policy(policy);
	return 0;
}
@@ -447,8 +343,12 @@ static int get_available_governors(unsigned int cpu)
{
	struct cpufreq_available_governors *governors =
		cpufreq_get_available_governors(cpu);
	if (!governors)

	printf(_("  available cpufreq governors: "));
	if (!governors) {
		printf(_("Not Available\n"));
		return -EINVAL;
	}

	while (governors->next) {
		printf("%s ", governors->governor);
@@ -465,8 +365,12 @@ static int get_available_governors(unsigned int cpu)
static int get_affected_cpus(unsigned int cpu)
{
	struct cpufreq_affected_cpus *cpus = cpufreq_get_affected_cpus(cpu);
	if (!cpus)

	printf(_("  CPUs which need to have their frequency coordinated by software: "));
	if (!cpus) {
		printf(_("Not Available\n"));
		return -EINVAL;
	}

	while (cpus->next) {
		printf("%d ", cpus->cpu);
@@ -482,8 +386,12 @@ static int get_affected_cpus(unsigned int cpu)
static int get_related_cpus(unsigned int cpu)
{
	struct cpufreq_affected_cpus *cpus = cpufreq_get_related_cpus(cpu);
	if (!cpus)

	printf(_("  CPUs which run at the same hardware frequency: "));
	if (!cpus) {
		printf(_("Not Available\n"));
		return -EINVAL;
	}

	while (cpus->next) {
		printf("%d ", cpus->cpu);
@@ -524,8 +432,12 @@ static int get_freq_stats(unsigned int cpu, unsigned int human)
static int get_latency(unsigned int cpu, unsigned int human)
{
	unsigned long latency = cpufreq_get_transition_latency(cpu);
	if (!latency)

	printf(_("  maximum transition latency: "));
	if (!latency || latency == UINT_MAX) {
		printf(_(" Cannot determine or is not supported.\n"));
		return -EINVAL;
	}

	if (human) {
		print_duration(latency);
@@ -535,6 +447,36 @@ static int get_latency(unsigned int cpu, unsigned int human)
	return 0;
}

static void debug_output_one(unsigned int cpu)
{
	struct cpufreq_available_frequencies *freqs;

	get_driver(cpu);
	get_related_cpus(cpu);
	get_affected_cpus(cpu);
	get_latency(cpu, 1);
	get_hardware_limits(cpu);

	freqs = cpufreq_get_available_frequencies(cpu);
	if (freqs) {
		printf(_("  available frequency steps:  "));
		while (freqs->next) {
			print_speed(freqs->frequency);
			printf(", ");
			freqs = freqs->next;
		}
		print_speed(freqs->frequency);
		printf("\n");
		cpufreq_put_available_frequencies(freqs);
	}

	get_available_governors(cpu);
	get_policy(cpu);
	if (get_freq_hardware(cpu, 1) < 0)
		get_freq_kernel(cpu, 1);
	get_boost_mode(cpu);
}

static struct option info_opts[] = {
	{"debug",	 no_argument,		 NULL,	 'e'},
	{"boost",	 no_argument,		 NULL,	 'b'},
@@ -647,11 +589,14 @@ int cmd_freq_info(int argc, char **argv)

		if (!bitmask_isbitset(cpus_chosen, cpu))
			continue;
		if (cpufreq_cpu_exists(cpu)) {
			printf(_("couldn't analyze CPU %d as it doesn't seem to be present\n"), cpu);

		printf(_("analyzing CPU %d:\n"), cpu);

		if (sysfs_is_cpu_online(cpu) != 1) {
			printf(_(" *is offline\n"));
			printf("\n");
			continue;
		}
		printf(_("analyzing CPU %d:\n"), cpu);

		switch (output_param) {
		case 'b':
@@ -693,6 +638,7 @@ int cmd_freq_info(int argc, char **argv)
		}
		if (ret)
			return ret;
		printf("\n");
	}
	return ret;
}
Loading