diff mbox

cpufreq: cpufreq_stats in the absence of frequency table

Message ID 1470179937-14698-1-git-send-email-pprakash@codeaurora.org (mailing list archive)
State Rejected, archived
Headers show

Commit Message

Prakash, Prashanth Aug. 2, 2016, 11:18 p.m. UTC
cpufreq drivers such as CPPC works on contigious scale and does
not have a static frequency table. This commit adds cpufreq_stats
support for such drivers by creating a pseudo frequency table by
discretizing the contigious scale.

Signed-off-by: Prashanth Prakash <pprakash@codeaurora.org>
---
 drivers/cpufreq/cpufreq_stats.c | 63 ++++++++++++++++++++++++++++++++---------
 1 file changed, 50 insertions(+), 13 deletions(-)

Comments

Prakash, Prashanth Aug. 2, 2016, 11:41 p.m. UTC | #1
Hi Rafael,

On 8/2/2016 5:27 PM, Rafael J. Wysocki wrote:
> On Tuesday, August 02, 2016 05:18:57 PM Prashanth Prakash wrote:
>> cpufreq drivers such as CPPC works on contigious scale and does
>> not have a static frequency table. This commit adds cpufreq_stats
>> support for such drivers by creating a pseudo frequency table by
>> discretizing the contigious scale.
> No.
>
> And why?
The motivation is to be able to collect the frequency distribution data via
time_in_state sysfs entry as we can collect for other cpufreq drivers that
uses a frequency table.

Thanks,
Prashanth
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rafael J. Wysocki Aug. 2, 2016, 11:49 p.m. UTC | #2
On Tuesday, August 02, 2016 05:41:24 PM Prakash, Prashanth wrote:
> Hi Rafael,
> 
> On 8/2/2016 5:27 PM, Rafael J. Wysocki wrote:
> > On Tuesday, August 02, 2016 05:18:57 PM Prashanth Prakash wrote:
> >> cpufreq drivers such as CPPC works on contigious scale and does
> >> not have a static frequency table. This commit adds cpufreq_stats
> >> support for such drivers by creating a pseudo frequency table by
> >> discretizing the contigious scale.
> > No.
> >
> > And why?
> The motivation is to be able to collect the frequency distribution data via
> time_in_state sysfs entry as we can collect for other cpufreq drivers that
> uses a frequency table.

Which can be done by using the cpu_frequency trace point just fine, can't it?

Plus, cpufreq_stats don't work with the schedutil governor and fast frequency
switching anyway.

Thanks,
Rafael

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Prakash, Prashanth Aug. 3, 2016, 3:41 p.m. UTC | #3
Hi Rafael,

On 8/2/2016 5:49 PM, Rafael J. Wysocki wrote:
> On Tuesday, August 02, 2016 05:41:24 PM Prakash, Prashanth wrote:
>> Hi Rafael,
>>
>> On 8/2/2016 5:27 PM, Rafael J. Wysocki wrote:
>>> On Tuesday, August 02, 2016 05:18:57 PM Prashanth Prakash wrote:
>>>> cpufreq drivers such as CPPC works on contigious scale and does
>>>> not have a static frequency table. This commit adds cpufreq_stats
>>>> support for such drivers by creating a pseudo frequency table by
>>>> discretizing the contigious scale.
>>> No.
>>>
>>> And why?
>> The motivation is to be able to collect the frequency distribution data via
>> time_in_state sysfs entry as we can collect for other cpufreq drivers that
>> uses a frequency table.
> Which can be done by using the cpu_frequency trace point just fine, can't it?
Yes, but wanted to make sure existing userspace tools can be used with
platforms using CPPC as well.
> Plus, cpufreq_stats don't work with the schedutil governor and fast frequency
> switching anyway.
If we are expecting that usage of cpufreq_stats will slowly go away as we
switch to schedutil and more drivers enable fast_switching, then I agree
it doesn't make much sense to add support for cpufreq_stats.

Thanks,
Prashanth
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rafael J. Wysocki Aug. 3, 2016, 9:41 p.m. UTC | #4
On Wed, Aug 3, 2016 at 5:41 PM, Prakash, Prashanth
<pprakash@codeaurora.org> wrote:
> Hi Rafael,
>
> On 8/2/2016 5:49 PM, Rafael J. Wysocki wrote:
>> On Tuesday, August 02, 2016 05:41:24 PM Prakash, Prashanth wrote:
>>> Hi Rafael,
>>>
>>> On 8/2/2016 5:27 PM, Rafael J. Wysocki wrote:
>>>> On Tuesday, August 02, 2016 05:18:57 PM Prashanth Prakash wrote:
>>>>> cpufreq drivers such as CPPC works on contigious scale and does
>>>>> not have a static frequency table. This commit adds cpufreq_stats
>>>>> support for such drivers by creating a pseudo frequency table by
>>>>> discretizing the contigious scale.
>>>> No.
>>>>
>>>> And why?
>>> The motivation is to be able to collect the frequency distribution data via
>>> time_in_state sysfs entry as we can collect for other cpufreq drivers that
>>> uses a frequency table.
>> Which can be done by using the cpu_frequency trace point just fine, can't it?
>
> Yes, but wanted to make sure existing userspace tools can be used with
> platforms using CPPC as well.

