Re: [ovs-dev] [PATCH v2 05/15] tests: Add very simple conntrack benchmark.

2016-04-27 Thread Daniele Di Proietto





On 26/04/2016 16:36, "Flavio Leitner"  wrote:

>On Fri, Apr 15, 2016 at 05:02:37PM -0700, Daniele Di Proietto wrote:
>> This introduces a very limited but simple benchmark for
>> conntrack_execute(). It just sends repeatedly the same batch of packets
>> through the connection tracker and returns the time spent to process
>> them.
>> 
>> While this is not a realistic benchmark, it has proven useful during
>> development to evaluate different batching and locking strategies.
>> 
>> E.g. the line:
>> 
>> `./test/ovstest test-conntrack benchmark 1 1488 32`
>
>14.88M? :-)

You got me :-)

>>
>> starts 1 thread that will send 1488 packets to the connection
>> tracker, 32 at a time. It will print the time taken to process them.
>> 
>> Signed-off-by: Daniele Di Proietto 
>> ---
>
>Acked-by: Flavio Leitner 

Thanks for the review!
___
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev


Re: [ovs-dev] [PATCH v2 05/15] tests: Add very simple conntrack benchmark.

2016-04-26 Thread Flavio Leitner
On Fri, Apr 15, 2016 at 05:02:37PM -0700, Daniele Di Proietto wrote:
> This introduces a very limited but simple benchmark for
> conntrack_execute(). It just sends repeatedly the same batch of packets
> through the connection tracker and returns the time spent to process
> them.
> 
> While this is not a realistic benchmark, it has proven useful during
> development to evaluate different batching and locking strategies.
> 
> E.g. the line:
> 
> `./test/ovstest test-conntrack benchmark 1 1488 32`

14.88M? :-)
>
> starts 1 thread that will send 1488 packets to the connection
> tracker, 32 at a time. It will print the time taken to process them.
> 
> Signed-off-by: Daniele Di Proietto 
> ---

Acked-by: Flavio Leitner 


___
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev


[ovs-dev] [PATCH v2 05/15] tests: Add very simple conntrack benchmark.

2016-04-15 Thread Daniele Di Proietto
This introduces a very limited but simple benchmark for
conntrack_execute(). It just sends repeatedly the same batch of packets
through the connection tracker and returns the time spent to process
them.

While this is not a realistic benchmark, it has proven useful during
development to evaluate different batching and locking strategies.

E.g. the line:

`./test/ovstest test-conntrack benchmark 1 1488 32`

starts 1 thread that will send 1488 packets to the connection
tracker, 32 at a time. It will print the time taken to process them.

Signed-off-by: Daniele Di Proietto 
---
 tests/automake.mk  |   1 +
 tests/test-conntrack.c | 167 +
 2 files changed, 168 insertions(+)
 create mode 100644 tests/test-conntrack.c

diff --git a/tests/automake.mk b/tests/automake.mk
index aed032b..9fbbd5a 100644
--- a/tests/automake.mk
+++ b/tests/automake.mk
@@ -310,6 +310,7 @@ tests_ovstest_SOURCES = \
tests/test-byte-order.c \
tests/test-classifier.c \
tests/test-cmap.c \
+   tests/test-conntrack.c \
tests/test-csum.c \
tests/test-flows.c \
tests/test-hash.c \
diff --git a/tests/test-conntrack.c b/tests/test-conntrack.c
new file mode 100644
index 000..414d7dc
--- /dev/null
+++ b/tests/test-conntrack.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2015 Nicira, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include 
+#include "conntrack.h"
+
+#include "dp-packet.h"
+#include "fatal-signal.h"
+#include "flow.h"
+#include "netdev.h"
+#include "ovs-thread.h"
+#include "ovstest.h"
+#include "timeval.h"
+
+static const char payload[] = 
"5054000a505400090800451c00110a0101010a010102000100020008";
+
+static struct dp_packet **
+prepare_packets(size_t n, bool change, unsigned tid)
+{
+struct dp_packet **pkts = xcalloc(n, sizeof *pkts);
+struct flow flow;
+size_t i;
+
+for (i = 0; i < n; i++) {
+struct udp_header *udp;
+
+pkts[i] = dp_packet_new(sizeof payload/2);
+dp_packet_put_hex(pkts[i], payload, NULL);
+flow_extract(pkts[i], );
+
+udp = dp_packet_l4(pkts[i]);
+udp->udp_src = htons(ntohs(udp->udp_src) + tid);
+
+if (change) {
+udp->udp_dst = htons(ntohs(udp->udp_dst) + i);
+}
+}
+
+return pkts;
+}
+
+static void
+destroy_packets(struct dp_packet **pkts, size_t n)
+{
+size_t i;
+
+for (i = 0; i < n; i++) {
+dp_packet_delete(pkts[i]);
+}
+
+free(pkts);
+}
+
+struct thread_aux {
+pthread_t thread;
+unsigned tid;
+};
+
+static struct conntrack ct;
+static unsigned long n_threads, n_pkts, batch_size;
+static bool change_conn = false;
+static pthread_barrier_t barrier;
+
+static void *
+ct_thread_main(void *aux_)
+{
+struct thread_aux *aux = aux_;
+struct dp_packet **pkts;
+size_t i;
+
+pkts = prepare_packets(batch_size, change_conn, aux->tid);
+pthread_barrier_wait();
+for (i = 0; i < n_pkts; i += batch_size) {
+conntrack_execute(, pkts, batch_size, true, 0, NULL, NULL, NULL);
+}
+pthread_barrier_wait();
+destroy_packets(pkts, batch_size);
+
+return NULL;
+}
+
+static void
+test_benchmark(struct ovs_cmdl_context *ctx)
+{
+struct thread_aux *threads;
+long long start;
+unsigned i;
+
+fatal_signal_init();
+
+/* Parse arguments */
+n_threads = strtoul(ctx->argv[1], NULL, 0);
+if (!n_threads) {
+ovs_fatal(0, "n_threads must be at least one");
+}
+n_pkts = strtoul(ctx->argv[2], NULL, 0);
+batch_size = strtoul(ctx->argv[3], NULL, 0);
+if (batch_size == 0 || batch_size > NETDEV_MAX_BURST) {
+ovs_fatal(0, "batch_size must be between 1 and NETDEV_MAX_BURST(%u)",
+  NETDEV_MAX_BURST);
+}
+if (ctx->argc > 4) {
+change_conn = strtoul(ctx->argv[4], NULL, 0);
+}
+
+threads = xcalloc(n_threads, sizeof *threads);
+pthread_barrier_init(, NULL, n_threads + 1);
+conntrack_init();
+
+/* Create threads */
+for (i = 0; i < n_threads; i++) {
+threads[i].tid = i;
+threads[i].thread = ovs_thread_create("ct_thread", ct_thread_main, 
[i]);
+}
+/* Starts the work inside the threads */
+pthread_barrier_wait();
+start = time_msec();
+
+/* Wait for the threads to finish the work */
+pthread_barrier_wait();
+printf("conntrack:  %5lld ms\n",