2011-01-18 29 views
13

Actualmente estoy llegando a un límite estricto de 130688 bytes. Si intento enviar algo más grande en un mensaje, recibo un error ENOBUFS.¿Cuál es el tamaño máximo del mensaje del datagrama AF_UNIX que se puede enviar en Linux?

He comprobado las opciones de net.core.rmem_default, net.core.wmem_default, net.core.rmem_max, net.core.wmem_max y net.unix.max_dgram_qlen sysctl y las he aumentado todas pero no tienen ningún efecto porque estos se refieren al tamaño total del búfer, no al tamaño del mensaje.

también han establecido las opciones de conector SO_SNDBUF y SO_RCVBUF, pero esto tiene el mismo problema que el anterior. El tamaño predeterminado del búfer de sockets se establece en función de las opciones de socket _default de todos modos.

He mirado en la fuente del kernel, donde ENOBUFS se devuelve en la pila zócalo, pero no estaba claro para mí donde venía. Los únicos lugares que parecen devolver este error tienen que ver con la imposibilidad de asignar memoria.

es el tamaño máximo de 130688 realidad? Si no, ¿se puede cambiar esto sin volver a compilar el kernel?

Gracias!

+2

Ese es un gran datagrama. En mi opinión, para el momento en que tenga un datagrama tan grande, también podría haber usado TCP. –

+1

Sí, eso no ayuda. Como dije en la publicación, no le permitirá enviar un mensaje más de 130688 independientemente de su configuración de wmem. Los tengo más de 32MB y he probado muchas combinaciones debajo de eso. – Jaime

+1

Solo para agregar a eso. Es una idea errónea de que los buffers de envío y los búferes de recepción son solo para mensajes. El buffer es el buffer total del núcleo para todos los mensajes. Las opciones wmem y qlen sysctl realmente afectarán cómo y cuándo enviar bloques. A medida que el búfer de envío se llena (asumiendo que nadie recibe), cuando el total de bytes en el búfer va más allá del tamaño del búfer o el conteo total va más allá del qlen, el envío se bloqueará. – Jaime

Respuesta

12

datagramas AF_UNIX SOCK_DATAGRAM/SOCK_SEQPACKET necesitan memoria contigua. memoria física contigua es difícil de encontrar, y la asignación falla, registrando algo similar a esto en el registro del núcleo:

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() llamadas sock_alloc_send_skb()lxr1, lo que exige sock_alloc_send_pskb() con data_len = 0 y header_len = tamaño de datagrama lxr2. sock_alloc_send_pskb() asigna header_len de espacio de amortiguación skbuff "normal", y data_len de dispersión/agrupación páginas lxr3. Por lo tanto, parece que los sockets AF_UNIX no son compatibles con scatter/gather en Linux actual.

+2

Excelente trabajo. Esto es esencialmente lo que encontré en mis rastros, pero me has dado una razón real. Me pregunto por qué los datagramas tendrían este límite pero no las secuencias. – Jaime

+2

Los sockets SOCK_STREAM no conservan los límites del mensaje. – ninjalj

+0

Ver también amplió respuesta a http://stackoverflow.com/questions/21856517/whats-the-practical-limit-on-the-size-of-single-packet-transmitted-over-domain –

Cuestiones relacionadas