Kernel fcache-bug
Upcoming SlideShare
Loading in...5
×
 

Kernel fcache-bug

on

  • 1,095 views

how to find a bug in kernel/fs about wrong page cache flush in resizing MD device.

how to find a bug in kernel/fs about wrong page cache flush in resizing MD device.

Statistics

Views

Total Views
1,095
Views on SlideShare
1,093
Embed Views
2

Actions

Likes
1
Downloads
3
Comments
0

1 Embed 2

https://twitter.com 2

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Kernel fcache-bug Kernel fcache-bug Presentation Transcript

  • ファイルキャッシュクリアの謎 技術Bar#9 2012/12/4 光成滋生
  • cybozu.comで障害発生 ストレージ容量拡張操作の結果、Officeが動 いているLinuxマシンのページキャッシュが約 15分おきに破棄されるという未知の現象が発 生したためです 2 / 20
  • 現象の詳細mdadmでLVMのパーティションを拡大する と15分毎にpage cacheがクリアされる メモリにキャッシュ MySQLなどのアプリ これがクリアされて 激遅に ext3 ファイルシステム mdadm ソフトウェアRAID LVM パーティション管理 kernel/device driver 犯人はだれか? hard disk 3 / 20
  • 調査のやりかた現象の再現方法の構築 頻度が低かったり環境によって起こらないと面倒原因を推測して絞り込み トライアンドエラー さまざまなツールを使う特定したら修正して確認 はずれていたらまた別の原因を推測 4 / 20
  • 現象の確認hazamaでの容量の変更は500GB→1TB バックグラウンドリサイズが長時間 数十MB程度では17分以内に終わってしまう手元の環境でディスクを用意して… 1時間待ったが発現しなかった 私の勘違い  キャッシュがクリアされるのはそのディスクに構築し たファイルシステム上のもののみ 再度テスト クリアされることを確認 約17分=>概ね1000秒であることも判明 5 / 20
  • 犯人は誰か全然見当がつかない 普通ユーザラウンドで明示的に破棄なんてしない page cacheを破棄しそうなkernelの関数を列挙 flush_disk, invalidate_disk, invalidate_parition, ... これらの関数を呼び出すやつを探そうftraceを使って探す ubuntuでは標準搭載 呼ばれた関数,stacktrace,eventなどがわかる /sys/kernel/debug/tracingに様々な値を書き込 むことでパラメータを設定する 結構複雑で慣れるまで難しかった 6 / 20
  • ftraceの例ext4系関数が呼ばれたときのcall treeを表示// debugfsをmountmount -t debugfs debugfs /sys/kernel/debug// stack tracerを有効echo 1 > /proc/sys/kernel/stack_tracer_enabledcd /sys/kernel/debug/tracing// ext4で始まる関数名をターゲットにecho "ext4*" > set_ftrace_filter// 関数トレーサーをセットecho function > current_tracerecho 0 > trace cat trace_pipeext4のファイルシステムをmoutすると関連関 数のlogが表示される 7 / 20
  • あたりをつけるディスクを交換したり,resize開始直後に呼ば れる関数をセットして17分待つ 呼ばれない… 別の関数を試すことの繰り返し このあたりが結構辛い 8 / 20
  • 漸くヒット__invalidate_deviceが網にかかった!mdadm-900 [001] .... 75491.384221: __invalidate_device <-invalidate_partitionmdadm-900 [001] .... 75491.384235: <stack trace>=> ftrace_call=> invalidate_partition=> rescan_partitions=> __blkdev_get 下の関数が上の関数=> blkdev_get=> blkdev_open を呼び出している=> do_dentry_open=> nameidata_to_filp=> do_last=> path_openat=> do_filp_open=> do_sys_open=> sys_open ここから下はユーザ空間=> system_call_fastpathここには重要な情報が… 9 / 20
  • 犯人はmdadmのdaemon? __invalidate_deviceが網にかかった! mdadm-900 [001] .... 75491.384221: __invalidate_device <-invalidate_partition mdadm-900 [001] .... 75491.384235: <stack trace> => ftrace_call ...ユーザ空間側なのでgdbでひっかけられるsudo gdb –p <processId>でatach backtraceしてみる gdb) bt #0 0x00007f85b1ebf103 in __select_nocancel () at ../sysdeps/unix/syscall-template.S:82 #1 0x000000000040de66 in mdstat_wait (seconds=1000) at mdstat.c:317 #2 0x000000000042dea1 in Monitor (devlist=0x0, mailaddr=0x1a7b020 "root",時間の間隔も正確に1000秒なのがわかる 10 / 20
  • 位置関係md daemon monitor daemon use space kernel ? md driver disk driver invalidate_partition hard disk clear page cache 11 / 20
  • mdadmのソースをで追いかけるまずこれで1000秒を30秒に短縮できる 調査効率が大幅に改善されるしかしやや戸惑いが monitorコマンドがクリアするとも思えない ファイルキャッシュがクリアされる関数が何か確認 しながらgdbでstep実行 daemon内部で/dev/mdをopenするだけでクリ アされることが判明 fd = open("dev/md/test..", O_RDONLY); mdのdevice driverの問題? 12 / 20
  • 位置関係md daemon monitor daemon use space kernel md driver md_open ? disk driver invalidate_partition hard disk clear page cache 13 / 20
  • md_openを追いかけるcheck_disk_changeが呼ばれている これが怪しい?しかしこいつは犯人ではなかったもう一度call graphをみる __invalidate_deviceが網にかかった! mdadm-900 [001] .... 75491.384221: __invalidate_device <-invalidate_partition mdadm-900 [001] .... 75491.384235: <stack trace> => ftrace_call => invalidate_partition => rescan_partitions => __blkdev_get => blkdev_get => blkdev_openblkdev_getのあたりから分岐してそう 14 / 20
  • blk_devの中身このあたり // こいつでmd_openが呼ばれる ret = disk->fops->open(bdev, mode); .. if (bdev->bd_invalidated) { if (!ret) rescan_partitions(disk, bdev); else if (ret == -ENOMEDIUM) // この中で__invalidate_paritionが呼ばれる invalidate_partitions(disk, bdev);bd_invalidatedフラグが怪しい 15 / 20
  • 位置関係md daemon monitor daemon use space kernel blk_dev md driver bd_invalidated md_open disk driver invalidate_partition hard disk clear page cache 16 / 20
  • bd_invalidatedフラグを探すクリアしているのは初期化と二カ所rescan_partitions() { .... disk->fops->revalidate_disk(disk); check_disk_size_change(disk, bdev); bdev->bd_invalidated = 0;invalidate_partitions() { ... set_capacity(disk, 0); check_disk_size_change(disk, bdev); bdev->bd_invalidated = 0; どちらもcheck_disk_size_change()を呼んで からbd_invalidatedを0クリア 17 / 20
  • クリアし忘れ?しかし,revalidate_disk()の中では check_disk_size_change()を呼んだあとクリ アしていない revalidate_disk() { ... mutex_lock(&bdev->bd_mutex); check_disk_size_change(disk, bdev); // bdev->bd_invalidated = 0; がない mutex_unlock(&bdev->bd_mutex); このせいでopenするたびに毎回キャッシュクリア 結局LVMでもmdadmでもなくkernel/fsが原因 18 / 20
  • 動作確認クリアするようにしてkernelをビルド キャッシュクリア問題は起こらないてか,そもそもcheck_disk_size_change()の 中でクリアすればええんとちゃうか? 19 / 20
  • その後LinuxのMLに投げる 作法がいろいろある patchの作り方 scripts/checkpatch.plでパッチフォーマットの検証 patchのMLへの投げかた  git send-emailを使う 題名のつけかたと投げる場所が不適切だったかも MLに投げたが黙殺 再度別のMLに挑戦 山本さんによる英語メールの推敲(という名の書き直し)  結局パッチを手動で張り付けたものがaccept...  http://git.kernel.org/?p=linux/kernel/git/next/lin ux-next.git;a=commit;h=9b4b0d9f9f9ad2 20 / 20