法楽日記

デジタル散策記&マインド探訪記

FreeBSD 11.1R: Receive Side Scaling (RSS)

最近の NIC (Network Interface Controller) は、送信キュー、受信キューとも複数個づつ持っているそうです。そしてマルチコア CPU 環境では、キューを CPU ごとに割り当てて、送受信処理に伴う割り込みを、担当の CPU に対してのみ送るようになっているそうです。これにより CPU の負荷分散が行われているそうです。

さて、CPU の負荷分散を行う際には、同じフローに属するパケットが送受信とも同じ CPU に割り当てられた方が、パケットの reordering が発生しにくくなったり、管理構造体などの排他制御で待ち時間が発生しにくくなったり、CPU のローカルキャッシュのヒット率が高まったり、といった効果が期待できます。

その実現方法として Microsoft が提案した「Receive Side Scaling (RSS)」は、NIC が受信パケットのハッシュ値を用いて受信キューを決める方式で、様々な NIC に実装されているそうです。

下記は Microsoft による「Receive Side Scaling (RSS)」の資料です。


FreeBSD 11.1R では、mbuf 構造体の一部である pkthdr 構造体のメンバ rsstype に、RSS hash タイプを収めるようになっています。RSS hash タイプのマクロ名は M_HASHTYPE_RSS_* です。具体的な名前は sys/sys/mbuf.h をご覧ください。

また、RSS hash 計算の実装は、sys/netinet/in_rss.[ch], sys/netinet6/in6_rss.[ch], sys/net/rss_config.[ch], sys/net/toeplitz.[ch] などで定義されています。

下記は FreeBSD Wiki に掲載されている「Receive Side Scaling (RSS)」の資料です。


RSS 以外にも、「Receive Packet Steering (RPS)」と「Receive Flow Steering (RFS)」という方式が提案されているそうです。どちらも受信パケットの担当 CPU を決めるのは OS だそうです。そのため、NIC で担当 CPU を決める RSS の方が効果が大きいようです。

下記の Linux カーネルのドキュメントに、RSS, RPS, RFS などについて解説がありました。