int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3;
        int reord = tp->packets_out;
        int prior_fackets;
-       u32 highest_sack_end_seq = tp->lost_retrans_low;
+       u32 highest_sack_end_seq;
        int flag = 0;
        int found_dup_sack = 0;
        int cached_fack_count;
        if (!tp->sacked_out) {
                if (WARN_ON(tp->fackets_out))
                        tp->fackets_out = 0;
-               tp->highest_sack = tp->snd_una;
+               tp->highest_sack = tcp_write_queue_head(sk);
        }
        prior_fackets = tp->fackets_out;
 
                                if (fack_count > tp->fackets_out)
                                        tp->fackets_out = fack_count;
 
-                               if (after(TCP_SKB_CB(skb)->seq, tp->highest_sack)) {
-                                       tp->highest_sack = TCP_SKB_CB(skb)->seq;
-                                       highest_sack_end_seq = TCP_SKB_CB(skb)->end_seq;
-                               }
+                               if (after(TCP_SKB_CB(skb)->seq, tcp_highest_sack_seq(tp)))
+                                       tp->highest_sack = skb;
+
                        } else {
                                if (dup_sack && (sacked&TCPCB_RETRANS))
                                        reord = min(fack_count, reord);
                        flag &= ~FLAG_ONLY_ORIG_SACKED;
        }
 
+       highest_sack_end_seq = TCP_SKB_CB(tp->highest_sack)->end_seq;
        if (tcp_is_fack(tp) && tp->retrans_out &&
            after(highest_sack_end_seq, tp->lost_retrans_low) &&
            icsk->icsk_ca_state == TCP_CA_Recovery)
 
  * tweak SACK fastpath hint too as it would overwrite all changes unless
  * hint is also changed.
  */
-static void tcp_adjust_fackets_out(struct tcp_sock *tp, struct sk_buff *skb,
+static void tcp_adjust_fackets_out(struct sock *sk, struct sk_buff *skb,
                                   int decr)
 {
+       struct tcp_sock *tp = tcp_sk(sk);
+
        if (!tp->sacked_out || tcp_is_reno(tp))
                return;
 
-       if (!before(tp->highest_sack, TCP_SKB_CB(skb)->seq))
+       if (!before(tcp_highest_sack_seq(tp), TCP_SKB_CB(skb)->seq))
                tp->fackets_out -= decr;
 
        /* cnt_hint is "off-by-one" compared with fackets_out (see sacktag) */
        TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq;
        TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq;
 
-       if (tcp_is_sack(tp) && tp->sacked_out &&
-           (TCP_SKB_CB(skb)->seq == tp->highest_sack))
-               tp->highest_sack = TCP_SKB_CB(buff)->seq;
+       if (tcp_is_sack(tp) && tp->sacked_out && (skb == tp->highest_sack))
+               tp->highest_sack = buff;
 
        /* PSH and FIN should only be set in the second packet. */
        flags = TCP_SKB_CB(skb)->flags;
                        tcp_dec_pcount_approx_int(&tp->sacked_out, diff);
                        tcp_verify_left_out(tp);
                }
-               tcp_adjust_fackets_out(tp, skb, diff);
+               tcp_adjust_fackets_out(sk, skb, diff);
        }
 
        /* Link BUFF into the send queue. */
                       tcp_skb_pcount(next_skb) != 1);
 
                if (WARN_ON(tcp_is_sack(tp) && tp->sacked_out &&
-                   (TCP_SKB_CB(next_skb)->seq == tp->highest_sack)))
+                   (next_skb == tp->highest_sack)))
                        return;
 
                /* Ok.  We will be able to collapse the packet. */
                if (tcp_is_reno(tp) && tp->sacked_out)
                        tcp_dec_pcount_approx(&tp->sacked_out, next_skb);
 
-               tcp_adjust_fackets_out(tp, next_skb, tcp_skb_pcount(next_skb));
+               tcp_adjust_fackets_out(sk, next_skb, tcp_skb_pcount(next_skb));
                tp->packets_out -= tcp_skb_pcount(next_skb);
 
                /* changed transmit queue under us so clear hints */
                        break;
                tp->forward_skb_hint = skb;
 
-               if (after(TCP_SKB_CB(skb)->seq, tp->highest_sack))
+               if (after(TCP_SKB_CB(skb)->seq, tcp_highest_sack_seq(tp)))
                        break;
 
                if (tcp_packets_in_flight(tp) >= tp->snd_cwnd)