powertop uses the cpu_frequency trace point already.

Generally, everything that works with intel_pstate should be using it
too, as intel_pstate doesn't use cpufreq_stats.

>> Plus, cpufreq_stats don't work with the schedutil governor and fast frequency
>> switching anyway.
>
> If we are expecting that usage of cpufreq_stats will slowly go away as we
> switch to schedutil and more drivers enable fast_switching, then I agree
> it doesn't make much sense to add support for cpufreq_stats.

Regardless of the expectations about the future, let's just say that
cpufreq_stats only makes sense if frequency tables are in use and only
if __target_index() is used to change frequencies.

And yes, I would like it to go away, because it is inefficient and clunky.

Thanks,
Rafael
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 06d3abd..4eb9c41 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -14,6 +14,9 @@ 
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/cputime.h>
+#include <linux/types.h>
+
+#define CPUFREQ_PSEUDO_FREQ_TABLE_COUNT (16)
 
 static DEFINE_SPINLOCK(cpufreq_stats_lock);
 
@@ -25,6 +28,7 @@  struct cpufreq_stats {
 	unsigned int last_index;
 	u64 *time_in_state;
 	unsigned int *freq_table;
+	bool pseudo_freq_table;
 #ifdef CONFIG_CPU_FREQ_STAT_DETAILS
 	unsigned int *trans_table;
 #endif
@@ -130,9 +134,17 @@  static struct attribute_group stats_attr_group = {
 static int freq_table_get_index(struct cpufreq_stats *stats, unsigned int freq)
 {
 	int index;
-	for (index = 0; index < stats->max_state; index++)
-		if (stats->freq_table[index] == freq)
-			return index;
+
+	if (stats->pseudo_freq_table) {
+		for (index = 0; index < stats->max_state; index++)
+			if (stats->freq_table[index] >= freq)
+				return index;
+	} else {
+		for (index = 0; index < stats->max_state; index++)
+			if (stats->freq_table[index] == freq)
+				return index;
+	}
+
 	return -1;
 }
 
@@ -154,14 +166,14 @@  void cpufreq_stats_free_table(struct cpufreq_policy *policy)
 
 void cpufreq_stats_create_table(struct cpufreq_policy *policy)
 {
-	unsigned int i = 0, count = 0, ret = -ENOMEM;
+	unsigned int i = 0, count = 0, ret = -ENOMEM, step_size;
 	struct cpufreq_stats *stats;
 	unsigned int alloc_size;
 	struct cpufreq_frequency_table *pos, *table;
 
-	/* We need cpufreq table for creating stats table */
+	/* We need cpufreq table or min < max for creating stats table */
 	table = policy->freq_table;
-	if (unlikely(!table))
+	if (!table && !(policy->min < policy->max))
 		return;
 
 	/* stats already initialized */
@@ -173,8 +185,20 @@  void cpufreq_stats_create_table(struct cpufreq_policy *policy)
 		return;
 
 	/* Find total allocation size */
-	cpufreq_for_each_valid_entry(pos, table)
-		count++;
+	if (table) {
+		cpufreq_for_each_valid_entry(pos, table)
+			count++;
+	} else {
+		stats->pseudo_freq_table = true;
+		count = CPUFREQ_PSEUDO_FREQ_TABLE_COUNT;
+		step_size = (policy->max - policy->min + 1) / count;
+
+		/* count is larger than min-max range */
+		if (!step_size) {
+			count = policy->max - policy->min + 1;
+			step_size = 1;
+		}
+	}
 
 	alloc_size = count * sizeof(int) + count * sizeof(u64);
 
@@ -195,10 +219,17 @@  void cpufreq_stats_create_table(struct cpufreq_policy *policy)
 
 	stats->max_state = count;
 
-	/* Find valid-unique entries */
-	cpufreq_for_each_valid_entry(pos, table)
-		if (freq_table_get_index(stats, pos->frequency) == -1)
-			stats->freq_table[i++] = pos->frequency;
+	if (table) {
+		/* Find valid-unique entries */
+		cpufreq_for_each_valid_entry(pos, table)
+			if (freq_table_get_index(stats, pos->frequency) == -1)
+				stats->freq_table[i++] = pos->frequency;
+	} else {
+		/* Create a pseudo frequency table */
+		for (i = 0 ; i < count ; i++)
+			stats->freq_table[i] = policy->min + i * step_size;
+		stats->freq_table[count-1] = policy->max;
+	}
 
 	stats->state_num = i;
 	stats->last_time = get_jiffies_64();
@@ -231,9 +262,15 @@  void cpufreq_stats_record_transition(struct cpufreq_policy *policy,
 	new_index = freq_table_get_index(stats, new_freq);
 
 	/* We can't do stats->time_in_state[-1]= .. */
-	if (old_index == -1 || new_index == -1 || old_index == new_index)
+	if (old_index == -1 || new_index == -1)
 		return;
 
+	if (old_index == new_index) {
+		if (stats->pseudo_freq_table)
+			stats->total_trans++;
+		return;
+	}
+
 	cpufreq_stats_update(stats);
 
 	stats->last_index = new_index;