4.4 TCP Small Queue(TSQ)

TCP Small Queue(TSQ)是Linux内核3.6.0引入的一种机制,旨在解决因数据发送过快或大流量非TCP数据流导致的队列满和数据包丢失问题。TSQ通过限制每个TCP连接可以排队的字节数,当超过限制时,数据会被放入tasklet并在软中断上下文发送,以缓解队列拥堵和减少TCP延时。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  TCP发送的数据经过IP层添加IP包头后,会被发送到IP数据栈和网卡之间的队列中,当网卡能够发送数据时会到这个队列中去取skb。当TCP发送数据过快时,或一个带宽很大或者包速率很大的非TCP数据流会把队列里的所有空间占满,造成数据包丢失和延时的问题。更糟的是,这样很可能会使另一个缓存产生,进而产生一个静止队列(standing queue),造成更严重的延时并使TCP的RTT和拥塞窗口的计算出现问题。Linux3.6.0出现后,Linux内核增加了TCP小队列(TCP Small Queue)的机制,用于解决该问题。TCP小队列对每个TCP数据流中,能够同时参与排队的字节数做出了限制,这个限制是通过net.ipv4.tcp_limit_output_bytes内核选项实现的。当TCP发送的数据超过这个限制时,多余的数据会被放入另外一个队列中,再通过tastlet机制择机发送。下面分析一下TSQ的实现。

  TSQ tasklet是一个每CPU变量,这样可以保证在多核条件下的并发:

 678 struct tsq_tasklet {     
 679     struct tasklet_struct   tasklet;
 680     struct list_head    head; /* queue of tcp sockets */
 681 };
 682 static DEFINE_PER_CPU(struct tsq_tasklet, tsq_tasklet);

  TSQ tasklet的初始化是在内核加载时完成:

3375 void __init tcp_init(void)
3376 {
...
3456     tcp_tasklet_init();
3457 }
 772 void __init tcp_tasklet_init(void)
 773 {   
 774     int i;
 775     
 776     for_each_possible_cpu(i) {
 777         struct tsq_tasklet *tsq = &per_cpu(tsq_tasklet, i);
 778 
 779         INIT_LIST_HEAD(&tsq->head);
 780         tasklet_init(&tsq->tasklet,
 781                  tcp_tasklet_func,
 782                  (unsigned long)tsq); //初始化tasklet任务
 783     }
 784 }       
  tasklet_init函数指定了tcp_tasklet_func函数为处理函数:
 697 static void tcp_tasklet_func(unsigned long data)
 698 {
 699     struct tsq_taskl
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值