之前看过interactive调度器,对应的还有ondemand、performance等调度器,调度器是上层策略,而调度器的实现则是通过policy来实现的。

policy

Governor是调频的上层策略, policy是一次调频操作的实体 (句柄), 一个policy可以与多个cpu对应.

struct cpufreq_policy {/* CPUs sharing clock, require sw coordination(协调) */cpumask_var_t        cpus;   /* Online CPUs only */cpumask_var_t     related_cpus; /* Online + Offline CPUs */cpumask_var_t     real_cpus; /* Related and present */unsigned int        shared_type; /* ACPI: ANY or ALL affected CPUsshould set cpufreq *///  policy的managed cpu号. 一般为注册policy的cpu; 当该cpu offline时, // 会选取cpus的下一cpu作为新的managed cpu. 此时前面的cpu称为last_cpu.unsigned int       cpu;    /* cpu managing this policy, must be online */struct clk        *clk;// 硬件特性struct cpufreq_cpuinfo  cpuinfo;/* see above */// 软件特性unsigned int      min;    /* in kHz */unsigned int        max;    /* in kHz */unsigned int        cur;    /* in kHz, only needed if cpufreq* governors are used */// 类似变频之前的freq和目标frequnsigned int       restore_freq; /* = policy->cur before transition */unsigned int     target_freq; /* freq that the policy wants to set */unsigned int        suspend_freq; /* freq to set during suspend */unsigned int      policy; /* see above */unsigned int     last_policy; /* policy before unplug(拔核) */// 当前使用的governor,governor_data是tuables,governor_enabled是witch开关struct cpufreq_governor *governor; /* see below */void          *governor_data;bool         governor_enabled; /* governor start/stop flag */// 因为governor是可以切换的char         last_governor[CPUFREQ_NAME_LEN]; /* last governor used */struct work_struct update; /* if update_policy() needs to be* called, but you're in IRQ context */// user_policy一般用于保存原始参数,因为温度过高的时候最大频率可能会发生变化struct cpufreq_user_policy user_policy;struct cpufreq_frequency_table   *freq_table;struct list_head        policy_list;struct kobject      kobj;struct completion  kobj_unregister;struct notifier_block pm_qos_freq_nb;/** The rules for this semaphore:* - Any routine that wants to read from the policy structure will*   do a down_read on this semaphore.* - Any routine that will write to the policy structure and/or may take away*   the policy altogether (eg. CPU hotplug), will hold this lock in write*   mode before doing so.** Additional rules:* - Lock should not be held across*     __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);*/struct rw_semaphore   rwsem;(信号量)/** Fast switch flags:* - fast_switch_possible should be set by the driver if it can*   guarantee that frequency can be changed on any CPU sharing the*   policy and that the change will affect all of the policy CPUs then.* - fast_switch_enabled is to be set by governors that support fast*   freqnency switching with the help of cpufreq_enable_fast_switch().*/bool                    fast_switch_possible;bool                    fast_switch_enabled;/** Preferred average time interval between consecutive invocations of* the driver to set the frequency for this policy.  To be set by the* scaling driver (0, which is the default, means no preference).*/unsigned int      up_transition_delay_us;unsigned int     down_transition_delay_us;/* Cached frequency lookup from cpufreq_driver_resolve_freq. */unsigned int cached_target_freq;int cached_resolved_idx;/* Synchronization for frequency transitions */bool         transition_ongoing; /* Tracks transition status */spinlock_t        transition_lock;wait_queue_head_t   transition_wait;struct task_struct  *transition_task; /* Task which is doing the transition *//* cpufreq-stats */// 对应的是stat这个节点struct cpufreq_stats    *stats;/* For cpufreq driver's internal use */void         *driver_data;
};

其中

struct cpufreq_cpuinfo {// 硬件特性unsigned int      max_freq;unsigned int       min_freq;/* in 10^(-9) s = nanoseconds */纳秒为单位unsigned int     transition_latency;
};
struct cpufreq_user_policy {unsigned int     min;    /* in kHz */unsigned int        max;    /* in kHz */
};

不管具体的驱动如何变化,核心层都提供了节点,而不是每家驱动各自添加的,这就解释了为什么不同芯片厂商,只要架构是相同的,他们的节点就都相同

