🦓

FRRouting Event & Thread (memo)

2023/10/30に公開

Routing Protocol Stack (Daemon) のデファクトである FRRouting のマルチスレッド化についてメモ。

1行でまとめると "マルチスレッド化しているけど、過去の遺産であるイベントシステム使いながらのマルチスレッド化なので、コード読む時や性能について考える時は注意しましょう" という状況。

マルチスレッド化が難しかった背景

  • Zebra -> Quagga -> FRRouting と名前を変えて進化してきた。
  • Zebra が開発された1999年頃はマルチプロセスなアーキテクチャで Routing Protocol Stack を実装する事自体が画期的であり、かつ GNU/Linux や FreeBSFD のマルチスレッドのライブラリは Routing Procotol を動かせるレベルまではまだ安定していなかった。
  • 結果、Zebra は独自のイベントシステム(Event System)を用いて動作するよう設計&実装された。

http://isp.vsi.ru/library/Other/Zebra/overview.html
Zebra was planned to use multi-threaded mechanism when it runs with a kernel that supports multi-threads. But at this moment, the thread library which comes with GNU/Linux or FreeBSD has some problems for running reliable services such as routing software, so we dont use threads at all, instead we use the select(2) system call for multiplexing the events.

マルチスレッド化のデザイン

  • マルチスレッド化する際、前述の制約により "既存のイベントシステムを pthread として動作させる" というデザインが採用された。
  • それぞれのイベントシステムには threadmaster ファシリティが存在し、スレッド内のイベント(タスク)制御や、スレッド間の連携などを実行する。
  • また、"BGP Keepalives" のように threadmaster ファシリティを利用しないスレッドも存在する。これはイベントが必要無い機能に関しては threadmasterのオーバーヘッドを減らすためである。

FRR latest documentation >> Process Architecture >> Kernel Thread Wrapper
This was done because the threadmaster facilities introduce a small but significant amount of overhead relative to the pthread’s task. In this case since the pthread does not need the event-driven model and does not need to receive tasks from other pthreads, it is simpler and more efficient to implement it outside of the provided event facilities.

マルチスレッド化により複雑化する実装

  • シングルスレッドで動作する事を前提として設計実装されたプログラムをマルチスレッド化する事は、切り分け難いバグ等を発生させるリスクが高まるため、既存のコードベースに十分配慮して開発を行う必要がある。
  • また、機能追加や変更を実施した場合には、キチンとドキュメントに記載する事が重要である。

FRR latest documentation >> Process Architecture >> Notes on Design and Documentation
However, designs in this direction must be very careful to take into account the existing codebase. Introducing kernel threads into programs that have been written under the assumption of a single thread of execution must be done very carefully to avoid insidious errors and to ensure the program remains understandable and maintainable.

Discussion