diff options
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r-- | net/ipv4/tcp.c | 55 |
1 files changed, 35 insertions, 20 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 0f8caf64caa3..6596b4feeddc 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -378,7 +378,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
378 | struct sock *sk = sock->sk; | 378 | struct sock *sk = sock->sk; |
379 | struct tcp_sock *tp = tcp_sk(sk); | 379 | struct tcp_sock *tp = tcp_sk(sk); |
380 | 380 | ||
381 | sock_poll_wait(file, sk->sk_sleep, wait); | 381 | sock_poll_wait(file, sk_sleep(sk), wait); |
382 | if (sk->sk_state == TCP_LISTEN) | 382 | if (sk->sk_state == TCP_LISTEN) |
383 | return inet_csk_listen_poll(sk); | 383 | return inet_csk_listen_poll(sk); |
384 | 384 | ||
@@ -2215,7 +2215,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
2215 | default: | 2215 | default: |
2216 | /* fallthru */ | 2216 | /* fallthru */ |
2217 | break; | 2217 | break; |
2218 | }; | 2218 | } |
2219 | 2219 | ||
2220 | if (optlen < sizeof(int)) | 2220 | if (optlen < sizeof(int)) |
2221 | return -EINVAL; | 2221 | return -EINVAL; |
@@ -2298,7 +2298,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
2298 | if (sock_flag(sk, SOCK_KEEPOPEN) && | 2298 | if (sock_flag(sk, SOCK_KEEPOPEN) && |
2299 | !((1 << sk->sk_state) & | 2299 | !((1 << sk->sk_state) & |
2300 | (TCPF_CLOSE | TCPF_LISTEN))) { | 2300 | (TCPF_CLOSE | TCPF_LISTEN))) { |
2301 | __u32 elapsed = tcp_time_stamp - tp->rcv_tstamp; | 2301 | u32 elapsed = keepalive_time_elapsed(tp); |
2302 | if (tp->keepalive_time > elapsed) | 2302 | if (tp->keepalive_time > elapsed) |
2303 | elapsed = tp->keepalive_time - elapsed; | 2303 | elapsed = tp->keepalive_time - elapsed; |
2304 | else | 2304 | else |
@@ -2721,7 +2721,7 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
2721 | struct tcphdr *th2; | 2721 | struct tcphdr *th2; |
2722 | unsigned int len; | 2722 | unsigned int len; |
2723 | unsigned int thlen; | 2723 | unsigned int thlen; |
2724 | unsigned int flags; | 2724 | __be32 flags; |
2725 | unsigned int mss = 1; | 2725 | unsigned int mss = 1; |
2726 | unsigned int hlen; | 2726 | unsigned int hlen; |
2727 | unsigned int off; | 2727 | unsigned int off; |
@@ -2771,10 +2771,10 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
2771 | 2771 | ||
2772 | found: | 2772 | found: |
2773 | flush = NAPI_GRO_CB(p)->flush; | 2773 | flush = NAPI_GRO_CB(p)->flush; |
2774 | flush |= flags & TCP_FLAG_CWR; | 2774 | flush |= (__force int)(flags & TCP_FLAG_CWR); |
2775 | flush |= (flags ^ tcp_flag_word(th2)) & | 2775 | flush |= (__force int)((flags ^ tcp_flag_word(th2)) & |
2776 | ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH); | 2776 | ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH)); |
2777 | flush |= th->ack_seq ^ th2->ack_seq; | 2777 | flush |= (__force int)(th->ack_seq ^ th2->ack_seq); |
2778 | for (i = sizeof(*th); i < thlen; i += 4) | 2778 | for (i = sizeof(*th); i < thlen; i += 4) |
2779 | flush |= *(u32 *)((u8 *)th + i) ^ | 2779 | flush |= *(u32 *)((u8 *)th + i) ^ |
2780 | *(u32 *)((u8 *)th2 + i); | 2780 | *(u32 *)((u8 *)th2 + i); |
@@ -2795,8 +2795,9 @@ found: | |||
2795 | 2795 | ||
2796 | out_check_final: | 2796 | out_check_final: |
2797 | flush = len < mss; | 2797 | flush = len < mss; |
2798 | flush |= flags & (TCP_FLAG_URG | TCP_FLAG_PSH | TCP_FLAG_RST | | 2798 | flush |= (__force int)(flags & (TCP_FLAG_URG | TCP_FLAG_PSH | |
2799 | TCP_FLAG_SYN | TCP_FLAG_FIN); | 2799 | TCP_FLAG_RST | TCP_FLAG_SYN | |
2800 | TCP_FLAG_FIN)); | ||
2800 | 2801 | ||
2801 | if (p && (!NAPI_GRO_CB(skb)->same_flow || flush)) | 2802 | if (p && (!NAPI_GRO_CB(skb)->same_flow || flush)) |
2802 | pp = head; | 2803 | pp = head; |
@@ -2839,7 +2840,6 @@ static void __tcp_free_md5sig_pool(struct tcp_md5sig_pool * __percpu *pool) | |||
2839 | if (p->md5_desc.tfm) | 2840 | if (p->md5_desc.tfm) |
2840 | crypto_free_hash(p->md5_desc.tfm); | 2841 | crypto_free_hash(p->md5_desc.tfm); |
2841 | kfree(p); | 2842 | kfree(p); |
2842 | p = NULL; | ||
2843 | } | 2843 | } |
2844 | } | 2844 | } |
2845 | free_percpu(pool); | 2845 | free_percpu(pool); |
@@ -2937,25 +2937,40 @@ retry: | |||
2937 | 2937 | ||
2938 | EXPORT_SYMBOL(tcp_alloc_md5sig_pool); | 2938 | EXPORT_SYMBOL(tcp_alloc_md5sig_pool); |
2939 | 2939 | ||
2940 | struct tcp_md5sig_pool *__tcp_get_md5sig_pool(int cpu) | 2940 | |
2941 | /** | ||
2942 | * tcp_get_md5sig_pool - get md5sig_pool for this user | ||
2943 | * | ||
2944 | * We use percpu structure, so if we succeed, we exit with preemption | ||
2945 | * and BH disabled, to make sure another thread or softirq handling | ||
2946 | * wont try to get same context. | ||
2947 | */ | ||
2948 | struct tcp_md5sig_pool *tcp_get_md5sig_pool(void) | ||
2941 | { | 2949 | { |
2942 | struct tcp_md5sig_pool * __percpu *p; | 2950 | struct tcp_md5sig_pool * __percpu *p; |
2943 | spin_lock_bh(&tcp_md5sig_pool_lock); | 2951 | |
2952 | local_bh_disable(); | ||
2953 | |||
2954 | spin_lock(&tcp_md5sig_pool_lock); | ||
2944 | p = tcp_md5sig_pool; | 2955 | p = tcp_md5sig_pool; |
2945 | if (p) | 2956 | if (p) |
2946 | tcp_md5sig_users++; | 2957 | tcp_md5sig_users++; |
2947 | spin_unlock_bh(&tcp_md5sig_pool_lock); | 2958 | spin_unlock(&tcp_md5sig_pool_lock); |
2948 | return (p ? *per_cpu_ptr(p, cpu) : NULL); | 2959 | |
2949 | } | 2960 | if (p) |
2961 | return *per_cpu_ptr(p, smp_processor_id()); | ||
2950 | 2962 | ||
2951 | EXPORT_SYMBOL(__tcp_get_md5sig_pool); | 2963 | local_bh_enable(); |
2964 | return NULL; | ||
2965 | } | ||
2966 | EXPORT_SYMBOL(tcp_get_md5sig_pool); | ||
2952 | 2967 | ||
2953 | void __tcp_put_md5sig_pool(void) | 2968 | void tcp_put_md5sig_pool(void) |
2954 | { | 2969 | { |
2970 | local_bh_enable(); | ||
2955 | tcp_free_md5sig_pool(); | 2971 | tcp_free_md5sig_pool(); |
2956 | } | 2972 | } |
2957 | 2973 | EXPORT_SYMBOL(tcp_put_md5sig_pool); | |
2958 | EXPORT_SYMBOL(__tcp_put_md5sig_pool); | ||
2959 | 2974 | ||
2960 | int tcp_md5_hash_header(struct tcp_md5sig_pool *hp, | 2975 | int tcp_md5_hash_header(struct tcp_md5sig_pool *hp, |
2961 | struct tcphdr *th) | 2976 | struct tcphdr *th) |