Каков максимальный размер сообщения дейтаграммы AF_UNIX, которое может быть отправлено в Linux?
В настоящее время я нажимаю жесткий лимит в 130688 байт. Если я попытаюсь отправить что-то большее в одном сообщении, я получаю ошибку ENOBUFS.
Я проверил параметры 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? Если это не может быть изменено без перекомпиляции ядра?
Спасибо!
Ответы
Ответ 1
AF_UNIX SOCK_DATAGRAM/SOCK_SEQPACKET датаграммы нуждаются в непрерывной памяти. Непрерывная физическая память трудно найти, а выделение не удастся, записав что-то похожее на это в журнале ядра:
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()
с data_len
= 0 и header_len
= размер дейтаграммы lxr2. sock_alloc_send_pskb()
выделяет header_len
из "нормального" буферного пространства skbuff, а data_len
- сбрасывает/собирает страницы lxr3. Таким образом, похоже, что сокеты AF_UNIX не поддерживают разброс/сборку в текущем Linux.