From patchwork Thu Oct 29 15:36:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dharmik Thakkar X-Patchwork-Id: 82831 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 27AACA04B5; Thu, 29 Oct 2020 16:38:15 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id E6AE7D13E; Thu, 29 Oct 2020 16:37:19 +0100 (CET) Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by dpdk.org (Postfix) with ESMTP id 8A003CC9D for ; Thu, 29 Oct 2020 16:37:10 +0100 (CET) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 09718143B; Thu, 29 Oct 2020 08:37:09 -0700 (PDT) Received: from localhost.localdomain (2p2660v4-1.austin.arm.com [10.118.13.220]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 01A8B3F66E; Thu, 29 Oct 2020 08:37:09 -0700 (PDT) From: Dharmik Thakkar To: Bruce Richardson , Vladimir Medvedkin Cc: dev@dpdk.org, nd@arm.com, Dharmik Thakkar Date: Thu, 29 Oct 2020 10:36:34 -0500 Message-Id: <20201029153634.10647-4-dharmik.thakkar@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201029153634.10647-1-dharmik.thakkar@arm.com> References: <20201029153634.10647-1-dharmik.thakkar@arm.com> Subject: [dpdk-dev] [PATCH 4/4] test/lpm: avoid code duplication in rcu qsbr perf X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Avoid code duplication by combining single and multi threaded tests Signed-off-by: Dharmik Thakkar Reviewed-by: Ruifeng Wang --- app/test/test_lpm_perf.c | 338 +++++++++------------------------------ 1 file changed, 73 insertions(+), 265 deletions(-) diff --git a/app/test/test_lpm_perf.c b/app/test/test_lpm_perf.c index 4f15db4f85ee..08312023b661 100644 --- a/app/test/test_lpm_perf.c +++ b/app/test/test_lpm_perf.c @@ -430,11 +430,16 @@ test_lpm_rcu_qsbr_writer(void *arg) { unsigned int i, j, si, ei; uint64_t begin, total_cycles; - uint8_t core_id = (uint8_t)((uintptr_t)arg); + uint8_t writer_id = (uint8_t)((uintptr_t)arg); uint32_t next_hop_add = 0xAA; - /* 2 writer threads are used */ - if (core_id % 2 == 0) { + /* Single writer (writer_id = 1) */ + if (writer_id == 1) { + si = 0; + ei = NUM_LDEPTH_ROUTE_ENTRIES; + } + /* 2 Writers (writer_id = 2/3)*/ + else if (writer_id == 2) { si = 0; ei = NUM_LDEPTH_ROUTE_ENTRIES / 2; } else { @@ -482,16 +487,17 @@ test_lpm_rcu_qsbr_writer(void *arg) /* * Functional test: - * 2 writers, rest are readers + * 1/2 writers, rest are readers */ static int -test_lpm_rcu_perf_multi_writer(void) +test_lpm_rcu_perf_multi_writer(uint8_t use_rcu) { struct rte_lpm_config config; size_t sz; - unsigned int i; + unsigned int i, j; uint16_t core_id; struct rte_lpm_rcu_config rcu_cfg = {0}; + int (*reader_f)(void *arg) = NULL; if (rte_lcore_count() < 3) { printf("Not enough cores for lpm_rcu_perf_autotest, expecting at least 3\n"); @@ -504,273 +510,76 @@ test_lpm_rcu_perf_multi_writer(void) num_cores++; } - printf("\nPerf test: 2 writers, %d readers, RCU integration enabled\n", - num_cores - 2); - - /* Create LPM table */ - config.max_rules = NUM_LDEPTH_ROUTE_ENTRIES; - config.number_tbl8s = NUM_LDEPTH_ROUTE_ENTRIES; - config.flags = 0; - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - /* Init RCU variable */ - sz = rte_rcu_qsbr_get_memsize(num_cores); - rv = (struct rte_rcu_qsbr *)rte_zmalloc("rcu0", sz, - RTE_CACHE_LINE_SIZE); - rte_rcu_qsbr_init(rv, num_cores); - - rcu_cfg.v = rv; - /* Assign the RCU variable to LPM */ - if (rte_lpm_rcu_qsbr_add(lpm, &rcu_cfg) != 0) { - printf("RCU variable assignment failed\n"); - goto error; - } - - writer_done = 0; - __atomic_store_n(&gwrite_cycles, 0, __ATOMIC_RELAXED); - - __atomic_store_n(&thr_id, 0, __ATOMIC_SEQ_CST); - - /* Launch reader threads */ - for (i = 2; i < num_cores; i++) - rte_eal_remote_launch(test_lpm_rcu_qsbr_reader, NULL, - enabled_core_ids[i]); - - /* Launch writer threads */ - for (i = 0; i < 2; i++) - rte_eal_remote_launch(test_lpm_rcu_qsbr_writer, - (void *)(uintptr_t)i, - enabled_core_ids[i]); - - /* Wait for writer threads */ - for (i = 0; i < 2; i++) - if (rte_eal_wait_lcore(enabled_core_ids[i]) < 0) - goto error; - - printf("Total LPM Adds: %d\n", TOTAL_WRITES); - printf("Total LPM Deletes: %d\n", TOTAL_WRITES); - printf("Average LPM Add/Del: %"PRIu64" cycles\n", - __atomic_load_n(&gwrite_cycles, __ATOMIC_RELAXED) / TOTAL_WRITES - ); - - writer_done = 1; - /* Wait until all readers have exited */ - for (i = 2; i < num_cores; i++) - rte_eal_wait_lcore(enabled_core_ids[i]); - - rte_lpm_free(lpm); - rte_free(rv); - lpm = NULL; - rv = NULL; - - /* Test without RCU integration */ - printf("\nPerf test: 2 writers, %d readers, RCU integration disabled\n", - num_cores - 2); - - /* Create LPM table */ - config.max_rules = NUM_LDEPTH_ROUTE_ENTRIES; - config.number_tbl8s = NUM_LDEPTH_ROUTE_ENTRIES; - config.flags = 0; - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - writer_done = 0; - __atomic_store_n(&gwrite_cycles, 0, __ATOMIC_RELAXED); - __atomic_store_n(&thr_id, 0, __ATOMIC_SEQ_CST); - - /* Launch reader threads */ - for (i = 2; i < num_cores; i++) - rte_eal_remote_launch(test_lpm_reader, NULL, - enabled_core_ids[i]); - - /* Launch writer threads */ - for (i = 0; i < 2; i++) - rte_eal_remote_launch(test_lpm_rcu_qsbr_writer, - (void *)(uintptr_t)i, - enabled_core_ids[i]); - - /* Wait for writer threads */ - for (i = 0; i < 2; i++) - if (rte_eal_wait_lcore(enabled_core_ids[i]) < 0) - goto error; - - printf("Total LPM Adds: %d\n", TOTAL_WRITES); - printf("Total LPM Deletes: %d\n", TOTAL_WRITES); - printf("Average LPM Add/Del: %"PRIu64" cycles\n", - __atomic_load_n(&gwrite_cycles, __ATOMIC_RELAXED) - / TOTAL_WRITES); - - writer_done = 1; - /* Wait until all readers have exited */ - for (i = 2; i < num_cores; i++) - rte_eal_wait_lcore(enabled_core_ids[i]); - - rte_lpm_free(lpm); - - return 0; - -error: - writer_done = 1; - /* Wait until all readers have exited */ - rte_eal_mp_wait_lcore(); - - rte_lpm_free(lpm); - rte_free(rv); - - return -1; -} - -/* - * Functional test: - * Single writer, rest are readers - */ -static int -test_lpm_rcu_perf(void) -{ - struct rte_lpm_config config; - uint64_t begin, total_cycles; - size_t sz; - unsigned int i, j; - uint16_t core_id; - uint32_t next_hop_add = 0xAA; - struct rte_lpm_rcu_config rcu_cfg = {0}; - - if (rte_lcore_count() < 2) { - printf("Not enough cores for lpm_rcu_perf_autotest, expecting at least 2\n"); - return TEST_SKIPPED; - } - - num_cores = 0; - RTE_LCORE_FOREACH_WORKER(core_id) { - enabled_core_ids[num_cores] = core_id; - num_cores++; - } - - printf("\nPerf test: 1 writer, %d readers, RCU integration enabled\n", - num_cores); - - /* Create LPM table */ - config.max_rules = NUM_LDEPTH_ROUTE_ENTRIES; - config.number_tbl8s = NUM_LDEPTH_ROUTE_ENTRIES; - config.flags = 0; - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - /* Init RCU variable */ - sz = rte_rcu_qsbr_get_memsize(num_cores); - rv = (struct rte_rcu_qsbr *)rte_zmalloc("rcu0", sz, - RTE_CACHE_LINE_SIZE); - rte_rcu_qsbr_init(rv, num_cores); - - rcu_cfg.v = rv; - /* Assign the RCU variable to LPM */ - if (rte_lpm_rcu_qsbr_add(lpm, &rcu_cfg) != 0) { - printf("RCU variable assignment failed\n"); - goto error; - } - - writer_done = 0; - __atomic_store_n(&thr_id, 0, __ATOMIC_SEQ_CST); - - /* Launch reader threads */ - for (i = 0; i < num_cores; i++) - rte_eal_remote_launch(test_lpm_rcu_qsbr_reader, NULL, - enabled_core_ids[i]); - - /* Measure add/delete. */ - begin = rte_rdtsc_precise(); - for (i = 0; i < RCU_ITERATIONS; i++) { - /* Add all the entries */ - for (j = 0; j < NUM_LDEPTH_ROUTE_ENTRIES; j++) - if (rte_lpm_add(lpm, large_ldepth_route_table[j].ip, - large_ldepth_route_table[j].depth, - next_hop_add) != 0) { - printf("Failed to add iteration %d, route# %d\n", - i, j); + for (j = 1; j < 3; j++) { + if (use_rcu) + printf("\nPerf test: %d writer(s), %d reader(s)," + " RCU integration enabled\n", j, num_cores - j); + else + printf("\nPerf test: %d writer(s), %d reader(s)," + " RCU integration disabled\n", j, num_cores - j); + + /* Create LPM table */ + config.max_rules = NUM_LDEPTH_ROUTE_ENTRIES; + config.number_tbl8s = NUM_LDEPTH_ROUTE_ENTRIES; + config.flags = 0; + lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); + TEST_LPM_ASSERT(lpm != NULL); + + /* Init RCU variable */ + if (use_rcu) { + sz = rte_rcu_qsbr_get_memsize(num_cores); + rv = (struct rte_rcu_qsbr *)rte_zmalloc("rcu0", sz, + RTE_CACHE_LINE_SIZE); + rte_rcu_qsbr_init(rv, num_cores); + + rcu_cfg.v = rv; + /* Assign the RCU variable to LPM */ + if (rte_lpm_rcu_qsbr_add(lpm, &rcu_cfg) != 0) { + printf("RCU variable assignment failed\n"); goto error; } - /* Delete all the entries */ - for (j = 0; j < NUM_LDEPTH_ROUTE_ENTRIES; j++) - if (rte_lpm_delete(lpm, large_ldepth_route_table[j].ip, - large_ldepth_route_table[j].depth) != 0) { - printf("Failed to delete iteration %d, route# %d\n", - i, j); - goto error; - } - } - total_cycles = rte_rdtsc_precise() - begin; + reader_f = test_lpm_rcu_qsbr_reader; + } else + reader_f = test_lpm_reader; - printf("Total LPM Adds: %d\n", TOTAL_WRITES); - printf("Total LPM Deletes: %d\n", TOTAL_WRITES); - printf("Average LPM Add/Del: %g cycles\n", - (double)total_cycles / TOTAL_WRITES); + writer_done = 0; + __atomic_store_n(&gwrite_cycles, 0, __ATOMIC_RELAXED); - writer_done = 1; - /* Wait until all readers have exited */ - for (i = 0; i < num_cores; i++) - if (rte_eal_wait_lcore(enabled_core_ids[i]); + __atomic_store_n(&thr_id, 0, __ATOMIC_SEQ_CST); - rte_lpm_free(lpm); - rte_free(rv); - lpm = NULL; - rv = NULL; + /* Launch reader threads */ + for (i = j; i < num_cores; i++) + rte_eal_remote_launch(reader_f, NULL, + enabled_core_ids[i]); - /* Test without RCU integration */ - printf("\nPerf test: 1 writer, %d readers, RCU integration disabled\n", - num_cores); + /* Launch writer threads */ + for (i = 0; i < j; i++) + rte_eal_remote_launch(test_lpm_rcu_qsbr_writer, + (void *)(uintptr_t)(i + j), + enabled_core_ids[i]); - /* Create LPM table */ - config.max_rules = NUM_LDEPTH_ROUTE_ENTRIES; - config.number_tbl8s = NUM_LDEPTH_ROUTE_ENTRIES; - config.flags = 0; - lpm = rte_lpm_create(__func__, SOCKET_ID_ANY, &config); - TEST_LPM_ASSERT(lpm != NULL); - - writer_done = 0; - __atomic_store_n(&thr_id, 0, __ATOMIC_SEQ_CST); - - /* Launch reader threads */ - for (i = 0; i < num_cores; i++) - rte_eal_remote_launch(test_lpm_reader, NULL, - enabled_core_ids[i]); - - /* Measure add/delete. */ - begin = rte_rdtsc_precise(); - for (i = 0; i < RCU_ITERATIONS; i++) { - /* Add all the entries */ - for (j = 0; j < NUM_LDEPTH_ROUTE_ENTRIES; j++) - if (rte_lpm_add(lpm, large_ldepth_route_table[j].ip, - large_ldepth_route_table[j].depth, - next_hop_add) != 0) { - printf("Failed to add iteration %d, route# %d\n", - i, j); + /* Wait for writer threads */ + for (i = 0; i < j; i++) + if (rte_eal_wait_lcore(enabled_core_ids[i]) < 0) goto error; - } - /* Delete all the entries */ - for (j = 0; j < NUM_LDEPTH_ROUTE_ENTRIES; j++) - if (rte_lpm_delete(lpm, large_ldepth_route_table[j].ip, - large_ldepth_route_table[j].depth) != 0) { - printf("Failed to delete iteration %d, route# %d\n", - i, j); - goto error; - } + printf("Total LPM Adds: %d\n", TOTAL_WRITES); + printf("Total LPM Deletes: %d\n", TOTAL_WRITES); + printf("Average LPM Add/Del: %"PRIu64" cycles\n", + __atomic_load_n(&gwrite_cycles, __ATOMIC_RELAXED) + / TOTAL_WRITES); + + writer_done = 1; + /* Wait until all readers have exited */ + for (i = j; i < num_cores; i++) + rte_eal_wait_lcore(enabled_core_ids[i]); + + rte_lpm_free(lpm); + rte_free(rv); + lpm = NULL; + rv = NULL; } - total_cycles = rte_rdtsc_precise() - begin; - - printf("Total LPM Adds: %d\n", TOTAL_WRITES); - printf("Total LPM Deletes: %d\n", TOTAL_WRITES); - printf("Average LPM Add/Del: %g cycles\n", - (double)total_cycles / TOTAL_WRITES); - - writer_done = 1; - /* Wait until all readers have exited */ - for (i = 0; i < num_cores; i++) - rte_eal_wait_lcore(enabled_core_ids[i]); - - rte_lpm_free(lpm); return 0; @@ -946,9 +755,8 @@ test_lpm_perf(void) rte_lpm_delete_all(lpm); rte_lpm_free(lpm); - test_lpm_rcu_perf(); - - test_lpm_rcu_perf_multi_writer(); + test_lpm_rcu_perf_multi_writer(0); + test_lpm_rcu_perf_multi_writer(1); return 0; }