From patchwork Wed Jul 27 00:58:06 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniele Di Proietto X-Patchwork-Id: 653025 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (archives.nicira.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 3rzc8t52wGz9sCy for ; Wed, 27 Jul 2016 10:59:58 +1000 (AEST) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 5D62F10E25; Tue, 26 Jul 2016 17:58:30 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx3v3.cudamail.com (mx3.cudamail.com [64.34.241.5]) by archives.nicira.com (Postfix) with ESMTPS id 322EF10D13 for ; Tue, 26 Jul 2016 17:58:23 -0700 (PDT) Received: from bar6.cudamail.com (localhost [127.0.0.1]) by mx3v3.cudamail.com (Postfix) with ESMTPS id BC24D1624EB for ; Tue, 26 Jul 2016 18:58:22 -0600 (MDT) X-ASG-Debug-ID: 1469581101-0b3237477569960001-byXFYA Received: from mx1-pf2.cudamail.com ([192.168.24.2]) by bar6.cudamail.com with ESMTP id ADAF5A3T0Z6Wo39E (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 26 Jul 2016 18:58:22 -0600 (MDT) X-Barracuda-Envelope-From: diproiettod@vmware.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.24.2 Received: from unknown (HELO EX13-EDG-OU-002.vmware.com) (208.91.0.190) by mx1-pf2.cudamail.com with ESMTPS (AES256-SHA encrypted); 27 Jul 2016 00:58:21 -0000 Received-SPF: error (mx1-pf2.cudamail.com: error in processing during lookup of vmware.com: DNS problem) Received: from sc9-mailhost1.vmware.com (10.113.161.71) by EX13-EDG-OU-002.vmware.com (10.113.208.156) with Microsoft SMTP Server id 15.0.1156.6; Tue, 26 Jul 2016 17:57:44 -0700 Received: from sc9-mailhost2.vmware.com (htb-1n-eng-dhcp84.eng.vmware.com [10.33.74.84]) by sc9-mailhost1.vmware.com (Postfix) with ESMTP id EBA861871A; Tue, 26 Jul 2016 17:58:19 -0700 (PDT) X-CudaMail-Envelope-Sender: diproiettod@vmware.com From: Daniele Di Proietto To: X-CudaMail-Whitelist-To: dev@openvswitch.org X-CudaMail-MID: CM-E2-725087369 X-CudaMail-DTE: 072616 X-CudaMail-Originating-IP: 208.91.0.190 Date: Tue, 26 Jul 2016 17:58:06 -0700 X-ASG-Orig-Subj: [##CM-E2-725087369##][PATCH v5 06/16] tests: Add very simple conntrack benchmark. Message-ID: <1469581096-42007-7-git-send-email-diproiettod@vmware.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1469581096-42007-1-git-send-email-diproiettod@vmware.com> References: <1469581096-42007-1-git-send-email-diproiettod@vmware.com> MIME-Version: 1.0 Received-SPF: None (EX13-EDG-OU-002.vmware.com: diproiettod@vmware.com does not designate permitted sender hosts) X-Barracuda-Connect: UNKNOWN[192.168.24.2] X-Barracuda-Start-Time: 1469581102 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-ASG-Whitelist: Header =?UTF-8?B?eFwtY3VkYW1haWxcLXdoaXRlbGlzdFwtdG8=?= X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 Subject: [ovs-dev] [PATCH v5 06/16] tests: Add very simple conntrack benchmark. X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@openvswitch.org Sender: "dev" 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: `./tests/ovstest test-conntrack benchmark 1 14880000 32` starts 1 thread that will send 14880000 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 --- tests/automake.mk | 1 + tests/test-conntrack.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 tests/test-conntrack.c diff --git a/tests/automake.mk b/tests/automake.mk index 575ffeb..a9ebf91 100644 --- a/tests/automake.mk +++ b/tests/automake.mk @@ -328,6 +328,7 @@ tests_ovstest_SOURCES = \ tests/test-classifier.c \ tests/test-ccmap.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 0000000..37c7277 --- /dev/null +++ b/tests/test-conntrack.c @@ -0,0 +1,172 @@ +/* + * 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[] = "50540000000a50540000000908004500001c0000000000" + "11a4cd0a0101010a0101020001000200080000"; + +static struct dp_packet_batch * +prepare_packets(size_t n, bool change, unsigned tid) +{ + struct dp_packet_batch *pkt_batch = xzalloc(sizeof *pkt_batch); + struct flow flow; + size_t i; + + ovs_assert(n <= ARRAY_SIZE(pkt_batch->packets)); + + dp_packet_batch_init(pkt_batch); + pkt_batch->count = n; + + for (i = 0; i < n; i++) { + struct udp_header *udp; + struct dp_packet *pkt = dp_packet_new(sizeof payload/2); + + dp_packet_put_hex(pkt, payload, NULL); + flow_extract(pkt, &flow); + + udp = dp_packet_l4(pkt); + udp->udp_src = htons(ntohs(udp->udp_src) + tid); + + if (change) { + udp->udp_dst = htons(ntohs(udp->udp_dst) + i); + } + + pkt_batch->packets[i] = pkt; + } + + return pkt_batch; +} + +static void +destroy_packets(struct dp_packet_batch *pkt_batch) +{ + dp_packet_delete_batch(pkt_batch, true); + free(pkt_batch); +} + +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 struct ovs_barrier barrier; + +static void * +ct_thread_main(void *aux_) +{ + struct thread_aux *aux = aux_; + struct dp_packet_batch *pkt_batch; + size_t i; + + pkt_batch = prepare_packets(batch_size, change_conn, aux->tid); + ovs_barrier_block(&barrier); + for (i = 0; i < n_pkts; i += batch_size) { + conntrack_execute(&ct, pkt_batch, true, 0, NULL, NULL, NULL); + } + ovs_barrier_block(&barrier); + destroy_packets(pkt_batch); + + 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); + ovs_barrier_init(&barrier, n_threads + 1); + conntrack_init(&ct); + + /* Create threads */ + for (i = 0; i < n_threads; i++) { + threads[i].tid = i; + threads[i].thread = ovs_thread_create("ct_thread", ct_thread_main, + &threads[i]); + } + /* Starts the work inside the threads */ + ovs_barrier_block(&barrier); + start = time_msec(); + + /* Wait for the threads to finish the work */ + ovs_barrier_block(&barrier); + printf("conntrack: %5lld ms\n", time_msec() - start); + + for (i = 0; i < n_threads; i++) { + xpthread_join(threads[i].thread, NULL); + } + + conntrack_destroy(&ct); + ovs_barrier_destroy(&barrier); + free(threads); +} + +static const struct ovs_cmdl_command commands[] = { + /* Connection tracker tests. */ + /* Starts 'n_threads' threads. Each thread will send 'n_pkts' packets to + * the connection tracker, 'batch_size' per call. If 'change_connection' + * is '1', each packet in a batch will have a different source and + * destination port */ + {"benchmark", "n_threads n_pkts batch_size [change_connection]", 3, 4, + test_benchmark}, + + {NULL, NULL, 0, 0, NULL}, +}; + +static void +test_conntrack_main(int argc, char *argv[]) +{ + struct ovs_cmdl_context ctx = { + .argc = argc - 1, + .argv = argv + 1, + }; + set_program_name(argv[0]); + ovs_cmdl_run_command(&ctx, commands); +} + +OVSTEST_REGISTER("test-conntrack", test_conntrack_main);