Linux는 tcp에 대한 기본 버퍼 크기를 문서화하지만 AF_UNIX("네이티브") 소켓에 대해서는 문서화하지 않습니다. 이 값은 런타임에 읽거나 쓸 수 있습니다.
cat /proc/sys/net/core/[rw]mem_default
이 값은 항상 다른 Linux 커널에서 동일하게 설정됩니까, 아니면 가능한 값의 범위가 있습니까?
답변1
기본값은 구성할 수 없지만 32비트와 64비트 Linux 간에 다릅니다. 이 값을 쓰면 패킷당 서로 다른 오버헤드(32비트 대 64비트 포인터 또는 정수 구조)를 고려하여 각각 256바이트의 256개 패킷을 허용하는 것으로 보입니다.
64비트 Linux 4.14.18: 212992바이트
32비트 Linux 4.4.92: 163840바이트
읽기 버퍼와 쓰기 버퍼의 기본 버퍼 크기는 동일합니다. 패킷당 오버헤드는 struct sk_buff
과 의 조합 struct skb_shared_info
이므로 이러한 구조의 정확한 크기에 따라 달라집니다(정렬을 위해 약간 반올림됨). 예를 들어 위의 64비트 커널에서 패킷당 오버헤드는 576바이트입니다.
http://elixir.free-electrons.com/linux/v4.5/source/net/core/sock.c#L265
/* Take into consideration the size of the struct sk_buff overhead in the
* determination of these values, since that is non-constant across
* platforms. This makes socket queueing behavior and performance
* not depend upon such differences.
*/
#define _SK_MEM_PACKETS 256
#define _SK_MEM_OVERHEAD SKB_TRUESIZE(256)
#define SK_WMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS)
#define SK_RMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS)
/* Run time adjustable parameters. */
__u32 sysctl_wmem_max __read_mostly = SK_WMEM_MAX;
EXPORT_SYMBOL(sysctl_wmem_max);
__u32 sysctl_rmem_max __read_mostly = SK_RMEM_MAX;
EXPORT_SYMBOL(sysctl_rmem_max);
__u32 sysctl_wmem_default __read_mostly = SK_WMEM_MAX;
__u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX;
흥미롭게도 기본값이 아닌 소켓 버퍼 크기를 설정하면 Linux는 오버헤드를 제공하기 위해 이를 두 배로 늘립니다. 즉, 더 작은 패킷(예: 위의 576바이트보다 작은 패킷)을 보내는 경우 지정한 버퍼에 사용자 데이터의 바이트 수를 맞출 수 없다는 의미입니다.