カーネル/VM Advent Calendar 2013 23日目: Linuxのseqlockに新しいreader typeが追加された話

カーネル/VM Advent Calendar 2013

こんにちは、hiraku_wfsです。
今年はちょっと大きなネタを構想していたのですが、ここ最近体調が芳しくなかったので小ネタになります。

seqlockとは

シーケンスロック(seqlock)というのは、読み書きロック(rwlock: reader同士はブロックせずに並列実行可能、writer実行中はそれ以外はブロックされる)に似ているのですが、読み書きロックと異なる点として、reader側ではロックを取らないためwriterをブロックしないという利点があります。
当然reader実行中にwriterが走ったらロック対象の値が変化するわけですが、これに対してはreader側の処理開始〜終了の区間にwriterが走ったかどうか確認し、走っていた場合はreader側でretryをかけます。

使い方としては下のような感じ。

writer側。

write_seqlock(&slock)
/* ここでロック対象の値を更新する */
write_sequnlock(&slock)

reader側。

do {
        seq = read_seqbegin(&slock);
        /* ここでロック対象の値を読み込む */
} while (read_seqretry(&slock, seq)); /* writerが走ってたらretry */

新しいreader type

Linux 3.12で次のパッチがmergeされました。

seqlock: Add a new locking reader type (by Waiman Long)

趣旨としては、データの更新を行わなくても他のwriterからの変更が許容できないような区間ではread_seqbegin()ではなくwrite_seqlock()を使わなければいけなかったけれど、それは非効率なので既存のreaderはブロックせず(retryさせず)writerのみをブロックするread_seqlock_excl()を追加したよ、という話です。

それぞれが同時に動作した場合に何が起こるかを表にしてみました。

read_seqbegin read_seqlock_excl write_seqlock
read_seqbegin 並行動作可能 並行動作可能 順番に関わらずreaderがretry
read_seqlock_excl - 後に入ってきた方がブロック 後に入ってきた方がブロック
write_seqlock - - 後に入ってきた方がブロック

今のところ、VFSのパス名探索まわりで使われてるみたいです。
(余談ですが、ちらっと見た感じVFSのコードも2.6の頃と結構変わってますねー。スケーラビリティ向上のためか、複雑になっているみたい。)

おわりに

かなりてきとーな説明になってしまったので辻斬りに遭いそうですが、来年もよろしくお願いいたします。
それでは、良いお年を。