Increase maximum latency supported by Early Loss Detection 25/73125/2
authorXavier Simonart <simonartxavier@gmail.com>
Mon, 20 Dec 2021 13:06:08 +0000 (13:06 +0000)
committerXavier Simonart <simonartxavier@gmail.com>
Thu, 30 Dec 2021 10:46:30 +0000 (10:46 +0000)
Early Loss Detection was supporting a maximum latency of 16k
packets i.e. 1ms at 64 Bytes / 10Gbps.
This has been increased by 64.
Drawback is that early loss detection might take much longer
(1 million packets)

Signed-off-by: Xavier Simonart <simonartxavier@gmail.com>
Change-Id: I3e8dae6a27e72e48757a66e0097d17be924211ad

VNFs/DPPD-PROX/eld.h
VNFs/DPPD-PROX/handle_lat.c
VNFs/DPPD-PROX/prox_args.c
VNFs/DPPD-PROX/task_init.h

index 2731beb..d3ec2f2 100644 (file)
@@ -17,7 +17,7 @@
 #ifndef _ELD_H_
 #define _ELD_H_
 
-#define PACKET_QUEUE_BITS      14
+#define PACKET_QUEUE_BITS      20
 #define PACKET_QUEUE_SIZE      (1 << PACKET_QUEUE_BITS)
 #define PACKET_QUEUE_MASK      (PACKET_QUEUE_SIZE - 1)
 
index 99740c1..550f3f5 100644 (file)
@@ -86,6 +86,11 @@ struct rx_pkt_meta_data {
        uint32_t bytes_after_in_bulk;
 };
 
+struct loss_buffer {
+       uint32_t packet_id;
+       uint32_t n;
+};
+
 struct task_lat {
        struct task_base base;
        uint64_t limit;
@@ -111,11 +116,15 @@ struct task_lat {
        struct rx_pkt_meta_data *rx_pkt_meta;
        // Following fields are only used when starting or stopping, not in general runtime
        uint64_t *prev_tx_packet_index;
+       FILE *fp_loss;
        FILE *fp_rx;
        FILE *fp_tx;
        struct prox_port_cfg *port;
        uint64_t *bytes_to_tsc;
        uint64_t *previous_packet;
+       uint32_t loss_buffer_size;
+       struct loss_buffer *loss_buffer;
+       uint32_t loss_id;
 };
 /* This function calculate the difference between rx and tx_time
  * Both values are uint32_t (see handle_lat_bulk)
@@ -402,6 +411,12 @@ static void lat_stop(struct task_base *tbase)
                task_lat_reset_eld(task);
                memset(task->previous_packet, 0, sizeof(task->previous_packet) * task->generator_count);
        }
+       if (task->loss_id) {
+               for (uint i = 0; i < task->loss_id; i++) {
+                       fprintf(task->fp_loss, "packet %d: %d\n", task->loss_buffer[i].packet_id, task->loss_buffer[i].n);
+               }
+       }
+       task->lat_test->lost_packets = 0;
        if (task->latency_buffer)
                lat_write_latency_to_file(task);
 }
@@ -637,7 +652,14 @@ static int handle_lat_bulk(struct task_base *tbase, struct rte_mbuf **mbufs, uin
                        }
                        lat_test_check_ordering(task, task->lat_test, packet_id, generator_id);
                        lat_test_check_duplicate(task, task->lat_test, packet_id, generator_id);
-                       lat_test_add_lost(task->lat_test, task_lat_early_loss_detect(task, packet_id, generator_id));
+                       uint32_t loss =  task_lat_early_loss_detect(task, packet_id, generator_id);
+                       if (loss) {
+                               lat_test_add_lost(task->lat_test, loss);
+                               if (task->loss_id < task->loss_buffer_size) {
+                                       task->loss_buffer[task->loss_id].packet_id = packet_id;
+                                       task->loss_buffer[task->loss_id++].n = loss;
+                               }
+                       }
                } else {
                        generator_id = 0;
                        packet_id = task->rx_packet_index;
@@ -780,6 +802,11 @@ static void init_task_lat(struct task_base *tbase, struct task_args *targ)
                init_task_lat_latency_buffer(task, targ->lconf->id);
        }
 
+       char name[256];
+       sprintf(name, "loss_%u.txt", targ->lconf->id);
+       task->fp_loss = fopen(name, "w+");
+       PROX_PANIC(task->fp_loss == NULL, "Failed to open %s\n", name);
+
        if (targ->bucket_size < DEFAULT_BUCKET_SIZE) {
                targ->bucket_size = DEFAULT_BUCKET_SIZE;
        }
@@ -832,9 +859,14 @@ static void init_task_lat(struct task_base *tbase, struct task_args *targ)
                                (uint8_t)(port - prox_port_cfg), 8 * bytes_per_hz / 1000000);
                }
        }
+       task->loss_buffer_size = targ->loss_buffer_size;
+       task->loss_buffer = prox_zmalloc(task->loss_buffer_size * sizeof(struct loss_buffer), rte_lcore_to_socket_id(targ->lconf->id));
+       PROX_PANIC(task->loss_buffer == NULL,
+               "Failed to allocate %lu bytes (in huge pages) for loss_buffer\n", task->loss_buffer_size * sizeof(struct loss_buffer));
+
        task->bytes_to_tsc = prox_zmalloc(max_frame_size * sizeof(task->bytes_to_tsc[0]) * MAX_PKT_BURST, rte_lcore_to_socket_id(targ->lconf->id));
        PROX_PANIC(task->bytes_to_tsc == NULL,
-               "Failed to allocate %u bytes (in huge pages) for bytes_to_tsc\n", max_frame_size);
+               "Failed to allocate %lu bytes (in huge pages) for bytes_to_tsc\n", max_frame_size * sizeof(task->bytes_to_tsc[0]) * MAX_PKT_BURST);
 
         // There are cases where hz estimate might be slighly over-estimated
         // This results in too much extrapolation
index bd2b59a..274e6c9 100644 (file)
@@ -1144,6 +1144,9 @@ static int get_core_cfg(unsigned sindex, char *str, void *data)
        if (STR_EQ(str, "latency buffer size")) {
                return parse_int(&targ->latency_buffer_size, pkey);
        }
+       if (STR_EQ(str, "loss buffer size")) {
+               return parse_int(&targ->loss_buffer_size, pkey);
+       }
        if (STR_EQ(str, "accuracy pos")) {
                return parse_int(&targ->accur_pos, pkey);
        }
index ec7b8e8..82a5825 100644 (file)
@@ -259,6 +259,7 @@ struct task_args {
        uint32_t        multiplier;
        uint32_t        mirror_size;
        uint32_t store_max;
+       uint32_t loss_buffer_size;
 };
 
 /* Return the first port that is reachable through the task. If the