Linux에서 기본 Unix 소켓 버퍼 크기로 사용할 수 있는 값은 무엇입니까?

Linux에서 기본 Unix 소켓 버퍼 크기로 사용할 수 있는 값은 무엇입니까?

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바이트보다 작은 패킷)을 보내는 경우 지정한 버퍼에 사용자 데이터의 바이트 수를 맞출 수 없다는 의미입니다.

관련 정보