Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UCT/TCP: Increase keepalive interval from 1 to 2 seconds and use system default for keepalive retries count #7093

Merged
merged 1 commit into from
Jul 15, 2021

Conversation

dmitrygx
Copy link
Member

@dmitrygx dmitrygx commented Jul 13, 2021

What

Increase keepalive interval from 1 to 2 seconds and use system default for keepalive retries count.

Why ?

Fixes #6705.
Fixes #6471.
When the large amount of connections are started simultaneously, it leads to network congestions and some TCP EPs are failed, because they don't receive ACK on previously sent KEEPALIVE packet. Increasing timeout helps to resolve the issue. 1s timeout between retries is too small one.

How ?

  1. Change value of UCT_TCP_EP_DEFAULT_KEEPALIVE_INTVL from 1 to 2.
  2. Update KEEPCNT configuration parameter to be ULUNITS and set "auto" as a default value. Handle it when setting socket options for KA.

@@ -65,7 +65,7 @@
#define UCT_TCP_EP_DEFAULT_KEEPALIVE_IDLE 10

/* The seconds between individual keepalive probes */
#define UCT_TCP_EP_DEFAULT_KEEPALIVE_INTVL 1
#define UCT_TCP_EP_DEFAULT_KEEPALIVE_INTVL 10
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't TCP get the interval from UCP layer?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't TCP get the interval from UCP layer?

we should get the interval from UCP layer for UCT_TCP_EP_DEFAULT_KEEPALIVE_IDLE - this parameter configures interval for starting KA if TCP socket is idle

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the difference between them? maybe we should set both?

Copy link
Member Author

@dmitrygx dmitrygx Jul 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the difference between them? maybe we should set both?

UCT_TCP_EP_DEFAULT_KEEPALIVE_INTVL is interval between retries when the KA started.
UCT_TCP_EP_DEFAULT_KEEPALIVE_IDLE is interval between last packet with user data and first KA message. The first KA message is sent if socket is idle.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

after KEEPALIVE_IDLE timeout kernel starts ping peer every KEEPALIVE_INTVL seconds till get response, after this kernel waits for KEEPALIVE_IDLE again

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

after KEEPALIVE_IDLE timeout kernel starts ping peer every KEEPALIVE_INTVL seconds till get response, after this kernel waits for KEEPALIVE_IDLE again

so it seems that if we set both IDLE and INVL to same value as UCP keepalive interval, the behavior will be similar to other transports which use ep_check, where each ep_check is sent after same amount of time

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I agree. Let's implement through extending uct_iface_open() API for built-in keepalive case?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, but here is issue: UCP KA may stop after N endpoints, but TCP KA will ping all EPs simultaneously.
that is why we didn't merge these values before.
not sure if this is issue, but there is different behaviour for timeouts

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UCP KA may stop after N endpoints, but TCP KA will ping all EPs simultaneously.

I see, this can happen

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ucs_time_t keepalive_interval;

@dmitrygx dmitrygx changed the title UCT/TCP: Increase keepalive interval from 1 to 10 seconds UCT/TCP: Increase keepalive interval from 1 to 2 seconds and use system default for keepalive retries count Jul 14, 2021
@@ -440,7 +440,7 @@ typedef struct uct_tcp_iface_config {
ucs_range_spec_t port_range;
struct {
ucs_time_t idle;
unsigned cnt;
size_t cnt;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unsigned long

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -402,7 +402,7 @@ typedef struct uct_tcp_iface {
ucs_time_t idle; /* The time the connection needs to remain
* idle before TCP starts sending keepalive
* probes (TCP_KEEPIDLE socket option) */
unsigned cnt; /* The maximum number of keepalive probes TCP
size_t cnt; /* The maximum number of keepalive probes TCP
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unsigned long

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -872,7 +872,7 @@ int uct_tcp_keepalive_is_enabled(uct_tcp_iface_t *iface)
{
#ifdef UCT_TCP_EP_KEEPALIVE
return (iface->config.keepalive.idle != UCS_TIME_INFINITY) &&
(iface->config.keepalive.cnt != 0) &&
(iface->config.keepalive.cnt != UCS_ULUNITS_INF) &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why changed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since, 0 is valid value and means no need to retry, fail immediately.
we should use inf as for other configuration parameters.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to document this in config param desc?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

if (time_val == UCS_TIME_AUTO) {
return auto_val;
}

return ucs_max(1, (int)ucs_time_to_sec(time_val));
time_sec = ucs_time_to_sec(time_val);
if ((time_val == UCS_TIME_INFINITY) || (time_sec >= (double)INT_MAX)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (time_val == AUTO)
 return AUTO_VAL
} else if (time_val == INFINITY)
  return INT_MAX
} else {
  return ucs_min(INT_MAX, ucs_max(1l, ucs_time_to_sec(time_val));
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -527,9 +535,13 @@ static ucs_status_t uct_tcp_ep_keepalive_enable(uct_tcp_ep_t *ep)
}

if (iface->config.keepalive.cnt != UCS_ULUNITS_AUTO) {
if ((iface->config.keepalive.cnt == UCS_ULUNITS_INF) ||
(iface->config.keepalive.cnt >= (unsigned long)keepalive_cnt)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems keepalive_cnt can be un initialized here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, fixed

if (time_val == UCS_TIME_AUTO) {
return auto_val;
} else if (time_val == UCS_TIME_INFINITY) {
return INT16_MAX;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe pass max_val?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 534 to 537
(iface->config.keepalive.cnt > INT8_MAX)) {
keepalive_cnt = INT8_MAX;
} else {
keepalive_cnt = (uint8_t)iface->config.keepalive.cnt;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keepalive_cnt = ucs_min(INT8_MAX, iface->config.keepalive.cnt)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@dmitrygx
Copy link
Member Author

@yosefe is it ok now?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants