Linuxにおけるpfifo_fastのTOSによる挙動

Linuxのqdisc(Queueing DISCipline:キューイング規則)でデフォルトで使用されるpfifi_fastを調べていたら、IPv4ヘッダのTOSフィールドに設定されている値によって挙動が変わるという仕様でした。そこでTOSの値を変えながら、色々と測定してみました。

pfifo_fast

pfifo_fastは、以下のリンク先にもある通り、FIFOで3つのバンドを持ちます(バンド0、バンド1、バンド2)。各バンドにはFIFOが適用されますが、バンド0に待ちパケットがあるとバンド1は処理されず、バンド1に待ちパケットがあるとバンド2は処理されないという仕様のようです。

シンプルな、クラスレスのキューイング規則

カーネルは各パケットのIPv4ヘッダのTOSフィールドを参照し、「最小遅延」パケットをバンド0に入れるみたいです。
他のフィールドの意味は、以下のリンク先の内容が参考になります。

レイヤ3スイッチのさまざまな機能

他にも、「最大スループット」はバンド2へ、「最大信頼性」はバンド1へ、何もなければバンド1へといった規則があります。

では、実際のパケットのTOSの値を変えた場合、Linuxではどのような挙動を示すのでしょうか。それを確認するため、いくつかの条件で測定して結果を見てみようというのが今回の目的です。

iperf3

iperf3はネットワークにTCPやUDPのトラフィックを流し、パフォーマンスを測定できるアプリケーションです。また、素晴らしいことに、”-S n”というオプションを使用すると、nとしてTOSの値が設定できます。よって今回は、iperf3を使いました。

https://iperf.fr/iperf-download.php

測定環境

1GbEで接続されたクライアントとサーバ上で、iperf3をポートを変えつつ2プロセス起動させ、それぞれ1GbpsのUDPトラフィックをサーバに投げさせました。片方のプロセスはTOSの値は変えずにデフォルトのまま。もう片方のプロセスのTOSの値を、変更なし、最小遅延、最大スループット、最大信頼性に変えてみました。

2プロセスの実行開始はできる限り同じにしたかったのですが、測定の主目的ではないため、多少の誤差(<1sec)は大目にみてください。実行開始は、TOSを変えないプロセスを実行した後、TOSを変えるプロセスを実行しました。

結果

変更なし

変えない側のプロセス

$ sudo iperf3 -c 192.168.1.173 -u -b 1G -p 5201
Connecting to host 192.168.1.173, port 5201
[  4] local 192.168.1.120 port 45708 connected to 192.168.1.173 port 5201
[ ID] Interval           Transfer     Bandwidth       Total Datagrams
[  4]   0.00-1.00   sec  99.3 MBytes   833 Mbits/sec  12715
[  4]   1.00-2.00   sec  56.7 MBytes   476 Mbits/sec  7257
[  4]   2.00-3.00   sec  56.6 MBytes   475 Mbits/sec  7251
[  4]   3.00-4.00   sec  56.6 MBytes   475 Mbits/sec  7251
[  4]   4.00-5.00   sec  56.7 MBytes   475 Mbits/sec  7253
[  4]   5.00-6.00   sec  56.6 MBytes   475 Mbits/sec  7250
[  4]   6.00-7.00   sec  56.7 MBytes   475 Mbits/sec  7254
[  4]   7.00-8.00   sec  56.6 MBytes   475 Mbits/sec  7251
[  4]   8.00-9.00   sec  56.6 MBytes   475 Mbits/sec  7249
[  4]   9.00-10.00  sec  56.6 MBytes   475 Mbits/sec  7249
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Jitter    Lost/Total Datagrams
[  4]   0.00-10.00  sec   609 MBytes   511 Mbits/sec  0.018 ms  1226/77977 (1.6%)
[  4] Sent 77977 datagrams

変える側のプロセス(変更なし条件なので変えない)

$ sudo iperf3 -c 192.168.1.173 -u -b 1G -p 5202
Connecting to host 192.168.1.173, port 5202
[  4] local 192.168.1.120 port 59428 connected to 192.168.1.173 port 5202
[ ID] Interval           Transfer     Bandwidth       Total Datagrams
[  4]   0.00-1.00   sec  51.0 MBytes   428 Mbits/sec  6533
[  4]   1.00-2.00   sec  56.7 MBytes   476 Mbits/sec  7257
[  4]   2.00-3.00   sec  56.7 MBytes   476 Mbits/sec  7256
[  4]   3.00-4.00   sec  56.7 MBytes   475 Mbits/sec  7253
[  4]   4.00-5.00   sec  56.7 MBytes   476 Mbits/sec  7258
[  4]   5.00-6.00   sec  56.7 MBytes   475 Mbits/sec  7255
[  4]   6.00-7.00   sec  56.7 MBytes   476 Mbits/sec  7256
[  4]   7.00-8.00   sec  56.7 MBytes   476 Mbits/sec  7259
[  4]   8.00-9.00   sec  56.7 MBytes   476 Mbits/sec  7261
[  4]   9.00-10.00  sec   105 MBytes   880 Mbits/sec  13429
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Jitter    Lost/Total Datagrams
[  4]   0.00-10.00  sec   610 MBytes   511 Mbits/sec  0.125 ms  806/78016 (1%)
[  4] Sent 78016 datagrams

