0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

msyncの闇に足を踏み込もう

Posted at

今回のまとめ

  • msync(MS_ASYNC)は、何もしないを実行する(意味不明)

msyncの闇に足を踏み込もう

この場合、メモリ領域がディスクへ書き戻す必要があることを通知するのはmsync(2)です。MS_ASYNCを指定すると、通知するだけでシステムコールは終了します。MS_SYNCを指定すると、通知に加え、内部でfsync(2)相当の処理も行われ、ディスクにまで書き戻します。

このあたりのソースコードを読んでいく。

Linux Kernelのコメント

/*

  • MS_SYNC syncs the entire file - including mappings.
  • MS_ASYNC does not start I/O (it used to, up to 2.5.67).
  • Nor does it marks the relevant pages dirty (it used to up to 2.6.17).
  • Now it doesn't do anything, since dirty pages are properly tracked.
  • The application may now run fsync() to
  • write out the dirty pages and wait on the writeout and check the result.
  • Or the application may run fadvise(FADV_DONTNEED) against the fd to start
  • async writeout immediately.
  • So by not starting I/O in MS_ASYNC we provide complete flexibility to
  • applications.
    */

MS_SYNC は、mappingを含むすべてのファイルを同期を取る。
MS_ASYNCは、I/Oを開始しません(2.5.67以前までは利用していました)。
更に、dirty pagesと関連付けてマークすることもしません(2.6.17以前まではマークしていました)。
現時点では、ダーティページは適切に追跡されるので、今は何もしていません。

アプリケーションは、dirty pagesを書きだすため、書き込みが終わるあるいは結果をチェックするためにfsync()を実行できる。
あるいは、アプリケーションは即座に非同期に書き出すために、fadvise(FADV_DONTNEED)を実行できる。
したがって、MS_ASYNCにおいて、I/Oを開始しないことによって、アプリケーションに対して完全な柔軟性を提供できる。

実際のソースコードを見てみる

重要な部分だけを抜き出すと、

	/*
	 * If the interval [start,end) covers some unmapped address ranges,
	 * just ignore them, but return -ENOMEM at the end.
	 */
	down_read(&mm->mmap_sem);
	vma = find_vma(mm, start);
	for (;;) {

<略>

		start = vma->vm_end;
		if ((flags & MS_SYNC) && file &&
				(vma->vm_flags & VM_SHARED)) {
			get_file(file);
			up_read(&mm->mmap_sem);
			error = vfs_fsync_range(file, fstart, fend, 1);
			fput(file);
			if (error || start >= end)
				goto out;
			down_read(&mm->mmap_sem);
			vma = find_vma(mm, start);
		} else {
			if (start >= end) {
				error = 0;
				goto out_unlock;
			}
			vma = vma->vm_next;
		}
	}

ということで、MS_SYNCが指定されていてマッピングできていれば、vfs_fsync_range()とfput(file)によって反映させる。
そうでない場合には、本当に何もしません、と。

そうしたら、MS_ASYNC指定したら、いつ反映されるのか?は、dirty pageの扱いで、pdflush()によるデフォルト5秒ごとの更新、と。

きれいにしたのはこちらのパッチ

どうやら、dirty statusのハンドリングが自動化できるようになったので、わざわざフラグ設定するのはムダになった、を含めてリファクタリングしたようでございますね。なるほどなるほど。

[PATCH] mm: msync() cleanup
With the tracking of dirty pages properly done now, msync doesn't need to scan the PTEs anymore to determine the dirty status.

From: Hugh Dickins

In looking to do that, I made some other tidyups: can remove several #includes, and sys_msync loop termination not quite right.

Most of those points are criticisms of the existing sys_msync, not of your patch.
In particular, the loop termination errors were introduced in 2.6.17: I did notice this shortly before it came out, but decided I was more likely to get it wrong myself, and make matters worse if I tried to rush a last-minute fix in. And it's not terribly likely to go wrong, nor disastrous if it does go wrong (may miss reporting an unmapped area; may also fsync file of a following vma).

ダーティページの追跡が適切に行うようになったため、msyncではdirty statusを判別するために、PTEをスキャンする必要がなくなりました。

From: Hugh Dickins

これを実行するためには、私は不要なinludeを削除するなどいくつかの整理を行いました。そして、sys_nsyncのループ終了条件が正しくありませんでした。

これらの点のほとんどは、あなたのパッチではなく、既存のsys_msyncへの問題指摘です。特に、ループ終了エラーについては2.6.17で導入されていました。この問題が起きる少し前に気が付きましたが、自分で間違える可能性が高く、土壇場で修正をすると自体がさらに悪化する事になりました。それはうまくいきませんでした(マップされていない領域の報告を見逃す可能性があります、また次のvmaのfsyncファイルもある可能性があります)。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?