* [PATCH 1/7] app/test/reciprocal_division: make it a fast test
2026-05-29 17:10 [PATCH 0/7] app/test: make perf tests usable on wider range of systems Stephen Hemminger
@ 2026-05-29 17:10 ` Stephen Hemminger
2026-05-29 17:10 ` [PATCH 2/7] app/test/reciprocal_division_perf: reduce test time Stephen Hemminger
` (5 subsequent siblings)
6 siblings, 0 replies; 14+ messages in thread
From: Stephen Hemminger @ 2026-05-29 17:10 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
This test is useful to have in CI, but the iteration values
were too large to make it usable as a fast test.
Redo the test with checks around boundary values and
use unit test framework for sub tests.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/test/test_reciprocal_division.c | 279 ++++++++++++++++------------
1 file changed, 157 insertions(+), 122 deletions(-)
diff --git a/app/test/test_reciprocal_division.c b/app/test/test_reciprocal_division.c
index 3d0736d8dd..80f8561523 100644
--- a/app/test/test_reciprocal_division.c
+++ b/app/test/test_reciprocal_division.c
@@ -5,162 +5,197 @@
#include "test.h"
#include <stdio.h>
-#include <unistd.h>
#include <inttypes.h>
#include <rte_common.h>
-#include <rte_cycles.h>
#include <rte_random.h>
#include <rte_reciprocal.h>
-#define MAX_ITERATIONS (1ULL << 32)
-#define DIVIDE_ITER (100)
+#define MAX_ITERATIONS (1ULL << 20)
+#define DIVISORS_RANDOM 64
static int
-test_reciprocal(void)
+test_u32_divide(uint32_t a, uint32_t d, struct rte_reciprocal r)
{
- int result = 0;
- uint32_t divisor_u32 = 0;
- uint32_t dividend_u32;
- uint32_t nresult_u32;
- uint32_t rresult_u32;
- uint64_t i, j;
- uint64_t divisor_u64 = 0;
- uint64_t dividend_u64;
- uint64_t nresult_u64;
- uint64_t rresult_u64;
- struct rte_reciprocal reci_u32 = {0};
- struct rte_reciprocal_u64 reci_u64 = {0};
-
- printf("Validating unsigned 32bit division.\n");
- for (i = 0; i < MAX_ITERATIONS; i++) {
- /* Change divisor every DIVIDE_ITER iterations. */
- if (i % DIVIDE_ITER == 0) {
- divisor_u32 = rte_rand();
- reci_u32 = rte_reciprocal_value(divisor_u32);
- }
-
- dividend_u32 = rte_rand();
- nresult_u32 = dividend_u32 / divisor_u32;
- rresult_u32 = rte_reciprocal_divide(dividend_u32,
- reci_u32);
- if (nresult_u32 != rresult_u32) {
- printf("Division failed, %"PRIu32"/%"PRIu32" = "
- "expected %"PRIu32" result %"PRIu32"\n",
- dividend_u32, divisor_u32,
- nresult_u32, rresult_u32);
- result = 1;
- break;
- }
- }
+ uint32_t expected = a / d;
+ uint32_t result = rte_reciprocal_divide(a, r);
- printf("Validating unsigned 64bit division.\n");
- for (i = 0; i < MAX_ITERATIONS; i++) {
- /* Change divisor every DIVIDE_ITER iterations. */
- if (i % DIVIDE_ITER == 0) {
- divisor_u64 = rte_rand();
- reci_u64 = rte_reciprocal_value_u64(divisor_u64);
- }
+ TEST_ASSERT_EQUAL(expected, result,
+ "%"PRIu32"/%"PRIu32" expected %"PRIu32" got %"PRIu32,
+ a, d, expected, result);
+ return 0;
+}
- dividend_u64 = rte_rand();
- nresult_u64 = dividend_u64 / divisor_u64;
- rresult_u64 = rte_reciprocal_divide_u64(dividend_u64,
- &reci_u64);
- if (nresult_u64 != rresult_u64) {
- printf("Division failed, %"PRIu64"/%"PRIu64" = "
- "expected %"PRIu64" result %"PRIu64"\n",
- dividend_u64, divisor_u64,
- nresult_u64, rresult_u64);
- result = 1;
- break;
+static int
+test_reciprocal_u32(void)
+{
+ const uint32_t edge_div_u32[] = {
+ 1, 2, 3, 7, 0x7fffffff, 0x80000000, 0xfffffffe, UINT32_MAX,
+ };
+ unsigned int n_div = RTE_DIM(edge_div_u32) + DIVISORS_RANDOM;
+
+ for (unsigned int di = 0; di < n_div; di++) {
+ uint32_t d;
+ if (di < RTE_DIM(edge_div_u32))
+ d = edge_div_u32[di]; /* Make sure and test the edge cases */
+ else
+ d = rte_rand_max(UINT32_MAX - 1) + 1;
+
+ struct rte_reciprocal r = rte_reciprocal_value(d);
+ uint32_t qmax = UINT32_MAX / d; /* largest q with q*d <= UINT32_MAX */
+ if (d != 1)
+ qmax++;
+
+ for (unsigned int k = 0; k < MAX_ITERATIONS; k++) {
+ uint32_t q = rte_rand_max(qmax);
+ uint32_t val = q * d; /* fits in u32 */
+
+ /* Check around the value.
+ * Under and overflow of 32 bit value are fine here.
+ */
+ if (test_u32_divide(val - 1, d, r) < 0 ||
+ test_u32_divide(val, d, r) < 0 ||
+ test_u32_divide(val + 1, d, r) < 0)
+ return -1;
}
}
+ return TEST_SUCCESS;
+}
- printf("Validating unsigned 64bit division with 32bit divisor.\n");
- for (i = 0; i < MAX_ITERATIONS; i++) {
- /* Change divisor every DIVIDE_ITER iterations. */
- if (i % DIVIDE_ITER == 0) {
- divisor_u64 = rte_rand() >> 32;
- reci_u64 = rte_reciprocal_value_u64(divisor_u64);
- }
+static int
+test_u64_divide(uint64_t a, uint64_t d, const struct rte_reciprocal_u64 *r)
+{
+ uint64_t expected = a / d;
+ uint64_t result = rte_reciprocal_divide_u64(a, r);
+
+ TEST_ASSERT_EQUAL(expected, result,
+ "%"PRIu64"/%"PRIu64" expected %"PRIu64" got %"PRIu64,
+ a, d, expected, result);
+ return 0;
+}
- dividend_u64 = rte_rand();
- nresult_u64 = dividend_u64 / divisor_u64;
- rresult_u64 = rte_reciprocal_divide_u64(dividend_u64,
- &reci_u64);
+static int
+test_reciprocal_u64(void)
+{
+ const uint64_t edge_div_u64[] = {
+ 1, 2, 3, 7, 0x7fffffff, 0x80000000, 0xfffffffe, UINT64_MAX,
+ };
+ unsigned int n_div = RTE_DIM(edge_div_u64) + DIVISORS_RANDOM;
+
+ for (unsigned int di = 0; di < n_div; di++) {
+ uint64_t d;
+ if (di < RTE_DIM(edge_div_u64))
+ d = edge_div_u64[di];
+ else
+ d = rte_rand_max(UINT64_MAX - 1) + 1;
+
+ struct rte_reciprocal_u64 r = rte_reciprocal_value_u64(d);
+ uint64_t qmax = UINT64_MAX / d; /* largest q with q*d <= UINT64_MAX */
+ if (d != 1)
+ ++qmax;
+
+ for (unsigned int k = 0; k < MAX_ITERATIONS; k++) {
+ uint64_t q = rte_rand_max(qmax);
+ uint64_t val = q * d;
+
+ if (test_u64_divide(val - 1, d, &r) < 0 ||
+ test_u64_divide(val, d, &r) < 0 ||
+ test_u64_divide(val + 1, d, &r) < 0)
+ return -1;
- if (nresult_u64 != rresult_u64) {
- printf("Division failed, %"PRIu64"/%"PRIu64" = "
- "expected %"PRIu64" result %"PRIu64"\n",
- dividend_u64, divisor_u64,
- nresult_u64, rresult_u64);
- result = 1;
- break;
}
}
+ return TEST_SUCCESS;
+}
- printf("Validating division by power of 2.\n");
- for (i = 0; i < 32; i++) {
- divisor_u64 = 1ull << i;
- reci_u64 = rte_reciprocal_value_u64(divisor_u64);
- reci_u32 = rte_reciprocal_value((uint32_t)divisor_u64);
+static int
+test_reciprocal_u64_small(void)
+{
+ /* 64-bit division with a 32-bit-range divisor */
+ uint64_t divisor_u64 = (rte_rand() >> 32) | 1;
+ struct rte_reciprocal_u64 reci_u64 = rte_reciprocal_value_u64(divisor_u64);
+
+ for (unsigned int i = 0; i < MAX_ITERATIONS; i++) {
+ uint64_t dividend_u64 = rte_rand();
+ uint64_t nresult_u64 = dividend_u64 / divisor_u64;
+ uint64_t rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, &reci_u64);
+
+ TEST_ASSERT_EQUAL(nresult_u64, rresult_u64,
+ "%"PRIu64"/%"PRIu64" = expected %"PRIu64" got %"PRIu64,
+ dividend_u64, divisor_u64, nresult_u64, rresult_u64);
+ }
- for (j = 0; j < MAX_ITERATIONS >> 4; j++) {
- dividend_u64 = rte_rand();
+ return TEST_SUCCESS;
+}
- nresult_u64 = dividend_u64 / divisor_u64;
- rresult_u64 = rte_reciprocal_divide_u64(dividend_u64,
+static int
+test_reciprocal_pow2(void)
+{
+ for (unsigned int i = 0; i < 32; i++) {
+ uint64_t divisor_u64 = 1ULL << i;
+ struct rte_reciprocal_u64 reci_u64 = rte_reciprocal_value_u64(divisor_u64);
+ struct rte_reciprocal reci_u32 = rte_reciprocal_value((uint32_t)divisor_u64);
+
+ for (unsigned int j = 0; j < MAX_ITERATIONS >> 4; j++) {
+ uint64_t dividend_u64 = rte_rand();
+ uint64_t nresult_u64 = dividend_u64 / divisor_u64;
+ uint64_t rresult_u64 = rte_reciprocal_divide_u64(dividend_u64,
&reci_u64);
- if (nresult_u64 != rresult_u64) {
- printf(
- "Division 64 failed, %"PRIu64"/%"PRIu64" = "
- "expected %"PRIu64" result %"PRIu64"\n",
- dividend_u64, divisor_u64,
- nresult_u64, rresult_u64);
- result = 1;
- }
-
- nresult_u32 = (dividend_u64 >> 32) / divisor_u64;
- rresult_u32 = rte_reciprocal_divide(
+ TEST_ASSERT_EQUAL(nresult_u64, rresult_u64,
+ "u64 %"PRIu64"/%"PRIu64" = expected %"PRIu64" got %"PRIu64,
+ dividend_u64, divisor_u64,
+ nresult_u64, rresult_u64);
+
+ uint32_t nresult_u32 = (dividend_u64 >> 32) / divisor_u64;
+ uint32_t rresult_u32 = rte_reciprocal_divide(
(dividend_u64 >> 32), reci_u32);
- if (nresult_u32 != rresult_u32) {
- printf(
- "Division 32 failed, %"PRIu64"/%"PRIu64" = "
- "expected %"PRIu64" result %"PRIu64"\n",
- dividend_u64 >> 32, divisor_u64,
- nresult_u64, rresult_u64);
- result = 1;
- break;
- }
+ TEST_ASSERT_EQUAL(nresult_u32, rresult_u32,
+ "u32 %"PRIu64"/%"PRIu64" = expected %"PRIu32" got %"PRIu32,
+ dividend_u64 >> 32, divisor_u64,
+ nresult_u32, rresult_u32);
}
}
- for (; i < 64; i++) {
- divisor_u64 = 1ull << i;
- reci_u64 = rte_reciprocal_value_u64(divisor_u64);
+ for (unsigned int i = 32; i < 64; i++) {
+ uint64_t divisor_u64 = 1ULL << i;
+ struct rte_reciprocal_u64 reci_u64 = rte_reciprocal_value_u64(divisor_u64);
- for (j = 0; j < MAX_ITERATIONS >> 4; j++) {
- dividend_u64 = rte_rand();
-
- nresult_u64 = dividend_u64 / divisor_u64;
- rresult_u64 = rte_reciprocal_divide_u64(dividend_u64,
+ for (unsigned int j = 0; j < MAX_ITERATIONS >> 4; j++) {
+ uint64_t dividend_u64 = rte_rand();
+ uint64_t nresult_u64 = dividend_u64 / divisor_u64;
+ uint64_t rresult_u64 = rte_reciprocal_divide_u64(dividend_u64,
&reci_u64);
- if (nresult_u64 != rresult_u64) {
- printf("Division failed, %"PRIu64"/%"PRIu64" = "
- "expected %"PRIu64" result %"PRIu64"\n",
- dividend_u64, divisor_u64,
- nresult_u64, rresult_u64);
- result = 1;
- break;
- }
+ TEST_ASSERT_EQUAL(nresult_u64, rresult_u64,
+ "u64 %"PRIu64"/%"PRIu64" = expected %"PRIu64" got %"PRIu64,
+ dividend_u64, divisor_u64,
+ nresult_u64, rresult_u64);
}
}
- return result;
+ return TEST_SUCCESS;
+}
+
+static struct unit_test_suite reciprocal_tests = {
+ .suite_name = "reciprocal division autotest",
+ .setup = NULL,
+ .teardown = NULL,
+ .unit_test_cases = {
+ TEST_CASE(test_reciprocal_u32),
+ TEST_CASE(test_reciprocal_u64),
+ TEST_CASE(test_reciprocal_u64_small),
+ TEST_CASE(test_reciprocal_pow2),
+ TEST_CASES_END()
+ }
+};
+
+static int
+test_reciprocal(void)
+{
+ return unit_test_suite_runner(&reciprocal_tests);
}
-REGISTER_PERF_TEST(reciprocal_division, test_reciprocal);
+REGISTER_FAST_TEST(reciprocal_division_autotest, NOHUGE_OK, ASAN_OK, test_reciprocal);
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 2/7] app/test/reciprocal_division_perf: reduce test time
2026-05-29 17:10 [PATCH 0/7] app/test: make perf tests usable on wider range of systems Stephen Hemminger
2026-05-29 17:10 ` [PATCH 1/7] app/test/reciprocal_division: make it a fast test Stephen Hemminger
@ 2026-05-29 17:10 ` Stephen Hemminger
2026-05-29 17:10 ` [PATCH 3/7] app/test/mempool_perf: size mempool by tested cores Stephen Hemminger
` (4 subsequent siblings)
6 siblings, 0 replies; 14+ messages in thread
From: Stephen Hemminger @ 2026-05-29 17:10 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
The test time was excessively long it does not need to go
for 2^32 iterations.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/test/test_reciprocal_division_perf.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/test/test_reciprocal_division_perf.c b/app/test/test_reciprocal_division_perf.c
index 6c8afc6e36..046a77f5f2 100644
--- a/app/test/test_reciprocal_division_perf.c
+++ b/app/test/test_reciprocal_division_perf.c
@@ -13,8 +13,8 @@
#include <rte_random.h>
#include <rte_reciprocal.h>
-#define MAX_ITERATIONS (1ULL << 32)
-#define DIVIDE_ITER (1ULL << 28)
+#define MAX_ITERATIONS (1ULL << 24)
+#define DIVIDE_ITER (1ULL << 10)
static int
test_reciprocal_division_perf(void)
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 3/7] app/test/mempool_perf: size mempool by tested cores
2026-05-29 17:10 [PATCH 0/7] app/test: make perf tests usable on wider range of systems Stephen Hemminger
2026-05-29 17:10 ` [PATCH 1/7] app/test/reciprocal_division: make it a fast test Stephen Hemminger
2026-05-29 17:10 ` [PATCH 2/7] app/test/reciprocal_division_perf: reduce test time Stephen Hemminger
@ 2026-05-29 17:10 ` Stephen Hemminger
2026-06-01 8:12 ` Andrew Rybchenko
2026-05-29 17:10 ` [PATCH 4/7] app/test/mempool_perf: drop constant-values replay Stephen Hemminger
` (3 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Stephen Hemminger @ 2026-05-29 17:10 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Andrew Rybchenko, Morten Brørup
The mempool size is computed from rte_lcore_count() so on systems
with many lcores the test requires multiple GB of hugepages even
for the single-core and dual-core variants. On a 20 lcore system
with 2 GB of hugepages the test fails with:
cannot populate ring_mp_mc mempool
Test Failed
Size the four mempools by the number of cores actually exercised.
Return TEST_SKIPPED rather than -1 when allocation or populate of
a mempool fails, so insufficient memory is reported as a skip and
not as a test failure. Propagate the skip through the combined
mempool_perf_autotest wrapper.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/test/test_mempool_perf.c | 44 +++++++++++++++++++-----------------
1 file changed, 23 insertions(+), 21 deletions(-)
diff --git a/app/test/test_mempool_perf.c b/app/test/test_mempool_perf.c
index e164eca788..19591ad0c9 100644
--- a/app/test/test_mempool_perf.c
+++ b/app/test/test_mempool_perf.c
@@ -84,7 +84,6 @@
#define MEMPOOL_ELT_SIZE 2048
#define MAX_KEEP 32768
#define N (128 * MAX_KEEP)
-#define MEMPOOL_SIZE ((rte_lcore_count()*(MAX_KEEP+RTE_MEMPOOL_CACHE_MAX_SIZE*2))-1)
/* Number of pointers fitting into one cache line. */
#define CACHE_LINE_BURST (RTE_CACHE_LINE_SIZE / sizeof(uintptr_t))
@@ -330,7 +329,7 @@ launch_cores(struct rte_mempool *mp, unsigned int cores)
n_get_bulk, n_put_bulk,
use_constant_values);
- if (rte_mempool_avail_count(mp) != MEMPOOL_SIZE) {
+ if (rte_mempool_avail_count(mp) != mp->size) {
printf("mempool is not full\n");
return -1;
}
@@ -449,22 +448,25 @@ do_all_mempool_perf_tests(unsigned int cores)
const char *mp_cache_ops;
const char *mp_nocache_ops;
const char *default_pool_ops;
+ unsigned int mempool_size = cores *
+ (MAX_KEEP + RTE_MEMPOOL_CACHE_MAX_SIZE * 2) - 1;
int ret = -1;
/* create a mempool (without cache) */
- mp_nocache = rte_mempool_create("perf_test_nocache", MEMPOOL_SIZE,
+ mp_nocache = rte_mempool_create("perf_test_nocache", mempool_size,
MEMPOOL_ELT_SIZE, 0, 0,
NULL, NULL,
my_obj_init, NULL,
SOCKET_ID_ANY, 0);
if (mp_nocache == NULL) {
printf("cannot allocate mempool (without cache)\n");
+ ret = TEST_SKIPPED;
goto err;
}
mp_nocache_ops = rte_mempool_get_ops(mp_nocache->ops_index)->name;
/* create a mempool (with cache) */
- mp_cache = rte_mempool_create("perf_test_cache", MEMPOOL_SIZE,
+ mp_cache = rte_mempool_create("perf_test_cache", mempool_size,
MEMPOOL_ELT_SIZE,
RTE_MEMPOOL_CACHE_MAX_SIZE, 0,
NULL, NULL,
@@ -472,6 +474,7 @@ do_all_mempool_perf_tests(unsigned int cores)
SOCKET_ID_ANY, 0);
if (mp_cache == NULL) {
printf("cannot allocate mempool (with cache)\n");
+ ret = TEST_SKIPPED;
goto err;
}
mp_cache_ops = rte_mempool_get_ops(mp_cache->ops_index)->name;
@@ -480,12 +483,13 @@ do_all_mempool_perf_tests(unsigned int cores)
/* Create a mempool (without cache) based on Default handler */
default_pool_nocache = rte_mempool_create_empty("default_pool_nocache",
- MEMPOOL_SIZE,
+ mempool_size,
MEMPOOL_ELT_SIZE,
0, 0,
SOCKET_ID_ANY, 0);
if (default_pool_nocache == NULL) {
printf("cannot allocate %s mempool (without cache)\n", default_pool_ops);
+ ret = TEST_SKIPPED;
goto err;
}
if (rte_mempool_set_ops_byname(default_pool_nocache, default_pool_ops, NULL) < 0) {
@@ -494,18 +498,20 @@ do_all_mempool_perf_tests(unsigned int cores)
}
if (rte_mempool_populate_default(default_pool_nocache) < 0) {
printf("cannot populate %s mempool\n", default_pool_ops);
+ ret = TEST_SKIPPED;
goto err;
}
rte_mempool_obj_iter(default_pool_nocache, my_obj_init, NULL);
/* Create a mempool (with cache) based on Default handler */
default_pool_cache = rte_mempool_create_empty("default_pool_cache",
- MEMPOOL_SIZE,
+ mempool_size,
MEMPOOL_ELT_SIZE,
RTE_MEMPOOL_CACHE_MAX_SIZE, 0,
SOCKET_ID_ANY, 0);
if (default_pool_cache == NULL) {
printf("cannot allocate %s mempool (with cache)\n", default_pool_ops);
+ ret = TEST_SKIPPED;
goto err;
}
if (rte_mempool_set_ops_byname(default_pool_cache, default_pool_ops, NULL) < 0) {
@@ -514,6 +520,7 @@ do_all_mempool_perf_tests(unsigned int cores)
}
if (rte_mempool_populate_default(default_pool_cache) < 0) {
printf("cannot populate %s mempool\n", default_pool_ops);
+ ret = TEST_SKIPPED;
goto err;
}
rte_mempool_obj_iter(default_pool_cache, my_obj_init, NULL);
@@ -584,27 +591,22 @@ test_mempool_perf_allcores(void)
static int
test_mempool_perf(void)
{
- int ret = -1;
+ int ret;
/* performance test with 1, 2 and max cores */
- if (do_all_mempool_perf_tests(1) < 0)
- goto err;
+ ret = do_all_mempool_perf_tests(1);
+ if (ret != 0)
+ return ret;
if (rte_lcore_count() == 1)
- goto done;
+ return 0;
- if (do_all_mempool_perf_tests(2) < 0)
- goto err;
+ ret = do_all_mempool_perf_tests(2);
+ if (ret != 0)
+ return ret;
if (rte_lcore_count() == 2)
- goto done;
-
- if (do_all_mempool_perf_tests(rte_lcore_count()) < 0)
- goto err;
+ return 0;
-done:
- ret = 0;
-
-err:
- return ret;
+ return do_all_mempool_perf_tests(rte_lcore_count());
}
REGISTER_PERF_TEST(mempool_perf_autotest, test_mempool_perf);
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH 3/7] app/test/mempool_perf: size mempool by tested cores
2026-05-29 17:10 ` [PATCH 3/7] app/test/mempool_perf: size mempool by tested cores Stephen Hemminger
@ 2026-06-01 8:12 ` Andrew Rybchenko
2026-06-01 12:22 ` Morten Brørup
0 siblings, 1 reply; 14+ messages in thread
From: Andrew Rybchenko @ 2026-06-01 8:12 UTC (permalink / raw)
To: Stephen Hemminger, dev; +Cc: Morten Brørup
On 5/29/26 8:10 PM, Stephen Hemminger wrote:
> The mempool size is computed from rte_lcore_count() so on systems
> with many lcores the test requires multiple GB of hugepages even
> for the single-core and dual-core variants. On a 20 lcore system
> with 2 GB of hugepages the test fails with:
>
> cannot populate ring_mp_mc mempool
> Test Failed
>
> Size the four mempools by the number of cores actually exercised.
>
> Return TEST_SKIPPED rather than -1 when allocation or populate of
> a mempool fails, so insufficient memory is reported as a skip and
> not as a test failure. Propagate the skip through the combined
> mempool_perf_autotest wrapper.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [PATCH 3/7] app/test/mempool_perf: size mempool by tested cores
2026-06-01 8:12 ` Andrew Rybchenko
@ 2026-06-01 12:22 ` Morten Brørup
0 siblings, 0 replies; 14+ messages in thread
From: Morten Brørup @ 2026-06-01 12:22 UTC (permalink / raw)
To: Andrew Rybchenko, Stephen Hemminger, dev
> From: Andrew Rybchenko [mailto:andrew.rybchenko@oktetlabs.ru]
> Sent: Monday, 1 June 2026 10.13
>
> On 5/29/26 8:10 PM, Stephen Hemminger wrote:
> > The mempool size is computed from rte_lcore_count() so on systems
> > with many lcores the test requires multiple GB of hugepages even
> > for the single-core and dual-core variants. On a 20 lcore system
> > with 2 GB of hugepages the test fails with:
> >
> > cannot populate ring_mp_mc mempool
> > Test Failed
> >
> > Size the four mempools by the number of cores actually exercised.
> >
> > Return TEST_SKIPPED rather than -1 when allocation or populate of
> > a mempool fails, so insufficient memory is reported as a skip and
> > not as a test failure. Propagate the skip through the combined
> > mempool_perf_autotest wrapper.
> >
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>
> Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
LGTM too.
Acked-by: Morten Brørup <mb@smartsharesystems.com>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 4/7] app/test/mempool_perf: drop constant-values replay
2026-05-29 17:10 [PATCH 0/7] app/test: make perf tests usable on wider range of systems Stephen Hemminger
` (2 preceding siblings ...)
2026-05-29 17:10 ` [PATCH 3/7] app/test/mempool_perf: size mempool by tested cores Stephen Hemminger
@ 2026-05-29 17:10 ` Stephen Hemminger
2026-06-01 8:34 ` Andrew Rybchenko
2026-05-29 17:10 ` [PATCH 5/7] app/test/mempool_perf: scale down for high core counts Stephen Hemminger
` (2 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Stephen Hemminger @ 2026-05-29 17:10 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Andrew Rybchenko, Morten Brørup
The second nested matrix replays each (n_get_bulk == n_put_bulk)
point with use_constant_values=1 to exercise the compile-time
constant bulk-size paths in test_loop(). This roughly doubles the
work for the get/put diagonal at every n_keep without adding new
signal: the cycles/op result for a constant bulk is interesting in
isolated inlining studies, not in routine regression sweeps.
Drop the replay. The use_constant_values switch and its branches
in test_loop() are retained for now since they are exercised by
hand in any local benchmarking.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/test/test_mempool_perf.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/app/test/test_mempool_perf.c b/app/test/test_mempool_perf.c
index 19591ad0c9..dd2f0bbaca 100644
--- a/app/test/test_mempool_perf.c
+++ b/app/test/test_mempool_perf.c
@@ -423,14 +423,6 @@ do_one_mempool_test(struct rte_mempool *mp, unsigned int cores, int external_cac
ret = launch_cores(mp, cores);
if (ret < 0)
return -1;
-
- /* replay test with constant values */
- if (n_get_bulk == n_put_bulk) {
- use_constant_values = 1;
- ret = launch_cores(mp, cores);
- if (ret < 0)
- return -1;
- }
}
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH 4/7] app/test/mempool_perf: drop constant-values replay
2026-05-29 17:10 ` [PATCH 4/7] app/test/mempool_perf: drop constant-values replay Stephen Hemminger
@ 2026-06-01 8:34 ` Andrew Rybchenko
2026-06-01 13:22 ` Morten Brørup
0 siblings, 1 reply; 14+ messages in thread
From: Andrew Rybchenko @ 2026-06-01 8:34 UTC (permalink / raw)
To: Stephen Hemminger, dev; +Cc: Morten Brørup
On 5/29/26 8:10 PM, Stephen Hemminger wrote:
> The second nested matrix replays each (n_get_bulk == n_put_bulk)
> point with use_constant_values=1 to exercise the compile-time
> constant bulk-size paths in test_loop(). This roughly doubles the
> work for the get/put diagonal at every n_keep without adding new
> signal: the cycles/op result for a constant bulk is interesting in
> isolated inlining studies, not in routine regression sweeps.
>
> Drop the replay. The use_constant_values switch and its branches
> in test_loop() are retained for now since they are exercised by
> hand in any local benchmarking.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
As far as I can see you delete the only place where use_constant_values
is set to 1. It looks suspicious and basically preserves dead code.
Since Morten added the code, the patch should wait for his approval.
> ---
> app/test/test_mempool_perf.c | 8 --------
> 1 file changed, 8 deletions(-)
>
> diff --git a/app/test/test_mempool_perf.c b/app/test/test_mempool_perf.c
> index 19591ad0c9..dd2f0bbaca 100644
> --- a/app/test/test_mempool_perf.c
> +++ b/app/test/test_mempool_perf.c
> @@ -423,14 +423,6 @@ do_one_mempool_test(struct rte_mempool *mp, unsigned int cores, int external_cac
> ret = launch_cores(mp, cores);
> if (ret < 0)
> return -1;
> -
> - /* replay test with constant values */
> - if (n_get_bulk == n_put_bulk) {
> - use_constant_values = 1;
> - ret = launch_cores(mp, cores);
> - if (ret < 0)
> - return -1;
> - }
> }
> }
> }
^ permalink raw reply [flat|nested] 14+ messages in thread* RE: [PATCH 4/7] app/test/mempool_perf: drop constant-values replay
2026-06-01 8:34 ` Andrew Rybchenko
@ 2026-06-01 13:22 ` Morten Brørup
0 siblings, 0 replies; 14+ messages in thread
From: Morten Brørup @ 2026-06-01 13:22 UTC (permalink / raw)
To: Andrew Rybchenko, Stephen Hemminger, dev
> From: Andrew Rybchenko [mailto:andrew.rybchenko@oktetlabs.ru]
> Sent: Monday, 1 June 2026 10.35
>
> On 5/29/26 8:10 PM, Stephen Hemminger wrote:
> > The second nested matrix replays each (n_get_bulk == n_put_bulk)
> > point with use_constant_values=1 to exercise the compile-time
> > constant bulk-size paths in test_loop(). This roughly doubles the
> > work for the get/put diagonal at every n_keep without adding new
> > signal: the cycles/op result for a constant bulk is interesting in
> > isolated inlining studies, not in routine regression sweeps.
> >
> > Drop the replay. The use_constant_values switch and its branches
> > in test_loop() are retained for now since they are exercised by
> > hand in any local benchmarking.
> >
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>
> As far as I can see you delete the only place where use_constant_values
> is set to 1. It looks suspicious and basically preserves dead code.
> Since Morten added the code, the patch should wait for his approval.
Having used the mempool perf test extensively myself, I agree that it is painfully slow.
Mempools are very often used with constant request sizes, so testing their performance remains relevant for regression sweeps too.
NAK to this change.
Maybe the testing of constant values could be reduced by using a subset of the non-constant mix of values.
>
> > ---
> > app/test/test_mempool_perf.c | 8 --------
> > 1 file changed, 8 deletions(-)
> >
> > diff --git a/app/test/test_mempool_perf.c
> b/app/test/test_mempool_perf.c
> > index 19591ad0c9..dd2f0bbaca 100644
> > --- a/app/test/test_mempool_perf.c
> > +++ b/app/test/test_mempool_perf.c
> > @@ -423,14 +423,6 @@ do_one_mempool_test(struct rte_mempool *mp,
> unsigned int cores, int external_cac
> > ret = launch_cores(mp, cores);
> > if (ret < 0)
> > return -1;
> > -
> > - /* replay test with constant values */
> > - if (n_get_bulk == n_put_bulk) {
> > - use_constant_values = 1;
> > - ret = launch_cores(mp, cores);
> > - if (ret < 0)
> > - return -1;
> > - }
> > }
> > }
> > }
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 5/7] app/test/mempool_perf: scale down for high core counts
2026-05-29 17:10 [PATCH 0/7] app/test: make perf tests usable on wider range of systems Stephen Hemminger
` (3 preceding siblings ...)
2026-05-29 17:10 ` [PATCH 4/7] app/test/mempool_perf: drop constant-values replay Stephen Hemminger
@ 2026-05-29 17:10 ` Stephen Hemminger
2026-06-01 8:42 ` Andrew Rybchenko
2026-06-01 12:58 ` Morten Brørup
2026-05-29 17:10 ` [PATCH 6/7] app/test/test_rcu_qsbr_perf: call quiescent more often Stephen Hemminger
2026-05-29 17:11 ` [PATCH 7/7] app/test/test_pmd_perf: skip if no device available Stephen Hemminger
6 siblings, 2 replies; 14+ messages in thread
From: Stephen Hemminger @ 2026-05-29 17:10 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Andrew Rybchenko, Morten Brørup
On a 32-core system the test matrix runs the cartesian product of
4 mempools, 3 core-count configurations and ~340 (n_keep, bulk)
points at TIME_S=1 second each: about 67 minutes total, well past
the 10 minute perf-test timeout.
Two reductions, no loss of meaningful signal:
1. Per-point duration: 1 second -> 200 ms. Each point currently
collects 10^5-10^6 mempool ops; 200 ms still yields >10^4
samples, well above the noise floor for a cycles-per-op average.
2. Matrix trim: drop adjacent bulk and n_keep points that don't
produce regime changes. Retained set covers the boundaries
that matter: 1, 4, cache-line burst (8), typical packet burst
(32) and cache size (RTE_MEMPOOL_CACHE_MAX_SIZE = 512) for bulk;
32 (fits in cache), 512 (= cache size) and 32768 (far exceeds
cache) for n_keep.
Combined effect: ~10x runtime reduction.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/test/test_mempool_perf.c | 32 ++++++++++++--------------------
1 file changed, 12 insertions(+), 20 deletions(-)
diff --git a/app/test/test_mempool_perf.c b/app/test/test_mempool_perf.c
index dd2f0bbaca..6801812a8d 100644
--- a/app/test/test_mempool_perf.c
+++ b/app/test/test_mempool_perf.c
@@ -61,26 +61,21 @@
*
* - Pseudorandom max bulk size (*n_max_bulk*)
*
- * - Max bulk from CACHE_LINE_BURST to 256, and RTE_MEMPOOL_CACHE_MAX_SIZE,
- * where CACHE_LINE_BURST is the number of pointers fitting into one CPU cache line.
+ * - Max bulk: CACHE_LINE_BURST, 32, RTE_MEMPOOL_CACHE_MAX_SIZE,
+ * where CACHE_LINE_BURST is the number of pointers fitting into
+ * one CPU cache line.
*
* - Fixed bulk size (*n_get_bulk*, *n_put_bulk*)
*
- * - Bulk get from 1 to 256, and RTE_MEMPOOL_CACHE_MAX_SIZE
- * - Bulk put from 1 to 256, and RTE_MEMPOOL_CACHE_MAX_SIZE
- * - Bulk get and put from 1 to 256, and RTE_MEMPOOL_CACHE_MAX_SIZE, compile time constant
+ * - Bulk get: 1, 4, CACHE_LINE_BURST, 32, RTE_MEMPOOL_CACHE_MAX_SIZE
+ * - Bulk put: 1, 4, CACHE_LINE_BURST, 32, RTE_MEMPOOL_CACHE_MAX_SIZE
*
* - Number of kept objects (*n_keep*)
*
- * - 32
- * - 128
- * - 512
- * - 2048
- * - 8192
- * - 32768
+ * - 32, 512, 32768
*/
-#define TIME_S 1
+#define TIME_MS 200
#define MEMPOOL_ELT_SIZE 2048
#define MAX_KEEP 32768
#define N (128 * MAX_KEEP)
@@ -257,7 +252,7 @@ per_lcore_mempool_test(void *arg)
start_cycles = rte_get_timer_cycles();
- while (time_diff/hz < TIME_S) {
+ while (time_diff < hz * TIME_MS / 1000) {
if (n_max_bulk != 0)
ret = test_loop_random(mp, cache, n_keep, n_max_bulk);
else if (!use_constant_values)
@@ -376,13 +371,10 @@ launch_cores(struct rte_mempool *mp, unsigned int cores)
static int
do_one_mempool_test(struct rte_mempool *mp, unsigned int cores, int external_cache)
{
- unsigned int bulk_tab_max[] = { CACHE_LINE_BURST, 32, 64, 128, 256,
- RTE_MEMPOOL_CACHE_MAX_SIZE, 0 };
- unsigned int bulk_tab_get[] = { 1, 4, CACHE_LINE_BURST, 32, 64, 128, 256,
- RTE_MEMPOOL_CACHE_MAX_SIZE, 0 };
- unsigned int bulk_tab_put[] = { 1, 4, CACHE_LINE_BURST, 32, 64, 128, 256,
- RTE_MEMPOOL_CACHE_MAX_SIZE, 0 };
- unsigned int keep_tab[] = { 32, 128, 512, 2048, 8192, 32768, 0 };
+ unsigned int bulk_tab_max[] = { CACHE_LINE_BURST, 32, RTE_MEMPOOL_CACHE_MAX_SIZE, 0 };
+ unsigned int bulk_tab_get[] = { 1, 4, CACHE_LINE_BURST, 32, RTE_MEMPOOL_CACHE_MAX_SIZE, 0 };
+ unsigned int bulk_tab_put[] = { 1, 4, CACHE_LINE_BURST, 32, RTE_MEMPOOL_CACHE_MAX_SIZE, 0 };
+ unsigned int keep_tab[] = { 32, 512, 32768, 0 };
unsigned int *max_bulk_ptr;
unsigned int *get_bulk_ptr;
unsigned int *put_bulk_ptr;
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH 5/7] app/test/mempool_perf: scale down for high core counts
2026-05-29 17:10 ` [PATCH 5/7] app/test/mempool_perf: scale down for high core counts Stephen Hemminger
@ 2026-06-01 8:42 ` Andrew Rybchenko
2026-06-01 12:58 ` Morten Brørup
1 sibling, 0 replies; 14+ messages in thread
From: Andrew Rybchenko @ 2026-06-01 8:42 UTC (permalink / raw)
To: Stephen Hemminger, dev; +Cc: Morten Brørup
On 5/29/26 8:10 PM, Stephen Hemminger wrote:
> On a 32-core system the test matrix runs the cartesian product of
> 4 mempools, 3 core-count configurations and ~340 (n_keep, bulk)
> points at TIME_S=1 second each: about 67 minutes total, well past
> the 10 minute perf-test timeout.
>
> Two reductions, no loss of meaningful signal:
>
> 1. Per-point duration: 1 second -> 200 ms. Each point currently
> collects 10^5-10^6 mempool ops; 200 ms still yields >10^4
> samples, well above the noise floor for a cycles-per-op average.
>
> 2. Matrix trim: drop adjacent bulk and n_keep points that don't
> produce regime changes. Retained set covers the boundaries
> that matter: 1, 4, cache-line burst (8), typical packet burst
> (32) and cache size (RTE_MEMPOOL_CACHE_MAX_SIZE = 512) for bulk;
> 32 (fits in cache), 512 (= cache size) and 32768 (far exceeds
> cache) for n_keep.
>
> Combined effect: ~10x runtime reduction.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
I have no strong opinion on the patch.
In general it LGTM and makes sense.
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> ---
> app/test/test_mempool_perf.c | 32 ++++++++++++--------------------
> 1 file changed, 12 insertions(+), 20 deletions(-)
>
> diff --git a/app/test/test_mempool_perf.c b/app/test/test_mempool_perf.c
> index dd2f0bbaca..6801812a8d 100644
> --- a/app/test/test_mempool_perf.c
> +++ b/app/test/test_mempool_perf.c
> @@ -61,26 +61,21 @@
> *
> * - Pseudorandom max bulk size (*n_max_bulk*)
> *
> - * - Max bulk from CACHE_LINE_BURST to 256, and RTE_MEMPOOL_CACHE_MAX_SIZE,
> - * where CACHE_LINE_BURST is the number of pointers fitting into one CPU cache line.
> + * - Max bulk: CACHE_LINE_BURST, 32, RTE_MEMPOOL_CACHE_MAX_SIZE,
> + * where CACHE_LINE_BURST is the number of pointers fitting into
> + * one CPU cache line.
> *
> * - Fixed bulk size (*n_get_bulk*, *n_put_bulk*)
> *
> - * - Bulk get from 1 to 256, and RTE_MEMPOOL_CACHE_MAX_SIZE
> - * - Bulk put from 1 to 256, and RTE_MEMPOOL_CACHE_MAX_SIZE
> - * - Bulk get and put from 1 to 256, and RTE_MEMPOOL_CACHE_MAX_SIZE, compile time constant
> + * - Bulk get: 1, 4, CACHE_LINE_BURST, 32, RTE_MEMPOOL_CACHE_MAX_SIZE
> + * - Bulk put: 1, 4, CACHE_LINE_BURST, 32, RTE_MEMPOOL_CACHE_MAX_SIZE
> *
> * - Number of kept objects (*n_keep*)
> *
> - * - 32
> - * - 128
> - * - 512
> - * - 2048
> - * - 8192
> - * - 32768
> + * - 32, 512, 32768
> */
>
> -#define TIME_S 1
> +#define TIME_MS 200
> #define MEMPOOL_ELT_SIZE 2048
> #define MAX_KEEP 32768
> #define N (128 * MAX_KEEP)
> @@ -257,7 +252,7 @@ per_lcore_mempool_test(void *arg)
>
> start_cycles = rte_get_timer_cycles();
>
> - while (time_diff/hz < TIME_S) {
> + while (time_diff < hz * TIME_MS / 1000) {
> if (n_max_bulk != 0)
> ret = test_loop_random(mp, cache, n_keep, n_max_bulk);
> else if (!use_constant_values)
> @@ -376,13 +371,10 @@ launch_cores(struct rte_mempool *mp, unsigned int cores)
> static int
> do_one_mempool_test(struct rte_mempool *mp, unsigned int cores, int external_cache)
> {
> - unsigned int bulk_tab_max[] = { CACHE_LINE_BURST, 32, 64, 128, 256,
> - RTE_MEMPOOL_CACHE_MAX_SIZE, 0 };
> - unsigned int bulk_tab_get[] = { 1, 4, CACHE_LINE_BURST, 32, 64, 128, 256,
> - RTE_MEMPOOL_CACHE_MAX_SIZE, 0 };
> - unsigned int bulk_tab_put[] = { 1, 4, CACHE_LINE_BURST, 32, 64, 128, 256,
> - RTE_MEMPOOL_CACHE_MAX_SIZE, 0 };
> - unsigned int keep_tab[] = { 32, 128, 512, 2048, 8192, 32768, 0 };
> + unsigned int bulk_tab_max[] = { CACHE_LINE_BURST, 32, RTE_MEMPOOL_CACHE_MAX_SIZE, 0 };
> + unsigned int bulk_tab_get[] = { 1, 4, CACHE_LINE_BURST, 32, RTE_MEMPOOL_CACHE_MAX_SIZE, 0 };
> + unsigned int bulk_tab_put[] = { 1, 4, CACHE_LINE_BURST, 32, RTE_MEMPOOL_CACHE_MAX_SIZE, 0 };
> + unsigned int keep_tab[] = { 32, 512, 32768, 0 };
> unsigned int *max_bulk_ptr;
> unsigned int *get_bulk_ptr;
> unsigned int *put_bulk_ptr;
^ permalink raw reply [flat|nested] 14+ messages in thread* RE: [PATCH 5/7] app/test/mempool_perf: scale down for high core counts
2026-05-29 17:10 ` [PATCH 5/7] app/test/mempool_perf: scale down for high core counts Stephen Hemminger
2026-06-01 8:42 ` Andrew Rybchenko
@ 2026-06-01 12:58 ` Morten Brørup
1 sibling, 0 replies; 14+ messages in thread
From: Morten Brørup @ 2026-06-01 12:58 UTC (permalink / raw)
To: Stephen Hemminger, Andrew Rybchenko, dev
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Friday, 29 May 2026 19.11
>
> On a 32-core system the test matrix runs the cartesian product of
> 4 mempools, 3 core-count configurations and ~340 (n_keep, bulk)
> points at TIME_S=1 second each: about 67 minutes total, well past
> the 10 minute perf-test timeout.
>
> Two reductions, no loss of meaningful signal:
>
> 1. Per-point duration: 1 second -> 200 ms. Each point currently
> collects 10^5-10^6 mempool ops; 200 ms still yields >10^4
> samples, well above the noise floor for a cycles-per-op average.
Ack to this.
>
> 2. Matrix trim: drop adjacent bulk and n_keep points that don't
> produce regime changes. Retained set covers the boundaries
> that matter: 1, 4, cache-line burst (8), typical packet burst
> (32) and cache size (RTE_MEMPOOL_CACHE_MAX_SIZE = 512) for bulk;
> 32 (fits in cache), 512 (= cache size) and 32768 (far exceeds
> cache) for n_keep.
My mempool optimization patch [1] introduces a bounce buffer limit, so huge requests are not needlessly copied twice to bounce through the cache, but are moved directly between application memory and the mempool backend driver.
The bounce buffer limit is half the cache size.
So, please keep 256. Maybe change it to RTE_MEMPOOL_CACHE_MAX_SIZE / 2.
[1]: https://patchwork.dpdk.org/project/dpdk/patch/20260526140000.175092-1-mb@smartsharesystems.com/
Also consider keeping 64; it seems to be a popular default burst size for some CPUs.
On the other hand, if the patch introducing default mbuf burst sizes [2] gets accepted, we could replace 32 with RTE_MBUF_BURST_SIZE_THROUGHPUT and 4 with RTE_MBUF_BURST_SIZE_LATENCY.
No strong opinion on 64; I'll leave that up to you.
[2]: https://patchwork.dpdk.org/project/dpdk/list/?series=37914
>
> Combined effect: ~10x runtime reduction.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
With suggested changes,
Acked-by: Morten Brørup <mb@smartsharesystems.com>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 6/7] app/test/test_rcu_qsbr_perf: call quiescent more often
2026-05-29 17:10 [PATCH 0/7] app/test: make perf tests usable on wider range of systems Stephen Hemminger
` (4 preceding siblings ...)
2026-05-29 17:10 ` [PATCH 5/7] app/test/mempool_perf: scale down for high core counts Stephen Hemminger
@ 2026-05-29 17:10 ` Stephen Hemminger
2026-05-29 17:11 ` [PATCH 7/7] app/test/test_pmd_perf: skip if no device available Stephen Hemminger
6 siblings, 0 replies; 14+ messages in thread
From: Stephen Hemminger @ 2026-05-29 17:10 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Honnappa Nagarahalli
The performance test would generate large backlog of quiescent
actions which caused test to take excessively long time.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/test/test_rcu_qsbr_perf.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/app/test/test_rcu_qsbr_perf.c b/app/test/test_rcu_qsbr_perf.c
index bdffd64e60..8768a9ce1a 100644
--- a/app/test/test_rcu_qsbr_perf.c
+++ b/app/test/test_rcu_qsbr_perf.c
@@ -313,9 +313,8 @@ test_rcu_qsbr_hash_reader(void *arg)
pdata[thread_id]++;
}
rte_rcu_qsbr_unlock(temp, thread_id);
+ rte_rcu_qsbr_quiescent(temp, thread_id);
}
- /* Update quiescent state counter */
- rte_rcu_qsbr_quiescent(temp, thread_id);
rte_rcu_qsbr_thread_offline(temp, thread_id);
loop_cnt++;
} while (!writer_done);
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 7/7] app/test/test_pmd_perf: skip if no device available
2026-05-29 17:10 [PATCH 0/7] app/test: make perf tests usable on wider range of systems Stephen Hemminger
` (5 preceding siblings ...)
2026-05-29 17:10 ` [PATCH 6/7] app/test/test_rcu_qsbr_perf: call quiescent more often Stephen Hemminger
@ 2026-05-29 17:11 ` Stephen Hemminger
6 siblings, 0 replies; 14+ messages in thread
From: Stephen Hemminger @ 2026-05-29 17:11 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
Rather than exiting with FAILURE the test should exit
with SKIPPED status if it can't find a device to attach to.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/test/test_pmd_perf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/test/test_pmd_perf.c b/app/test/test_pmd_perf.c
index 995b0a6f20..8eff0a1223 100644
--- a/app/test/test_pmd_perf.c
+++ b/app/test/test_pmd_perf.c
@@ -691,7 +691,7 @@ test_pmd_perf(void)
if (nb_ports < NB_ETHPORTS_USED) {
printf("At least %u port(s) used for perf. test\n",
NB_ETHPORTS_USED);
- return -1;
+ return TEST_SKIPPED;
}
nb_lcores = rte_lcore_count();
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread