Skip to content

Instantly share code, notes, and snippets.

@cyring
Last active May 15, 2019 16:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cyring/8219a57178670f7a0003c5198e103c7e to your computer and use it in GitHub Desktop.
Save cyring/8219a57178670f7a0003c5198e103c7e to your computer and use it in GitHub Desktop.
cpufreq driver
---
corefreq-api.h
---
struct {
signed int AutoClock,
Experimental,
hotplug,
pci,
nmi;
struct {
unsigned int
cpuidle: 1-0,
cpufreq: 2-1;
} Driver;
} Registration;
---
corefreqk.c
---
static signed short CPU_Idle_Enable = -1;
module_param(CPU_Idle_Enable, short, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
MODULE_PARM_DESC(CPU_Idle_Enable, "Enable the Kernel cpuidle driver");
static signed short CPU_Freq_Enable = -1;
module_param(CPU_Freq_Enable, short, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
MODULE_PARM_DESC(CPU_Freq_Enable, "Enable the Kernel cpufreq driver");
#if FEAT_DBG > 1 /*TODO: LEVEL 2 */
static int CoreFreqK_Policy_Exit(struct cpufreq_policy *policy) ;
static int CoreFreqK_Policy_Init(struct cpufreq_policy *policy) ;
static int CoreFreqK_Policy_Verify(struct cpufreq_policy *policy) ;
static int CoreFreqK_SetPolicy(struct cpufreq_policy *policy) ;
static unsigned int CoreFreqK_GetFreq(unsigned int cpu) ;
#endif /* FEAT_DBG */
static struct {
signed int Major;
struct cdev *kcdev;
dev_t nmdev, mkdev;
struct class *clsdev;
#if FEAT_DBG > 1 /*TODO: LEVEL 2 */
struct cpuidle_driver IdleDriver;
struct cpufreq_driver FreqDriver;
#endif /* FEAT_DBG */
} CoreFreqK = {
#if FEAT_DBG > 1 /*TODO: LEVEL 2 */
.IdleDriver = {
.name = "corefreqk-idle",
.owner = THIS_MODULE
},
.FreqDriver = {
.name = "corefreqk-perf",
.flags = CPUFREQ_CONST_LOOPS,
.exit = CoreFreqK_Policy_Exit,
/*MANDATORY*/ .init = CoreFreqK_Policy_Init,
/*MANDATORY*/ .verify = CoreFreqK_Policy_Verify,
/*MANDATORY*/ .setpolicy = CoreFreqK_SetPolicy,
.get = CoreFreqK_GetFreq
}
#endif /* FEAT_DBG */
};
#if FEAT_DBG > 1 /*TODO: LEVEL 2 */
static int CoreFreqK_Policy_Exit(struct cpufreq_policy *policy)
{
return(0);
}
static int CoreFreqK_Policy_Init(struct cpufreq_policy *policy)
{
if (policy != NULL) {
unsigned int cpu = policy->cpu;
if ((cpu >= 0) && (cpu < Proc->CPU.Count)) {
policy->cpuinfo.min_freq =(Proc->Boost[BOOST(MIN)]
* KPublic->Core[cpu]->Clock.Hz)
/ 1000LLU;
policy->cpuinfo.max_freq =(Proc->Boost[BOOST(MAX)]
* KPublic->Core[cpu]->Clock.Hz)
/ 1000LLU;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->min = policy->cpuinfo.min_freq;
policy->max = policy->cpuinfo.max_freq;
}
}
return(0);
}
static int CoreFreqK_Policy_Verify(struct cpufreq_policy *policy)
{
if (policy != NULL) {
cpufreq_verify_within_cpu_limits(policy);
}
return(0);
}
static int CoreFreqK_SetPolicy(struct cpufreq_policy *policy)
{
if (policy != NULL) {
}
return(0);
}
static unsigned int CoreFreqK_GetFreq(unsigned int cpu)
{
if ((cpu >= 0) && (cpu < Proc->CPU.Count)) {
if (Proc->Features.HWP_Enable)
return((Proc->Boost[BOOST(HWP_TGT)]
* KPublic->Core[cpu]->Clock.Hz)
/ 1000LLU);
else
return((Proc->Boost[BOOST(TGT)]
* KPublic->Core[cpu]->Clock.Hz)
/ 1000LLU);
} else {
return(0);
}
}
static void CoreFreqK_FreqDriver_UnInit(void)
{
cpufreq_unregister_driver(&CoreFreqK.FreqDriver);
}
static int CoreFreqK_FreqDriver_Init(void)
{
int rc = -EPERM;
rc = cpufreq_register_driver(&CoreFreqK.FreqDriver);
return(rc);
}
#endif /* FEAT_DBG */
static int __init CoreFreqK_init(void)
{
#if FEAT_DBG > 1 /*TODO: LEVEL 2 */
if (CPU_Idle_Enable == 1) {
Proc->Registration.Driver.cpuidle = CoreFreqK_IdleDriver_Init() == 0;
}
if (CPU_Freq_Enable == 1) {
Proc->Registration.Driver.cpufreq = CoreFreqK_FreqDriver_Init() == 0;
}
#endif
}
static void __exit CoreFreqK_cleanup(void)
{
#if FEAT_DBG > 1 /*TODO: LEVEL 2 */
if (Proc->Registration.Driver.cpufreq) {
CoreFreqK_FreqDriver_UnInit();
}
if (Proc->Registration.Driver.cpuidle) {
CoreFreqK_IdleDriver_UnInit();
}
#endif
}
@cyring
Copy link
Author

cyring commented May 15, 2019

$ make FEAT_DBG=2 clean all

# insmod corefreqk.ko CPU_Idle_Enable=1 CPU_Freq_Enable=1

$ cat /sys/devices/system/cpu/cpuidle/current_driver 
corefreqk-idle

$ ls /sys/devices/system/cpu/cpufreq/
policy0  policy1  policy2  policy3  policy4  policy5  policy6  policy7

$ cat /sys/devices/system/cpu/cpufreq/policy?/scaling_driver
corefreqk-perf
corefreqk-perf
corefreqk-perf
corefreqk-perf
corefreqk-perf
corefreqk-perf
corefreqk-perf
corefreqk-perf

$ cat /sys/devices/system/cpu/cpufreq/policy?/scaling_min_freq
801907
801897
801907
801896
801898
801899
801888
801896

$ cat /sys/devices/system/cpu/cpufreq/policy?/scaling_max_freq
3408107
3408063
3408105
3408058
3408069
3408073
3408025
3408058

$ cat /sys/devices/system/cpu/cpufreq/policy?/scaling_cur_freq
3897495
3798064
3808000
3971040
3990633
3925888
3898240
3952864

$ cat /sys/devices/system/cpu/cpufreq/policy?/cpuinfo_min_freq 
801907
801897
801907
801896
801898
801899
801888
801896

$ cat /sys/devices/system/cpu/cpufreq/policy?/cpuinfo_max_freq 
3408107
3408063
3408105
3408058
3408069
3408073
3408025
3408058

$ sudo cat /sys/devices/system/cpu/cpufreq/policy?/cpuinfo_cur_freq 
4010542
4010529
4010255
4010381
4010395
4010380
4010254
4010374

$ cat /sys/devices/system/cpu/cpufreq/policy?/affected_cpus
0
1
2
3
4
5
6
7

$ cat /sys/devices/system/cpu/cpufreq/policy?/related_cpus
0
1
2
3
4
5
6
7

$ cat /sys/devices/system/cpu/cpufreq/policy?/cpuinfo_transition_latency
4294967295
4294967295
4294967295
4294967295
4294967295
4294967295
4294967295
4294967295

$ cat /sys/devices/system/cpu/cpufreq/policy?/scaling_available_governors
performance powersave
performance powersave
performance powersave
performance powersave
performance powersave
performance powersave
performance powersave
performance powersave

$ cat /sys/devices/system/cpu/cpufreq/policy?/scaling_governor
cat: /sys/devices/system/cpu/cpufreq/policy0/scaling_governor: Invalid argument
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment