tracepoints利用法

Similar documents
自己紹介 湯浅陽一 1999 年より Linux kernel 開発に参加 MIPS アーキテクチャのいくつかの CPU へ Linux kernel を移植

演算増幅器

目次 1. DB 更新情報受信 SW 仕様書 構成および機能 全体の構成 DB 更新情報受信 SW の機能 ソフトウェアの設計仕様 DB 更新情報受信 SW の仕様 資料編... 5

通信プログラムの試作ーーー UDP を用いたじゃんけんゲームシステム ーーーー裘彬濱 南山大学情報理工学部 ソフトウェア工学科青山研究室

1) // 2) I/O 3) Japan Advanced Institute of Science and Technology 2013/07/26 1

DA100データアクイジションユニット通信インタフェースユーザーズマニュアル

【注意事項】RXファミリ 組み込み用TCP/IP M3S-T4-Tiny

ネーミング(1)

多言語ドメイン名の実装 mdnkit 石曽根信 ( 株 ) SRA 2001/12/04 日本語ドメイン名解説 / mdnkit 1 mdnkit 多言語ドメイン名を扱うためのツールキット 正規化 エンコード変換等を提供するライブラリとコマンド 既存アプリケーシ

04-process_thread_2.ppt

3 3.1 LAN ISDN (IP) 2 TCP/UDP IP IP IP IP (Ethernet) Ethernet LAN TCP/UDP LAN Ethernet LAN 2: Ethernet ATM, FDDI, LAN IP IP IP 3 IP 2 IP IP IP IP IP 3

今週の進捗

I /07/30 Dependable Network Innovation Center, Japan Advanced Institute of Science and Technology

エラー処理・分割コンパイル・コマンドライン引数

RTC_STM32F4 の説明 2013/10/20 STM32F4 内蔵 RTC の日付 時刻の設定および読み込みを行うプログラムです UART2( 非同期シリアル通信ポート 2) を使用して RTC の設定および読み込みを行います 無料の開発ツール Atollic TrueSTUDIO for

untitled

13 I/O

スライド 1

スライド 1

TRQerS - Introduction

