2022-05-06 06:21:02

by Artem Savkov

[permalink] [raw]
Subject: [PATCH v5 2/2] net: make tcp keepalive timer upper bound

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 <[email protected]>
---
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);

--
2.34.1



2022-05-07 05:26:28

by Josh Poimboeuf

[permalink] [raw]
Subject: Re: [PATCH v5 2/2] net: make tcp keepalive timer upper bound

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 <[email protected]>
> > > ---
> > > 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 <[email protected]>

--
Josh

2022-05-07 08:05:22

by Josh Poimboeuf

[permalink] [raw]
Subject: Re: [PATCH v5 2/2] net: make tcp keepalive timer upper bound

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 <[email protected]>
> ---
> 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.

--
Josh

2022-05-09 03:39:38

by Artem Savkov

[permalink] [raw]
Subject: Re: [PATCH v5 2/2] net: make tcp keepalive timer upper bound

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 <[email protected]>
> > ---
> > 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.


--
Artem