Skip to contentSkip to conversation

libcpupower/cpufreq-info: Add basic functions to detect AMD CPB information

PATCH In review Thomas Renninger 2 participants 5 messages Feb 9, 2011 – Feb 16, 2011 1 message not in the archive

Subsystems (2)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

PATCH 1/8 libcpupower/cpufreq-info: Add basic functions to detect AMD CPB information

From: Andreas Herrmann <[email protected]>

To gather boost state information on AMD we need to access CPU northbridge PCI functions.

Thus this change introduces a dependency on libpci (part of pciutils and usually installed on Linux systems).

Detect whether CPB is enabled/disabled and number of boosted states.

---
 Makefile             |    8 ++--
 lib/cpufreq.c        |    8 ++--
 lib/cpufreq.h        |    2 +-
 lib/msr.c            |   11 ------
 lib/msr.h            |    2 -
 lib/pci.c            |   89 ++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/pci.h            |    1 +
 utils/cpufreq-info.c |    5 ++-
 8 files changed, 102 insertions(+), 24 deletions(-)
 create mode 100644 lib/pci.c
 create mode 100644 lib/pci.h
Makefile +4 -4
index 2cd9e83..0386f53 100644
@@ -113,9 +113,9 @@ CPPFLAGS += -DVERSION=\"$(VERSION)\" -DPACKAGE=\"$(PACKAGE)\" \
 
 UTIL_SRC = 	utils/cpufreq-info.c utils/cpufreq-set.c utils/cpufreq-aperf.c utils/cpuidle-info.c
 UTIL_BINS = 	utils/cpufreq-info utils/cpufreq-set utils/cpufreq-aperf utils/cpuidle-info
-LIB_HEADERS = 	lib/cpufreq.h lib/cpuidle.h lib/sysfs.h lib/msr.h lib/cpuid.h
-LIB_SRC = 	lib/cpufreq.c lib/cpuidle.c lib/sysfs.c lib/msr.c
-LIB_OBJS = 	lib/cpufreq.o lib/cpuidle.o lib/sysfs.o lib/msr.o
+LIB_HEADERS = 	lib/cpufreq.h lib/cpuidle.h lib/sysfs.h lib/msr.h lib/cpuid.h lib/pci.h
+LIB_SRC = 	lib/cpufreq.c lib/cpuidle.c lib/sysfs.c lib/msr.c lib/pci.c
+LIB_OBJS = 	lib/cpufreq.o lib/cpuidle.o lib/sysfs.o lib/msr.o lib/pci.o
 
 CFLAGS +=	-pipe
 
@@ -163,7 +163,7 @@ lib/%.o: $(LIB_SRC) $(LIB_HEADERS) build/ccdv
 	$(QUIET) $(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -o $@ -c lib/$*.c
 
 libcpupower.so.$(LIB_MAJ): $(LIB_OBJS)
-	$(CC) -shared $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ \
+	$(CC) -shared $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ -l pci \
 		-Wl,-soname,libcpupower.so.$(LIB_MIN) $(LIB_OBJS)
 	@ln -sf $@ libcpupower.so
 	@ln -sf $@ libcpupower.so.$(LIB_MIN)
lib/cpufreq.c +4 -4
index 0b5fe9f..731d61f 100644
@@ -14,6 +14,7 @@
 #include "sysfs.h"
 #include "cpuid.h"
 #include "msr.h"
+#include "pci.h"
 
 int cpufreq_cpu_exists(unsigned int cpu)
 {
@@ -191,12 +192,12 @@ unsigned long cpufreq_get_transitions(unsigned int cpu) {
 	return (ret);
 }
 
-int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active)
+int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, int * states)
 {
 	struct cpupower_cpu_info cpu_info;
 	int ret;
 
-	*support = *active = 0;
+	*support = *active = *states = 0;
 
 	ret = get_cpu_info(0, &cpu_info);
 	if (ret)
@@ -218,10 +219,9 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active)
 			*support = 1;
 		else
 			return 0;
-		ret = msr_amd_boost_is_active(cpu);
+		amd_pci_get_num_boost_states(active, states);
 		if (ret <= 0)
 			return ret;
-		*active = ret;
 	}
 	return 0;
 }
lib/cpufreq.h +1 -1
index 506b6fc..378c063 100644
@@ -213,7 +213,7 @@ extern int cpufreq_set_frequency(unsigned int cpu, unsigned long target_frequenc
  * Check whether Intel's "Turbo Boost Technology" or AMD's
  * "Dynamic Speed Boost Technology" is supported and if, whether it's activated
  */
-extern int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active);
+extern int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, int *states);
 
 
 #ifdef __cplusplus
lib/msr.c +0 -11
index 3b59fb5..285290f 100644
@@ -127,17 +127,6 @@ int msr_amd_get_fidvid(unsigned int cpu, uint32_t *fid, uint32_t *vid)
 	return 0;
 }
 
