]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/ipv4/tcp_output.c
foundations of per-cgroup memory pressure controlling.
[mv-sheeva.git] / net / ipv4 / tcp_output.c
index 980b98f6288c3f82f85da0ac61f74ecfa0cbc12b..8c8de2780c7a7add9e91805300824e7182d40f28 100644 (file)
@@ -1093,6 +1093,13 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
 {
        int i, k, eat;
 
+       eat = min_t(int, len, skb_headlen(skb));
+       if (eat) {
+               __skb_pull(skb, eat);
+               len -= eat;
+               if (!len)
+                       return;
+       }
        eat = len;
        k = 0;
        for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
@@ -1124,11 +1131,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
        if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
                return -ENOMEM;
 
-       /* If len == headlen, we avoid __skb_pull to preserve alignment. */
-       if (unlikely(len < skb_headlen(skb)))
-               __skb_pull(skb, len);
-       else
-               __pskb_trim_head(skb, len - skb_headlen(skb));
+       __pskb_trim_head(skb, len);
 
        TCP_SKB_CB(skb)->seq += len;
        skb->ip_summed = CHECKSUM_PARTIAL;
@@ -1382,7 +1385,7 @@ static inline int tcp_minshall_check(const struct tcp_sock *tp)
 /* Return 0, if packet can be sent now without violation Nagle's rules:
  * 1. It is full sized.
  * 2. Or it contains FIN. (already checked by caller)
- * 3. Or TCP_NODELAY was set.
+ * 3. Or TCP_CORK is not set, and TCP_NODELAY is set.
  * 4. Or TCP_CORK is not set, and all sent packets are ACKed.
  *    With Minshall's modification: all sent small packets are ACKed.
  */
@@ -1581,7 +1584,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
                 * frame, so if we have space for more than 3 frames
                 * then send now.
                 */
-               if (limit > tcp_max_burst(tp) * tp->mss_cache)
+               if (limit > tcp_max_tso_deferred_mss(tp) * tp->mss_cache)
                        goto send_now;
        }
 
@@ -1919,7 +1922,7 @@ u32 __tcp_select_window(struct sock *sk)
        if (free_space < (full_space >> 1)) {
                icsk->icsk_ack.quick = 0;
 
-               if (tcp_memory_pressure)
+               if (sk_under_memory_pressure(sk))
                        tp->rcv_ssthresh = min(tp->rcv_ssthresh,
                                               4U * tp->advmss);
 
@@ -2147,7 +2150,15 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
         */
        TCP_SKB_CB(skb)->when = tcp_time_stamp;
 
-       err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
+       /* make sure skb->data is aligned on arches that require it */
+       if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) {
+               struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER,
+                                                  GFP_ATOMIC);
+               err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) :
+                            -ENOBUFS;
+       } else {
+               err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
+       }
 
        if (err == 0) {
                /* Update global TCP statistics. */