enable kexec
[linux-2.6.git] / include / net / tcp.h
index 6c9bcf8..bbdd19e 100644 (file)
@@ -33,6 +33,7 @@
 #include <net/checksum.h>
 #include <net/sock.h>
 #include <net/snmp.h>
+#include <net/ip.h>
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 #include <linux/ipv6.h>
 #endif
@@ -275,20 +276,20 @@ static __inline__ int tw_del_dead_node(struct tcp_tw_bucket *tw)
 
 #define tcptw_sk(__sk) ((struct tcp_tw_bucket *)(__sk))
 
-static inline const u32 tcp_v4_rcv_saddr(const struct sock *sk)
+static inline u32 tcp_v4_rcv_saddr(const struct sock *sk)
 {
        return likely(sk->sk_state != TCP_TIME_WAIT) ?
                inet_sk(sk)->rcv_saddr : tcptw_sk(sk)->tw_rcv_saddr;
 }
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-static inline const struct in6_addr *__tcp_v6_rcv_saddr(const struct sock *sk)
+static inline struct in6_addr *__tcp_v6_rcv_saddr(const struct sock *sk)
 {
        return likely(sk->sk_state != TCP_TIME_WAIT) ?
                &inet6_sk(sk)->rcv_saddr : &tcptw_sk(sk)->tw_v6_rcv_saddr;
 }
 
-static inline const struct in6_addr *tcp_v6_rcv_saddr(const struct sock *sk)
+static inline struct in6_addr *tcp_v6_rcv_saddr(const struct sock *sk)
 {
        return sk->sk_family == AF_INET6 ? __tcp_v6_rcv_saddr(sk) : NULL;
 }
@@ -675,6 +676,10 @@ struct open_request {
                struct tcp_v6_open_req v6_req;
 #endif
        } af;
+#ifdef CONFIG_ACCEPT_QUEUES
+       unsigned long acceptq_time_stamp;
+       int           acceptq_class;
+#endif
 };
 
 /* SLAB cache for open requests. */
@@ -874,7 +879,6 @@ extern void                 tcp_close(struct sock *sk,
                                          long timeout);
 extern struct sock *           tcp_accept(struct sock *sk, int flags, int *err);
 extern unsigned int            tcp_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait);
-extern void                    tcp_write_space(struct sock *sk); 
 
 extern int                     tcp_getsockopt(struct sock *sk, int level, 
                                               int optname,
@@ -975,6 +979,9 @@ extern int tcp_sync_mss(struct sock *sk, u32 pmtu);
 
 extern const char timer_bug_msg[];
 
+/* tcp_diag.c */
+extern void tcp_get_info(struct sock *, struct tcp_info *);
+
 /* Read 'sendfile()'-style from a TCP socket */
 typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *,
                                unsigned int, size_t);
@@ -991,9 +998,7 @@ static inline void tcp_clear_xmit_timer(struct sock *sk, int what)
                tp->pending = 0;
 
 #ifdef TCP_CLEAR_TIMERS
-               if (timer_pending(&tp->retransmit_timer) &&
-                   del_timer(&tp->retransmit_timer))
-                       __sock_put(sk);
+               sk_stop_timer(sk, &tp->retransmit_timer);
 #endif
                break;
        case TCP_TIME_DACK:
@@ -1001,9 +1006,7 @@ static inline void tcp_clear_xmit_timer(struct sock *sk, int what)
                tp->ack.pending = 0;
 
 #ifdef TCP_CLEAR_TIMERS
-               if (timer_pending(&tp->delack_timer) &&
-                   del_timer(&tp->delack_timer))
-                       __sock_put(sk);
+               sk_stop_timer(sk, &tp->delack_timer);
 #endif
                break;
        default:
@@ -1032,19 +1035,17 @@ static inline void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long
        case TCP_TIME_PROBE0:
                tp->pending = what;
                tp->timeout = jiffies+when;
