10.3 接收缓存管理

       TCP收到对端发送的数据后,通常不能立即交付应用进程。在应用进程取走数据之前,数据需要保存在接收缓存之中。如果应用进程取数据的速度比TCP从对端收数据的速度慢,则接收缓存中的数据会越来越多。因此在skb被放入接收缓存之前必须检查接收缓存能容纳的内存数,如果超出限制则必须丢弃skb

10.3.1 缓存占用

        tcp_rcv_established会检查接收缓存的使用情况:

 5076 int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
5077             const struct tcphdr *th, unsigned int len)
5078 {           
5079     struct tcp_sock *tp = tcp_sk(sk);
...
5201             if (!eaten) {
...
5205                 if ((int)skb->truesize > sk->sk_forward_alloc) //剩余空间无法容纳skb
5206                     goto step5;//进入慢速路径
...
5221                 /* Bulk data transfer: receiver */
5222                 eaten = tcp_queue_rcv(sk, skb, tcp_header_len,
5223                               &fragstolen);
...
5265 step5:
...
5275     tcp_data_queue(sk, skb);
...
        tcp_queue_rcv 函数:

4244 static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int hdrlen,
4245           bool *fragstolen)
4246 {
4247     int eaten;
4248     struct sk_buff *tail = skb_peek_tail(&sk->sk_receive_queue);
4249
4250     __skb_pull(skb, hdrlen);
4251     eaten = (tail &&
4252          tcp_try_coalesce(sk, tail, skb, fragstolen)) ? 1 : 0;
4253     tcp_sk(sk)->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
4254     if (!eaten) {
4255         __skb_queue_tail(&sk->sk_receive_queue, skb);
4256         skb_set_owner_r(skb, sk);      
4257     }
4258     return eaten;
4259 }
        skb_set_owner_r函数:
1995 static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
1996 {         
1997     skb_orphan(skb);
1998     skb->sk = sk;
1999     skb->destructor = sock_rfree;
2000     atomic_add(skb->truesize, &sk->sk_rmem_alloc);
2001     sk_mem_charge(sk, skb->truesize);    //sk->sk_forward_alloc -= size
2002 } 
        在tcp_data_queue 函数中:
4300 static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
4301 {
4302     const struct tcphdr *th = tcp_hdr(skb);
4303     struct tcp_sock *tp = tcp_sk(sk);
4304     int eaten = -1;
4305     bool fragstolen = false;
...
4344         if (eaten <= 0) {
4345 queue_and_out:
4346             if (eaten < 0 &&
4347                 tcp_try_rmem_schedule(sk, skb, skb->
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值