Linux tcp_write_queue_tail 发送队列管理与 tsq 处理
Linux tcp_write_queue_tail 发送队列管理与 tsq 处理tcp_write_queue_tail 是 TCP 发送队列sk_write_queue的操作宏定义在 include/net/tcp.h 中。sk_write_queue 是 struct sock 的 sk_write_queue 字段类型为 struct sk_buff_head管理所有已构造但尚未完全确认的 TCP 报文段。队列中的每个 skb 使用 tcp_skb_cb-seq、tcp_skb_cb-end_seq 以及 tcp_skb_cb-tcp_flags 标识数据边界和控制信息。cstatic inline struct sk_buff *tcp_write_queue_tail(const struct sock *sk){return skb_peek_tail(sk-sk_write_queue);}static inline struct sk_buff *tcp_write_queue_head(const struct sock *sk){return skb_peek(sk-sk_write_queue);}static inline struct sk_buff *tcp_send_head(const struct sock *sk){return skb_peek(sk-sk_write_queue);}tcp_send_head 返回发送队列头部即最早未被确认的 skb而 tcp_write_queue_tail 返回队列尾部——即最新被追加的 skb。两者的差异在 GSO 分段和 Nagle 算法中至关重要tcp_write_xmit 循环遍历时从 tcp_send_head 开始每次发送后如果整个 skb 被确认则调用 tcp_advance_send_head 前移队列头部。若 tcp_write_queue_head tcp_write_queue_tail仅一个 skb被完全发送并确认队列变空tcp_send_head(NULL) 作为写关闭信号。skb 追加操作通过 __skb_queue_tail 或 skb_queue_tail 完成。用户进程调用 tcp_sendmsg 经过 tcp_push_one 或 tcp_write_xmit 的分段逻辑后新 skb 附着到队列尾部。这里的关键约束skb-truesize 累积计入 sk-sk_wmem_queued 和 sk-sk_forward_alloctcp_sendmsg 在 sk_stream_alloc_skb 失败时返回 -ENOMEM此时 skb 未入队数据可能部分写入到 cork 的 frags 中。cstatic int tcp_push_one(struct sock *sk, unsigned int mss_now, unsigned int nonagle){struct tcp_sock *tp tcp_sk(sk);struct sk_buff *skb tcp_send_head(sk);if (!skb)return 0;tcp_mark_push(tp, skb);__skb_queue_tail(sk-sk_write_queue, skb);...return tcp_write_xmit(sk, mss_now, nonagle, 0, GFP_KERNEL);}write_queue 的管理涉及三个关键尾指针操作tcp_write_queue_tail(sk) 用于获取最后一个 skb 以在其后追加新数据tcp_fragment 分割时同样需要尾部插入tcp_write_queue_next(sk, skb) 和 tcp_write_queue_prev(sk, skb) 用于遍历。遍历过程在 tcp_sacktag_write_queue 和 tcp_clean_rtx_queue 中大量使用。当 tcp_write_xmit 循环发送时每次调用 tcp_transmit_skb 之前检查是否触发了 TSQ 限速。TSQ 在 tcp_write_xmit 内部的判断通过 tcp_small_queue_check 完成。若触发TSQ_THROTTLED 位置位且发送中断。此时 __tcp_transmit_skb 尚未移除 skb重传队列头部保持不变。cstatic void tcp_tsq_handler(struct sock *sk){struct tcp_sock *tp tcp_sk(sk);unsigned long flags smp_load_acquire(sk-sk_tsq_flags);if (flags TCPF_TSQ_DEFERRED) {bh_lock_sock(sk);if (!sock_owned_by_user(sk)) {if (tp-lost_out tp-retrans_out)tcp_write_xmit(sk, tcp_current_mss(sk), tp-nonagle,0, GFP_ATOMIC);tcp_push_pending_frames(sk);}bh_unlock_sock(sk);}}tsq 的 deferred 处理通过 tcp_release_cb 被调用。当发送路径因 TSQ 被限速并且用户进程持有 lock_sock 时skb 释放后的 tcp_wfree 将 TSQ_DEFERRED 置位。随后用户进程在 release_sock 中调用 tcp_release_cb触发 tcp_tsq_handler 重新尝试发送。这里是 TSQ 的核心竞争点tcp_wfree 运行在 NET_TX_SOFTIRQ 上下文而 tcp_release_cb 运行在进程上下文两者对 sk_tsq_flags 的 test_and_set_bit 操作通过原子位操作保证可见性。tcp_push_pending_frames 在发送队列尾部处理 PSH 标志和紧急数据。该函数检查 tcp_send_head(sk) 是否为 NULL若不为空则调用 tcp_write_xmit 继续发送。在 tp-packets_out 为 0 但 write_queue 非空即所有数据已发送但未确认时__tcp_push_pending_frames 只做极简的 wmem 检查后返回。超时重传对 write_queue 尾部的影响tcp_retransmit_skb 不从队列中移除 skb而是克隆后重新提交给 IP 层。skb-sk 指针维持指向原 socket但 cloned skb 的 destructor 由 tcp_wfree 处理。原始 skb 保留在 write_queue 中直到被 tcp_clean_rtx_queue 移除。cint tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs){struct tcp_sock *tp tcp_sk(sk);int err __tcp_retransmit_skb(sk, skb);if (err 0) {tp-retrans_out tcp_skb_pcount(skb);...if (TCP_SKB_CB(skb)-seq tp-snd_una) {if (tp-lost_out)tp-lost_out - tcp_skb_pcount(skb);}}...return err;}write_queue 中存在一个边界情况TCP_SKB_CB(skb)-tcp_flags TCPHDR_SYN 出现在三次握手阶段的 SYN/ACK 重传。此时 skb 处于 sk_write_queue 中但 writeset即 tp-write_seq尚未初始化完全tcp_retransmit_skb 的检查路径要求验证 sk-sk_state TCP_SYN_SENT 或 TCP_SYN_RECV。另一个边界条件是 tcp_write_queue_tail 与 tcp_collapse 的交互。当发送缓冲区积压过多小包tcp_collapse 将相邻 skb 合并以降低 sk_buff 管理开销。tcp_collapse 从 write_queue 中移除多个 skb 并合并成一个重新追加到尾部。这要求操作持有 write_queue 的自旋锁且如果 collapse 发生在 BH 上下文的 tcp_ack 中不能与用户态的 tcp_sendmsg 并发操作 write_queue——通常通过 sk-sk_lock 的 owned_by_user 标志互斥。

