2011-01-18 16 views
13

Şu anda 130688 baytlık bir katı sınırı aşıyorum. Bir iletide daha büyük bir şey göndermeye çalışırsam, bir ENOBUFS hatası alıyorum.Linux'ta gönderilebilecek maksimum AF_UNIX datagram mesajı boyutu nedir?

Ben net.core.rmem_default, net.core.wmem_default, net.core.rmem_max, net.core.wmem_max ve net.unix.max_dgram_qlen sysctl seçenekleri kontrol ve hepsini artmış ancak hiçbir etkisi nedeniyle var olan bunlar, toplam arabellek boyutuyla değil, ileti boyutuyla ilgilidir.

Ayrıca, SO_SNDBUF ve SO_RCVBUF yuva seçeneklerini de ayarladım, ancak bu yukarıdakiyle aynı sorunu yaşıyor. Varsayılan soket arabellek boyutu, zaten _default soket seçeneklerine göre ayarlanır.

Soket yığında ENOBUFS'nin döndüğü çekirdek kaynağına baktım, ancak nereden geldiğini açık değildi. Bu hatayı geri döndürecek gibi görünen tek yer, belleği ayırmama ile ilgilidir.

Maksimum boyut aslında 130688 mi? Eğer değilse, bu çekirdeği yeniden derlemeden değiştirilebilir mi?

Teşekkürler! AF_UNIX SOCK_DATAGRAM/SOCK_SEQPACKET datagramları, bitişik belleğe gereksinim duyar.

+2

Bu büyük bir datagramdır. Benim düşünceme göre, büyük bir datagramınız olduğu zaman, TCP'yi de kullanmış olabilirsiniz. –

+1

Evet, bu yardımcı olmuyor. Gönderide belirttiğim gibi, 60688'in üzerinde şahane ayarlarınıza bakılmaksızın bir mesaj göndermenize izin vermez. Onları 32MB üzerinde var ve bunun altında birçok kombinasyonları denedim. – Jaime

+1

Sadece buna eklemek için. Gönderme arabellekleri ve alma arabellekleri tek iletiler için olduğu yanılsaması. Tampon, tüm mesajlar için toplam çekirdek tamponu. Wmem ve qlen sysctl seçenekleri aslında blokları nasıl ve ne zaman göndereceğini etkiler. Gönderme arabelleği dolduğunda (kimsenin almadığı varsayılarak), arabelleğin toplam baytları arabellek boyutunun ötesine geçtiğinde veya toplam sayım qlen'in ötesine geçerse, gönderme engellenir. – Jaime

cevap

12

Bitişik fiziksel bellek bulmak zor, ve tahsis çekirdek günlüğüne üzerinde buna benzer bir şey günlüğü, başarısız: datagram`ının lxr2 ait data_len = 0 ve header_len = boyutuyla sock_alloc_send_pskb() çağırır

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() aramalar sock_alloc_send_skb()lxr1. sock_alloc_send_pskb(), header_len "normal" skbuff arabellek boşluğundan ve data_len, dağılımdan/toplama sayfalarından lxr3. Yani, AF_UNIX soketleri mevcut Linux üzerinde dağılımı/toplamayı desteklemiyor gibi görünüyor.

+2

Mükemmel çalışma. Bu aslında izlerimde bulduğum şey, ama asıl sebebi verdin. Datagramların neden bu limite sahip olacağına merak ediyorum ama akarsu değil? – Jaime

+2

SOCK_STREAM yuvaları mesaj sınırlarını korumaz. – ninjalj

+0

Ayrıca bkz. Http://stackoverflow.com/questions/21856517/whats-the-practical-limit-on-the-size-of-single-packet-transmitted-over-domain –

İlgili konular