On Thu, 2016-09-08 at 14:02 +0300, Ilpo Järvinen wrote:
> On Wed, 7 Sep 2016, Eric Dumazet wrote:
> While testing, was there any check done for the data that was delivered
> in order to ensure that no corruption occured (either by you or Yaogong)?
> ...This kind of changes have some potential to cause some corruption to
> the stream content and it would be nice to be sure there wasn't any
> accidents.
Sure, we did tests on real GFE, serving real data to users.
My ssh/scp sessions did not catch any error, even with up to 10% packet
losses.
> > }
> >
> > - seq = TCP_SKB_CB(skb)->seq;
> > - end_seq = TCP_SKB_CB(skb)->end_seq;
>
> I hate to nitpick but moving these variables earlier and the
> TCP_SKB_CB(skb)->seq/end_seq simplifications seem unrelated and
> could be done in another patch?
You are right.
I could split this patch in 3 parts if David requests it.
1) One patch adding skb_rbtree_purge(struct rb_root *root) helper
2) One patch doing this seq/end_seq cleanup.
3) RB patch
> > -
> > - for (;;) {
> > - struct sk_buff *next = NULL;
> >
> > - if (!skb_queue_is_last(&tp->out_of_order_queue, skb))
> > - next = skb_queue_next(&tp->out_of_order_queue, skb);
> > - skb = next;
> > + for (head = skb;;) {
> > + skb = tcp_skb_next(skb, NULL);
> >
> > - /* Segment is terminated when we see gap or when
> > - * we are at the end of all the queue. */
> > + /* Range is terminated when we see a gap or when
> > + * we are at the queue end.
> > + */
> > if (!skb ||
> > after(TCP_SKB_CB(skb)->seq, end) ||
> > before(TCP_SKB_CB(skb)->end_seq, start)) {
> > - tcp_collapse(sk, &tp->out_of_order_queue,
> > + tcp_collapse(sk, NULL, &tp->out_of_order_queue,
> > head, skb, start, end);
> > - head = skb;
> > - if (!skb)
> > - break;
> > - /* Start new segment */
> > + goto new_range;
> > + }
> > +
> > + if (unlikely(before(TCP_SKB_CB(skb)->seq, start)))
> > start = TCP_SKB_CB(skb)->seq;
> > + if (after(TCP_SKB_CB(skb)->end_seq, end))
> > end = TCP_SKB_CB(skb)->end_seq;
> > - } else {
> > - if (before(TCP_SKB_CB(skb)->seq, start))
> > - start = TCP_SKB_CB(skb)->seq;
> > - if (after(TCP_SKB_CB(skb)->end_seq, end))
> > - end = TCP_SKB_CB(skb)->end_seq;
> > - }
> > }
> > }
>
> I tried long to think if I could propose alternative layout which would
> make this function to exit from the end but couldn't come up anything
> sensible. As is, it's always exiting within that top if block which is
> somewhat unintuitive :-).
>
> Acked-By: Ilpo Järvinen <ilpo.jarvinen@helsinki>
>
Thanks for the review !