Add a helper to directly set the TCP_KEEPINTVL sockopt from kernel space without going through a fake uaccess.
Unified · Split
| @@ -499,6 +499,7 @@ int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from, int pcount, · 498 unmodified lines | |||
| 499 | 499 | ||
| 500 | void tcp_sock_set_cork(struct sock *sk, bool on); | 500 | void tcp_sock_set_cork(struct sock *sk, bool on); |
| 501 | int tcp_sock_set_keepidle(struct sock *sk, int val); | 501 | int tcp_sock_set_keepidle(struct sock *sk, int val); |
| 502 | int tcp_sock_set_keepintvl(struct sock *sk, int val); | ||
| 502 | void tcp_sock_set_nodelay(struct sock *sk); | 503 | void tcp_sock_set_nodelay(struct sock *sk); |
| 503 | void tcp_sock_set_quickack(struct sock *sk, int val); | 504 | void tcp_sock_set_quickack(struct sock *sk, int val); |
| 504 | int tcp_sock_set_syncnt(struct sock *sk, int val); | 505 | int tcp_sock_set_syncnt(struct sock *sk, int val); |
| @@ -2934,6 +2934,18 @@ int tcp_sock_set_keepidle(struct sock *sk, int val) · 2933 unmodified lines | |||
| 2934 | } | 2934 | } |
| 2935 | EXPORT_SYMBOL(tcp_sock_set_keepidle); | 2935 | EXPORT_SYMBOL(tcp_sock_set_keepidle); |
| 2936 | 2936 | ||
| 2937 | int tcp_sock_set_keepintvl(struct sock *sk, int val) | ||
| 2938 | { | ||
| 2939 | if (val < 1 || val > MAX_TCP_KEEPINTVL) | ||
| 2940 | return -EINVAL; | ||
| 2941 | |||
| 2942 | lock_sock(sk); | ||
| 2943 | tcp_sk(sk)->keepalive_intvl = val * HZ; | ||
| 2944 | release_sock(sk); | ||
| 2945 | return 0; | ||
| 2946 | } | ||
| 2947 | EXPORT_SYMBOL(tcp_sock_set_keepintvl); | ||
| 2948 | |||
| 2937 | /* | 2949 | /* |
| 2938 | * Socket option code for TCP. | 2950 | * Socket option code for TCP. |
| 2939 | */ | 2951 | */ |
| @@ -53,12 +53,10 @@ int rds_tcp_keepalive(struct socket *sock) · 52 unmodified lines | |||
| 53 | goto bail; | 53 | goto bail; |
| 54 | 54 | ||
| 55 | tcp_sock_set_keepidle(sock->sk, keepidle); | 55 | tcp_sock_set_keepidle(sock->sk, keepidle); |
| 56 | |||
| 57 | /* KEEPINTVL is the interval between successive probes. We follow | 56 | /* KEEPINTVL is the interval between successive probes. We follow |
| 58 | * the model in xs_tcp_finish_connecting() and re-use keepidle. | 57 | * the model in xs_tcp_finish_connecting() and re-use keepidle. |
| 59 | */ | 58 | */ |
| 60 | ret = kernel_setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, | 59 | tcp_sock_set_keepintvl(sock->sk, keepidle); |
| 61 | (char *)&keepidle, sizeof(keepidle)); | ||
| 62 | bail: | 60 | bail: |
| 63 | return ret; | 61 | return ret; |
| 64 | } | 62 | } |
| @@ -2108,8 +2108,7 @@ static void xs_tcp_set_socket_timeouts(struct rpc_xprt *xprt, · 2107 unmodified lines | |||
| 2108 | /* TCP Keepalive options */ | 2108 | /* TCP Keepalive options */ |
| 2109 | sock_set_keepalive(sock->sk); | 2109 | sock_set_keepalive(sock->sk); |
| 2110 | tcp_sock_set_keepidle(sock->sk, keepidle); | 2110 | tcp_sock_set_keepidle(sock->sk, keepidle); |
| 2111 | kernel_setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, | 2111 | tcp_sock_set_keepintvl(sock->sk, keepidle); |
| 2112 | (char *)&keepidle, sizeof(keepidle)); | ||
| 2113 | kernel_setsockopt(sock, SOL_TCP, TCP_KEEPCNT, | 2112 | kernel_setsockopt(sock, SOL_TCP, TCP_KEEPCNT, |
| 2114 | (char *)&keepcnt, sizeof(keepcnt)); | 2113 | (char *)&keepcnt, sizeof(keepcnt)); |
| 2115 | 2114 | ||