xenlasy: xen の i/o 処理を 追跡するための アスペクト指向プロファイラ
DESCRIPTION
XenLASY: Xen の I/O 処理を 追跡するための アスペクト指向プロファイラ. 柳澤 佳里 光来 健一 千葉 滋 東京工業大学 情報理工学研究科. ドメイン U. ドメイン 0. OS. OS. 実ドライバ. 仮想ドライバ. 仮想ドライバ. 仮想マシンモニタ. (VMM). ハードウェア. VM を考慮したチューニングを支援するツール. OS 単体でのチューニングでは不十分 I/O がドメイン 0 を通る 複数の VM の I/O が競合. 例 ) Xen の I/O 処理. I/O フローの追跡が大切. I/O フローとは - PowerPoint PPT PresentationTRANSCRIPT
1
XenLASY: Xen の I/O 処理を追跡するためのアスペクト指向プロファイラ
柳澤 佳里 光来 健一 千葉 滋東京工業大学 情報理工学研究科
2
VM を考慮したチューニングを支援するツール OS 単体でのチューニングでは不十分
I/O がドメイン 0 を通る 複数の VM の I/O が競合
OSOS
ドメイン Uドメイン 0
仮想マシンモニタ (VMM)
仮想ドライバ仮想ドライバ実ドライバ
ハードウェア
例 ) Xen の I/O 処理
3
I/O フローの追跡が大切 I/O フローとは
I/O を発行してデバイスが送出する流れ デバイスで受信しアプリケーションが受け取る流れ
個別のデータの動き ( フロー ) の追跡が必要 データがドメイン U やドメイン 0 でどう処理されるかを
知りたい 複数のドメインが I/O した場合に、区別して追跡したい
余計なフローは取りたくない
個々のフローはフロー識別子 (ID) が必要 一つ一つのデータの流れを区別するため
4
単純なフロー追跡では不十分 コールフロー
関数呼び出しの流れを追跡 実行スレッドが変わると追跡不可
ドメイン間の追跡が不可能 トップハーフ / ボトムハーフの追跡が不可能
単純なデータフロー データのポインタを追跡 データ形式が変化すると追跡不可
ドメイン間ではデータ形式が変化し、追跡不可 データの複製、分割すると追跡不可
5
XenLASY Xen 上の I/O 処理をプロファイリングをするための
アスペクト指向システム xflow ポイントカット
Xen 上のデータフローを選択するポイントカット 指定した種類のフローに指定したデータが入っている時を選択
文法 : xflow( フロー名 , データへのポインタ ) 追跡すべきデータの流れをきめ細かく指定可能
開始点、中継点、終了点を指定 データ形式の変化、分割などにも対処 余計なデータが含まれないようにできる
xflow_id ポイントカットでフロー ID を取得
6
KLASY を拡張して開発 KLASY [Yanagisawa ’06] とは、
カーネル用動的アスペクト指向システム ソースコードレベルの情報を実行時の織り込みで利用
access ポイントカットを実現 構造体メンバーへのアクセスをポイントカット
Source-based binary-level dynamic weaving
xflow 、 xflow_id を扱えるよう言語拡張 @ ドメイン名を使えるよう言語拡張 Xen 上のドメインに織り込めるよう変更
7
XenLASY のアスペクト例
sk_buff 構造体インスタンスがnetflow のデータだった場合にpc 、時間、フロー id をログ出力
netflow: ネットワーク I/O のフロー
<pointcut> access(sk_buff.%) AND target(skb) AND xflow(netflow, skb) AND xflow_id(id) </pointcut>
<before> long long tsc; DO_RDTSC(tsc); STORE_DATA3($pc$, tsc, id); </before>
</advice></aspect>
<aspect> <advice>
br_for
wardSk
GeXmit
Tcp_s
endm
sg
Network
_star
t_xmit
Netif_r
x
Netif_r
eceiv
e_sk
b
Netbk_
fill_f
lags
copy
_from
_user
DomainU Domain0
access ポイントカットで選択
データフロー (netflow)id1id2
アドバイス
ポイントカット
8
xflow ポイントカットの定義 netflow
Xen 上のネットワーク I/O 処理フロー
start: 開始点 データフローの開始点を
指定 transit: 中継点
データ形式が変わる場合 skb_clone は複製を作成
ドメイン間の場合 quit: 終了点
<transit><pointcut> access(sk_buff.head) AND within_function(skb_clone) </pointcut> <move from=“skb” to=“n” /> </transit>
<quit><pointcut> access(sk_buff.%) AND within_function(__kfree_skb) </pointcut></quit>
<start><pointcut> access(sk_buff.data) AND within_function(alloc_skb_from_cache) </pointcut></start>
</xflow>
<xflow name=“netflow”>
9
start/quit ( 開始点 / 終了点 ) 構造体インスタンスから IDを引けるよう登録、削除 構造体インスタンスの指定
省略時は access ポイントカットで選択した構造体のインスタンスを選択 select で任意の変数も指定可
DB 登録 / 削除処理は自動で設定 任意のコードを指定する場合は action を利用
<start><pointcut> access(sk_buff.data) AND within_function(alloc_skb_from_cache)</pointcut></start>
<start><pointcut>…</pointcut> <select local_var=“data” /></start>
そのほかの記述例
<start><pointcut>…</pointcut> <action> int id = new_flowid(); … </action></start>
10
transit ( 中継点 ) move で対応付けを指
示 skb: フロー ID 格納元 n: フロー ID 格納先 skb を鍵としてフロー
ID が引けないようエントリを抹消
エントリを保持する copy も用意
<transit><pointcut> access(sk_buff.head) AND within_function(skb_clone) </pointcut> <move from=“skb” to=“n” /></transit>
<transit><pointcut> … </pointcut> <copy from=“skb” to=“n” /></transit>
そのほかの記述例
11
ドメインをまたがる transit 定義 xin_move 、 xout_move 要素を用意
ドメインをまたがるとデータのアドレスからフロー ID を引けない ドメイン間ではアドレス空間が違う ドメイン間ではデータベースを共有していない
フロー ID を送信先ドメインに伝搬 ドメイン間で渡されるヘッダの空き領域に ID を格
納
ドメイン 0 DomU
実データ
ヘッダ
フロー ID を格納
12
ドメイン間 transit の例 linU から lin0 にフロー ID
を伝搬 xin_move
skb のフロー ID を tx に格納 flags メンバーの下位 4
ビット目から 12 ビットを使用
xout_move xin_move の逆処理でフ
ロー ID を取得し、 skb に割当 対象 xin_move は name
で選択 @ ドメイン名で選択する
ドメインを指定tx->flags 12bit 4bit
<transit><pointcut> access(netif_tx_request.flags) AND within_file(drivers/../netback.c@lin0) </pointcut> <xout_move name=“netin” from=”tx” to=“skb” /></transit>
<transit><pointcut> access(netif_tx_request.flags) AND within_file(drivers/../netfront.c@linU) </pointcut> <xin_move name=“netin” from=“skb” to=“tx”> <field name=“flags” offset=“4” size=“12” /> </xin_move></transit>
13
xflow の実装 : start/quit の変換
<pointcut> access(sk_buff.data) AND target(skb) AND within_function(alloc_skb_from_cache)</pointcut><before> id = get_new_flowid(); register_flowid(netflow, id, skb);</before>
<start><pointcut> access(sk_buff.data) AND within_function(alloc_skb_from_cache)</pointcut></start>
quit も同様
target ポイントカットを追加構造体インスタンスへの参照を取得
DB に参照を鍵としてID を取り出せるよう登録
•alloc_skb_from_cacheで skb から新規フローID を引けるよう DB に登録
14
xflow の実装 : transit の変換
<pointcut> access(sk_buff.head) AND within_function(skb_clone) AND local_var(skb, skbp) AND local_var(n, np)</pointcut><before> void *skb = *((void **)skbp); void *n = *((void **)np); int id = get_flowid(netflow, skb); if (id != 0) { register_flowid(netflow, id, n); remove_flowid(netflow, skb);}</before>
skb に割り当てられていたフロー ID を n に割り当てる
•local_var ポイントカットでローカル変数への参照取得
<transit><pointcut> access(sk_buff.head) AND within_function(skb_clone) </pointcut> <move from=“skb” to=“n” /></transit>
15
xflow の実装 : ドメイン間 transit の変換
<pointcut> access(netif_tx_request.flags) AND within_file(drivers/.../netfront.c@linU) AND local_var(tx, txp) AND local_var(skb, skbp)</pointcut><after> struct netif_tx_request *tx = txp; void *skb = *((void **)skbp); id = get_flowid(skb); if (id != 0) { tx->flags |= id << 4; id >>= 12; } remove_flowid(netflow, skb);</after> 送信先でフロー ID を受け取るコードは割愛
•Xen のネットワーク I/O はドメイン U で netif_tx_request 構造体にヘッダを格納
ポインタに対応づけられたフローID をヘッダに格納
<transit><pointcut> access(netif_tx_request.flags) AND within_file(drivers/../netfront.c@linU) </pointcut> <xin_move name=“netin” from=“skb” to=“tx” /> <field name=“flags” offset=“4” size=“12” /> </xin_move></transit>
local_var ポイントカットでローカル変数への参照
取得
16
実装 : Kerninst の Xen 対応 アスペクトの織り込みに Kerninst [Tamches ’99] を使
用 割り込みテーブル読み込みを除去
ブレークポイントトラップ処理関数をエクスポートし、Kerninst から直接参照
割り込みテーブル読み込みは特権命令 ドメイン U やドメイン 0 から読み込めない
特権レベル判定を変更 Xen 上ドメインでの実行に対応 Kerninst は ring0 でカーネルが動作していると仮定
17
マイクロベンチマーク 目的
xflow のバックエンド関数のオーバーヘッドを調査
実験方法 各関数を 2000回呼び出し、平均を計算
実験環境 CPU: AMD Athlon™ 64 35
00+ メモリー : 2GB
ドメイン 0: 256MBドメイン U: 128MB
ドメイン 0 で実施
結果
バックエンド関数のオーバーヘッドは低い
関数名 実行時間 ( ナノ秒 )get_new_flowid 3 ± 0.0
空要素 get_flowid 9 ± 0.0
register_flowid 33 ± 4.0
get_flowid 15 ± 1.0
remove_flowid 32 ± 2.0
18
ネットワーク I/O のボトルネックの調査 目的
ドメイン U からドメイン 0 までの処理の流れ、ボトルネックを調査
xflow を用いて、ドメイン U からドメイン 0までのデータフローを調査 sk_buff 構造体のメンバーにアクセスがあった箇所
でフロー ID を取得し、時間とともに記録 例に出したアスペクトを使用
19
実験結果 処理の流れがわかった
skb_clone 関数でできた複製も追跡可能 TCP再送処理のために TCP層で実行され、ドライバーは複
製を利用 ボトルネックはドメイン 0 の内部ボトムハーフ → トップハーフのところ netif_receive_skb はトップハーフの処理割り当て関数
送信時のパケットの流れ
0 500 1000 1500 2000 2500 3000 3500 4000 (μ )経過時間 秒
alloc_skb_from_cachetcp_sendmsg
network_start_xmit
netbk_fill_flagsnetif_rx
netif_receive_skb__br_forward
SkGeXmit
FreeTxDescriptors
20
xflow によるオーバーヘッドの削減 目的
xflow を使うことでプロファイルのオーバーヘッドを削減できるか調査
方法 上のケーススタディのアスペクトで xflowありとなしを比較 ApacheBench を 300 リクエスト、 10並列で実行
結果
ドメイン 0 ドメイン U 性能 (req/s)xflowあり 1.6MB 10.6MB 382xflow なし 13.6MB 15.7MB 382
メモリー使用量
約 60% のメモリーを削減
21
関連研究 Dflow pointcut [Masuhara ’03]
データの流れを選択するポイントカット 自動的にデータを追うのでデフォルトでは追跡しすぎ
る コンパイル時に dflow のためのコードを織り込み
DJcutter [Nishizawa ’04] 、 DAC++ [Almajali ’05] 分散環境に対応したアスペクト指向システム ユーザーランドのアプリケーションを対象とする
Causeway [Chanda ’05] メタデータを伝搬させ処理の流れを追跡 FreeBSD のネットワーク I/O コードを改造して実装
22
まとめ XenLASY を提案
xflow ポイントカットを提供 データフロー追跡をアスペクトとして容易に記述可能
複数ドメインに自動でアスペクトを織り込み KLASY を拡張した動的アスペクト指向システム
ケーススタディ ネットワーク I/O のボトルネックがドメイン 0 の処理
にあることを発見 フロー追跡機能により調査に必要なメモリー使用量の削減を確認
23
今後の課題 データフロー分割時のフロー ID の割り当て方
例 ) TCP におけるフラグメント処理 同じ ID だと、分割同士の区別ができない 違う ID だと、分割同士の関係が不明瞭
ヘッダに空き領域がない場合に対応 ドメイン間で共有メモリーによりフロー ID を渡す実装を検討