競合状態になった場合、同じくらいの送信量になりました。

最小遅延

変えない側のプロセス

$ sudo iperf3 -c 192.168.1.173 -u -b 1G -p 5201
Connecting to host 192.168.1.173, port 5201
[  4] local 192.168.1.120 port 59717 connected to 192.168.1.173 port 5201
[ ID] Interval           Transfer     Bandwidth       Total Datagrams
[  4]   0.00-1.00   sec  79.5 MBytes   667 Mbits/sec  10176
[  4]   1.00-2.00   sec  30.2 MBytes   253 Mbits/sec  3860
[  4]   2.00-3.00   sec  30.2 MBytes   253 Mbits/sec  3863
[  4]   3.00-4.00   sec  30.2 MBytes   253 Mbits/sec  3864
[  4]   4.00-5.00   sec  33.6 MBytes   282 Mbits/sec  4307
[  4]   5.00-6.00   sec  34.5 MBytes   289 Mbits/sec  4415
[  4]   6.00-7.00   sec  34.0 MBytes   285 Mbits/sec  4352
[  4]   7.00-8.00   sec  32.6 MBytes   273 Mbits/sec  4172
[  4]   8.00-9.00   sec  31.7 MBytes   266 Mbits/sec  4061
[  4]   9.00-10.00  sec  31.4 MBytes   263 Mbits/sec  4017
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Jitter    Lost/Total Datagrams
[  4]   0.00-10.00  sec   368 MBytes   309 Mbits/sec  0.101 ms  1229/47087 (2.6%)
[  4] Sent 47087 datagrams

変える側のプロセス

$ sudo iperf3 -c 192.168.1.173 -u -b 1G -p 5202 -S 16
Connecting to host 192.168.1.173, port 5202
[  4] local 192.168.1.120 port 53699 connected to 192.168.1.173 port 5202
[ ID] Interval           Transfer     Bandwidth       Total Datagrams
[  4]   0.00-1.00   sec  74.9 MBytes   628 Mbits/sec  9586
[  4]   1.00-2.00   sec  83.2 MBytes   698 Mbits/sec  10646
[  4]   2.00-3.00   sec  83.2 MBytes   698 Mbits/sec  10645
[  4]   3.00-4.00   sec  81.6 MBytes   685 Mbits/sec  10448
[  4]   4.00-5.00   sec  78.3 MBytes   657 Mbits/sec  10027
[  4]   5.00-6.00   sec  79.3 MBytes   665 Mbits/sec  10151
[  4]   6.00-7.00   sec  80.0 MBytes   671 Mbits/sec  10243
[  4]   7.00-8.00   sec  81.4 MBytes   683 Mbits/sec  10420
[  4]   8.00-9.00   sec  81.9 MBytes   687 Mbits/sec  10482
[  4]   9.00-10.00  sec   102 MBytes   853 Mbits/sec  13013
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Jitter    Lost/Total Datagrams
[  4]   0.00-10.00  sec   825 MBytes   692 Mbits/sec  0.127 ms  0/105658 (0%)
[  4] Sent 105658 datagrams

最小遅延を設定したプロセスの方で、多くのデータが送信されるという結果になりました。
もっと偏るのではないかと予想していたのですが、変えない側のプロセスでもある程度のデータが送信されました。

最大スループット

変えない側のプロセス

$ sudo iperf3 -c 192.168.1.173 -u -b 1G -p 5201
Connecting to host 192.168.1.173, port 5201
[  4] local 192.168.1.120 port 38351 connected to 192.168.1.173 port 5201
[ ID] Interval           Transfer     Bandwidth       Total Datagrams
[  4]   0.00-1.00   sec  90.6 MBytes   760 Mbits/sec  11596
[  4]   1.00-2.00   sec  83.2 MBytes   698 Mbits/sec  10648
[  4]   2.00-3.00   sec  80.6 MBytes   676 Mbits/sec  10314
[  4]   3.00-4.00   sec  79.6 MBytes   668 Mbits/sec  10189
[  4]   4.00-5.00   sec  81.4 MBytes   682 Mbits/sec  10413
[  4]   5.00-6.00   sec  82.2 MBytes   690 Mbits/sec  10528
[  4]   6.00-7.00   sec  83.2 MBytes   698 Mbits/sec  10648
[  4]   7.00-8.00   sec  83.2 MBytes   698 Mbits/sec  10648
[  4]   8.00-9.00   sec  83.2 MBytes   698 Mbits/sec  10649
[  4]   9.00-10.00  sec  83.2 MBytes   698 Mbits/sec  10648
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Jitter    Lost/Total Datagrams
[  4]   0.00-10.00  sec   830 MBytes   697 Mbits/sec  0.003 ms  1233/106279 (1.2%)
[  4] Sent 106279 datagrams

