diff mbox series

[v5,2/2] net: make tcp keepalive timer upper bound

Message ID 20220505131811.3744503-3-asavkov@redhat.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series Upper bound kernel timers | expand

Checks

Context Check Description
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 5 this patch: 5
netdev/cc_maintainers warning 3 maintainers not CCed: kuba@kernel.org edumazet@google.com pabeni@redhat.com
netdev/build_clang success Errors and warnings before: 9 this patch: 9
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 5 this patch: 5
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 8 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/tree_selection success Guessing tree name failed - patch did not apply

Commit Message

Artem Savkov May 5, 2022, 1:18 p.m. UTC
Make sure TCP keepalive timer does not expire late. Switching to upper
bound timers means it can fire off early but in case of keepalive
tcp_keepalive_timer() handler checks elapsed time and resets the timer
if it was triggered early. This results in timer "cascading" to a
higher precision and being just a couple of milliseconds off it's
original mark.
This adds minimal overhead as keepalive timers are never re-armed and
are usually quite long.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
---
 net/ipv4/inet_connection_sock.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Josh Poimboeuf May 5, 2022, 5:56 p.m. UTC | #1
On Thu, May 05, 2022 at 03:18:11PM +0200, Artem Savkov wrote:
> Make sure TCP keepalive timer does not expire late. Switching to upper
> bound timers means it can fire off early but in case of keepalive
> tcp_keepalive_timer() handler checks elapsed time and resets the timer
> if it was triggered early. This results in timer "cascading" to a
> higher precision and being just a couple of milliseconds off it's
> original mark.
> This adds minimal overhead as keepalive timers are never re-armed and
> are usually quite long.
> 
> Signed-off-by: Artem Savkov <asavkov@redhat.com>
> ---
>  net/ipv4/inet_connection_sock.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
> index 1e5b53c2bb26..bb2dbfb6f5b5 100644
> --- a/net/ipv4/inet_connection_sock.c
> +++ b/net/ipv4/inet_connection_sock.c
> @@ -589,7 +589,7 @@ EXPORT_SYMBOL(inet_csk_delete_keepalive_timer);
>  
>  void inet_csk_reset_keepalive_timer(struct sock *sk, unsigned long len)
>  {
> -	sk_reset_timer(sk, &sk->sk_timer, jiffies + len);
> +	sk_reset_timer(sk, &sk->sk_timer, jiffies + upper_bound_timeout(len));
>  }
>  EXPORT_SYMBOL(inet_csk_reset_keepalive_timer);

As I mentioned before, there might be two sides to the same coin,
depending on whether the keepalive is detecting vs preventing the
disconnect.  So this might possibly fix one case, while breaking
another.

Hopefully a networking expert can chime in.
Artem Savkov May 6, 2022, 6:39 a.m. UTC | #2
On Thu, May 05, 2022 at 10:56:54AM -0700, Josh Poimboeuf wrote:
> On Thu, May 05, 2022 at 03:18:11PM +0200, Artem Savkov wrote:
> > Make sure TCP keepalive timer does not expire late. Switching to upper
> > bound timers means it can fire off early but in case of keepalive
> > tcp_keepalive_timer() handler checks elapsed time and resets the timer
> > if it was triggered early. This results in timer "cascading" to a
> > higher precision and being just a couple of milliseconds off it's
> > original mark.
> > This adds minimal overhead as keepalive timers are never re-armed and
> > are usually quite long.
> > 
> > Signed-off-by: Artem Savkov <asavkov@redhat.com>
> > ---
> >  net/ipv4/inet_connection_sock.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
> > index 1e5b53c2bb26..bb2dbfb6f5b5 100644
> > --- a/net/ipv4/inet_connection_sock.c
> > +++ b/net/ipv4/inet_connection_sock.c
> > @@ -589,7 +589,7 @@ EXPORT_SYMBOL(inet_csk_delete_keepalive_timer);
> >  
> >  void inet_csk_reset_keepalive_timer(struct sock *sk, unsigned long len)
> >  {
> > -	sk_reset_timer(sk, &sk->sk_timer, jiffies + len);
> > +	sk_reset_timer(sk, &sk->sk_timer, jiffies + upper_bound_timeout(len));
> >  }
> >  EXPORT_SYMBOL(inet_csk_reset_keepalive_timer);
> 
> As I mentioned before, there might be two sides to the same coin,
> depending on whether the keepalive is detecting vs preventing the
> disconnect.  So this might possibly fix one case, while breaking
> another.

But cascading is still there in the handler so it will fire off quite
close to original timer in any case.
Josh Poimboeuf May 6, 2022, 4:24 p.m. UTC | #3
On Fri, May 06, 2022 at 08:39:08AM +0200, Artem Savkov wrote:
> On Thu, May 05, 2022 at 10:56:54AM -0700, Josh Poimboeuf wrote:
> > On Thu, May 05, 2022 at 03:18:11PM +0200, Artem Savkov wrote:
> > > Make sure TCP keepalive timer does not expire late. Switching to upper
> > > bound timers means it can fire off early but in case of keepalive
> > > tcp_keepalive_timer() handler checks elapsed time and resets the timer
> > > if it was triggered early. This results in timer "cascading" to a
> > > higher precision and being just a couple of milliseconds off it's
> > > original mark.
> > > This adds minimal overhead as keepalive timers are never re-armed and
> > > are usually quite long.
> > > 
> > > Signed-off-by: Artem Savkov <asavkov@redhat.com>
> > > ---
> > >  net/ipv4/inet_connection_sock.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
> > > index 1e5b53c2bb26..bb2dbfb6f5b5 100644
> > > --- a/net/ipv4/inet_connection_sock.c
> > > +++ b/net/ipv4/inet_connection_sock.c
> > > @@ -589,7 +589,7 @@ EXPORT_SYMBOL(inet_csk_delete_keepalive_timer);
> > >  
> > >  void inet_csk_reset_keepalive_timer(struct sock *sk, unsigned long len)
> > >  {
> > > -	sk_reset_timer(sk, &sk->sk_timer, jiffies + len);
> > > +	sk_reset_timer(sk, &sk->sk_timer, jiffies + upper_bound_timeout(len));
> > >  }
> > >  EXPORT_SYMBOL(inet_csk_reset_keepalive_timer);
> > 
> > As I mentioned before, there might be two sides to the same coin,
> > depending on whether the keepalive is detecting vs preventing the
> > disconnect.  So this might possibly fix one case, while breaking
> > another.
> 
> But cascading is still there in the handler so it will fire off quite
> close to original timer in any case.

Ah, indeed it does.  Sorry, I should try actually reading the patch
description next time :-/ Looks good to me.

Reviewed-by: Josh Poimboeuf <jpoimboe@kernel.org>
diff mbox series

Patch

diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 1e5b53c2bb26..bb2dbfb6f5b5 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -589,7 +589,7 @@  EXPORT_SYMBOL(inet_csk_delete_keepalive_timer);
 
 void inet_csk_reset_keepalive_timer(struct sock *sk, unsigned long len)
 {
-	sk_reset_timer(sk, &sk->sk_timer, jiffies + len);
+	sk_reset_timer(sk, &sk->sk_timer, jiffies + upper_bound_timeout(len));
 }
 EXPORT_SYMBOL(inet_csk_reset_keepalive_timer);