試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

マルチコアCPU環境におけるcpufreqdの動作に関するメモ(前半・2010/11/10現在)

最近、念願のマルチコアCPU(Athlon II X3 445)を手に入れた*1のだが、マルチコアCPU環境になってcpufreqdの動作について新しく分かったことがあるので、ここにまとめておく。

  1. プロファイル手動設定の挙動
  2. プロファイル自動切り替えモード(非マニュアルモード)におけるコアごとのプロファイル割り当て
    1. バージョン2.4.2の時点ではうまく動作しない?

プロファイル手動設定の挙動

バージョン2.4.2の時点では、cpufreqd-set(関連記事)やUNIXドメインソケットを用いた通信(関連記事)といった方法によるプロファイルの手動設定では全てのコアに同時に同一のプロファイル(gonvernorやクロック範囲など)が適用される。これが特に有用なのは、全てのコアに対してクロックを最低もしくは最高にするという極端な設定を適用したい場合など(そのような内容のプロファイルを事前に/etc/cpufreqd.confに定義しておく必要がある)。

プロファイル自動切り替えモード(非マニュアルモード)におけるコアごとのプロファイル割り当て

/etc/cpufreqd.confについてのmanページを見たところ、システムの状態によって自動的にプロファイルを切り替えるモード(非マニュアルモード/既定のモード)であれば、/etc/cpufreqd.confの個別のルールにおいて、CPU(コア)単位でプロファイルを割り当てることができるようだということが分かった。
[引用] cpufreqd.confのmanページ より

[Rule]
    profile
           A character string that must  match  a  [Profile]  section  name
           property.   A  Rule  can  also associate profiles to single cpus
           providing a list of the format CPU%d:%s separated by  semicolons
           (";"),  e.g.:  profile=CPU0:profile0;CPU1:profile1.  The keyword
           "ALL" can be used to indicate that all cpus must have  the  pro‐
           file applied.  The "ALL" keyword has a lower priority so you can
           mix up CPU%d and ALL meaning that if no specific profile is sup‐
           plied, the "ALL" one will be used. [REQUIRED]

書式としてはルールの項目profileに「CPU[CPU番号(0からコア数未満の整数)]:[そのコアに割り当てたいプロファイル名]」を「;」区切りで記述したものを値として指定するようで

# 2コアの場合
profile=CPU0:[CPU0のプロファイル名];CPU1:[CPU1のプロファイル名]

# 3コアの場合
profile=CPU0:[CPU0のプロファイル名];CPU1:[CPU1のプロファイル名];CPU2:[CPU2のプロファイル名]

のようになる。なお、ここに記述しない番号のコアがある場合、システム状態が条件を満たしてそのルールが適用されても、適用プロファイルを記述していないコアに対しては何もしない。例えば、3コアCPUを用いているときに

profile=CPU0:[CPU0のプロファイル名];CPU1:[CPU1のプロファイル名]

のように記述した場合、CPU0とCPU1はそれぞれ指定したプロファイルになるが、CPU2の状態に変化はない。

バージョン2.4.2の時点ではうまく動作しない?
このコアごとのプロファイル指定について、テスト用のルールを作って試してみたのだが、cpufreqdのデーモンがうまく動かず、-D -V 7オプションを付けて試してみると

init_configuration       : Wrong format for Profile name "CPU0:[1つ目のプロファイル名]".
main                     : Unable to parse config file: /etc/cpufreqd.conf

という出力があった。この「Wrong format ...」のメッセージからソースをたどって(該当ファイルはsrc/config_parser.c)修正/ビルド/動作確認の流れで試行錯誤した結果、以下の修正を行うことで(コアごとのプロファイルの割り当てまで含め)正しく動作するようになったが、これで不具合修正として正しいのかは不明。修正として問題があった場合に他の人が使いやすいようにパブリックドメインのもとで公開する。
[任意]ファイル名: cpufreqd-2.4.2-parse_smp_rule.patch ライセンス: パブリックドメイン

diff -ur cpufreqd-2.4.2.orig/src/config_parser.c cpufreqd-2.4.2/src/config_parser.c
--- cpufreqd-2.4.2.orig/src/config_parser.c
+++ cpufreqd-2.4.2/src/config_parser.c
@@ -834,7 +834,7 @@
 
 				strncpy(profile_name, strstr(token, ":") + 1, MAX_STRING_LEN);
 				cpu_num = atoi(token + 3);
-				if (profile_name[0]) {
+				if (! profile_name[0]) {
 					clog(LOG_ERR, "Wrong format for Profile name \"%s\".\n",
 							token);
 					return -1;
@@ -851,7 +851,7 @@
 					/* go through profiles */
 					if (strcmp(profile_name, tmp_profile->name) == 0) {
 						/* bail out if the rule has a profile already for that CPU */
-						if (tmp_rule->assigned_cpus & cpu_num) {
+						if (tmp_rule->assigned_cpus & 1 << cpu_num) {
 							clog(LOG_ERR, "Rule \"%s\" has a Profile for "
 									"CPU%d already, exiting\n",
 									tmp_rule->name, cpu_num);

この修正を行ったMandriva Linux向けパッケージを別館の配布ページに公開した。
(2014/10/12)配布ページは削除済み。

使用したバージョン:

  • cpufreqd 2.4.2

*1:以前はAthlon 64 3500+のCPUを用いていた