変える側のプロセス

$ sudo iperf3 -c 192.168.1.173 -u -b 1G -p 5202 -S 8
Connecting to host 192.168.1.173, port 5202
[  4] local 192.168.1.120 port 48346 connected to 192.168.1.173 port 5202
[ ID] Interval           Transfer     Bandwidth       Total Datagrams
[  4]   0.00-1.00   sec  27.2 MBytes   228 Mbits/sec  3483
[  4]   1.00-2.00   sec  30.3 MBytes   254 Mbits/sec  3874
[  4]   2.00-3.00   sec  35.3 MBytes   296 Mbits/sec  4523
[  4]   3.00-4.00   sec  32.0 MBytes   268 Mbits/sec  4095
[  4]   4.00-5.00   sec  32.0 MBytes   268 Mbits/sec  4094
[  4]   5.00-6.00   sec  30.2 MBytes   253 Mbits/sec  3860
[  4]   6.00-7.00   sec  30.2 MBytes   253 Mbits/sec  3860
[  4]   7.00-8.00   sec  30.1 MBytes   253 Mbits/sec  3859
[  4]   8.00-9.00   sec  30.1 MBytes   253 Mbits/sec  3859
[  4]   9.00-10.00  sec  73.4 MBytes   616 Mbits/sec  9396
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Jitter    Lost/Total Datagrams
[  4]   0.00-10.00  sec   351 MBytes   294 Mbits/sec  0.132 ms  811/44900 (1.8%)
[  4] Sent 44900 datagrams

最大スループットのパケットは、バンド2に入れられるため、先程と逆の結果になりました。

最大信頼性

変えない側のプロセス

$ sudo iperf3 -c 192.168.1.173 -u -b 1G -p 5201
Connecting to host 192.168.1.173, port 5201
[  4] local 192.168.1.120 port 48531 connected to 192.168.1.173 port 5201
[ ID] Interval           Transfer     Bandwidth       Total Datagrams
[  4]   0.00-1.00   sec  92.6 MBytes   776 Mbits/sec  11849
[  4]   1.00-2.00   sec  56.7 MBytes   476 Mbits/sec  7263
[  4]   2.00-3.00   sec  56.7 MBytes   476 Mbits/sec  7263
[  4]   3.00-4.00   sec  56.7 MBytes   476 Mbits/sec  7256
[  4]   4.00-5.00   sec  56.7 MBytes   476 Mbits/sec  7260
[  4]   5.00-6.00   sec  56.8 MBytes   476 Mbits/sec  7265
[  4]   6.00-7.00   sec  56.7 MBytes   476 Mbits/sec  7260
[  4]   7.00-8.00   sec  56.7 MBytes   476 Mbits/sec  7258
[  4]   8.00-9.00   sec  56.8 MBytes   476 Mbits/sec  7268
[  4]   9.00-10.00  sec  56.7 MBytes   476 Mbits/sec  7257
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Jitter    Lost/Total Datagrams
[  4]   0.00-10.00  sec   603 MBytes   506 Mbits/sec  0.073 ms  1231/77198 (1.6%)
[  4] Sent 77198 datagrams

変える側のプロセス

$ sudo iperf3 -c 192.168.1.173 -u -b 1G -p 5202 -S 4
Connecting to host 192.168.1.173, port 5202
[  4] local 192.168.1.120 port 53602 connected to 192.168.1.173 port 5202
[ ID] Interval           Transfer     Bandwidth       Total Datagrams
[  4]   0.00-1.00   sec  51.0 MBytes   428 Mbits/sec  6529
[  4]   1.00-2.00   sec  56.6 MBytes   475 Mbits/sec  7243
[  4]   2.00-3.00   sec  56.6 MBytes   475 Mbits/sec  7250
[  4]   3.00-4.00   sec  56.6 MBytes   475 Mbits/sec  7247
[  4]   4.00-5.00   sec  56.6 MBytes   475 Mbits/sec  7246
[  4]   5.00-6.00   sec  56.6 MBytes   475 Mbits/sec  7247
[  4]   6.00-7.00   sec  56.6 MBytes   475 Mbits/sec  7250
[  4]   7.00-8.00   sec  56.6 MBytes   475 Mbits/sec  7241
[  4]   8.00-9.00   sec  56.6 MBytes   475 Mbits/sec  7246
[  4]   9.00-10.00  sec  98.1 MBytes   823 Mbits/sec  12562
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Jitter    Lost/Total Datagrams
[  4]   0.00-10.00  sec   602 MBytes   505 Mbits/sec  0.121 ms  0/77060 (0%)
[  4] Sent 77060 datagrams

変更なしの条件と同様、どちらのプロセスでも同じくらいの送信量になりました。

まとめ

Linuxのpfifo_fastを使用している場合、パケットのTOSの値を変えることで、パケットのキューイング先のバンドが変わり、バンドが小さい程、優先して送信されることが確認できました。

裏で大量のデータが送信されている環境で、システムの重要なデータを送る際などに最小遅延を設定しておくと、届きやすくなる可能性があります。

以上。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*