問題タブ [xdp-bpf]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - AF_XDP-Socket と Linux ソケットの比較: AF-XDP ソケットではパケットが失われるのに、一般的な Linux ソケットでは失われないのはなぜですか?
AF-XDP ソケットと Linux ソケットを、パケット損失なしで処理できるパケット数に関して比較しています (パケット損失は、現在のパケットの RTP シーケンス番号が、前のパケット+ 1
)。
AF-XDP ソケット プログラム (この問題がカーネル プログラムに関連しているのか、ユーザー空間プログラムに関連しているのかは判断できません) は、一般的な Linux ソケットを使用した同等のプログラムが約 1 秒あたりのパケット数~25
で約 1 秒あたりのパケット数を失っていることに気付きました。390.000
パケットを失いません。
distributor
XDPカーネルプログラムを1回ロードし、汎用Linuxソケットをセットアップし、setsockopt(IP_ADD_MEMBERSHIP)
コマンドライン経由でプログラムに渡すすべてのマルチキャストアドレスに対してこの汎用ソケットに追加する、いわゆるプログラムを実装しました。この後、XDP カーネル プログラムに配置されdistributor
たファイル記述子をロードしBPF_MAP_TYPE_HASH
、単一の AF-XDP ソケットが後でその umem を共有する必要がある場合に備えて、トラフィックのルートを挿入します。
次に、XDP カーネル プログラムは、そのハッシュ マップにエントリがあるかどうか、各 IPv4/UDP パケットをチェックします。これは基本的に次のようになります。
存在する場合idx
、これは のそのインデックスの後ろにソケットがあることを意味しますBPF_MAP_TYPE_XSKMAP
。
すべての処理を行った後、そのプロセスによって処理されるすべてのマルチキャスト アドレス (宛先ポートを含む)distributor
を渡すことによって、新しいプロセスfork()
が生成されます (1 つのプロセスが 1 つの RX キューを処理します)。十分な RX キューがない場合、一部のプロセスが複数のマルチキャスト アドレスを受信することがあります。これは、 を使用することを意味しますSHARED UMEM
。
私は基本的に、このサンプル コードで AF-XDP ユーザー空間プログラムを方向付けました: https://github.com/torvalds/linux/blob/master/samples/bpf/xdpsock_user.c
私は同じxsk_configure_umem
, xsk_populate_fill_ring
andxsk_configure_socket
関数を使用しています。
このアプリケーションには最大レイテンシーは必要ないと判断したため、プロセスを特定の時間 (約1 - 2ms
) スリープ状態に送り、その後、すべての AF-XDP ソケット (ほとんどの場合、ソケットは 1 つだけ) をループしてプロセスを処理します。そのソケットの受信パケットごとに、パケットが失われていないことを確認します。
私の意見では、これについてはそれほど派手なことは何もありませんが、UMEM が 1GB の RAM に近いにもかかわらず、どういうわけか約~25
パケットでパケットを失います。390.000
比較すると、私の一般的な Linux ソケット プログラムは (要するに) 次のようになります。
distributor
プログラムは、一般的な Linux ソケットが使用されている場合に、特定のマルチキャスト IP ごとに新しいプロセスを作成します (一般的なソケットには SHARED-UMEM などの洗練された方法がないため、プロセスごとに複数のマルチキャスト ストリームを使用する必要はありません) 。後でもちろん、マルチキャスト メンバーシップに参加します。
パケットの処理を開始します (スリープ状態ではなく、busy-loop
同様の方法で):
それだけです。
使用していないパケットを失い始める、説明した使用例ではSHARED UMEM
、マルチキャスト ストリームを受信する単一の RX-Queue にすぎないことに注意してください。小規模なマルチキャスト ストリームを処理する場合150.000 pps
、AF-XDP ソリューションはパケットを失いません。しかし、それは逆でもあります -520.000 pps
同じ RX-Queue で ( を使用してSHARED UMEM
) の損失が発生し12.000 pps
ます。
私が見逃しているアイデアはありますか?
c - BPF/XDP: `bpf_ntohs` が検証エラーを生成するのはなぜですか?
BPF/XDP ベリファイアに問題があります。UDP パケットをフィルタリングし、パケットの最後にタイムスタンプを書き込もうとしています ( を使用udh->len
)。はネットワーク バイト オーダーであるためudh->len
、最初に「ホスト」バイト オーダーに変換する必要があります。だから私はこのようにそれを試しました:
しかし、私は得るmath between pkt pointer and register with unbounded min value is not allowed
。
これが失敗する方法が思いつかなかったのでbpf_ntohs
、テスト目的のためだけに削除しようとしました (そのようには機能しないことはわかっています)。
しかし、私は実際にこの方法でプログラムを実行できます-bpf_ntohs
検証エラーが発生する理由はありますか?