-int msr_amd_boost_is_active(unsigned int cpu)
-{
-	uint64_t k7_hwcr;
-	int ret;
-
-	ret = read_msr(cpu, MSR_K7_HWCR, &k7_hwcr);
-	if (ret)
-		return ret;
-	return !((k7_hwcr >> 25) & 0x1);
-}
-
 /* Intel X86 MSRs **********************************/
 int msr_intel_get_perf_status(unsigned int cpu, uint64_t perf_status)
 {
lib/msr.h +0 -2
index 6b743ce..ac44a6a 100644
@@ -6,5 +6,3 @@ extern int msr_intel_get_perf_status(unsigned int cpu, uint64_t perf_status);
 
 extern int msr_intel_has_boost_support(unsigned int cpu);
 extern int msr_intel_boost_is_active(unsigned int cpu);
-
-extern int msr_amd_boost_is_active(unsigned int cpu);
lib/pci.c new file +89 -0

89 lines not on this page · raw message

lib/pci.h new file +1 -0
new file mode 100644
index 0000000..d29df49
@@ -0,0 +1 @@
+extern int amd_pci_get_num_boost_states(int *active, int *states);
utils/cpufreq-info.c +3 -2
index 4d479f3..bb8e425 100644
@@ -290,9 +290,9 @@ static void debug_output(unsigned int cpu, unsigned int all) {
 /* --boost / -b */
 
 static int get_boost_mode(unsigned int cpu) {
-	int support, active, ret;
+	int support, active, states, ret;
 
-	ret = cpufreq_has_boost_support(cpu, &support, &active);
+	ret = cpufreq_has_boost_support(cpu, &support, &active, &states);
 	if (ret) {
 		printf(gettext ("Error while evaluating Boost Capabilities"
 				" on CPU %d -- are you root?\n"), cpu);
@@ -302,6 +302,7 @@ static int get_boost_mode(unsigned int cpu) {
 	printf(gettext ("Analyzing Boost Capabilities on CPU %d:\n"), cpu);
 	printf("Supported: %s\n", support ? "yes" : "no");
 	printf("Active: %s\n", active ? "yes" : "no");
+	printf("Boost States: %d\n", states);
 
 	return 0;
 }
Signature · 1 line
1.7.3.4
#2 lore raw
Quoted 7 lines · Thomas Renninger

From: Andreas Herrmann <[email protected]>

To gather boost state information on AMD we need to access CPU northbridge PCI functions.

Thus this change introduces a dependency on libpci (part of pciutils and usually installed on Linux systems).

Do we need to depend on libpci unconditionally, or can we make this per-arch?

Best,
Dominik

#3 lore raw

PATCH 2/8 Make linking quiet again

In reply to a message not in the archive
---
 Makefile |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
Makefile +2 -2
index 0386f53..510b10f 100644
@@ -163,7 +163,7 @@ lib/%.o: $(LIB_SRC) $(LIB_HEADERS) build/ccdv
 	$(QUIET) $(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -o $@ -c lib/$*.c
 
 libcpupower.so.$(LIB_MAJ): $(LIB_OBJS)
-	$(CC) -shared $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ -l pci \
+	$(QUIET) $(CC) -shared $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ -l pci \
 		-Wl,-soname,libcpupower.so.$(LIB_MIN) $(LIB_OBJS)
 	@ln -sf $@ libcpupower.so
 	@ln -sf $@ libcpupower.so.$(LIB_MIN)
@@ -171,7 +171,7 @@ libcpupower.so.$(LIB_MAJ): $(LIB_OBJS)
 # Still Provide the old lib, but apps should get fixed to
 # not link against it anymore
 libcpufreq.so.$(LIB_MAJ): libcpupower.so.$(LIB_MAJ)
-	$(CC) -shared $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ \
+	$(QUIET) $(CC) -shared $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ \
 		-Wl,-soname,libcpufreq.so.$(LIB_MIN) -l cpupower -L .
 	@ln -sf $@ libcpufreq.so
 	@ln -sf $@ libcpufreq.so.$(LIB_MIN)
Signature · 1 line
1.7.3.4
#4 lore raw

PATCH 3/8 libcpupower: libcpufreq: Provide boost information also for AMD family 12h and 15h

In reply to a message not in the archive

From: Andreas Herrmann <[email protected]>

---
 lib/pci.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
lib/pci.c +2 -2
index 8887aa5..2304e4d 100644
@@ -66,7 +66,7 @@ int amd_pci_get_num_boost_states(int *active, int *states)
 {
 	struct pci_access *pci_acc;
 	int vendor_id = 0x1022;
-	int boost_dev_ids[2] = {0x1204, 0};
+	int boost_dev_ids[4] = {0x1204, 0x1604, 0x1704, 0};
 	struct pci_dev *device;
 	uint8_t val = 0;
 
@@ -82,7 +82,7 @@ int amd_pci_get_num_boost_states(int *active, int *states)
 		*active = 1;
 	else
 		*active = 0;
-	*states = (val >> 2) & 1;
+	*states = (val >> 2) & 7;
 
 	pci_acc_cleanup(pci_acc);
 	return 0;
Signature · 1 line
1.7.3.4
#5 lore raw

PATCH 4/8 cpufreq-aperf: mperf might tick faster than expected, esp on Intel

In reply to a message not in the archive
---
 utils/cpufreq-aperf.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)
utils/cpufreq-aperf.c +4 -1
index c9461ae..07494a8 100644
@@ -153,7 +153,10 @@ static int get_C_state_time(struct timeval time_diff, uint64_t mperf_diff,
 	expected_ticks = max_freq * overall_msecs;
 	*percent = (mperf_diff * 100) / expected_ticks;
 
-	cx_time = (expected_ticks - mperf_diff) / max_freq;
+	if (mperf_diff > expected_ticks)
+		cx_time = 0;
+	else
+		cx_time = (expected_ticks - mperf_diff) / max_freq;
 	c0_time = mperf_diff / max_freq;
 
 	CX_time->tv_sec  = cx_time / 1000;
Signature · 1 line
1.7.3.4