本文原创为freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/article/details/19424109
在2013年11月19日, Andrey Vagin提交了一个patch,该patch修复了 snd_nxt做update的逻辑。
这个patch其实逻辑很简单,也正是因为简单,所以适合给初学者学习。
kernel的oops信息如下:
[ 103.043194] BUG: unable to handle kernel NULL pointer dereference at 0000000000000048
[ 103.044025] IP: [<ffffffff815aaaaf>] tcp_rearm_rto+0xcf/0x150
...
[ 146.301158] Call Trace:
[ 146.301158] [<ffffffff815ab7f0>] tcp_ack+0xcc0/0x12c0
在出现本oops之前,Linux正把sk强制转换为tcp_sk:
void tcp_send_window_probe(struct sock *sk)
{ if (sk->sk_state == TCP_ESTABLISHED) { tcp_sk(sk)->snd_wl1 = tcp_sk(sk)->rcv_nxt - 1; tcp_sk(sk)->snd_nxt = tcp_sk(sk)->write_seq; tcp_xmit_probe_skb(sk, 0); } }
转换之前,数据结构关系如下:
snd_una snd_nxt write_seq |_________|________| |
转换之后,数据结构关系如下:
snd_una snd_nxt, write_seq |_________ ________| | sk_send_headsnd_nxt与sk_send_head已经错开了。
事实上,如下一行代码是不需要的。
tcp_sk(sk)->snd_nxt = tcp_sk(sk)->write_seq;
童鞋们,从这篇文章你学习到了什么呢?