Add the ability to test deletion rate for flow performance
application.

This feature is disabled by default, and can be enabled by
add "--deletion-rate" in the application command line options.

Signed-off-by: Wisam Jaddo <wis...@mellanox.com>
---
 app/test-flow-perf/main.c      | 87 ++++++++++++++++++++++++++++++++++
 doc/guides/tools/flow-perf.rst |  4 ++
 2 files changed, 91 insertions(+)

diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 59dc5ae0f4..84f2c0c39b 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -62,6 +62,7 @@ static uint16_t flow_actions;
 static uint8_t flow_attrs;
 static volatile bool force_quit;
 static volatile bool dump_iterations;
+static volatile bool delete_flag;
 static struct rte_mempool *mbuf_mp;
 static uint32_t nb_lcores;
 static uint32_t flows_count;
@@ -75,6 +76,8 @@ static void usage(char *progname)
                " flows to insert, default is 4,000,000\n");
        printf("  --dump-iterations: To print rates for each"
                " iteration\n");
+       printf("  --deletion-rate: Enable deletion rate"
+               " calculations\n");
 
        printf("To set flow attributes:\n");
        printf("  --ingress: set ingress attribute in flows\n");
@@ -123,6 +126,7 @@ args_parse(int argc, char **argv)
                { "help",                       0, 0, 0 },
                { "flows-count",                1, 0, 0 },
                { "dump-iterations",            0, 0, 0 },
+               { "deletion-rate",              0, 0, 0 },
                /* Attributes */
                { "ingress",                    0, 0, 0 },
                { "egress",                     0, 0, 0 },
@@ -304,6 +308,8 @@ args_parse(int argc, char **argv)
                        }
                        if (!strcmp(lgopts[opt_idx].name, "dump-iterations"))
                                dump_iterations = true;
+                       if (!strcmp(lgopts[opt_idx].name, "deletion-rate"))
+                               delete_flag = true;
                        break;
                default:
                        usage(argv[0]);
@@ -323,9 +329,75 @@ print_flow_error(struct rte_flow_error error)
                error.message ? error.message : "(no stated reason)");
 }
 
+static inline void
+destroy_flows(int port_id, struct rte_flow **flow_list)
+{
+       struct rte_flow_error error;
+       clock_t start_iter, end_iter;
+       double cpu_time_used = 0;
+       double flows_rate;
+       double cpu_time_per_iter[MAX_ITERATIONS];
+       double delta;
+       uint32_t i;
+       int iter_id;
+
+       for (i = 0; i < MAX_ITERATIONS; i++)
+               cpu_time_per_iter[i] = -1;
+
+       if (iterations_number > flows_count)
+               iterations_number = flows_count;
+
+       /* Deletion Rate */
+       printf("Flows Deletion on port = %d\n", port_id);
+       start_iter = clock();
+       for (i = 0; i < flows_count; i++) {
+               if (!flow_list[i])
+                       break;
+
+               memset(&error, 0x33, sizeof(error));
+               if (rte_flow_destroy(port_id, flow_list[i], &error)) {
+                       print_flow_error(error);
+                       rte_exit(EXIT_FAILURE, "Error in deleting flow");
+               }
+
+               if (i && !((i + 1) % iterations_number)) {
+                       /* Save the deletion rate of each iter */
+                       end_iter = clock();
+                       delta = (double) (end_iter - start_iter);
+                       iter_id = ((i + 1) / iterations_number) - 1;
+                       cpu_time_per_iter[iter_id] =
+                               delta / CLOCKS_PER_SEC;
+                       cpu_time_used += cpu_time_per_iter[iter_id];
+                       start_iter = clock();
+               }
+       }
+
+       /* Deletion rate per iteration */
+       if (dump_iterations)
+               for (i = 0; i < MAX_ITERATIONS; i++) {
+                       if (cpu_time_per_iter[i] == -1)
+                               continue;
+                       delta = (double)(iterations_number /
+                               cpu_time_per_iter[i]);
+                       flows_rate = delta / 1000;
+                       printf(":: Iteration #%d: %d flows "
+                               "in %f sec[ Rate = %f K/Sec ]\n",
+                               i, iterations_number,
+                               cpu_time_per_iter[i], flows_rate);
+               }
+
+       /* Deletion rate for all flows */
+       flows_rate = ((double) (flows_count / cpu_time_used) / 1000);
+       printf("\n:: Total flow deletion rate -> %f K/Sec\n",
+               flows_rate);
+       printf(":: The time for deleting %d in flows %f seconds\n",
+               flows_count, cpu_time_used);
+}
+
 static inline void
 flows_handler(void)
 {
+       struct rte_flow **flow_list;
        struct rte_flow_error error;
        clock_t start_iter, end_iter;
        double cpu_time_used = 0;
@@ -337,6 +409,7 @@ flows_handler(void)
        int port_id;
        int iter_id;
        uint32_t eagain_counter = 0;
+       uint32_t flow_index;
 
        nr_ports = rte_eth_dev_count_avail();
 
@@ -348,7 +421,14 @@ flows_handler(void)
 
        printf(":: Flows Count per port: %d\n", flows_count);
 
+       flow_list = rte_zmalloc("flow_list",
+               (sizeof(struct rte_flow *) * flows_count) + 1, 0);
+       if (flow_list == NULL)
+               rte_exit(EXIT_FAILURE, "No Memory available!");
+
        for (port_id = 0; port_id < nr_ports; port_id++) {
+               flow_index = 0;
+
                if (flow_group > 0) {
                        /*
                         * Create global rule to jumo into flow_group
@@ -365,6 +445,7 @@ flows_handler(void)
                                print_flow_error(error);
                                rte_exit(EXIT_FAILURE, "error in creating 
flow");
                        }
+                       flow_list[flow_index++] = flow;
                }
 
                /* Insertion Rate */
@@ -388,6 +469,8 @@ flows_handler(void)
                                rte_exit(EXIT_FAILURE, "error in creating 
flow");
                        }
 
+                       flow_list[flow_index++] = flow;
+
                        if (i && !((i + 1) % iterations_number)) {
                                /* Save the insertion rate of each iter */
                                end_iter = clock();
@@ -421,6 +504,9 @@ flows_handler(void)
                printf(":: The time for creating %d in flows %f seconds\n",
                                                flows_count, cpu_time_used);
                printf(":: EAGAIN counter = %d\n", eagain_counter);
+
+               if (delete_flag)
+                       destroy_flows(port_id, flow_list);
        }
 }
 
@@ -579,6 +665,7 @@ main(int argc, char **argv)
 
        force_quit = false;
        dump_iterations = false;
+       delete_flag = false;
        flows_count = 4000000;
        iterations_number = 100000;
        flow_group = 0;
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 62e038c430..e07e659df5 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -18,6 +18,8 @@ give different flow each time, and all other items will have 
open masks.
 The current design have single core insertion rate. In the future we may
 have a multi core insertion rate measurement support in the app.
 
+The application also provide the ability to measure rte flow deletion rate.
+
 
 Compiling the Application
 =========================
@@ -89,6 +91,8 @@ The command line options are:
        Print rates for each iteration of flows.
        Default iteration is 1,00,000.
 
+*      ``--deletion-rate``
+       Enable deletion rate calculations.
 
 Attributes:
 
-- 
2.17.1

Reply via email to