TCP的发送系列 — 发送缓存的管理(一)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

TCP的发送系列—发送缓存的管理(一)

数据结构

TCP对发送缓存的管理是在两个层面上进行的,一个层面是单个socket的发送缓存管理,

另一个层面是整个TCP层的内存管理。

单个socket的发送缓存所涉及的变量。

[java]

struct sock {

...

/* 预分配缓存大小,是已经分配但尚未使用的部分 */

int sk_forward_alloc;

...

/* 提交给IP层的发送数据大小(累加skb->truesize) */

atomic_t sk_wmem_alloc;

...

int sk_sndbuf; /* 发送缓冲区大小的上限 */

struct sk_buff_head sk_write_queue; /* 发送队列 */

...

/* 发送队列的总大小,包含发送队列中skb负荷大小,

* 以及sk_buff、sk_shared_info结构体、协议头的额外开销。

*/

int sk_wmem_queued;

...

};

整个TCP层的内存相关变量。

[java]

struct proto tcp_prot = {

.name = "TCP",

.owner = THIS_MODULE,

...

/* 设置TCP的内存压力标志,把tcp_memory_pressure置为1 */

.enter_memory_pressure = tcp_enter_memory_pressure,

/* 检查sock是否有剩余的发送缓存(sk_wmem_queued < sk_sndbuf)。

* 值得注意的是,用户可以使用TCP_NOTSENT_LOWAT选项来避免占用过多的发送缓存。

*/

.stream_memory_free = tcp_stream_memory_free,

...

/* TCP目前已经分配的内存 */

.memory_allocated = &tcp_memory_allocated,

/* TCP内存压力标志,超过tcp_mem[1]后设置,低于tcp_mem[0]后清除 */ .memory_pressure = &tcp_memory_pressure,

/* TCP内存使用的最小值、压力值、最大值,单位为页 */

.sysctl_mem = sysctl_tcp_mem,

/* 每个sock写缓存的最小值、默认值、最大值,单位为字节 */

.sysctl_wmem = sysctl_tcp_wmem,

/* 每个sock读缓存的最小值、默认值、最大值,单位为字节 */

.sysctl_rmem = sysctl_tcp_rmem,

.max_header = MAX_TCP_HEADER, /* 协议头的最大长度 */

...

};

atomic_long_t tcp_memory_allocated; /* Current allocated memory. */

int tcp_memory_pressure __read_mostly;

初始化

(1) tcp_mem

tcp_mem是整个TCP层的内存消耗,单位为页。

long sysctl_tcp_mem[3] __read_mostly;

tcp_mem - vector of 3 INTEGERs: min, pressure, max

min: below this number of pages TCP is not bothered about its memory appetite.

pressure: when amount of memory allocated by TCP exceeds this number of pages,

TCP moderates it memory consumption and enters memory pressure mode, which is exited when memory consumption falls under min.

max: number of pages allowed for queueing by all TCP sockets. Defaults are calculated at boot time from amount of available memory.

在tcp_init()中,调用tcp_init_mem()来初始化sysctl_tcp_mem[3]数组。tcp_mem[0]是最小值,为3/32的系统内存。

tcp_mem[1]是压力值,为1/8的系统内存,也是最小值的4/3。

tcp_mem[2]是最大值,为3/16的系统内存,也是最小值的2倍。

[java]

static void tcp_init_mem(void)

{

/* nr_free_buffer_pages()计算ZONE_DMA和ZONE_NORMAL的页数,* 对于64位系统来说,其实就是所有内存了。

*/

unsigned long limit = nr_free_buffer_pages() / 8;

limit = max(limit, 128UL); /* 不能低于128页 */

sysctl_tcp_mem[0] = limit / 4 * 3; /* 最小值设为3/32的系统内存 */

sysctl_tcp_mem[1] = limit; /* 压力值设为1/8的系统内存 */ sysctl_tcp_mem[2] = sysctl_tcp_mem[0] * 2; /* 最大值设为3/16的系统内存 */

}

(2) tcp_wmem

tcp_wmem是每个sock的写缓存,单位为字节。

int sysctl_tcp_wmem[3] __read_mostly;

相关文档
最新文档