[Xfce4-commits] <xfce4-cpufreq-plugin:master> Add support for the Intel P-State driver.

Harald Judt noreply at xfce.org
Sun Aug 18 11:32:16 CEST 2013


Updating branch refs/heads/master
         to f3bfa666503563ea9d0e2fb6ce2e8f1d558d738e (commit)
       from e5b824087d347de8edd088834c09aa1c69cf953a (commit)

commit f3bfa666503563ea9d0e2fb6ce2e8f1d558d738e
Author: Harald Judt <h.judt at gmx.at>
Date:   Sun Aug 11 13:22:48 2013 +0200

    Add support for the Intel P-State driver.
    
    This makes the current version work with the intel pstate driver.
    Showing governors and performance values works, the pstate parameters
    are read but not used yet; The UI has to be reworked to accommodate
    for that.

 panel-plugin/xfce4-cpufreq-linux.c  |  251 ++++++++++++++++++++++++++---------
 panel-plugin/xfce4-cpufreq-linux.h  |    3 +
 panel-plugin/xfce4-cpufreq-plugin.c |    2 +
 panel-plugin/xfce4-cpufreq-plugin.h |   14 +-
 4 files changed, 203 insertions(+), 67 deletions(-)

diff --git a/panel-plugin/xfce4-cpufreq-linux.c b/panel-plugin/xfce4-cpufreq-linux.c
index 954048e..11a7ddb 100644
--- a/panel-plugin/xfce4-cpufreq-linux.c
+++ b/panel-plugin/xfce4-cpufreq-linux.c
@@ -35,48 +35,53 @@
 #endif
 
 static gboolean
