之前看过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. Java集合7 (NavigableSet)
  2. matlab 直方图_MATLAB作图实例:19:用二元直方图分析图片颜色
  3. web前端-移动端HTML5微商城项目实战分享案例
  4. 【转】最流行的编程语言JavaScript能做什么?
  5. pytorch 训练过程acc_Pytorch之Softmax多分类任务
  6. Spring Spring MVC Hibernate 整合备忘
  7. lua——alien库实现lua调用C动态链接库(dll、so)
  8. matlab seed函数_如何用matlab生成随机数函数_matlab随机数生成函数
  9. OpenCV-腐蚀cv::erode
  10. 计算机信息数据集通信的概念,南京信息工程大学数据通信与计算机网络复习题库.doc...
  11. css 固定列头,表格头部固定和表格列固定
  12. Java HashSet和LinkedHashSet的用法
  13. 五、瞰景Smart3D空三解算
  14. 做个合格的吃货~利用Python爬取美食网站3032个菜谱并分析
  15. cython使用说明
  16. 修改 ubnt 路由器固件
  17. 十一、mysql连接查询
  18. 单片机控制LED灯长亮
  19. 实现抢拍竞答——多线程
  20. Unity无缝大世界实现调研

热门文章

  1. 一起了解一下手机产业中工业机器人的应用
  2. 计算机网络技术极实践应用,计算机网络技术及在实践中的具体应用
  3. 东京爱情故事主题曲的日文版歌词
  4. Centos7安装jdk
  5. 用CE来找出对对碰游戏 坐位号基址,棋盘数组基址 并把它读出来
  6. InstructGPT 精简总结:Training language models to follow instructions with human feedback
  7. Word占用CPU很高?如何解决?已完结
  8. 用友通 服务器配置文件,如何打开用友t3服务器配置
  9. 火车票座位分布图 怎样买到靠窗座位号
  10. 批量删除PDF中的高亮和划线