tcp: drop tcp_bound_rto, merge content of it tcp_set_rto
[safe/jmp/linux-2.6] / net / ipv4 / tcp.c
index 1ab341e..0192434 100644 (file)
 
 int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT;
 
-atomic_t tcp_orphan_count = ATOMIC_INIT(0);
-
+struct percpu_counter tcp_orphan_count;
 EXPORT_SYMBOL_GPL(tcp_orphan_count);
 
 int sysctl_tcp_mem[3] __read_mostly;
@@ -290,9 +289,12 @@ EXPORT_SYMBOL(sysctl_tcp_rmem);
 EXPORT_SYMBOL(sysctl_tcp_wmem);
 
 atomic_t tcp_memory_allocated; /* Current allocated memory. */
-atomic_t tcp_sockets_allocated;        /* Current number of TCP sockets. */
-
 EXPORT_SYMBOL(tcp_memory_allocated);
+
+/*
+ * Current number of TCP sockets.
+ */
+struct percpu_counter tcp_sockets_allocated;
 EXPORT_SYMBOL(tcp_sockets_allocated);
 
 /*
@@ -384,13 +386,17 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
 
        /* Connected? */
        if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) {
+               int target = sock_rcvlowat(sk, 0, INT_MAX);
+
+               if (tp->urg_seq == tp->copied_seq &&
+                   !sock_flag(sk, SOCK_URGINLINE) &&
+                   tp->urg_data)
+                       target--;
+
                /* Potential race condition. If read of tp below will
                 * escape above sk->sk_state, we can be illegally awaken
                 * in SYN_* states. */
-               if ((tp->rcv_nxt != tp->copied_seq) &&
-                   (tp->urg_seq != tp->copied_seq ||
-                    tp->rcv_nxt != tp->copied_seq + 1 ||
-                    sock_flag(sk, SOCK_URGINLINE) || !tp->urg_data))
+               if (tp->rcv_nxt - tp->copied_seq >= target)
                        mask |= POLLIN | POLLRDNORM;
 
                if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
@@ -493,10 +499,8 @@ static inline void skb_entail(struct sock *sk, struct sk_buff *skb)
 static inline void tcp_mark_urg(struct tcp_sock *tp, int flags,
                                struct sk_buff *skb)
 {
-       if (flags & MSG_OOB) {
-               tp->urg_mode = 1;
+       if (flags & MSG_OOB)
                tp->snd_up = tp->write_seq;
-       }
 }
 
 static inline void tcp_push(struct sock *sk, int flags, int mss_now,
@@ -1157,7 +1161,7 @@ static void tcp_prequeue_process(struct sock *sk)
         * necessary */
        local_bh_disable();
        while ((skb = __skb_dequeue(&tp->ucopy.prequeue)) != NULL)
-               sk->sk_backlog_rcv(sk, skb);
+               sk_backlog_rcv(sk, skb);
        local_bh_enable();
 
        /* Clear memory counter. */
@@ -1372,8 +1376,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                            sk->sk_state == TCP_CLOSE ||
                            (sk->sk_shutdown & RCV_SHUTDOWN) ||
                            !timeo ||
-                           signal_pending(current) ||
-                           (flags & MSG_PEEK))
+                           signal_pending(current))
                                break;
                } else {
                        if (sock_flag(sk, SOCK_DONE))
@@ -1679,7 +1682,7 @@ void tcp_set_state(struct sock *sk, int state)
                        inet_put_port(sk);
                /* fall through */
        default:
-               if (oldstate==TCP_ESTABLISHED)
+               if (oldstate == TCP_ESTABLISHED)
                        TCP_DEC_STATS(sock_net(sk), TCP_MIB_CURRESTAB);
        }
 
@@ -1689,7 +1692,7 @@ void tcp_set_state(struct sock *sk, int state)
        sk->sk_state = state;
 
 #ifdef STATE_TRACE
-       SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]);
+       SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n", sk, statename[oldstate], statename[state]);
 #endif
 }
 EXPORT_SYMBOL_GPL(tcp_set_state);
@@ -1833,7 +1836,7 @@ adjudge_to_death:
        state = sk->sk_state;
        sock_hold(sk);
        sock_orphan(sk);
-       atomic_inc(sk->sk_prot->orphan_count);
+       percpu_counter_inc(sk->sk_prot->orphan_count);
 
        /* It is the last release_sock in its life. It will remove backlog. */
        release_sock(sk);
@@ -1884,9 +1887,11 @@ adjudge_to_death:
                }
        }
        if (sk->sk_state != TCP_CLOSE) {
+               int orphan_count = percpu_counter_read_positive(
+                                               sk->sk_prot->orphan_count);
+
                sk_mem_reclaim(sk);
-               if (tcp_too_many_orphans(sk,
-                               atomic_read(sk->sk_prot->orphan_count))) {
+               if (tcp_too_many_orphans(sk, orphan_count)) {
                        if (net_ratelimit())
                                printk(KERN_INFO "TCP: too many of orphaned "
                                       "sockets\n");
@@ -2649,7 +2654,7 @@ EXPORT_SYMBOL(tcp_md5_hash_key);
 
 void tcp_done(struct sock *sk)
 {
-       if(sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV)
+       if (sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV)
                TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_ATTEMPTFAILS);
 
        tcp_set_state(sk, TCP_CLOSE);
@@ -2684,6 +2689,8 @@ void __init tcp_init(void)
 
        BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb));
 
+       percpu_counter_init(&tcp_sockets_allocated, 0);
+       percpu_counter_init(&tcp_orphan_count, 0);
        tcp_hashinfo.bind_bucket_cachep =
                kmem_cache_create("tcp_bind_bucket",
                                  sizeof(struct inet_bind_bucket), 0,
@@ -2706,8 +2713,8 @@ void __init tcp_init(void)
                                        thash_entries ? 0 : 512 * 1024);
        tcp_hashinfo.ehash_size = 1 << tcp_hashinfo.ehash_size;
        for (i = 0; i < tcp_hashinfo.ehash_size; i++) {
-               INIT_HLIST_HEAD(&tcp_hashinfo.ehash[i].chain);
-               INIT_HLIST_HEAD(&tcp_hashinfo.ehash[i].twchain);
+               INIT_HLIST_NULLS_HEAD(&tcp_hashinfo.ehash[i].chain, i);
+               INIT_HLIST_NULLS_HEAD(&tcp_hashinfo.ehash[i].twchain, i);
        }
        if (inet_ehash_locks_alloc(&tcp_hashinfo))
                panic("TCP: failed to alloc ehash_locks");