/*** show_cpuinfo_cur_freq - current CPU frequency as detected by hardware*/
static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,char *buf)
{unsigned int cur_freq = __cpufreq_get(policy);if (cur_freq)return sprintf(buf, "%u\n", cur_freq);return sprintf(buf, "<unknown>\n");
}
/*** show_scaling_driver - show the cpufreq driver currently loaded*/
static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
{return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", cpufreq_driver->name);
}
/*** show_scaling_governor - show the current policy for the specified CPU*/static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
{// 也就是说policy里面的powersave和performance,和governor里面的是不一样的嘛!if (policy->policy == CPUFREQ_POLICY_POWERSAVE)return sprintf(buf, "powersave\n");else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)return sprintf(buf, "performance\n");else if (policy->governor)return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", policy->governor->name);return -EINVAL;
}
static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf)
{ssize_t ret;if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get)ret = sprintf(buf, "%u\n", cpufreq_driver->get(policy->cpu));elseret = sprintf(buf, "%u\n", policy->cur);return ret;
}
static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf)
{ssize_t ret;// 一般都是没有设置setpolicy函数的if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get)ret = sprintf(buf, "%u\n", cpufreq_driver->get(policy->cpu));elseret = sprintf(buf, "%u\n", policy->cur);return ret;
}

driver

struct cpufreq_driver {char      name[CPUFREQ_NAME_LEN];u8       flags;void      *driver_data;/* needed by all drivers */int     (*init)(struct cpufreq_policy *policy);int      (*verify)(struct cpufreq_policy *policy);//检查policy的参数是否被支持// 定义下面两个中的一个/* define one out of two *///如果不支持通过governor选择合适的运行频率,则实现setpolicy回调函数,//这样系统只能支持CPUFREQ_POLICY_POWERSAVE和CPUFREQ_POLICY_PERFORMANCE这两种工作策略 int       (*setpolicy)(struct cpufreq_policy *policy);/** On failure, should always restore frequency to policy->restore_freq* (i.e. old freq).*///实现target回调函数,通过target回调设定governor所需要的频率//target或者target_index设定目标频率int       (*target)(struct cpufreq_policy *policy,unsigned int target_freq,unsigned int relation);    /* Deprecated */int     (*target_index)(struct cpufreq_policy *policy,unsigned int index);/** Only for drivers with target_index() and CPUFREQ_ASYNC_NOTIFICATION* unset.** get_intermediate should return a stable intermediate frequency* platform wants to switch to and target_intermediate() should set CPU* to to that frequency, before jumping to the frequency corresponding* to 'index'. Core will take care of sending notifications and driver* doesn't have to handle them in target_intermediate() or* target_index().** Drivers can return '0' from get_intermediate() in case they don't* wish to switch to intermediate frequency for some target frequency.* In that case core will directly call ->target_index().*/unsigned int    (*get_intermediate)(struct cpufreq_policy *policy,unsigned int index);int       (*target_intermediate)(struct cpufreq_policy *policy,unsigned int index);/* should be defined, if possible */// 从硬件获取当前frequnsigned int (*get)(unsigned int cpu);/* optional */int      (*bios_limit)(int cpu, unsigned int *limit);// 与init对应int       (*exit)(struct cpufreq_policy *policy);void     (*stop_cpu)(struct cpufreq_policy *policy);// 针对boot cpu, 因为其他cpu已经在suspend前offline了int     (*suspend)(struct cpufreq_policy *policy);int       (*resume)(struct cpufreq_policy *policy);/* Will be called after the driver is fully initialized */void     (*ready)(struct cpufreq_policy *policy);struct freq_attr **attr;/* platform specific boost support code */bool      boost_supported;bool        boost_enabled;int       (*set_boost)(int state);
};

governor

struct cpufreq_governor {char    name[CPUFREQ_NAME_LEN];int  initialized;//指向一个回调函数,CPUFreq Core会在不同的阶段调用该回调函数,用于该governor的启动、停止、初始化、退出动作int   (*governor) (struct cpufreq_policy *policy,unsigned int event);ssize_t  (*show_setspeed)    (struct cpufreq_policy *policy,char *buf);int   (*store_setspeed)   (struct cpufreq_policy *policy,unsigned int freq);unsigned int max_transition_latency; /* HW must be able to switch tonext freq faster than this value in nano secs or wewill fallback to performance governor *///所有注册的governor都会利用该字段链接在一个全局链表中,以供系统查询和使用struct list_head  governor_list;struct module     *owner;
};