実験 6 通信基礎実験 1 目的 ネットワークを通じてデータ転送を行うことを体験的に学ぶために 本実験ではT CP/IPプロトコルを使い ワークステーション間で通信を行うクライアントサーバモデルのプログラムを作成する 2 解説 1 ネットワークとプロトコルネットワーク ( コンピュータネットワーク

CashDrawer ライブラリ API 仕様書 2014/07/09 CashDrawer ライブラリ API 仕様書 Rev / 10

演算増幅器

// このクラスの有効期間中の各呼び出しに使用される キャッシュされた Socket オブジェクト Socket socket = null; // 非同期処理が完了したことを通知するために信号を送るオブジェクト static ManualResetEvent clientdone = new Ma

注意 2013 年くらいに調べた話なので 変化していることもあるかもしれません 2

bitvisor_summit.pptx

PowerPoint プレゼンテーション

AquesTalk プログラミングガイド

Microsoft Word - 第5回 基本データ構造2(連結リスト).doc

情報科学実験ガイダンス

Presentation title (on one or two lines)

FreeBSD 1

NUMAの構成

Microsoft PowerPoint - WRR-celinux-upload 1.ppt

thesis.dvi

IP L09( Tue) : Time-stamp: Tue 14:52 JST hig TCP/IP. IP,,,. ( ) L09 IP (2017) 1 / 28

スライド 1

AquesTalk Win Manual

PowerPoint プレゼンテーション

組込み Linux の起動高速化 株式会社富士通コンピュータテクノロジーズ 亀山英司 1218ka01 Copyright 2013 FUJITSU COMPUTER TECHNOLOGIES LIMITED

FUJITSU Software Systemwalker Centric Manager Lite Edition V13.5 機能紹介資料

目次 1 はじめに 登録商標 商標 注意事項 免債事項 SR-IOV の機能概要 性能検証事例 測定環境 測定結果 各方式による共有 NIC 性能比較 ( ポートあ

情報ネットワーク演習 2006年10月5日

BSDソケットによるIPv6プログラミングを紐解く

arduino プログラミング課題集 ( Ver /06/01 ) arduino と各種ボードを組み合わせ 制御するためのプログラミングを学 ぼう! 1 入出力ポートの設定と利用方法 (1) 制御( コントロール ) する とは 外部装置( ペリフェラル ) が必要とする信号をマイ

次に示す数値の並びを昇順にソートするものとする このソートでは配列の末尾側から操作を行っていく まず 末尾の数値 9 と 8 に着目する 昇順にソートするので この値を交換すると以下の数値の並びになる 次に末尾側から 2 番目と 3 番目の 1

AquesTalk for WinCE プログラミングガイド

J.JSSAC Vol. 7, No. 2, Mathematica Maple,., Open asir Open xxx asir. Open xxx Open asir, asir., Open xxx, Linux Open asir Open sm1 (kan/sm1). C

4 実験結果 // 用意されたヘッダファイル #include < stdio.h> #include < fcntl.h> #include < netdb.h> #include < sys/types.h> #include < sys/socket.h> #include < sys/sta

slide5.pptx

第 2 章インタフェース定義言語 (IDL) IDL とは 言語や OS に依存しないインタフェース定義を行うためのインタフェース定義言語です CORBA アプリケーションを作成する場合は インタフェースを定義した IDL ファイルを作成する必要があります ここでは IDL の文法や IDL ファイ

main main Makefile Makefile C.5 Makefile Makefile Makefile A Mech (TA ) 1. Web ( iku

SDC_SDIO_STM32F4 の説明 2013/09/17 SDIO インターフェースで SD カードをアクセスするプログラムのプロジェクトサンプルです FAT でファイルアクセスするために FatFs( 汎用 FAT ファイルシステム モジュール ) を使用しています VCP(USB 仮想 C

Microsoft PowerPoint - 計算機言語 第7回.ppt

IEEE1888 開発キットの活用 電力管理システムを作る 慶應義塾大学 メディアデザイン研究科 秋山寛子

AquesTalk2 Win マニュアル

Microsoft Word - Training10_プリプロセッサ.docx

( ) 3 1 ( ), ( ).. 1

A B 1: Ex. MPICH-G2 C.f. NXProxy [Tanaka] 2:

10/ / /30 3. ( ) 11/ 6 4. UNIX + C socket 11/13 5. ( ) C 11/20 6. http, CGI Perl 11/27 7. ( ) Perl 12/ 4 8. Windows Winsock 12/11 9. JAV

Microsoft PowerPoint - CproNt02.ppt [互換モード]

PowerPoint プレゼンテーション

Microsoft Word - EGX100によるH663通信手引

ダンプ取得機能強化サポートオプション Enterprise Edition

電子情報通信学会ワードテンプレート (タイトル)

Application Note Application Note No. ESC-APN Document No.: ESC-APN adviceluna Linux デバッグ手順 (MIPS コア編 ) はじめに adviceluna Linux デバッグ手順 ( 以

Linuxのベンチマーク評価 とボトルネック解析

netmapによる 実践パケット処理プログラミング

Linux2.4でのメモリ管理機構

Microsoft PowerPoint pptx

tri_s_tg12864_vcp の説明 2014/02/05 飛石伝ひ CPU 基板 の LCD TG12864 の表示プログラムです 漢字表示 (JIS208) を行うことができます USB の VCP ( 仮想 COM ポート ) を使用して非同期シリアル通信により 表示試験を行うことができ

プロセス間通信

Microsoft PowerPoint - lec10.ppt

r08.dvi

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

O(N) ( ) log 2 N

1 telnet WWW 1.1 telnet WWW URL html 1.2 URL 1 % telnet 80 Trying 2001:2f8:1c:d048::850d: telnet: c

プログラミング方法論 II 第 14,15 回 ( 担当 : 鈴木伸夫 ) 問題 17. x 座標と y 座標をメンバに持つ構造体 Point を作成せよ 但し座標 は double 型とする typedef struct{ (a) x; (b) y; } Point; 問題 18. 問題 17 の

情報ネットワーク演習 2007 年 10 月 11 日 ( 木 )

Apache Web Server 2 Compaq ActiveAnswers Deskpro Compaq Insight Manager Fastart Systempro Systempro/LT ProLiant ROMPaq Qvision SmartStart NetFlex Quic

Taro-ポインタ変数Ⅰ(公開版).j

PowerPoint プレゼンテーション

‚æ4›ñ

ohp08.dvi

1. USB の VCP( 仮想 COM ポート ) について USB の VCP( 仮想 COM ポート ) は USB を非同期シリアル通信として使用するための USB のドライバです PC には VCP ドライバをインストールする必要があります USB の VCP( 仮想 COM ポート )

slide4.pptx

昨年度までの研究紹介 および 研究計画

1.SqlCtl クラスリファレンス SqlCtl クラスのリファレンスを以下に示します メソッドの実行中にエラーが発生した場合は標準エラー出力にメッセージを出力します (1)Connect() メソッド データベースへ connect 要求を行います boolean Connect(String

Microsoft Word - Cプログラミング演習(12)

Microsoft Word - IPC-intro.docx

bitvisor-ipc v12b.key

Microsoft PowerPoint - 第5章補足-DB2組み込みSQL.ppt

Red Hat Enterprise Linuxのcron(8)デーモンにデフォルト定義されたtmpwatch命令の動作による、WebOTXのトラブル対処方法

オペレーティングシステム2004 プロセス \(1\)

SystemC言語概論

スライド 1

CoIDE 用 F4D_VCP の説明 V /07/05 USB の VCP( 仮想 COM ポート ) による非同期シリアル通信を行うプログラムです Free の開発ツール CoIDE で作成した STM32F4 Discovery 用のプロジェクトです プログラムの開始番地は 0x

Microsoft Word - Win-Outlook.docx

char int float double の変数型はそれぞれ 文字あるいは小さな整数 整数 実数 より精度の高い ( 数値のより大きい より小さい ) 実数 を扱う時に用いる 備考 : 基本型の説明に示した 浮動小数点 とは数値を指数表現で表す方法である 例えば は指数表現で 3 書く

問 2 ( 型変換 ) 次のプログラムを実行しても正しい結果が得られない 何が間違いかを指摘し 正しく修正せよ ただし int サイズが 2 バイト long サイズが 4 バイトの処理系での演算を仮定する #include <stdio.h> int main( void ) { int a =

Transcription:

CE Linux Forum Japan Technical Jamboree #34 2010/9/3 tracepoints 利用法 ~cputime モニタリング ~ ( 株 ) 日立製作所中央研究所 茂岡知彦 (SHIGEOKA Tomohiko)

背景 Linux や Unix ではプロセスの CPU 時間統計はサンプリング方式 組込み機器ではサンプリングによる CPU 時間測定は不正確なことがある 性能のチューニングには正確な情報が必要 ~ 正確に測れないものは改善できない ~ カーネルトレースは事後にのみ正確な CPU 時間を計算できるが リアルタイムで計測出来ず 2

Linux のプロセス CPU 時間算出方法 サンプリングで CPU 時間を算出 定期的割込み (tick) の発生時に実行中のプロセス 割込み間隔時間 CPU を占有 ( と仮定 ) プロセス数少 タスクスイッチ頻度少ならば OK フ ロセスA フ ロセスB フ ロセスC 10ms 10ms 10ms 10ms 2tick=20ms 1tick=10ms 2tick=20ms t CPU 時間 tick interrupt 組込みや最近のサーバ環境では? プロセス数多 割込み タスクスイッチ頻度多 仮想化すると他のVMが実はCPUを使っている 3

サンプリングによる問題点 標本化定理によると (CPU 時間はアナログ信号ではないが ) サンプリング周波数は信号周波数の 2 倍以上 HZ の 1/2 以上のタスクスイッチはめずらしくない フ ロセスA フ ロセスB フ ロセス C 10ms(HZ=100) 0tick=0ms?? 1tick=10ms?? 1tick=10ms?? t 不正確な CPU 時間 組込みでは周期実行タスクがよく使われる 周期によってはサンプリングでまったくヒットしない 周期実行フ ロセス A フ ロセス B フ ロセス C 10ms 10ms 10ms 0tick=0ms?? 3tick=30ms?? 1tick=10ms?? t 不正確な CPU 時間 タスクスイッチの間隔で CPU 時間を測れば正確 4

タスクスイッチによる CPU 時間算出 CELF ジャンボリー #15 上床 @Toshiba さん発表 [1] netcpurate( タスクスイッチなどに計測コードを追加,netpoll 送信 ) (LAN 経由で ) その場でわかるがカーネルを改造 CONFIG_VIRT_CPU_ACCOUNTING[2] ppc64,s390 などの ( 仮想化 ) 特定環境用の測定機能 カーネルトレース (LKST,LTTng, ftrace など ) の利用 トレースデータを事後処理して計測 性能がその場でわからない リアルタイム計測に不向き tracepoints(v2.6.28 から ) をフックしてリアルタイム計測 フックから呼ばれるモジュールは本体改造不要 5

tracepoints 概要 : 埋め込み カーネル内のイベントをフックする標準フレームワーク ソースへの埋め込みが必要 [4] 有効 無効や各種条件フィルタは実行時設定 埋め込み箇所 :subsys/file.c 宣言 :include/trace/subsys.h #include <linux/tracepoint.h> DECLARE_TRACE(subsys_myevent, TP_PROTO(int arg, struct task_struct *p), TP_ARGS(arg,p)); カーネル内にすでに埋め込み済み #include <trace/subsys.h> DEFINE_TRACE(subsys_myevent); void func(void) {... trace_subsys_myevent(arg, task);... } 赤字はイベント名 対応コードがマクロで展開 割込み スケジューラ システムコール メモリ管理その他 (v2.6.33.5 で 150 以上のイベントを定義済み ) 6

tracepoints 概要 : プローブ 各種トレース用のプローブ ( トレーサ ) が標準装備 実行時に呼び出すプローブは動的に設定 blk,function,function,sched_switch 他多数 汎用ログバッファ機能 (ringbuffer) 有 #include <trace/subsys.h> static void probe_subsys_myevent(int arg, struct task_struct *p) { printk(kern_info "myevent! arg=%d tsk=%p n", arg, p); } static int init myevent_probe_init(void) { int ret; ret = register_trace_subsys_myevent(probe_subsys_myevent);... } static void exit myevent_probe_exit(void) { unregister_trace_subsys_myevent(probe_subsys_myevent); tracepoint_synchronize_unregister(); } 7

tracepoints による CPU 時間測定 通常のプロセス CPU 時間統計 tick によるサンプリング ( 最小時間単位 1tick) ユーザ (user) 時間 カーネル (sys) 時間をカウント 割込みハンドラ実行中は除外 その他 (real など ) 今回 単純化のためプロセス実行中かどうかのみ考慮 リアルタイム観測用に動作中プロセスを毎秒集計 (top コマンド風 ) sched_switch イベントをフック 8

リアルタイム観測方式 netpoll/netconsole カーネル内から udp でデータを簡単に送信 割込み不使用 オーバヘッド 副作用が少ない 普通の NIC ドライバはほぼ対応 今回 USB 接続 NIC を使用 USB 接続 NIC は netpoll 非対応 (USB ホストが割込み要 ) カーネルスレッドでソケットを使用 [3] MTU 以下の少量データを UDP 送信しオーバヘッド削減 9

カーネルスレッドでのソケット使用法 ユーザランド API との違い ファイルディスクリプタを使わない ユーザランド API @sys/socket.h カーネル内 API @include/linux/inet.h 説明 socket() sock_create() ソケット作成 fdなし struct socketを使用 inet_aton() in_aton() dot 区切り数値文字列をバ イナリ値に変換 connect() sock->ops->connect() ソケットに関連する connect() 等を呼ぶ sendmsg() sock_sendmsg() メッセージ送信 事前に set_fs(kernel_ds) する recvmsg() sock_recvmsg() メッセージ受信 事前に set_fs(kernel_ds) する close() sock_release() ソケットを開放 10

プロセス単位の集計方法 カーネル内のプロセス毎の情報 通常のCPU 時間統計はstruct task_structに格納 情報追加はカーネル本体改造 ( バイナリ非互換 ) 別のデータ構造でモジュール側で保持 毎秒 1 回集計 LAN 経由で観測するためカーネルスレッドで毎秒 1 回集計 ソートして Top10 のみ抽出 ( 送信データ削減のため ) 11

システム構成 観察は nc(netcat) コマンド実行のみ text formatting などはターゲットで実施 Monitor(Linux PC) Target(Linux Board) # nc l u 11111 ----- cpu0 total:1699243330 klogd[ 3629]: 402020( 0.0%) probe-cputime[ 4043]: 373870( 0.0%) syslogd[ 3626]: 353810( 0.0%) events/0[ 6]: 27400( 0.0%) sync_supers[ 106]: 16510( 0.0%) UDP Application Application Application probe-cputime Linux kernel sched_switch USB NIC LAN 12

probe-cputime.c (1) 1 /* Copyright (c) 2010 Hitachi, Ltd. */ 2 /* TODO: add error check */ 3 #include <linux/version.h> 4 #include <linux/init.h> 5 #include <linux/module.h> 6 #include <linux/kthread.h> 7 #include <linux/string.h> 8 #include <linux/types.h> 9 #include <linux/delay.h> 10 #include <linux/smp_lock.h> 11 #include <linux/sort.h> 12 #include <asm/atomic.h> 13 #include <linux/netdevice.h> 14 #include <linux/ip.h> 15 #include <linux/in.h> 16 #include <linux/inet.h> 17 #include <net/udp.h> 18 #include <trace/events/sched.h> 19 20 #define MODULENAME "probe-cputime" 21 MODULE_DESCRIPTION("Tracepoint module for measuring cputime."); 22 MODULE_LICENSE("GPL"); 23 24 #define UDP_HOST "192.168.220.1" 25 #define UDP_PORT 11111 26 #define INTERVAL 1000 27 #define NCPU 2 28 #define NBUFS 2 29 #define NPROCS 256 30 struct cputime_struct { 31 struct task_struct *tsk; 32 pid_t pid; 33 u32 cputime; 34 u32 padding; 35 char comm[task_comm_len]; 36 } cputime_data[ncpu][nbufs][nprocs]; 37 static atomic_t cur_buf_idx[ncpu]; 39 static int cmp_cputime(const void *a, const void *b) 40 { /* for sort function */ 41 u32 x = ((struct cputime_struct*)a)->cputime; 42 u32 y = ((struct cputime_struct*)b)->cputime; 43 if (x < y)return 1;if (x > y)return -1;return 0; 44 } 45 46 static void add_cputime(struct task_struct *tsk, pid_t pid, u32 cputime) 47 { /* TODO: USE HashTable */ 48 int cpu = smp_processor_id(); 49 int buf_idx = atomic_read(&cur_buf_idx[cpu])%nbufs; 50 int i; 51 52 /* total time */ 53 cputime_data[cpu][buf_idx][0].cputime += cputime; 54 if (pid == 0) { /* idle task */ 55 cputime_data[cpu][buf_idx][1].cputime += cputime; 56 return; 57 } 58 for (i = 2; i < NPROCS; i++) { /* other task */ 59 struct cputime_struct *e = &cputime_data[cpu][buf_idx][i]; 60 if (e->pid == pid) { 61 e->cputime += cputime; break; 62 } 63 if (e->tsk == NULL) { 64 e->tsk = tsk; e->pid = pid; 65 strncpy(e->comm, tsk->comm, 16); 66 e->cputime = cputime; break; 67 } 68 } 69 } cputime 加算 13

probe-cputime.c (2) 71 static int helper_running = 0; 72 static struct task_struct *helper_thread; 73 static char send_buf[1024]; kernel thread function L75-L165 74 75 static int helper_func(void *arg) 76 { /* function for thread */ 77 int err, optval; 78 static struct socket *sock; 79 struct sockaddr_in addr; 80 81 lock_kernel(); 82 current->flags = PF_NOFREEZE; 83 daemonize(modulename); 84 allow_signal(sigkill); 85 helper_running = 1; 86 unlock_kernel(); 87 88 /* setup socket */ 89 err = sock_create(af_inet, SOCK_DGRAM, IPPROTO_UDP, &sock); 90 91 /* TODO:fix host addrress */ 92 memset(&addr, 0, sizeof(struct sockaddr)); 93 addr.sin_family = AF_INET; 94 addr.sin_addr.s_addr = in_aton(udp_host); 95 addr.sin_port = htons(udp_port); 96 97 optval = 1; 98 sock_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(int)); 99 udp socket loop block L100-L160 100 do { 101 int cpu; 102 int buf_lastpos = 0; 103 104 if (signal_pending(current)) break; 105 msleep(interval); 106 for (cpu = 0; cpu < num_online_cpus(); cpu++) { 107 int i; 108 int bufidx = (atomic_inc_return(&cur_buf_idx[cpu])- 1)%NBUFS; 109 110 /* sort */ 111 sort(cputime_data[cpu][bufidx], NPROCS, sizeof(struct cputime_struct), cmp_cputime, NULL); 112 113 /* format text */ 114 buf_lastpos += snprintf(send_buf+buf_lastpos, sizeof(send_buf)-buf_lastpos, 115 "%23s:%10u n", cputime_data[cpu][bufidx][0].comm, 116 cputime_data[cpu][bufidx][0].cputime); 117 u32 totaltime_h = cputime_data[cpu][bufidx][0].cputime>>10; 118 for (i = 1; i < 11; i++) { 119 u32 cputime_h = cputime_data[cpu][bufidx][i].cputime>>10; 120 if (cputime_h == 0) { 121 buf_lastpos += snprintf(send_buf+buf_lastpos, sizeof(send_buf)-buf_lastpos, 122 " n"); break; 123 } 124 buf_lastpos += snprintf(send_buf+buf_lastpos, sizeof(send_buf)-buf_lastpos, 125 "%16s[%5d]:%10u(%2d.%1d%%) n", 126 cputime_data[cpu][bufidx][i].comm, 127 cputime_data[cpu][bufidx][i].pid, 128 cputime_data[cpu][bufidx][i].cputime, 129 (cputime_h*100/totaltime_h), 130 (cputime_h*1000/totaltime_h % 10)); 131 } 14

probe-cputime.c (3) 133 /* clear old buffer */ 134 memset(cputime_data[cpu][bufidx], 0, sizeof(struct cputime_struct)*nprocs); 135 snprintf (cputime_data[cpu][bufidx][0].comm, 16, "cpu%d total", cpu); 136 snprintf (cputime_data[cpu][bufidx][1].comm, 16, "idle"); 137 } 138 snprintf(send_buf+buf_lastpos, sizeof(send_buf)-buf_lastpos, 139 "----- n"); 140 141 if (sock->sk) { /* send */ 142 mm_segment_t oldfs; send! 143 int sz; 144 struct iovec iov = { 145.iov_base = send_buf,.iov_len = strlen(send_buf), 146 }; 147 struct msghdr msg = { 148.msg_flags = 0,.msg_name = &addr, 149.msg_namelen = sizeof(struct sockaddr_in), 150.msg_control = NULL, 151.msg_controllen = 0, 152.msg_iov = &iov,.msg_iovlen = 1, 153.msg_control = NULL, 154 }; 155 156 oldfs=get_fs(); set_fs(kernel_ds); 157 sz = sock_sendmsg(sock, &msg, iov.iov_len); 158 set_fs(oldfs); 159 } 160 } while (1); 161 162 sock_release(sock); sock = NULL; 163 helper_running = 0;helper_thread = NULL; 164 return 0; 165 } 166 167 static u32 last_ctxsw_time[ncpu]; 168 static void probe_sched_switch(struct rq *rq, struct task_struct *prev, struct task_struct *next) 169 { /* tracepoints probe */ 170 unsigned long flags; probe for sched_switch 171 pid_t pid = prev->pid; 172 int cpu = smp_processor_id(); 173 u32 now = get_cycles(); 174 local_irq_save(flags); 175 if (last_ctxsw_time[cpu]) { 176 add_cputime(prev, pid, (now-last_ctxsw_time[cpu])); 177 } 178 last_ctxsw_time[cpu] = now; 179 local_irq_restore(flags); 180 } 181 182 static int init probe_cputime_init(void) 183 { /* module init */ 184 int ret = 0; 185 if (num_online_cpus() > NCPU) return -ENOMEM; 186 ret = register_trace_sched_switch(probe_sched_switch); 187 WARN_ON(ret); if (ret) return ret; 188 helper_thread = kthread_create(helper_func, NULL, MODULENAME "-helper"); 189 kthread_bind(helper_thread, num_online_cpus()-1); 190 wake_up_process(helper_thread); 191 return 0; 192 } 193 module_init(probe_cputime_init); 15

probe-cputime.c (4) 195 static void exit probe_cputime_exit(void) 196 { /* module clear */ 197 int err; 198 if (helper_thread) { /* terminate thread */ 199 lock_kernel(); 200 err = kill_pid(find_vpid(helper_thread->pid), SIGKILL, 1); 201 unlock_kernel(); 202 if (err >= 0) while (helper_running) msleep(100); 203 } 204 unregister_trace_sched_switch(probe_sched_switch); 205 tracepoint_synchronize_unregister(); 206 } 207 module_exit(probe_cputime_exit); 16

評価 評価環境 Atom D510(1.66GHz,1core,noHT), USBLAN(100Mbps) kernel2.6.33.2, CentOS5, HZ100, PREEMPT_VOLUNTARY 評価内容 データ集計とネットワーク送信のオーバヘッドを測定 probe-cputimeなしとあり 負荷なしとあり (dd if=/dev/zero dd dd if=/dev/null) 17

性能測定 (1) 高負荷時の影響 dd if=/dev/zero bs=1k count=100k dd dd of=/dev/null 項目 probe-cputimeあり probe-cputimeなし 影響度 real 7.57s 7.40s +2.8% user 0.64s 0.62s +3.4% sys 6.91s 6.77s +2.1% ctxsw は 60798 回 /s cpu0 total:1699243330 dd[ 4214]: 885568160(52.1%) 引数なし dd[ 4215]: 634279990(37.3%) of=/dev/null dd[ 4213]: 178221570(10.4%) if=/dev/zero klogd[ 3629]: 402020( 0.0%) probe-cputime[ 4043]: 373870( 0.0%) 0.02% syslogd[ 3626]: 353810( 0.0%) events/0[ 6]: 27400( 0.0%) sync_supers[ 106]: 16510( 0.0%) 18

性能測定 (2) 低負荷時の影響 ほとんどなし dd if=/dev/zero bs=1k count=1000k of=/dev/null 項目 probe-cputimeあり probe-cputimeなし real 1.40s 1.40s user 0.44s 0.45s sys 0.96s 0.94s ctxsw は 36 回 /s カーネルスレッドの負荷は同等 (0.02%) cpu0 total:1699211580 dd[10904]:1697940180(99.9%) klogd[ 3629]: 386170( 0.0%) probe-cputime[10890]: 357770( 0.0%) 0.02% syslogd[ 3626]: 336960( 0.0%) init[ 1]: 147980( 0.0%) events/0[ 6]: 24660( 0.0%) sync_supers[ 106]: 17860( 0.0%) 19

考察 tracepoints の負荷はイベント発生回数次第 超大量タスクスイッチ 60000 回 /s で 2% は優秀 今回はプロセス数の影響は不明 データ構造などの工夫 (hashtable 等 ) が必要 データ集計のCPU 負荷に影響 少量の UDP データ送信は誤差程度 20

まとめ tracepoints は主要なカーネル内イベントを簡単にフック可能 tracepoints の負荷もあまり心配ない 標準のトレーサ以外にも tracepoints はいろいろ活用できる 21

参考文献 [1] Linux NetPoll の活用, http://www.celinuxforum.org/celfpubwiki /JapanTechnicalJamboree15?action=AttachFile&do=get& target=celf_netpoll.pdf [2] CONFIG_VIRT_CPU_ACCOUNTING まとめ, http://mkosaki.blog46.fc2.com/blog-entry-453.html [3] Simple UDP Server, http://kernelnewbies.org/simple_udp_server [4] Using the Linux Kernel Tracepoints, $KERNELSRC/Documentation/trace/tracepoints.txt 22