カーネル用アスペクト指向システム KLAS 柳澤 佳里* 光来 健一* 千葉 滋* 石川 零* *東京工業大学 情報理工学研究科 1 カーネルプロファイラは必要 カーネルのパフォーマンス向上は重要 近年でもOSの性能を向上する改良は行われる FreeBSD、Linuxのスケジューラの改良 FreeBSD、Linuxのロック粒度の改善 TUX HTTP Server…など 性能向上には劣化させているコードの発見が第一 劣化させているところを改善したほうが費用対効果が 大きい 劣化しているところがわからないと改良しようがない 2 従来のカーネルプロファイラの問題 プロファイリングを行える点が限定的 指定されたイベントにて調査 関数の開始、終了点にて調査 プロファイリングを行う点の構造化が困難 プロファイリングをする箇所のソースコードに記述 ソースコードにロジックに関係がないコードが混在し、 可読性が低下 開発中に十分なモジュール化が必要だが、困難 3 カーネル用アスペクト指向システム: KLAS 動的アスペクト指向システム アスペクトでプロファイリングの箇所、コードを指定 粒度の細かい構造化されたプロファイリング箇所の 指定が可能 Source-based binary-level dynamic weaving により、構造体メンバーへのアクセスをポイントカット可能 カーネルを停止せずにプロファイリングの開始、 終了が可能 カーネルの停止、再起動による状態の消失がない 再現に時間がかかる問題のプロファイリングに有利 4 KLASのアスペクト例 <aspect> int inode_change_ok(…) <import>linux/time.h</import> { <advice><pointcut> … ポイントカット access(inode.i_uid) AND if ((ia_valid & ATTR_UID) && … within_function(inode_change_ok) フック attr->ia_uid != inode->i_uid) … AND target(inode_value) goto error; ポイントカット箇所 </pointcut> <before> if ((ia_valid & ATTR_GID) && struct inode *i = … (struct inode *)inode_value; } struct timeval tv; do_gettimeofday(&tv); printk(“inode.i_uid: %d at %d.%d\n”, •inode構造体のi_uidメンバーへの i->uid, tv.tv_sec, tv.tv_usec); アクセスをポイントカット </before></advice> アドバイス •アクセス時間を記録するアドバイスを実行 </aspect> 5 KLASのアスペクト ポイントカット:プロファイリング実施点の指定 execution: 関数実行点を指定 args: executionで指定した関数の引数を指定 access: 構造体メンバーアクセスの行頭を指定 target: accessで指定した構造体を指定 local: accessで指定した箇所のローカル変数を 指定 アドバイス: 実行するプロファイリングのコード 6 実装 (Overview) OS ソースコード アスペクト KLAS Cコンパイラ アスペクトコンパイラ ポイントカット OSカーネル コンパイル済みアドバイス トランポリン シンボル情報 デバッグ情報 ウィーバー OSカーネル 本体 フック 7 KLAS Cコンパイラ: コンパイル時の動作 コンパイル時にシンボル情報を収集 改造したgccにより、構造体メンバーへのアクセスをした ファイル名、行番号を記録 改造したgccにより、構造体の名前、アクセス方法を記録 Gcc、gasの改造により、最適化による行番号と アドレスのマッピング情報の消失を抑制 通常のGcc、gasはアドレスに対応する行を1つだけ記録 ヘッダファイル中のメンバアクセスの行情報が消失 inode.i_uid:fs/attr.c:31,inode &(*(*(struct inode **)inode)) シンボル情報 デバッグ情報 KLAS gcc/gas fs/attr.c:31 0xc010ccbb if ((ia_valid & ATTR_UID) && attr->ia_uid != inode->i_uid) … goto error; if ((ia_valid & ATTR_GID) &&8 ウィーバー: フック挿入アドレスの解決 構造体メンバーアクセスに対応するファイル名、行番号を調査 コンパイラの作ったデバッグ情報を用いて、ファイル名、行番号に 相当するアドレスを解決 コンパイラの作ったシンボル情報により、ジョインポイント変数の アクセス方法を特定 デバッグ情報 シンボル情報 … fs/attr.c:31:inode,’(*(*struct inode **)inode)):inode.i_uid fs/attr.c:31:attr,&(*(*(struct iattr **)attr)):iattr.ia_uid fs/attr.c:31:inode,&(*(*struct inode **)inode)):inode.i_uid fs/attr.c:37:inode,&(*(*(struct inode **)inode)):inode.i_uid ... 構造体メンバー アクセス 35 2 0 4 1 “fs/attr.c” “GNU C Compiler” … ファイル名 行番号 アドレス 9 ウィーバー: トランポリンの作成 トランポリンを用いてジョインポイントのコンテキストを 利用 target、local、argsポイントカットを実現 デバッグ情報より変数の格納位置を特定 例) ローカル変数attrを参照 デバッグ情報 DW_AT_name: inode_change_ok DW_AT_low_pc: 0xc017e494 DW_AT_high_pc: 0xc017e5b9 Abbrev Number: 53 (DW_TAG_formal_parameter) DW_AT_name: attr DW_AT_location: 1 byte block: 53 (DW_OP_reg7) … トランポリン void trampoline_c017e50b(unsigned long addr) { void ***ebp, *ecx; __asm__ __volatile(“movl %%ecx, %0”: “=r”(ecx)); … { void *arg0 = &(ebp[3 + (8 – 7)]); advice(ecx, arg0); } } 10 ウィーバー: フックの挿入 Kerninst [Ariel et al. ’99]を利用して動的にフック挿入 APIを用いてフック挿入箇所のアドレス、呼び出すトランポリン コードを指示 APIを用いてフックが有効な位置に入っているか調査 フックは挿入される位置の機械語長で変化 5バイト以上: jmp命令 4バイト以下: int3命令(ブレークポイントトラップ) ウィーバー OSカーネル コンパイル済みアドバイス Kerninst フック トランポリン 11 実験 実験環境 CPU: AMD Athlon XP 1800+、Mem: 1GB Fedora Core 2 Linux (2.6.10 kernel) GNU C Compiler 3.3.3、Kerninst 2.1 目的 KLASを利用した際のオーバーヘッドを測定 KLASのフックのオーバーヘッドを測定 UnixBenchを用いてKLAS gccでコンパイルされた カーネルのオーバーヘッドを測定 KLASは変数値の取得のためにフレームポインタを使用 KLASはデバッグ情報を作成 12 実験結果 フックのオーバーヘッド (ナノ秒) トランポリン使用 no register フックの jmp 種類 int3 frame 16 18 19 200 202 203 UnixBenchによるKLAS gccと通常gccの比較 dhry2reg execl pipe context 通常 397.6 708.5 872.6 731.1 KLAS 397.2 735.4 803.8 717.8 0 -3.7 8.6 1.9 オーバーヘッド 13 使用例: ネットワーク I/Oのプロファイリング 得られたログ (生データ) 使用したアスペクト <aspect><import>linux/skbuff.h</import> <import>linux/netdevice.h</import> <advice><pointcut> access(sk_buff.%) AND target(arg0) </pointcut> <before> struct sk_buff *skb = (struct sk_buff *)arg0; unsigned long long timestamp; if (skb->>protocol != ETH_P_ARP) { DO_RDTSC(timestamp); STORE_DATA(timestamp); STORE_DATA($pc$); STORE_DATA(arg0);} </before></advice></aspect> 8684196258043, 8684196258614, 8684196259462, 8684196259661, 8684196260215, 8684196260807, … 0xc02db384, 0xc02db3a1, 0xc02db3d7, 0xc02db3e7, 0xc02db3ff, 0xc02da4da, 0xf6b03420 0xf6b03420 0xf6b03420 0xf6b03420 0xf6b03420 0xf6b03420 解析結果 関数名 e1000_rx_checksum 1000_clean_rx_irq eth_type_trans netif_receive_skb netif_rx ip_rcv ip_rcv_finish ip_local_deliver ip_local_deliver_finish tcp_v4_rcv tcp_v4_do_rcv tcp_rcv_established tcp_measure_rcv_mss tcp_event_data_recv tcp_grow_window tcp_rcv_established skb_copy_datagram_iovec __kfree_skb ファイル名 e1000_main.c eth.c dev.c dev.c dev.c ip_input.c ip_input.c ip_input.c ip_input.c tcp_ipv4.c tcp_ipv4.c tcp_input.c tcp_input.c tcp_input.c tcp_input.c tcp_input.c datagram.c skbuff.c 行番号 2773 2434 164 1638 1500 367 287 275 201 1741 1688 4238 140 554 268 4355 234 225 経過時間 0.00 0.34 0.47 1.06 1.68 3.43 4.83 5.56 6.02 6.84 10.83 11.14 12.46 13.36 13.68 14.23 25.93 27.14 14 関連研究: カーネル用システム 実行時コード挿入システム 実行時に指定された位置にフックを挿入 コード挿入の指定が機械語粒度で使いにくい Kerninst [Ariel et al. ’99] GILK [David et al. ’02] トレーサー/プロファイラー イベント、関数開始終了点でログ取得、コード実行 指定するイベントの構造化が困難 LTT [Karim et al. ’00] Dtrace [Bryan et al. ’04] SystemTAP [Vara et al. ’05] 15 関連研究: C言語用アスペクト指向システム 静的アスペクト指向システム ウィーブ、アンウィーブにシステムの停止が必要 AspectC [Yvonne et al. ’03] AspectC++ [Olaf et al. ’02] 動的アスペクト指向システム 実行時にアスペクトをウィーブ、アンウィーブ コンパイル時の情報を用いない 構造体のメンバーアクセスをポイントカット不可 μDyner [Marc et al. ’03] Arachne [Remi et al. ’05] TOSKANA [Michael et al. ’05] 16 落ち穂拾い KLASはカーネル限定か? ユーザーランドの動的アスペクト指向システムにも 応用可能 カーネルは停止の影響が大きい カーネルは構造体の利用が多い なぜプロファイリングにアスペクト指向か? プログラムの構造を考慮したモジュール化が可能 構造化のための特別なコードや下準備が不要 17 まとめと今後の課題 まとめ KLASの提案 プロファイリングのコードをアスペクトとして記述 動的にウィーブ・アンウィーブが可能 構造体のメンバーをポイントカット可能 ポイントカットした箇所のコンテキストを利用可能 実験でKLASのオーバーヘッドが少ないことを確認 コンテキストを利用してもフックのオーバーヘッドは最大で200ナノ秒程度 UnixBenchにより性能が1割程度劣化する場合があることを確認した sk_buffに基づいたネットワーク I/Oのトレース KLASの利用例の提示 今後の課題 実装の洗練 さらなる応用例の発見 18
© Copyright 2024 ExpyDoc