-cpufreq_cpu_parse_sysfs_init (gint cpu_number)
+cpufreq_cpu_parse_sysfs_init (gint cpu_number, CpuInfo *cpu)
 {
-	CpuInfo *cpu;
 	FILE    *file;
 	gchar   *filePath, *fileContent, **tokens;
+	gboolean add_cpu = FALSE;
 
-	cpu = g_new0 (CpuInfo, 1);
+	if (cpu == NULL) {
+		cpu = g_new0 (CpuInfo, 1);
+		add_cpu = TRUE;
+	}
 
 	/* read available cpu freqs */
-	filePath = g_strdup_printf (
-		"/sys/devices/system/cpu/cpu%i/cpufreq/scaling_available_frequencies",
-		cpu_number);
-	if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
-		goto file_error;
-	file = fopen (filePath, "r");
-	if (file)
-	{
-		gint i = 0;
+	if (cpuFreq->intel_pstate == NULL) {
+		filePath =
+			g_strdup_printf ("/sys/devices/system/cpu/cpu%i/"
+							 "cpufreq/scaling_available_frequencies",
+							 cpu_number);
+		if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
+			goto file_error;
+		file = fopen (filePath, "r");
+		if (file) {
+			gint i = 0;
 
-		fileContent = g_new (gchar, 255);
-		fgets (fileContent, 255, file);
-		fclose (file);
+			fileContent = g_new (gchar, 255);
+			fgets (fileContent, 255, file);
+			fclose (file);
 
-		fileContent = g_strchomp (fileContent);
-		tokens = g_strsplit (fileContent, " ", 0);
-		g_free (fileContent);
+			fileContent = g_strchomp (fileContent);
+			tokens = g_strsplit (fileContent, " ", 0);
+			g_free (fileContent);
 
-		while (tokens[i] != NULL)
-		{
-			gint freq = atoi (tokens[i]);
-			cpu->available_freqs = g_list_append (
-				cpu->available_freqs, GINT_TO_POINTER(freq));
-			i++;
+			while (tokens[i] != NULL) {
+				gint freq = atoi (tokens[i]);
+				cpu->available_freqs =
+					g_list_append (cpu->available_freqs,
+								   GINT_TO_POINTER(freq));
+				i++;
+			}
+			g_strfreev (tokens);
 		}
-		g_strfreev (tokens);
+		g_free (filePath);
 	}
-	g_free (filePath);
 
 	/* read available cpu governors */
 	filePath = g_strdup_printf (
 		"/sys/devices/system/cpu/cpu%i/cpufreq/scaling_available_governors",
-       		cpu_number);
+		cpu_number);
 	if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
 		goto file_error;
 	file = fopen (filePath, "r");
@@ -112,6 +117,7 @@ cpufreq_cpu_parse_sysfs_init (gint cpu_number)
 	file = fopen (filePath, "r");
 	if (file)
 	{
+		g_free (cpu->scaling_driver);
 		cpu->scaling_driver = g_new (gchar, 15);
 		fscanf (file, "%15s", cpu->scaling_driver);
 		fclose (file);
@@ -119,18 +125,20 @@ cpufreq_cpu_parse_sysfs_init (gint cpu_number)
 	g_free (filePath);
 
 	/* read current cpu freq */
-	filePath = g_strdup_printf (
-		"/sys/devices/system/cpu/cpu%i/cpufreq/scaling_cur_freq",
-		cpu_number);
-	if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
-		goto file_error;
-	file = fopen (filePath, "r");
-	if (file)
-	{
-		fscanf (file, "%d", &cpu->cur_freq);
-		fclose (file);
+	if (cpuFreq->intel_pstate == NULL) {
+		filePath =
+			g_strdup_printf ("/sys/devices/system/cpu/cpu%i/"
+							 "cpufreq/scaling_cur_freq",
+							 cpu_number);
+		if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
+			goto file_error;
+		file = fopen (filePath, "r");
+		if (file) {
+			fscanf (file, "%d", &cpu->cur_freq);
+			fclose (file);
+		}
+		g_free (filePath);
 	}
-	g_free (filePath);
 
 	/* read current cpu governor */
 	filePath = g_strdup_printf (
@@ -141,6 +149,7 @@ cpufreq_cpu_parse_sysfs_init (gint cpu_number)
 	file = fopen (filePath, "r");
 	if (file)
 	{
+		g_free (cpu->cur_governor);
 		cpu->cur_governor = g_new (gchar, 15);
 		fscanf (file, "%15s", cpu->cur_governor);
 		fclose (file);
@@ -175,11 +184,14 @@ cpufreq_cpu_parse_sysfs_init (gint cpu_number)
 	}
 	g_free (filePath);
 
-	g_ptr_array_add (cpuFreq->cpus, cpu);
+	if (add_cpu)
+		g_ptr_array_add (cpuFreq->cpus, cpu);
 
 	return TRUE;
 
 file_error:
+	if (add_cpu && cpu != NULL)
+		cpuinfo_free (cpu);
 	g_free (filePath);
 	return FALSE;
 }
@@ -194,18 +206,20 @@ cpufreq_cpu_read_sysfs_current (gint cpu_number)
 	cpu = g_ptr_array_index (cpuFreq->cpus, cpu_number);
 
 	/* read current cpu freq */
-	filePath = g_strdup_printf (
-		"/sys/devices/system/cpu/cpu%i/cpufreq/scaling_cur_freq",
-		cpu_number);
-	if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
-		goto file_error;
-	file = fopen (filePath, "r");
-	if (file)
-	{
-		fscanf (file, "%d", &cpu->cur_freq);
-		fclose (file);
+	if (cpuFreq->intel_pstate == NULL) {
+		filePath =
+			g_strdup_printf ("/sys/devices/system/cpu/cpu%i/"
+							 "cpufreq/scaling_cur_freq",
+							 cpu_number);
+		if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
+			goto file_error;
+		file = fopen (filePath, "r");
+		if (file) {
+			fscanf (file, "%d", &cpu->cur_freq);
+			fclose (file);
+		}
+		g_free (filePath);
 	}
-	g_free (filePath);
 
 	/* read current cpu governor */
 	filePath = g_strdup_printf (
@@ -234,6 +248,8 @@ cpufreq_cpu_read_procfs_cpuinfo ()
 	CpuInfo	*cpu;
 	FILE	*file;
 	gchar	*freq, *filePath, *fileContent;
+	gint     i = 0;
+	gboolean add_cpu;
 
 	filePath = g_strdup ("/proc/cpuinfo");
 	if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
@@ -249,12 +265,24 @@ cpufreq_cpu_read_procfs_cpuinfo ()
 		{
 			if (g_ascii_strncasecmp (fileContent, "cpu MHz", 7) == 0)
 			{
-				cpu = g_new0 (CpuInfo, 1);
-				cpu->max_freq = 0;
-				cpu->min_freq = 0;
-				cpu->cur_governor = NULL;
-				cpu->available_freqs = NULL;
-				cpu->available_governors = NULL;
+				cpu = NULL;
+				add_cpu = FALSE;
+
+				if (cpuFreq->cpus && cpuFreq->cpus->len > i)
+				{
+					cpu = g_ptr_array_index (cpuFreq->cpus, i);
+				}
+
+				if (cpu == NULL)
+				{
+					cpu = g_new0 (CpuInfo, 1);
+					cpu->max_freq = 0;
+					cpu->min_freq = 0;
+					cpu->cur_governor = NULL;
+					cpu->available_freqs = NULL;
+					cpu->available_governors = NULL;
+					add_cpu = TRUE;
+				}
 
 				freq = g_strrstr (fileContent, ":");
 				if (freq != NULL)
@@ -262,10 +290,16 @@ cpufreq_cpu_read_procfs_cpuinfo ()
 					sscanf (++freq, "%d.", &cpu->cur_freq);
 					cpu->cur_freq *= 1000;
 				}
-				else
+				else {
+					if (add_cpu)
+						cpuinfo_free (cpu);
 					break;
+				}
 
-				g_ptr_array_add (cpuFreq->cpus, cpu);
+				if (add_cpu && cpu != NULL)
+					g_ptr_array_add (cpuFreq->cpus, cpu);
+
+				++i;
 			}
 		}
 		fclose (file);
@@ -305,7 +339,7 @@ cpufreq_cpu_read_procfs ()
 				cpu->available_freqs = NULL;
 				cpu->available_governors = NULL;
 
-				sscanf (fileContent, 
+				sscanf (fileContent,
 					"CPU %*d %d kHz (%*d %%) - %d kHz (%*d %%) - %20s",
 					&cpu->min_freq,
 					&cpu->max_freq,
@@ -359,18 +393,104 @@ cpufreq_cpu_read_sysfs ()
 
 	for (j = 0; j < i; j++)
 	{
-		cpufreq_cpu_parse_sysfs_init (j);
+		cpufreq_cpu_parse_sysfs_init (j, NULL);
 	}
 
 	return TRUE;
 }
 
 gboolean
+cpufreq_intel_pstate_params (void)
+{
+	FILE    *file;
+	gchar   *filePath, *fileContent;
+	IntelPState *ips;
+
+	ips = g_slice_new0(IntelPState);
+
+	filePath =
+		g_strdup ("/sys/devices/system/cpu/intel_pstate/min_perf_pct");
+	if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
+		goto file_error;
+	file = fopen (filePath, "r");
+	if (file) {
+		fscanf (file, "%d", &ips->min_perf_pct);
+		fclose (file);
+	}
+	g_free (filePath);
+
+	filePath =
+		g_strdup ("/sys/devices/system/cpu/intel_pstate/max_perf_pct");
+	if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
+		goto file_error;
+	file = fopen (filePath, "r");
+	if (file) {
+		fscanf (file, "%d", &ips->max_perf_pct);
+		fclose (file);
+	}
+	g_free (filePath);
+
+	filePath =
+		g_strdup ("/sys/devices/system/cpu/intel_pstate/no_turbo");
+	if (!g_file_test (filePath, G_FILE_TEST_EXISTS))
+		goto file_error;
+	file = fopen (filePath, "r");
+	if (file) {
+		fscanf (file, "%d", &ips->no_turbo);
+		fclose (file);
+	}
+	g_free (filePath);
+
+	g_slice_free (IntelPState, cpuFreq->intel_pstate);
+	cpuFreq->intel_pstate = ips;
+	return TRUE;
+
+file_error:
+	g_slice_free (IntelPState, ips);
+	g_free (filePath);
+	return FALSE;
+}
+
+static gboolean
+cpufreq_cpu_intel_pstate_read ()
+{
+	CpuInfo *cpu;
+	gint i;
+
+	/* gather intel pstate parameters */
+	if (!cpufreq_intel_pstate_params ())
+		return FALSE;
+
+	/* Read /proc/cpuinfo, that's where intel pstate stores
+	   the "current frequencies" that are readable by
+	   unprivileged users. */
+	if (!cpufreq_cpu_read_procfs_cpuinfo ())
+		return FALSE;
+
+	/* now read the remaining cpufreq info for each cpu from sysfs */
+	for (i = 0; i < cpuFreq->cpus->len; i++) {
+		cpu = g_ptr_array_index (cpuFreq->cpus, i);
+		cpufreq_cpu_parse_sysfs_init (i, cpu);
+	}
+	return TRUE;
+}
+
+gboolean
 cpufreq_update_cpus (gpointer data)
 {
 	gint i;
 
-	if (g_file_test ("/sys/devices/system/cpu/cpu0/cpufreq", G_FILE_TEST_EXISTS))
+	if (g_file_test ("/sys/devices/system/cpu/intel_pstate", G_FILE_TEST_EXISTS))
+	{
+		/* read current cpu frequencies from /proc/cpuinfo */
+		cpufreq_cpu_read_procfs_cpuinfo ();
+
+		/* read current scaling governor from sysfs */
+		for (i = 0; i < cpuFreq->cpus->len; i++)
+			cpufreq_cpu_read_sysfs_current (i);
+	}
+	else if (g_file_test ("/sys/devices/system/cpu/cpu0/cpufreq",
+						  G_FILE_TEST_EXISTS))
 	{
 		for (i = 0; i < cpuFreq->cpus->len; i++)
 			cpufreq_cpu_read_sysfs_current (i);
@@ -382,8 +502,7 @@ cpufreq_update_cpus (gpointer data)
 		{
 			CpuInfo *cpu = g_ptr_array_index (cpuFreq->cpus, i);
 			g_ptr_array_remove_fast (cpuFreq->cpus, cpu);
-			g_free (cpu->cur_governor);
-			g_free (cpu);
+			cpuinfo_free (cpu);
 		}
 		cpufreq_cpu_read_procfs ();
 	}
@@ -402,8 +521,10 @@ cpufreq_linux_init (void)
 	if (cpuFreq->cpus == NULL)
 		return FALSE;
 
-	if (g_file_test ("/sys/devices/system/cpu/cpu0/cpufreq", G_FILE_TEST_EXISTS) &&
-		!g_file_test ("/sys/devices/system/cpu/intel_pstate", G_FILE_TEST_EXISTS))
+	if (g_file_test ("/sys/devices/system/cpu/intel_pstate", G_FILE_TEST_EXISTS))
+		return cpufreq_cpu_intel_pstate_read ();
+	else if (g_file_test ("/sys/devices/system/cpu/cpu0/cpufreq",
+						  G_FILE_TEST_EXISTS))
 		return cpufreq_cpu_read_sysfs ();
 	else if (g_file_test ("/proc/cpufreq", G_FILE_TEST_EXISTS))
 		return cpufreq_cpu_read_procfs ();
diff --git a/panel-plugin/xfce4-cpufreq-linux.h b/panel-plugin/xfce4-cpufreq-linux.h
index 04c87e1..7360c42 100644
--- a/panel-plugin/xfce4-cpufreq-linux.h
+++ b/panel-plugin/xfce4-cpufreq-linux.h
@@ -26,6 +26,9 @@ gboolean
 cpufreq_update_cpus (gpointer data);
 
 gboolean
+cpufreq_intel_pstate_params (void);
+
+gboolean
 cpufreq_linux_init (void);
 
 G_END_DECLS
diff --git a/panel-plugin/xfce4-cpufreq-plugin.c b/panel-plugin/xfce4-cpufreq-plugin.c
index ce7d7e5..f19b9d3 100644
--- a/panel-plugin/xfce4-cpufreq-plugin.c
+++ b/panel-plugin/xfce4-cpufreq-plugin.c
@@ -366,6 +366,8 @@ cpufreq_free (XfcePanelPlugin *plugin)
 	if (cpuFreq->timeoutHandle)
 		g_source_remove (cpuFreq->timeoutHandle);
 
+	g_slice_free (IntelPState, cpuFreq->intel_pstate);
+
 	for (i = 0; i < cpuFreq->cpus->len; i++)
 	{
 		CpuInfo *cpu = g_ptr_array_index (cpuFreq->cpus, i);
diff --git a/panel-plugin/xfce4-cpufreq-plugin.h b/panel-plugin/xfce4-cpufreq-plugin.h
index 890b22e..0f2d313 100644
--- a/panel-plugin/xfce4-cpufreq-plugin.h
+++ b/panel-plugin/xfce4-cpufreq-plugin.h
@@ -38,8 +38,15 @@ typedef struct
 
 typedef struct
 {
-	guint 	 timeout; 	/* time between refreash */
-	guint	 show_cpu;  	/* cpu number in panel */
+	gint     min_perf_pct;
+	gint     max_perf_pct;
+	gint     no_turbo;
+} IntelPState;
+
+typedef struct
+{
+	guint 	 timeout;       /* time between refresh */
+	guint	 show_cpu;      /* cpu number in panel */
 	gboolean show_icon;
 	gboolean show_label_governor;
 	gboolean show_label_freq;
@@ -55,6 +62,9 @@ typedef struct
 	/* Array with all CPUs */
 	GPtrArray *cpus;
 
+	/* Intel P-State parameters */
+	IntelPState *intel_pstate;
+
 	/* Widgets */
 	GtkWidget *button, *box, *icon, *label;
 


More information about the Xfce4-commits mailing list