相关新闻

2026 需要视频解析工具怎么选不踩雷?亲测筛选后只留这一个

2026 需要视频解析工具怎么选不踩雷?亲测筛选后只留这一个

先给可执行答案 针对2026年自媒体创作者选视频解析工具的需求,核心要围绕你做内容二次创作的实际需求选,不要为用不到的功能付费。我长期测试过目前主流的5款工具,亲测筛选后,如果你需要把视频内容整理成逐字稿、推文素材或者创作…

2026/7/21 18:14:09 阅读更多 →
Why-Not-Compose动画秘籍:10个超炫效果实现教程与源码解析

Why-Not-Compose动画秘籍:10个超炫效果实现教程与源码解析

Why-Not-Compose动画秘籍:10个超炫效果实现教程与源码解析 【免费下载链接】Why-Not-Compose A collection of animations, compositions, UIs using Jetpack Compose. You can say Jetpack Compose cookbook, showcase or play-ground if you want! 项目地址: ht…

2026/7/21 18:14:09 阅读更多 →
threepp跨平台部署指南:Windows、Linux、macOS与WebAssembly全平台配置教程

threepp跨平台部署指南:Windows、Linux、macOS与WebAssembly全平台配置教程

threepp跨平台部署指南:Windows、Linux、macOS与WebAssembly全平台配置教程 【免费下载链接】threepp A cross-platform C20 3D library with the high-level API of three.js 项目地址: https://gitcode.com/gh_mirrors/th/threepp 想要在Windows、Linux、m…

2026/7/21 18:14:09 阅读更多 →

最新新闻

AI 评测系列(03):LLM-as-Judge——让 LLM 评价 LLM 的正确姿势

AI 评测系列(03):LLM-as-Judge——让 LLM 评价 LLM 的正确姿势