-               if (!mod_timer(&tp->retransmit_timer, tp->timeout))
-                       sock_hold(sk);
+               sk_reset_timer(sk, &tp->retransmit_timer, tp->timeout);
                break;
 
        case TCP_TIME_DACK:
                tp->ack.pending |= TCP_ACK_TIMER;
                tp->ack.timeout = jiffies+when;
-               if (!mod_timer(&tp->delack_timer, tp->ack.timeout))
-                       sock_hold(sk);
+               sk_reset_timer(sk, &tp->delack_timer, tp->ack.timeout);
                break;
 
        default:
-               printk(KERN_DEBUG "bug: unknown timer value\n");
+               printk(timer_bug_msg);
        };
 }
 
@@ -1194,30 +1195,8 @@ struct tcp_skb_cb {
 
 #define TCP_SKB_CB(__skb)      ((struct tcp_skb_cb *)&((__skb)->cb[0]))
 
-#define for_retrans_queue(skb, sk, tp) \
-               for (skb = (sk)->sk_write_queue.next;                   \
-                    (skb != (tp)->send_head) &&                        \
-                    (skb != (struct sk_buff *)&(sk)->sk_write_queue);  \
-                    skb=skb->next)
-
-
 #include <net/tcp_ecn.h>
 
-
-/*
- *     Compute minimal free write space needed to queue new packets. 
- */
-static inline int tcp_min_write_space(struct sock *sk)
-{
-       return sk->sk_wmem_queued / 2;
-}
-static inline int tcp_wspace(struct sock *sk)
-{
-       return sk->sk_sndbuf - sk->sk_wmem_queued;
-}
-
-
 /* This determines how many packets are "in the network" to the best
  * of our knowledge.  In many cases it is conservative, but where
  * detailed information is available from the receiver (via SACK
@@ -1424,7 +1403,7 @@ tcp_nagle_check(struct tcp_opt *tp, struct sk_buff *skb, unsigned mss_now, int n
                  tcp_minshall_check(tp))));
 }
 
-/* This checks if the data bearing packet SKB (usually tp->send_head)
+/* This checks if the data bearing packet SKB (usually sk->sk_send_head)
  * should be put on the wire right now.
  */
 static __inline__ int tcp_snd_test(struct tcp_opt *tp, struct sk_buff *skb,
@@ -1481,7 +1460,7 @@ static __inline__ void __tcp_push_pending_frames(struct sock *sk,
                                                 unsigned cur_mss,
                                                 int nonagle)
 {
-       struct sk_buff *skb = tp->send_head;
+       struct sk_buff *skb = sk->sk_send_head;
 
        if (skb) {
                if (!tcp_skb_is_last(sk, skb))
@@ -1501,7 +1480,7 @@ static __inline__ void tcp_push_pending_frames(struct sock *sk,
 
 static __inline__ int tcp_may_send_now(struct sock *sk, struct tcp_opt *tp)
 {
-       struct sk_buff *skb = tp->send_head;
+       struct sk_buff *skb = sk->sk_send_head;
 
        return (skb &&
                tcp_snd_test(tp, skb, tcp_current_mss(sk, 1),
@@ -1574,7 +1553,7 @@ static __inline__ int tcp_prequeue(struct sock *sk, struct sk_buff *skb)
 
                        while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) {
                                sk->sk_backlog_rcv(sk, skb1);
-                               NET_INC_STATS_BH(TCPPrequeueDropped);
+                               NET_INC_STATS_BH(LINUX_MIB_TCPPREQUEUEDROPPED);
                        }
 
                        tp->ucopy.memory = 0;
@@ -1606,12 +1585,12 @@ static __inline__ void tcp_set_state(struct sock *sk, int state)
        switch (state) {
        case TCP_ESTABLISHED:
                if (oldstate != TCP_ESTABLISHED)
-                       TCP_INC_STATS(TcpCurrEstab);
+                       TCP_INC_STATS(TCP_MIB_CURRESTAB);
                break;
 
        case TCP_CLOSE:
                if (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED)
-                       TCP_INC_STATS(TcpEstabResets);
+                       TCP_INC_STATS(TCP_MIB_ESTABRESETS);
 
                sk->sk_prot->unhash(sk);
                if (tcp_sk(sk)->bind_hash &&
@@ -1620,7 +1599,7 @@ static __inline__ void tcp_set_state(struct sock *sk, int state)
                /* fall through */
        default:
                if (oldstate==TCP_ESTABLISHED)
-                       TCP_DEC_STATS(TcpCurrEstab);
+                       TCP_DEC_STATS(TCP_MIB_CURRESTAB);
        }
 
        /* Change state AFTER socket is unhashed to avoid closed
@@ -1803,28 +1782,90 @@ static inline int tcp_full_space( struct sock *sk)
        return tcp_win_from_space(sk->sk_rcvbuf); 
 }
 
-static inline void tcp_acceptq_removed(struct sock *sk)
+struct tcp_listen_opt
 {
-       sk->sk_ack_backlog--;
+       u8                      max_qlen_log;   /* log_2 of maximal queued SYNs */
+       int                     qlen;
+#ifdef CONFIG_ACCEPT_QUEUES
+       int                     qlen_young[NUM_ACCEPT_QUEUES];
+#else
+       int                     qlen_young;
+#endif
+       int                     clock_hand;
+       u32                     hash_rnd;
+       struct open_request     *syn_table[TCP_SYNQ_HSIZE];
+};
+
+#ifdef CONFIG_ACCEPT_QUEUES
+static inline void sk_acceptq_removed(struct sock *sk, int class)
+{
+       tcp_sk(sk)->acceptq[class].aq_backlog--;
 }
 
-static inline void tcp_acceptq_added(struct sock *sk)
+static inline void sk_acceptq_added(struct sock *sk, int class)
 {
-       sk->sk_ack_backlog++;
+       tcp_sk(sk)->acceptq[class].aq_backlog++;
 }
 
-static inline int tcp_acceptq_is_full(struct sock *sk)
+static inline int sk_acceptq_is_full(struct sock *sk, int class)
 {
-       return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
+       return tcp_sk(sk)->acceptq[class].aq_backlog >
+               sk->sk_max_ack_backlog;
 }
 
+static inline void tcp_set_acceptq(struct tcp_opt *tp, struct open_request *req)
+{
+       int class = req->acceptq_class;
+       int prev_class;
+
+       if (!tp->acceptq[class].aq_ratio) {
+               req->acceptq_class = 0;
+               class = 0;
+       }
+
+       tp->acceptq[class].aq_qcount++;
+       req->acceptq_time_stamp = jiffies;
+
+       if (tp->acceptq[class].aq_tail) {
+               req->dl_next = tp->acceptq[class].aq_tail->dl_next;
+               tp->acceptq[class].aq_tail->dl_next = req;
+               tp->acceptq[class].aq_tail = req;
+       } else { /* if first request in the class */
+               tp->acceptq[class].aq_head = req;
+               tp->acceptq[class].aq_tail = req;
+
+               prev_class = class - 1;
+               while (prev_class >= 0) {
+                       if (tp->acceptq[prev_class].aq_tail)
+                               break;
+                       prev_class--;
+               }
+               if (prev_class < 0) {
+                       req->dl_next = tp->accept_queue;
+                       tp->accept_queue = req;
+               }
+               else {
+                       req->dl_next = tp->acceptq[prev_class].aq_tail->dl_next;
+                       tp->acceptq[prev_class].aq_tail->dl_next = req;
+               }
+       }
+}
+static inline void tcp_acceptq_queue(struct sock *sk, struct open_request *req,
+                                        struct sock *child)
+{
+       tcp_set_acceptq(tcp_sk(sk),req);
+       req->sk = child;
+       sk_acceptq_added(sk,req->acceptq_class);
+}
+
+#else
 static inline void tcp_acceptq_queue(struct sock *sk, struct open_request *req,
                                         struct sock *child)
 {
        struct tcp_opt *tp = tcp_sk(sk);
 
        req->sk = child;
-       tcp_acceptq_added(sk);
+       sk_acceptq_added(sk);
 
        if (!tp->accept_queue_tail) {
                tp->accept_queue = req;
@@ -1835,15 +1876,41 @@ static inline void tcp_acceptq_queue(struct sock *sk, struct open_request *req,
        req->dl_next = NULL;
 }
 
-struct tcp_listen_opt
+#endif
+
+
+#ifdef CONFIG_ACCEPT_QUEUES
+static inline void
+tcp_synq_removed(struct sock *sk, struct open_request *req)
 {
-       u8                      max_qlen_log;   /* log_2 of maximal queued SYNs */
-       int                     qlen;
-       int                     qlen_young;
-       int                     clock_hand;
-       u32                     hash_rnd;
-       struct open_request     *syn_table[TCP_SYNQ_HSIZE];
-};
+       struct tcp_listen_opt *lopt = tcp_sk(sk)->listen_opt;
+
+       if (--lopt->qlen == 0)
+               tcp_delete_keepalive_timer(sk);
+       if (req->retrans == 0)
+               lopt->qlen_young[req->acceptq_class]--;
+}
+
+static inline void tcp_synq_added(struct sock *sk, struct open_request *req)
+{
+       struct tcp_listen_opt *lopt = tcp_sk(sk)->listen_opt;
+
+       if (lopt->qlen++ == 0)
+               tcp_reset_keepalive_timer(sk, TCP_TIMEOUT_INIT);
+       lopt->qlen_young[req->acceptq_class]++;
+}
+
+static inline int tcp_synq_len(struct sock *sk)
+{
+       return tcp_sk(sk)->listen_opt->qlen;
+}
+
+static inline int tcp_synq_young(struct sock *sk, int class)
+{
+       return tcp_sk(sk)->listen_opt->qlen_young[class];
+}
+
+#else
 
 static inline void
 tcp_synq_removed(struct sock *sk, struct open_request *req)
@@ -1874,6 +1941,7 @@ static inline int tcp_synq_young(struct sock *sk)
 {
        return tcp_sk(sk)->listen_opt->qlen_young;
 }
+#endif
 
 static inline int tcp_synq_is_full(struct sock *sk)
 {
@@ -1913,102 +1981,7 @@ static __inline__ void tcp_openreq_init(struct open_request *req,
        req->rmt_port = skb->h.th->source;
 }
 
-#define TCP_MEM_QUANTUM        ((int)PAGE_SIZE)
-
-static inline void tcp_free_skb(struct sock *sk, struct sk_buff *skb)
-{
-       tcp_sk(sk)->queue_shrunk = 1;
-       sk->sk_wmem_queued -= skb->truesize;
-       sk->sk_forward_alloc += skb->truesize;
-       __kfree_skb(skb);
-}
-
-static inline void tcp_charge_skb(struct sock *sk, struct sk_buff *skb)
-{
-       sk->sk_wmem_queued += skb->truesize;
-       sk->sk_forward_alloc -= skb->truesize;
-}
-
-extern void __tcp_mem_reclaim(struct sock *sk);
-extern int tcp_mem_schedule(struct sock *sk, int size, int kind);
-
-static inline void tcp_mem_reclaim(struct sock *sk)
-{
-       if (sk->sk_forward_alloc >= TCP_MEM_QUANTUM)
-               __tcp_mem_reclaim(sk);
-}
-
-static inline void tcp_enter_memory_pressure(void)
-{
-       if (!tcp_memory_pressure) {
-               NET_INC_STATS(TCPMemoryPressures);
-               tcp_memory_pressure = 1;
-       }
-}
-
-static inline void tcp_moderate_sndbuf(struct sock *sk)
-{
-       if (!(sk->sk_userlocks & SOCK_SNDBUF_LOCK)) {
-               sk->sk_sndbuf = min(sk->sk_sndbuf, sk->sk_wmem_queued / 2);
-               sk->sk_sndbuf = max(sk->sk_sndbuf, SOCK_MIN_SNDBUF);
-       }
-}
-
-static inline struct sk_buff *tcp_alloc_pskb(struct sock *sk, int size, int mem, int gfp)
-{
-       struct sk_buff *skb = alloc_skb(size+MAX_TCP_HEADER, gfp);
-
-       if (skb) {
-               skb->truesize += mem;
-               if (sk->sk_forward_alloc >= (int)skb->truesize ||
-                   tcp_mem_schedule(sk, skb->truesize, 0)) {
-                       skb_reserve(skb, MAX_TCP_HEADER);
-                       return skb;
-               }
-               __kfree_skb(skb);
-       } else {
-               tcp_enter_memory_pressure();
-               tcp_moderate_sndbuf(sk);
-       }
-       return NULL;
-}
-
-static inline struct sk_buff *tcp_alloc_skb(struct sock *sk, int size, int gfp)
-{
-       return tcp_alloc_pskb(sk, size, 0, gfp);
-}
-
-static inline struct page * tcp_alloc_page(struct sock *sk)
-{
-       if (sk->sk_forward_alloc >= (int)PAGE_SIZE ||
-           tcp_mem_schedule(sk, PAGE_SIZE, 0)) {
-               struct page *page = alloc_pages(sk->sk_allocation, 0);
-               if (page)
-                       return page;
-       }
-       tcp_enter_memory_pressure();
-       tcp_moderate_sndbuf(sk);
-       return NULL;
-}
-
-static inline void tcp_writequeue_purge(struct sock *sk)
-{
-       struct sk_buff *skb;
-
-       while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
-               tcp_free_skb(sk, skb);
-       tcp_mem_reclaim(sk);
-}
-
-extern void tcp_rfree(struct sk_buff *skb);
-
-static inline void tcp_set_owner_r(struct sk_buff *skb, struct sock *sk)
-{
-       skb->sk = sk;
-       skb->destructor = tcp_rfree;
-       atomic_add(skb->truesize, &sk->sk_rmem_alloc);
-       sk->sk_forward_alloc -= skb->truesize;
-}
+extern void tcp_enter_memory_pressure(void);
 
 extern void tcp_listen_wlock(void);
 
@@ -2094,18 +2067,18 @@ static inline int tcp_use_frto(const struct sock *sk)
         * unsent new data, and the advertised window should allow
         * sending it.
         */
-       return (sysctl_tcp_frto && tp->send_head &&
-               !after(TCP_SKB_CB(tp->send_head)->end_seq,
+       return (sysctl_tcp_frto && sk->sk_send_head &&
+               !after(TCP_SKB_CB(sk->sk_send_head)->end_seq,
                       tp->snd_una + tp->snd_wnd));
 }
 
 static inline void tcp_mib_init(void)
 {
        /* See RFC 2012 */
-       TCP_ADD_STATS_USER(TcpRtoAlgorithm, 1);
-       TCP_ADD_STATS_USER(TcpRtoMin, TCP_RTO_MIN*1000/HZ);
-       TCP_ADD_STATS_USER(TcpRtoMax, TCP_RTO_MAX*1000/HZ);
-       TCP_ADD_STATS_USER(TcpMaxConn, -1);
+       TCP_ADD_STATS_USER(TCP_MIB_RTOALGORITHM, 1);
+       TCP_ADD_STATS_USER(TCP_MIB_RTOMIN, TCP_RTO_MIN*1000/HZ);
+       TCP_ADD_STATS_USER(TCP_MIB_RTOMAX, TCP_RTO_MAX*1000/HZ);
+       TCP_ADD_STATS_USER(TCP_MIB_MAXCONN, -1);
 }
 
 /* /proc */