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