Oprofileでプロファイリングしよう
カーネルモジュールのボトルネックを測定したい。こんなことよくあります。Oprofileは、そんな要求に応えられる、非常にいけてるプロファイラです。最近のLinuxカーネルであれば、再コンパイルなしにプロファイリングすることができます:D。
本記事では「Ubuntu上でカーネルモジュールのプロファイリング」が行えることを目標とします。
もちろんユーザプロセスでもプロファイリング可能ですが、これについてはBinary HacksやWeb上にたくさん載っているので、そちらを参照してください。
まずはインストール
apt経由でOprofileをインストールしましょう。
sudo aptitude install oprofile
生のvmlinuxを用意する
カーネルモジュールのプロファイリングを行うためには、「生のvmlinux」が必要です。
一方、Ubuntuのインストーラによってインストールされるvmlinuz-`uname -r`は、ブート時のカーネル解凍ルーチンと圧縮カーネルがくっついているので、bunzipでは解凍できません。*1 *2
Ubuntu*3の場合、このイメージはパッケージ化されているので、aptでインストールすることができます。
# `は Backquotation sudo aptitude install linux-image-debug-`uname -r`
Oprofileの初期化
Oprofileカーネルモジュールを読み込み、初期化処理を行います。
sudo modprobe oprofile # 初期化処理 sudo opcontrol --init # vmlinuxのパスを指定 sudo opcontrol --vmlinux=/boot/vmlinux-`uname -r`
これで準備は整いました。
Let's profile vmlinux!
まずはカーネル全体のプロファイリングをしてみましょう!以下のコマンドで開始できます。
sudo opcontrol --start # profiling デーモンの開始 sleep 30 #30秒でどんな処理が行われているのかを見る。 sudo opcontrol --stop sudo opcontrol --dump # プロファイルした値を読める値にダンプ sudo opreport # プロファイルの結果を表示
Let's profile kernel module!
つぎに、カーネルモジュールのプロファイリングです。カーネルモジュールをhello.koとしてみましょう。
sudo insmod ./hello.ko -- sudo opcontrol --start sleep 30 #30秒でどんな処理が行われているのかを見る。 sudo opcontrol --stop sudo opcontrol --dump # プロファイルした値を読める値にダンプ sudo opreport # プロファイルの結果を表示 -- sudo opreport -p kmod-dir-path # プロファイルの結果を表示。
勘の良い方は気づかれたかもしれませんが、実はプロファイルング自体の処理はカーネル全体のプロファイリングと変わりません。このことから、opreportを呼ぶときにカーネルモジュールのシンボル情報を与えて、人間に読めるようにしているということが予測できます。
例を挟みたい感じ。あとで更新するかも。
バッドノウハウ
Oprofile Q&Aにある通り、vmwareと一緒だと動きません。
CPUによってとれる値が変わるようです。i686系だと全機能を使えるのだとか。