5.2 快速路径处理

        在Linux中,有两种方法来处理传入TCP数据段:快速路径(Fast Path)和慢速路径(Slow Path)。使用快速路径只进行最少的处理,如处理数据段、发生ACK、存储时间戳等。使用慢速路径可以处理乱序数据段、PAWS、socket内存管理和紧急数据等。Linux通过预测标志来区分这两种处理模式,预测标志存储在tp->pred_flags,生成这个标志的函数是__tcp_fast_path_on和tcp_fast_path_on,TCP会直接使用这两个函数来生成预测标记,也可以调用tcp_fast_path_check来完成这一任务:

 613 static inline void __tcp_fast_path_on(struct tcp_sock *tp, u32 snd_wnd)
 614 {   
 615     tp->pred_flags = htonl((tp->tcp_header_len << 26) |
 616                    ntohl(TCP_FLAG_ACK) |
 617                    snd_wnd);
 618 }   
 619         
 620 static inline void tcp_fast_path_on(struct tcp_sock *tp)
 621 {   
 622     __tcp_fast_path_on(tp, tp->snd_wnd >> tp->rx_opt.snd_wscale);
 623 }   
 624         
 625 static inline void tcp_fast_path_check(struct sock *sk)
 626 {   
 627     struct tcp_sock *tp = tcp_sk(sk);
 628         
 629     if (skb_queue_empty(&tp->out_of_order_queue) &&
 630         tp->rcv_wnd &&
 631         atomic_read(&sk->sk_rmem_alloc) < sk->sk_rcvbuf &&
 632         !tp->urg_data)
 633         tcp_fast_path_on(tp);
 634 }   
        613-617:__tcp_fast_path_on函数做的工作实际上是在构建TCP首部的第4个字节,即首部长度、标记位、窗口(格式见1.2节)。其中tp->tcp_header_len是首部长度的字节数,TCP首部中记录首部长度的数值位于第4个字节的高4bit,即第28-31bit,而且这个数值乘以4才是首部长度的字节数。故tp->tcp_header_len需要左移28位,再右移2位(除以4),即左移26位。
        620-622:tcp_fast_path_on封装了__tcp_fast_path_on函数,它在设置预测标记时会考虑窗口扩大因子的影响

        625-633:tcp_fast_path_check会先检查条件是否满足,如果满足再设置预测标记。条件是:

(1)没有乱序数据(629)

(2)接收窗口不为0(630)

(3)接收缓存未耗尽(631)

(4)没有紧急数据(632)

        TCP直接调用__tcp_fast_path_on的时机是connect系统调用即将结束时:

5291 void tcp_finish_connect(struct sock *sk, struct sk_buff *skb)
5292 {
...
5320     if (!tp->rx_opt.snd_wscale)
5321         __tcp_fast_path_on(tp, tp->snd_wnd);
5322     else           
5323         tp->pred_flags = 0;
...
        TCP直接调用tcp_fast_path_on的时机是收到三次握手中的ACK报文时:
5600 int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
5601               const struct tcphdr *th, unsigned int len)
5602 {
...
5678         int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH |
5679                           FLAG_UPDATE_TS_RECENT) > 0;
5680 
5681         switch (sk->sk_state) {
5682         case TCP_SYN_RECV:
5683             if (acceptable) {
...
5745                 tcp_fast_path_on(tp);
5746             } else {
5747                 return 1;
5748             }
5749             break;
...
        TCP直接调用tcp_fast_path_check的时机有3处:

(1)当读过紧急数据时;紧急数据是由慢速路径处理,需要保持在慢速路径模式直到收完紧急数据,然后就可以开启快速路径模式了。

1545 int tcp_recvmsg(struct kiocb *ioc
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值