LLM-as-Judge 的工作原理 LLM-as-Judge 把一个 LLM 的输出质量评估任务,交给另一个(或同一个)LLM 来完成。 基本形态有两种: 单答案打分(Pointwise) JUDGE_PROMPT = """评估以下 AI 回答的质量(1-10分): 维度:准确性、相关性、清晰度 问题:{ques…

2026/7/21 22:17:19 阅读更多 →
保姆级C语言与单片机实战教程:从语法到项目,打通嵌入式开发学习路径

保姆级C语言与单片机实战教程:从语法到项目,打通嵌入式开发学习路径

这次我们来看一套被很多初学者和工程师称为“保姆级”的C语言与单片机视频教程。这套教程最大的特点就是“全”,从C语言语法基础一直讲到单片机项目实战,并且完全免费。对于想入门嵌入式开发、准备蓝桥杯比赛、或者正在做单片机课程设计的学生来说&#…

2026/7/21 22:17:19 阅读更多 →
每日一个开源项目(第164篇):毕昇(BISHENG)- 面向企业的开源 LLM DevOps 平台

每日一个开源项目(第164篇):毕昇(BISHENG)- 面向企业的开源 LLM DevOps 平台

引言 “毕昇,活字印刷术的发明者。BISHENG,帮助企业把大模型的能力’活字排版’进自己的业务流程里。” 这是"每日一个开源项目"系列的第164篇文章。今天的主角是 毕昇(BISHENG)——DataElem 开源的企业级 LLM 应用 Dev…

2026/7/21 22:17:19 阅读更多 →
连锁门店会员数据同步问题分析与解决方案

连锁门店会员数据同步问题分析与解决方案

1. 多门店会员数据同步失败的典型场景会员数据同步问题在连锁零售、餐饮、服务业中极为常见。去年我们团队接手过一个连锁烘焙品牌的案例:他们在全国23个城市拥有187家直营门店,使用某知名SAAS系统管理会员,却频繁出现新注册会员在A店消费后&…

2026/7/21 22:17:19 阅读更多 →
颠覆传统励志语录推送成功案例,编写程序,每日推送知名人物的失败经历,提炼失败中的经验,作为当天创新试错的底气。

颠覆传统励志语录推送成功案例,编写程序,每日推送知名人物的失败经历,提炼失败中的经验,作为当天创新试错的底气。

一、实际应用场景描述(基于心理健康与创新能力视角)在心理健康与创新能力研究中,“失败耐受性(Failure Tolerance)” 和 “成长型思维(Growth Mindset)” 被视为持续创新的关键心理基础。一个典…

2026/7/21 22:17:19 阅读更多 →
STM32汽车防撞系统设计与实现

STM32汽车防撞系统设计与实现

1. 项目概述:汽车防撞系统的嵌入式实现方案这个基于STM32的汽车防撞系统本质上是一个实时监测与预警装置。我在实际车载环境测试中发现,传统防撞方案存在响应延迟大(普遍超过200ms)和误报率高的问题。而采用STM32F103系列单片机配…

2026/7/21 22:16:19 阅读更多 →

日新闻

Octane Render与C4D汉化版安装与优化指南

Octane Render与C4D汉化版安装与优化指南

1. Octane Render与C4D的黄金组合:为什么选择这个方案?在三维创作领域,渲染器的选择往往决定了作品的最终呈现质量和工作效率。作为Cinema 4D(C4D)用户,Octane Render的GPU加速特性与实时预览功能&#xff…

2026/7/21 0:00:19 阅读更多 →
GPMC接口设计:异步/同步模式与多路复用配置实战

GPMC接口设计:异步/同步模式与多路复用配置实战

1. GPMC接口设计:从硬件连接到软件配置的全局视角在嵌入式系统开发中,尤其是基于TI Sitara系列如AM263x这类高性能微控制器的项目里,外部存储器的扩展几乎是绕不开的一环。无论是存放大量非易失性代码的NOR Flash,还是作为高速数据…

2026/7/21 0:00:19 阅读更多 →
UE5 GAS框架下RPG被动技能系统:从核心原理到实战实现

UE5 GAS框架下RPG被动技能系统:从核心原理到实战实现

1. 项目概述:UE5 GAS RPG被动技能的核心价值在UE5里用GAS(Gameplay Ability System)做RPG游戏,主动技能像是你手里的武器,按一下打一下,逻辑直接,反馈也快。但被动技能,它更像是你身…

2026/7/21 0:00:19 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/21 8:48:31 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/21 5:34:47 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/21 8:25:39 阅读更多 →

月新闻