]> err.no Git - linux-2.6/blobdiff - include/net/tcp.h
[TCP]: Abstract tp->highest_sack accessing & point to next skb
[linux-2.6] / include / net / tcp.h
index cb5b033e0e59c205980243d2b7e494db0925f218..5ec1cacca8a1e7a3b741f7af6e5a11715a3ac0a6 100644 (file)
@@ -309,6 +309,9 @@ extern int                  tcp_twsk_unique(struct sock *sk,
 
 extern void                    tcp_twsk_destructor(struct sock *sk);
 
+extern ssize_t                 tcp_splice_read(struct socket *sk, loff_t *ppos,
+                                               struct pipe_inode_info *pipe, size_t len, unsigned int flags);
+
 static inline void tcp_dec_quickack_mode(struct sock *sk,
                                         const unsigned int pkts)
 {
@@ -649,7 +652,7 @@ struct tcp_congestion_ops {
        /* lower bound for congestion window (optional) */
        u32 (*min_cwnd)(const struct sock *sk);
        /* do new cwnd calculation (required) */
-       void (*cong_avoid)(struct sock *sk, u32 ack, u32 in_flight, int good_ack);
+       void (*cong_avoid)(struct sock *sk, u32 ack, u32 in_flight);
        /* call before changing ca_state (optional) */
        void (*set_state)(struct sock *sk, u8 new_state);
        /* call when cwnd event occurs (optional) */
@@ -680,7 +683,7 @@ extern void tcp_slow_start(struct tcp_sock *tp);
 
 extern struct tcp_congestion_ops tcp_init_congestion_ops;
 extern u32 tcp_reno_ssthresh(struct sock *sk);
-extern void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 in_flight, int flag);
+extern void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 in_flight);
 extern u32 tcp_reno_min_cwnd(const struct sock *sk);
 extern struct tcp_congestion_ops tcp_reno;
 
@@ -1078,7 +1081,6 @@ static inline void tcp_clear_retrans_hints_partial(struct tcp_sock *tp)
 static inline void tcp_clear_all_retrans_hints(struct tcp_sock *tp)
 {
        tcp_clear_retrans_hints_partial(tp);
-       tp->fastpath_skb_hint = NULL;
 }
 
 /* MD5 Signature */
@@ -1227,6 +1229,11 @@ static inline struct sk_buff *tcp_write_queue_next(struct sock *sk, struct sk_bu
                for (; (skb != (struct sk_buff *)&(sk)->sk_write_queue);\
                     skb = skb->next)
 
+#define tcp_for_write_queue_from_safe(skb, tmp, sk)                    \
+               for (tmp = skb->next;                                   \
+                    (skb != (struct sk_buff *)&(sk)->sk_write_queue);  \
+                    skb = tmp, tmp = skb->next)
+
 static inline struct sk_buff *tcp_send_head(struct sock *sk)
 {
        return sk->sk_send_head;
@@ -1234,14 +1241,9 @@ static inline struct sk_buff *tcp_send_head(struct sock *sk)
 
 static inline void tcp_advance_send_head(struct sock *sk, struct sk_buff *skb)
 {
-       struct tcp_sock *tp = tcp_sk(sk);
-
        sk->sk_send_head = skb->next;
        if (sk->sk_send_head == (struct sk_buff *)&sk->sk_write_queue)
                sk->sk_send_head = NULL;
-       /* Don't override Nagle indefinately with F-RTO */
-       if (tp->frto_counter == 2)
-               tp->frto_counter = 3;
 }
 
 static inline void tcp_check_send_head(struct sock *sk, struct sk_buff *skb_unlinked)
@@ -1265,8 +1267,12 @@ static inline void tcp_add_write_queue_tail(struct sock *sk, struct sk_buff *skb
        __tcp_add_write_queue_tail(sk, skb);
 
        /* Queue it, remembering where we must start sending. */
-       if (sk->sk_send_head == NULL)
+       if (sk->sk_send_head == NULL) {
                sk->sk_send_head = skb;
+
+               if (tcp_sk(sk)->highest_sack == NULL)
+                       tcp_sk(sk)->highest_sack = skb;
+       }
 }
 
 static inline void __tcp_add_write_queue_head(struct sock *sk, struct sk_buff *skb)
@@ -1309,6 +1315,45 @@ static inline int tcp_write_queue_empty(struct sock *sk)
        return skb_queue_empty(&sk->sk_write_queue);
 }
 
+/* Start sequence of the highest skb with SACKed bit, valid only if
+ * sacked > 0 or when the caller has ensured validity by itself.
+ */
+static inline u32 tcp_highest_sack_seq(struct tcp_sock *tp)
+{
+       if (!tp->sacked_out)
+               return tp->snd_una;
+
+       if (tp->highest_sack == NULL)
+               return tp->snd_nxt;
+
+       return TCP_SKB_CB(tp->highest_sack)->seq;
+}
+
+static inline void tcp_advance_highest_sack(struct sock *sk, struct sk_buff *skb)
+{
+       tcp_sk(sk)->highest_sack = tcp_skb_is_last(sk, skb) ? NULL :
+                                               tcp_write_queue_next(sk, skb);
+}
+
+static inline struct sk_buff *tcp_highest_sack(struct sock *sk)
+{
+       return tcp_sk(sk)->highest_sack;
+}
+
+static inline void tcp_highest_sack_reset(struct sock *sk)
+{
+       tcp_sk(sk)->highest_sack = tcp_write_queue_head(sk);
+}
+
+/* Called when old skb is about to be deleted (to be combined with new skb) */
+static inline void tcp_highest_sack_combine(struct sock *sk,
+                                           struct sk_buff *old,
+                                           struct sk_buff *new)
+{
+       if (tcp_sk(sk)->sacked_out && (old == tcp_sk(sk)->highest_sack))
+               tcp_sk(sk)->highest_sack = new;
+}
+
 /* /proc */
 enum tcp_seq_states {
        TCP_SEQ_STATE_LISTENING,