ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Linux 内核 CPU 性能调节驱动程序历史文档全解:AMD PowerNow!、cpufreq-nforce2 与 pcc-cpufreq

Linux 内核 CPU 性能调节驱动程序历史文档全解:AMD PowerNow!、cpufreq-nforce2 与 pcc-cpufreq Linux 内核 CPU 性能调节驱动程序历史文档全解AMD PowerNow!、cpufreq-nforce2 与 pcc-cpufreq【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux导读本文基于 Linux 内核源码树中的 Documentation/admin-guide/pm/cpufreq_drivers.rstLegacy Documentation of CPU Performance Scaling Drivers系统讲解三类具有代表性的历史 CPU 性能调节CPU performance scaling驱动程序AMD 面向六至八代处理器的 PowerNow! 系列驱动powernow-k6/k7/k8、通过修改前端总线FSB来调频的 cpufreq-nforce2 驱动以及基于固件与操作系统协调接口 PCC 的 pcc-cpufreq 驱动。文章将文档中的每一处细节与 drivers/cpufreq 目录下的真实源码一一印证帮助读者理解这些驱动程序的设计动机、硬件交互方式、模块参数含义与 /sys 接口行为为研究现代 cpufreq 驱动如 acpi-cpufreq、amd-pstate、intel_pstate提供宝贵的历史背景与对照参考。文档定位为何这些驱动被称为“历史文档”文档开篇即声明其内容为描述若干 CPU 性能调节驱动的历史性文档historic documents原文逐字保留reproduced verbatim连原始空白与缩进格式都原样呈现。这并不意味着这些驱动已从内核中删除——恰恰相反它们的实现仍然完整地保留在当前仓库的 drivers/cpufreq 目录下powernow-k6.c、powernow-k7.c、powernow-k8.c对应 AMD PowerNow! 系列cpufreq-nforce2.c对应 nForce2 FSB 调频驱动pcc-cpufreq.c对应 PCC 接口驱动。将历史文档与现行源码对照阅读是理解“CPU 频率管理能力随硬件代际演进”的最佳途径每一代处理器都在改变频率/电压控制的硬件实现因此每一代都有对应的独立驱动。AMD PowerNow! 驱动按处理器代际划分的调频实现命名与代际对应关系PowerNow! 与 CoolnQuiet 是 AMD 对其处理器频率管理能力的两个品牌名PowerNow! 主要面向移动处理器CoolnQuiet 则是桌面处理器的对应特性。由于新世代处理器的硬件实现发生了变化每个世代都有独立的 cpu-freq 驱动处理器代际驱动适用处理器第 6 代powernow-k6Mobile K6-2 / K6-3第 7 代powernow-k7Athlon、Duron、Geode第 8 代powernow-k8Athlon、Athlon 64、Opteron、Sempron文档特别提醒两个实用要点驱动不会在“错误”的硬件上加载因此当你无法确定哪个驱动正确时可以逐个尝试安全无副作用。这一点在 Kconfig.x86 中也有印证X86_POWERNOW_K6依赖X86_32X86_POWERNOW_K8依赖ACPI ACPI_PROCESSOR X86_ACPI_CPUFREQ构建时按配置裁剪运行时则靠 CPU 特性探测决定是否加载。并非所有处理器都具备变频及调压能力。驱动通过cpuid指令检测该能力能力缺失时驱动会拒绝加载。频率与电压数据的来源BIOS 表与 ACPI驱动依赖BIOS 提供的表来获取适用于特定平台的频率和电压信息若 BIOS 不提供这些表频率切换功能将不可用。对 powernow-k7 与 powernow-k8BIOS 提供的数据可能来自PSB 表PowerNow! BIOS 表或ACPI 对象_PSS 等性能状态。ACPI 支持仅在开启CONFIG_ACPI_PROCESSOR时可用见 Kconfig.x86 中X86_POWERNOW_K7_ACPI的依赖关系。powernow-k8在配置了 ACPI 时优先尝试 ACPI失败则回退到 PSB 表。powernow-k7则优先使用 PSB 支持失败后才回退到 ACPI并提供一个名为acpi_force的模块参数强制改用 ACPI 而不用 PSB。从源码看powernow-k8 对 PSB/PST 表的处理逻辑位于 powernow-k8.c驱动扫描 BIOS 内存查找 PSB 头PSB_ID_STRING校验表版本必须为 v1.4逐项解析 PST 记录若既找不到 PSB 表也找不到 ACPI _PSS 对象则打印FW_BUG No PSB or ACPI _PSS objects并失败。transition latency切换延迟也分别按 PSB 或 ACPI 两条路径取值见get_transition_latency()powernow-k8.c。powernow-k7 的源码 powernow-k7.c 定义了psb_s表头签名、表版本、flags、settlingtime、PST 数量与pst_s每条性能状态记录cpuid、FSB 速度、maxfid、startvid、状态数两个结构体与文档描述的 PSB/PST 机制完全对应。powernow-k6 的模块参数与频率表从源码 powernow-k6.c 可以看到该驱动暴露的两个模块参数max_multiplier最大倍频允许取值 20、30、35、40、45、50、55、60即 2.0x–6.0x乘以 10 表示bus_frequency总线频率单位 kHz。驱动的倍频与 CPU 内部寄存器码register code的对应关系通过两张表维护index_to_register[8]与register_to_index[8]powernow-k6.c实现“频率表索引 ↔ 硬件寄存器值”的双向映射。usual_frequency_table[]powernow-k6.c则列出常见“FSB × 倍频”组合例如 100 MHz × 5.5 550 MHz、120 MHz × 6 720 MHz可直接作为调频目标参考。cpufreq-nforce2通过修改 FSB 调节频率工作原理cpufreq-nforce2通过改变 nVidia nForce2 平台的FSB前端总线频率来实现 CPU 调频。文档指出其在这类平台上效果优于其他平台原因是CPU 的 FSB 可以独立于 PCI/AGP 时钟被控制调频不会连带干扰外设总线时钟。源码 cpufreq-nforce2.c 的实现细节印证了这一点驱动通过 PCI 配置空间直接操作芯片组的 PLL 寄存器NFORCE2_PLLREG、NFORCE2_PLLADR、NFORCE2_PLLENABLE见 cpufreq-nforce2.c晶振频率固定为 25 MHzNFORCE2_XTALFSB 25 × multiplier / divider芯片组的 PLL 值由nforce2_calc_pll()通过遍历 multiplier/divider 组合反算得出cpufreq-nforce2.c并以写满 64 个寄存器槽位的方式写入nforce2_write_pll()cpufreq-nforce2.cFSB 切换采用逐 MHz 步进的渐进方式nforce2_set_fsb()cpufreq-nforce2.c每次只变化 1 MHz 并重算 PLL 值以降低稳定性风险。值得注意该驱动源码头部注明“基于逆向工程信息”reverse engineered information并带有“BIG FAT DISCLAIMER: Work in progress code. Possiblydangerous”警告说明这类直接操作芯片组寄存器的驱动存在天然风险这也解释了文档为何要强调 FSB 可用范围向下受限的问题。模块参数fid 与 min_fsb文档给出的两个模块选项在源码中有完全对应的定义cpufreq-nforce2.c参数含义默认值fid倍频 × 10例如 8.5 85未设置时根据当前 CPU 速度与 FSB 反算min_fsb最小 FSB默认 开机时 FSB − 50 MHz源码中对应的常量定义最小 FSB 硬下限为 50 MHzNFORCE2_MIN_FSB默认下限与开机 FSB 的安全距离为 50 MHzNFORCE2_SAFE_DISTANCE见 cpufreq-nforce2.c。重要限制可用范围向下受限文档以醒目字体IMPORTANT强调可用 FSB 范围是向下受限的且不同系统的最小可用 FSB 可能不同例如对于以 200 MHz 启动的系统150 MHz 通常总是可用。从源码看nforce2_set_fsb()会先校验目标 FSB 不超过max_fsb即开机 FSB且不低于NFORCE2_MIN_FSB并在每次切换时保持tfsb落在[min_fsb, max_fsb]区间内cpufreq-nforce2.c一旦超出即返回-EINVAL。这解释了“向下受限”的根源调频动作只能发生在系统当前 FSB 及其安全下限之间。pcc-cpufreq基于固件协调接口的处理器时钟控制PCC 接口与设计动机Processor Clocking ControlPCC是平台固件platform firmware与 OSPM操作系统电源管理之间的接口用于在固件与操作系统之间协调处理器性能即频率。pcc-cpufreq驱动源码见 pcc-cpufreq.c让 OSPM 得以利用该接口。工作机制可以概括为OS 通过 PCC 接口告知平台固件它希望某个逻辑处理器运行在什么频率上固件负责尝试达成该频率。如果固件无法满足目标频率请求通常意味着存在功耗预算约束即发生了“power capping”功率封顶——此时固件正在主动限制功耗。PCC 的技术基础是共享内存区域shared memory regionOS 与平台固件之间的通信通道门铃doorbellOS 用来通知固件“已发送命令”的机制ACPI PCCH() 方法用于发现 PCC 共享内存区域的位置共享内存区域的头部包含“command”和“status”接口PCCH() 还提供访问平台门铃的细节ACPI PCCP() 方法为每个逻辑处理器实现用于发现输入/输出缓冲区在共享内存区域中的偏移量。源码中的结构体定义与之一一对应pcc-cpufreq.c 的struct pcc_header包含 signature、command、status、latency、minimum_time、maximum_time、nominal标称频率、throttled_frequency、minimum_frequency 等字段pcc-cpufreq.c 的struct pcc_cpu保存每个 CPU 的input_offset与output_offset。探测流程pcc_cpufreq_evaluate()pcc-cpufreq.c先检查\_SB下是否存在PCCH方法再解析 PCCH() 返回的内存资源描述与门铃寄存器描述映射共享内存并读取头部字段pcc_get_offset()pcc-cpufreq.c则为每个 CPU 求值 PCCP()取得输入/输出缓冲区偏移。PCC 支持的命令PCC 接口支持两个命令Get Average Frequency获取平均频率OSPM 用它查询处理器自上次命令完成以来的运行频率。输出缓冲区给出逻辑处理器的平均未暂停unhalted频率表示为标称即最大CPU 频率的百分比同时输出缓冲区还标明 CPU 频率是否受功耗预算条件限制。对应源码pcc_get_freq()pcc-cpufreq.c写入输入缓冲区、写入CMD_GET_FREQ命令字、敲击门铃并轮询状态直到CMD_COMPLETE然后以nominal × (output 0xff) / 100计算当前频率输出字节的高 8 位(output_buffer 8) 0xff若非0xff则表示频率正被临时封顶capped。Set Desired Frequency设置期望频率OSPM 用它向固件传达逻辑处理器的期望频率输出缓冲区当前被 OSPM 忽略下一次 “Get Average Frequency” 会告知 OSPM 期望频率是否达成。对应源码pcc_cpufreq_target()pcc-cpufreq.c按1 | ((target_freq * 100) / (nominal * 1000)) 8组装输入缓冲区bit0 表示“新命令”高字节为频率占标称频率的百分比写入CMD_SET_FREQ命令字敲击门铃并等待完成。与原生 P-state 驱动的关系文档明确PCC 模式启用时平台不会向 OSPM 暴露处理器性能或节流状态_PSS、_TSS 及相关 ACPI 对象因此原生 P-state 驱动如面向 Intel 的 acpi-cpufreq、面向 AMD 的 powernow-k8不会加载。但OSPM 仍然掌握策略控制权调速器governor例如 ondemand根据服务器工作负载计算每个处理器所需的性能PCC 驱动填充命令接口与输入缓冲区将请求交给平台固件由固件负责交付所请求的性能。另一个关键特性是PCC 命令的“全局global”作用域每个 PCC 命令都会影响系统中的所有逻辑 CPU因此 PCC 具备“组更新group updates”能力——OS 只需一次调用 BIOS 即可获取/设置系统中所有逻辑 CPU 的频率。源码中pcc_cpufreq_probe()在 CPU 数大于 4 时会为驱动设置CPUFREQ_NO_AUTO_DYNAMIC_SWITCHING标志并打印错误信息pcc-cpufreq.c建议在 CPU 过多的系统上通过 BIOS 设置启用其他 scaling 驱动这正是该全局作用域特性带来的实际约束。受影响的平台与加载行为PCC 驱动会在满足以下条件的任何系统上加载平台固件支持 PCC 接口及配套的 PCCH()、PCCP() 方法固件承担管理硬件时钟控制、以交付所请求处理器性能的职责。文档指出目前某些 HP ProLiant 平台实现了 PCC 接口在这些平台上 PCC 是“默认”选择。但该接口可以通过 BIOS 设置禁用此时以及在未实现 PCC 接口的平台上PCC 驱动会静默加载失败fail to load silently。驱动加载时打印最低与最高 CPU 频率限制示例消息pcc-cpufreq: (v1.00.00) driver loaded with frequency limits: 1600 MHz, 2933 MHz这意味着 OSPM 可以请求 CPU 运行在 1600 MHz 与 2933 MHz 之间的任意频率。当前源码中的版本字符串为1.10.00pcc-cpufreq.c打印语句位于 pcc-cpufreq.c。文档还解释了版本号格式v.xy.ab的语义ab随驱动的 bug 修复/功能增强而递增xy则是驱动所遵循的 PCC 规范版本。另外内部层面驱动无需将“目标频率”转换为对应的 P-state——频率请求是连续的不与离散 P-state 绑定。从驱动结构看struct cpufreq_driver pcc_cpufreq_driverpcc-cpufreq.c只实现了.verify、.target、.get、.init四个回调没有频率表freq table相关回调与文档描述完全吻合。驱动与 /sys 接口的细节文档针对四个 /sys 字段逐一说明了 PCC 驱动下的行为scaling_available_frequencies不创建PCC 驱动不会在 /sys 中创建scaling_available_frequencies。原因在于 BIOS 会尝试达成调速器请求的范围内任意频率频率不必严格关联某个 P-state因此无需列出中间频率。cpuinfo_transition_latency恒为 0cpuinfo_transition_latency字段为0。因为 PCC 规范目前没有包含用于暴露该值的字段。cpuinfo_cur_freq两个典型现象文档给出两种常见情况A) 因 “turbo boost” 出现的偏差cpuinfo_cur_freq常会显示与scaling_available_frequencies、scaling_cur_freq或scaling_max_freq不同的值。若满足特定条件BIOS 能达到比 OSPM 请求值略高的速度例如scaling_cur_freq : 2933000 cpuinfo_cur_freq : 3196000B) 舍入误差由于驱动从 BIOS 获取的当前频率是标称频率的“百分比”scaling_cur_freq与cpuinfo_cur_freq显示的值有时不匹配例如scaling_cur_freq : 1600000 cpuinfo_cur_freq : 1583000本例中标称频率为 2933 MHz驱动获取的当前频率为标称频率的 54%54% × 2933 MHz ≈ 1583 MHz。标称频率即处理器最大频率通常对应 P0 P-state。这一计算逻辑在源码 pcc-cpufreq.c 中清晰可见curr_freq (nominal * (output 0xff) / 100) * 1000。related_cpus与 affected_cpus 相同related_cpus字段与affected_cpus完全一致例如affected_cpus : 4 related_cpus : 4原因在于 PCC 驱动目前不求值 _PSD且支持 PCC 的平台不实现 SW_ALL 依赖协调语义因此 OSPM 无需执行任何协调动作来确保所有依赖 CPU 请求相同频率。使用限制Caveats文档明确指出一个重要的兼容性限制cpufreq_stats模块在其现有形式下无法与 PCC 驱动协同工作。因为cpufreq_stats提供的是针对每个 P-state 的统计信息而 PCC 驱动并不基于 P-state 工作。这意味着启用 PCC 驱动的系统上基于 P-state 的统计功能将不适用。配置与加载方式小结结合 Kconfig.x86 与 drivers/cpufreq/Makefile这些驱动均以模块tristate形式供选择X86_POWERNOW_K6模块名为powernow-k6仅限X86_32X86_POWERNOW_K7模块名为powernow-k7仅限X86_32搭配X86_POWERNOW_K7_ACPI依赖ACPI_PROCESSOR启用 ACPI 支持X86_POWERNOW_K8模块名为powernow-k8依赖ACPI ACPI_PROCESSOR X86_ACPI_CPUFREQK10 及更新处理器已由 acpi-cpufreq 接管X86_CPUFREQ_NFORCE2目标文件为cpufreq-nforce2.o见 Makefile模块加载参数为fid与min_fsbX86_PCC_CPUFREQ模块名为pcc-cpufreq依赖ACPI ACPI_PROCESSORKconfig.x86其帮助文本明确指向本文档Documentation/admin-guide/pm/cpufreq_drivers.rst。由于这些驱动在“错误”硬件上不会加载实际使用中可将对应模块加入启动加载列表由驱动自身的硬件探测机制决定是否生效PCC 驱动则以late_initcall注册为平台驱动pcc-cpufreq.c若已存在其他 cpufreq 驱动则主动跳过初始化。总结与历史意义这三个驱动分别代表了 CPU 频率管理的三条经典技术路线处理器内置的 FID/VID 状态表AMD PowerNow!依赖 BIOS PSB 表或 ACPI _PSS、通过芯片组修改外频nForce2 FSB/PLL、OS 与固件通过共享内存协商频率PCC。它们共同展示了内核 cpufreq 框架“驱动只负责与硬件交互、调速器负责决策策略”的核心分层思想也为理解现代驱动acpi-cpufreq 的 P-state 表、amd-pstate 的精细频率范围、intel_pstate 的内置调速器提供了清晰的历史坐标系。对于希望深入 cpufreq 子系统源码的开发者先读懂这三份“历史文档”及其对应实现是性价比极高的入门路径。【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表