[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20110127152057.GA4153@swordfish.minsk.epam.com>
Date: Thu, 27 Jan 2011 17:20:57 +0200
From: Sergey Senozhatsky <sergey.senozhatsky@...il.com>
To: "David S. Miller" <davem@...emloft.net>
Cc: Alexey Kuznetsov <kuznet@....inr.ac.ru>,
Eric Dumazet <eric.dumazet@...il.com>,
"Pekka Savola (ipv6)" <pekkas@...core.fi>, netdev@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: skb_split in tcp_retransmit_skb question
Hello,
Suppose we have the following scenario:
tcp_write_timer ->
tcp_retransmit_skb
in tcp_retransmit_skb we have `if (skb->len > cur_mss)' evaluted to true, which leads
to tcp_fragment(sk, skb, cur_mss, cur_mss) call. tcp_fragment calls skb_split(skb, buff, len)
which, in turn, calls skb_split_no_header(skb, skb1, len, pos), where we have
`skb_shinfo(skb)->nr_frags++' while in `for (i = 0; i < nfrags; i++)' loop.
Now we fall back to:
tcp_retransmit_skb ->
tcp_transmit_skb ->
pskb_copy(skb, gfp_mask)
In pskb_copy we perform iteration on nr_frags:
729 if (skb_shinfo(skb)->nr_frags) {
730 int i;
731 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
732 skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i];
733 get_page(skb_shinfo(n)->frags[i].page);
734 }
735 skb_shinfo(n)->nr_frags = i;
736 }
The problem here is that nr_frags was increased in skb_split, yet new page was not allocated.
So, get_page(skb_shinfo(n)->frags[i].page) is actually get_page(NULL):
mov (%rdx), %eax
where %rdx is 0x00
Please correct me if I'm missing something.
Sergey
Content of type "application/pgp-signature" skipped
Powered by blists - more mailing lists