2011-01-18 22 views
13

現在、私は130688バイトのハード限界に達しています。 1つのメッセージで大きなものを送信しようとすると、ENOBUFSエラーが発生します。linuxで送信できるAF_UNIXデータグラムメッセージの最大サイズは?

私はnet.core.rmem_default、net.core.wmem_default、net.core.rmem_max、net.core.wmem_max、net.unix.max_dgram_qlen sysctlオプションをチェックしてそれらをすべて増やしましたが、効果がありません。これらはメッセージサイズではなく合計バッファサイズを処理します。

SO_SNDBUFとSO_RCVBUFソケットオプションも設定しましたが、上記と同じ問題があります。デフォルトのソケットバッファサイズは、_defaultソケットオプションに基づいて設定されます。

ソケットスタックでENOBUFSが返されるカーネルソースを調べましたが、どこから来たのかはわかりませんでした。このエラーを返すように見える唯一の場所は、メモリを割り当てることができないことです。

実際には最大サイズは130688ですか?そうでない場合は、カーネルを再コンパイルせずに変更できますか?

ありがとうございます!

+2

これは巨大なデータグラムです。私の意見では、データグラムのサイズが大きくなる頃には、TCPを使用している可能性もあります。 –

+1

そうです、それは助けになりません。私がこの記事で述べたように、あなたのwmemの設定に関係なく130688以上のメッセージを送ることはできません。私はそれらを32MB以上持っていて、その下の多くの組み合わせを試しました。 – Jaime

+1

これを追加するだけです。送信バッファと受信バッファが単一のメッセージ用であるという誤解です。バッファは、すべてのメッセージの合計カーネルバッファです。 wmemとqlen sysctlオプションは実際にブロックを送信する方法とタイミングに実際に影響します。送信バッファがいっぱいになると(誰も受信しないと仮定して)、バッファ内の合計バイトがバッファサイズを超えたり、合計カウントがqlenを超えたりすると、sendはブロックされます。 – Jaime

答えて

12

AF_UNIX SOCK_DATAGRAM/SOCK_SEQPACKETデータグラムには連続したメモリが必要です。連続した物理メモリが見つけるのは難しいですし、割り当てがカーネルログに次のような何かをログに記録する、失敗:データグラムlxr2data_len = 0とheader_len =サイズでsock_alloc_send_pskb()呼び出す

udgc: page allocation failure. order:7, mode:0x44d0 
[...snip...] 
DMA: 185*4kB 69*8kB 34*16kB 27*32kB 11*64kB 1*128kB 1*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 3788kB 
Normal: 13*4kB 6*8kB 100*16kB 62*32kB 24*64kB 10*128kB 0*256kB 1*512kB 0*1024kB 0*2048kB 0*4096kB = 7012kB 
[...snip...] 

unix_dgram_sendmsg()通話sock_alloc_send_skb()lxr1、。 sock_alloc_send_pskb()は、通常のskbuffバッファ領域からheader_lenを割り当て、スキャッタ/ギャザーページlxr3からdata_lenを割り当てます。だから、AF_UNIXソケットは現在のLinuxでスキャッター/ギャザーをサポートしていないようです。

+2

優れた作業。これは本質的に私の痕跡で見つかったものですが、あなたは実際の理由を提供しました。私はなぜデータグラムがストリームではなく、この制限を持つのだろうか? – Jaime

+2

SOCK_STREAMソケットはメッセージ境界を保持しません。 – ninjalj

+0

拡張応答も参照してください。http://stackoverflow.com/questions/21856517/whats-the-practical-limit-on-the-size-of-single-packet-transmitted-over-domain –

関連する問題