lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Mon, 16 Nov 2015 10:37:16 +0000
From:	"Zhang, Lin-Bao (Linux Kernel R&D)" <linbao.zhang@....com>
To:	"rjw@...ysocki.net" <rjw@...ysocki.net>,
	"viresh.kumar@...aro.org" <viresh.kumar@...aro.org>,
	"linux-pm@...r.kernel.org" <linux-pm@...r.kernel.org>,
	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: [PATCH v1 1/2] enforce max/min time between commands


In Processor Clocking Control specification v1.0 ,there are 2 definitions:
2.1.8 Minimum Time Between Commands
2.1.9 Maximum Time Between Commands
that means 2 commands' interval should be located between Minimum Time Between Commands and Maximum Time Between Commands.

3.1 Get Average Frequency
The Get Average Frequency command is used by the Operating System to query the running frequency of the processor since the last time this command was last completed.

This patch implements this feature, while old pcc-cpufreq.c didn't follow the rule.
Especially ,at boot time there will be no "last time" and BIOS can return out bounds frequencies including the value zero. 
In booting kernel case, we would run querying again as PCC spec.
In normal case, we also need to make sure these 2 commands interval is larger than Minimum Time Between Commands, and also smaller than the max time, although perhaps that is more rare.


Signed-off-by: Pearson, Greg <greg.pearson@....com>
Signed-off-by: Zhang, Lin-Bao <linbao.zhang@....com>
---
 drivers/cpufreq/pcc-cpufreq.c | 39 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c
index 2a0d589..c8f1616 100644
--- a/drivers/cpufreq/pcc-cpufreq.c
+++ b/drivers/cpufreq/pcc-cpufreq.c
@@ -29,6 +29,8 @@
 #include <linux/smp.h>
 #include <linux/sched.h>
 #include <linux/cpufreq.h>
+#include <linux/jiffies.h>
+#include <linux/delay.h>
 #include <linux/compiler.h>
 #include <linux/slab.h>

@@ -105,8 +107,12 @@ static u8 OSC_UUID[16] = {0x9F, 0x2C, 0x9B, 0x63, 0x91, 0x70, 0x1f, 0x49,
 struct pcc_cpu {
        u32 input_offset;
        u32 output_offset;
+       u64 prev_time;
 };

+static u32 max_time_between_cmds = 0;
+static u32 min_time_between_cmds = 0;
+
 static struct pcc_cpu __percpu *pcc_cpu_info;

 static int pcc_cpufreq_verify(struct cpufreq_policy *policy)
@@ -137,7 +143,7 @@ static inline void pcc_clear_mapping(void)
        pcch_virt_addr = NULL;
 }

-static unsigned int pcc_get_freq(unsigned int cpu)
+static unsigned int real_pcc_get_freq(unsigned int cpu)
 {
        struct pcc_cpu *pcc_cpu_data;
        unsigned int curr_freq;
@@ -185,6 +191,8 @@ static unsigned int pcc_get_freq(unsigned int cpu)
                        " capped at %d\n", cpu, curr_freq);
        }

+       pcc_cpu_data->prev_time = get_jiffies_64();
+
        spin_unlock(&pcc_lock);
        return curr_freq;

@@ -194,6 +202,32 @@ cmd_incomplete:
        return 0;
 }

+static unsigned int pcc_get_freq(unsigned int cpu)
+{
+       struct pcc_cpu *pcc_cpu_data;
+       unsigned int curr_freq;
+       u64 cur_time;
+       u32 diff_time;
+
+       pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
+       cur_time = get_jiffies_64();
+       diff_time = jiffies_to_usecs(cur_time - pcc_cpu_data->prev_time);
+
+       if (diff_time > max_time_between_cmds) {
+               curr_freq = real_pcc_get_freq(cpu);
+               cur_time = get_jiffies_64();
+               diff_time =
+                       jiffies_to_usecs(cur_time - pcc_cpu_data->prev_time);
+       }
+
+       if (diff_time < min_time_between_cmds)
+               msleep((min_time_between_cmds - diff_time) / 1000);
+
+       curr_freq = real_pcc_get_freq(cpu);
+
+       return curr_freq;
+}
+
 static int pcc_cpufreq_target(struct cpufreq_policy *policy,
                              unsigned int target_freq,
                              unsigned int relation)
@@ -521,6 +555,9 @@ static int __init pcc_cpufreq_probe(void)
                goto pcch_free;
        }

+       max_time_between_cmds = ioread32(&pcch_hdr->maximum_time);
+       min_time_between_cmds = ioread32(&pcch_hdr->minimum_time);
+
        printk(KERN_DEBUG "pcc-cpufreq: (v%s) driver loaded with frequency"
               " limits: %d MHz, %d MHz\n", PCC_VERSION,
               ioread32(&pcch_hdr->minimum_frequency),
--
1.8.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