]> git.proxmox.com Git - mirror_kronosnet.git/commitdiff
[latency] fix incorrect math that could lead to bad latency calculation
authorFabio M. Di Nitto <fdinitto@redhat.com>
Wed, 29 Jan 2020 15:02:46 +0000 (16:02 +0100)
committerFabio M. Di Nitto <fdinitto@redhat.com>
Thu, 30 Jan 2020 11:31:14 +0000 (12:31 +0100)
Also, document a bit better how latency is calculated

Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
libknet/internals.h
libknet/links.c
libknet/tests/api_knet_link_set_ping_timers.c
libknet/threads_rx.c

index 4fa12543ef1a59f606d233d93117f8b1b963beb0..00216241d92642267a19283a22c803c75514fbba 100644 (file)
@@ -65,7 +65,8 @@ struct knet_link {
        unsigned long long pong_timeout;        /* timeout */
        unsigned long long pong_timeout_adj;    /* timeout adjusted for latency */
        uint8_t pong_timeout_backoff;           /* see link.h for definition */
-       unsigned int latency_fix;               /* precision */
+       unsigned int latency_max_samples;       /* precision */
+       unsigned int latency_cur_samples;
        uint8_t pong_count;                     /* how many ping/pong to send/receive before link is up */
        uint64_t flags;
        /* status */
@@ -77,7 +78,6 @@ struct knet_link {
        int outsock;
        unsigned int configured:1;              /* set to 1 if src/dst have been configured transport initialized on this link*/
        unsigned int transport_connected:1;     /* set to 1 if lower level transport is connected */
-       unsigned int latency_exp;
        uint8_t received_pong;
        struct timespec ping_last;
        /* used by PMTUD thread as temp per-link variables and should always contain the onwire_len value! */
index f7eccc3f3e2e3d7d946d9240f4c7b80478414a17..2b5dca3fdaa22dc7650b975127273eb9dae81104 100644 (file)
@@ -226,9 +226,8 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
        link->pong_timeout = KNET_LINK_DEFAULT_PING_TIMEOUT * 1000; /* microseconds */
        link->pong_timeout_backoff = KNET_LINK_PONG_TIMEOUT_BACKOFF;
        link->pong_timeout_adj = link->pong_timeout * link->pong_timeout_backoff; /* microseconds */
-       link->latency_fix = KNET_LINK_DEFAULT_PING_PRECISION;
-       link->latency_exp = KNET_LINK_DEFAULT_PING_PRECISION - \
-                           ((link->ping_interval * KNET_LINK_DEFAULT_PING_PRECISION) / 8000000);
+       link->latency_max_samples = KNET_LINK_DEFAULT_PING_PRECISION;
+       link->latency_cur_samples = 0;
        link->flags = flags;
 
        if (transport_link_set_config(knet_h, link, transport) < 0) {
@@ -813,9 +812,7 @@ int knet_link_set_ping_timers(knet_handle_t knet_h, knet_node_id_t host_id, uint
 
        link->ping_interval = interval * 1000; /* microseconds */
        link->pong_timeout = timeout * 1000; /* microseconds */
-       link->latency_fix = precision;
-       link->latency_exp = precision - \
-                           ((link->ping_interval * precision) / 8000000);
+       link->latency_max_samples = precision;
 
        log_debug(knet_h, KNET_SUB_LINK,
                  "host: %u link: %u timeout update - interval: %llu timeout: %llu precision: %u",
@@ -888,7 +885,7 @@ int knet_link_get_ping_timers(knet_handle_t knet_h, knet_node_id_t host_id, uint
 
        *interval = link->ping_interval / 1000; /* microseconds */
        *timeout = link->pong_timeout / 1000;
-       *precision = link->latency_fix;
+       *precision = link->latency_max_samples;
 
 exit_unlock:
        pthread_rwlock_unlock(&knet_h->global_rwlock);
index 46170f6e4f841d0294d4c6ee15ace1cc073e3168..bc4d142e3b911b68e991d8a192ff7eb3bd25f5f3 100644 (file)
@@ -156,7 +156,7 @@ static void test(void)
 
        if ((knet_h->host_index[1]->link[0].ping_interval != 1000000) ||
            (knet_h->host_index[1]->link[0].pong_timeout != 2000000) ||
-           (knet_h->host_index[1]->link[0].latency_fix != 2048)) {
+           (knet_h->host_index[1]->link[0].latency_max_samples != 2048)) {
                printf("knet_link_set_ping_timers failed to set values\n");
                knet_link_clear_config(knet_h, 1, 0);
                knet_host_remove(knet_h, 1);
index 1d136aea574b36a6e766e6ce032346366e2106f7..f42cacb940367cf85282f3fadb0106001a7c66ce 100644 (file)
@@ -624,11 +624,21 @@ retry_pong:
                                  "Incoming pong packet from host: %u link: %u has higher latency than pong_timeout. Discarding",
                                  src_host->host_id, src_link->link_id);
                } else {
+
+                       /*
+                        * in words : ('previous mean' * '(count -1)') + 'new value') / 'count'
+                        */
+
+                       src_link->latency_cur_samples++;
+
+                       /*
+                        * limit to max_samples (precision)
+                        */
+                       if (src_link->latency_cur_samples >= src_link->latency_max_samples) {
+                               src_link->latency_cur_samples = src_link->latency_max_samples;
+                       }
                        src_link->status.latency =
-                               ((src_link->status.latency * src_link->latency_exp) +
-                               ((latency_last / 1000llu) *
-                                       (src_link->latency_fix - src_link->latency_exp))) /
-                                               src_link->latency_fix;
+                               (((src_link->status.latency * (src_link->latency_cur_samples - 1)) + (latency_last / 1000llu)) / src_link->latency_cur_samples);
 
                        if (src_link->status.latency < src_link->pong_timeout_adj) {
                                if (!src_link->status.connected) {