【policy】【driver】【governor】相关推荐

  1. MyBatis-学习笔记01【01.Mybatis课程介绍及环境搭建】

    Java后端 学习路线 笔记汇总表[黑马程序员] MyBatis-学习笔记01[01.Mybatis课程介绍及环境搭建][day01] MyBatis-学习笔记02[02.Mybatis入门案例] M ...

  2. 【复杂系统迁移 .NET Core平台系列】之调度服务改造

    源宝导读:微软跨平台技术框架-.NET Core已经日趋成熟,已经具备了支撑大型系统稳定运行的条件.本文将介绍明源云ERP平台从.NET Framework向.NET Core迁移过程中的实践经验. ...

  3. 【复杂系统迁移 .NET Core平台系列】之认证和授权

    源宝导读:微软跨平台技术框架-.NET Core已经日趋成熟,已经具备了支撑大型系统稳定运行的条件.本文将介绍明源云ERP平台从.NET Framework向.NET Core迁移过程中的实践经验. ...

  4. jdbc mysql分页_JDBC【数据库连接池、DbUtils框架、分页】

    1.数据库连接池 什么是数据库连接池 简单来说:数据库连接池就是提供连接的... 为什么我们要使用数据库连接池 数据库的连接的建立和关闭是非常消耗资源的 频繁地打开.关闭连接造成系统性能低下 编写连接 ...

  5. dbcp连接池配置详解_JDBC第四篇【数据库连接池、DbUtils框架、分页】(修订版)

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 1.数据库连接池 什么是数据库连接池 简单来说:数据 ...

  6. CCNP13:QOS【分类、队列、标记、丢弃】技术

    文章目录 CCNP13:QOS[分类.队列.标记.丢弃]技术 一.浅谈网络通讯: 二.QOS的工具概述: 1.分类: 2.队列: 3.标记: 4.丢弃机制: 三.分类: 四.标记: 1.优先级: 2. ...

  7. 【北邮国院大三上】电子商务法(e-commerce law)知识点整理——Banking Lawe-Payment

    北邮国院大三电商在读,随课程进行整理知识点.仅整理PPT和相关法条中相对重要的知识点,个人认为相对不重要的细小的知识点不列在其中.如有错误请指出.转载请注明出处,祝您学习愉快. Why are leg ...

  8. JDBC第四篇【数据库连接池、DbUtils框架、分页】(修订版)

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 1.数据库连接池 什么是数据库连接池 简单来说:数据 ...

  9. JDBC【数据库连接池、DbUtils框架、分页】

    1.数据库连接池 什么是数据库连接池 简单来说:数据库连接池就是提供连接的... 为什么我们要使用数据库连接池 数据库的连接的建立和关闭是非常消耗资源的 频繁地打开.关闭连接造成系统性能低下 编写连接 ...

  10. 【梅哥的Ring0湿润插入教程】第一课Windows内核/驱动编程概述及应用、商业驱动保护软件原理分析...

    [梅哥的Ring0湿润插入教程] Email:mlkui@163.com 转载请注明出处,谢绝喷子记者等,如引起各类不适请自觉滚J8蛋! 第一课Windows内核/驱动编程概述及应用. 商业驱动保护软 ...

最新文章

  1. 互联网协议 — RTSP 实时流传输协议
  2. C++11 正则表达式——实例1
  3. 树莓派4B装载ROS系统启动摄像头
  4. python tk 当输入数值错误是报错_Python的异常处理
  5. gulp+babel实现es6压缩,并替换es6语法,压缩html,css
  6. from mysql_MySQL的FROM
  7. apktoolkit apk反编译没有文件_[工具] Mac下一键APK逆向环境
  8. linux命令取数字前两位,linux中head命令使用详解(显示开头数量的文字块)
  9. 华为云UGO正式公测:4大核心优势破解异构数据库迁移难题
  10. 微服务2.0时代,论其痛点与触点
  11. HDU1760 A New Tetris Game NP态
  12. 关于U盘物理读写锁失效解决(只读状态):工具解锁或U盘量产
  13. html万花筒相册旋转效果,jquery css3 3D万花筒图片相册展示特效
  14. 【SDCC讲师专访】Swoole开源项目创始人韩天峰:PHP是最好的编程语言
  15. Mysql orchestrator高可用
  16. 孕育独角兽独立融资上市,互联网巨头都藏着什么“阳谋“?
  17. 敖丙带你设计【秒杀系统】
  18. hdu 5145 NPY and girls (莫队算法)
  19. mac 终端 创建java文件_第一个 终端Java程序 (Mac)
  20. 二次规划问题(qp)和序列二次规划问题(sqp)的简单理解

热门文章

  1. 神了,用 Python 预测世界杯决赛,发现准确率还挺高
  2. NLP —— 文本预处理
  3. 从码农到工匠,程序员必备的两本提升自我修养的书
  4. 共享内存(一)—— 共享内存的创建与释放
  5. .Net魔法堂:AssemblyInfo.cs文件详解
  6. 疫情下AnalyticDB亮出社区管理的宝藏神器 !
  7. 爬虫实战之《流浪地球》豆瓣影评分析(一)
  8. 精品MySQL面试题,备战八月99%必问!过不了面试算我的
  9. Ubuntu中Matplotlib绘图的中文乱码
  10. 全网首发,自制ADK To Win11PE(1)中文+包