mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: unit: atomics: add cmpxchg threaded test
Add a threaded test for nvgpu_cmpxchg API. This test implements an atomic increment using cmpxchg. It uses the existing arithmetic threaded framework to use the cmpxchg_inc() function to verify 100 parallel threads increment the atomic the correct number of times. These are L1 tests since they have longer run times and are unlikely to regress. JIRA NVGPU-2251 Change-Id: I9c2b68052b3a1b6ef20adfa24e7d50746902f754 Signed-off-by: Philip Elcan <pelcan@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2100748 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Alex Waterman <alexw@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
1bfc68ef46
commit
82ce44d882
@@ -44,11 +44,26 @@
|
|||||||
"test_level": 0,
|
"test_level": 0,
|
||||||
"unit": "atomic"
|
"unit": "atomic"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"test": "atomic_cmpxchg_32_threaded",
|
||||||
|
"test_level": 0,
|
||||||
|
"unit": "atomic"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"test": "atomic_cmpxchg_64",
|
"test": "atomic_cmpxchg_64",
|
||||||
"test_level": 0,
|
"test_level": 0,
|
||||||
"unit": "atomic"
|
"unit": "atomic"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"test": "atomic_cmpxchg_64_threaded",
|
||||||
|
"test_level": 0,
|
||||||
|
"unit": "atomic"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test": "atomic_cmpxchg_not_atomic_threaded",
|
||||||
|
"test_level": 0,
|
||||||
|
"unit": "atomic"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"test": "atomic_dec_32",
|
"test": "atomic_dec_32",
|
||||||
"test_level": 0,
|
"test_level": 0,
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ enum atomic_op {
|
|||||||
op_dec_and_test,
|
op_dec_and_test,
|
||||||
op_sub_and_test,
|
op_sub_and_test,
|
||||||
op_add_unless,
|
op_add_unless,
|
||||||
|
op_cmpxchg,
|
||||||
};
|
};
|
||||||
struct atomic_test_args {
|
struct atomic_test_args {
|
||||||
enum atomic_op op;
|
enum atomic_op op;
|
||||||
@@ -558,6 +559,19 @@ static int test_atomic_arithmetic(struct unit_module *m,
|
|||||||
return UNIT_SUCCESS;
|
return UNIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cmpxchg_inc(enum atomic_type type, struct atomic_struct *ref)
|
||||||
|
{
|
||||||
|
bool done = false;
|
||||||
|
long old;
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
old = func_read(type, ref);
|
||||||
|
if (old == func_cmpxchg(type, ref, old, old + 1)) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Support function that runs in the threads for the arithmetic threaded
|
* Support function that runs in the threads for the arithmetic threaded
|
||||||
* test below
|
* test below
|
||||||
@@ -570,7 +584,10 @@ static void *arithmetic_thread(void *__args)
|
|||||||
pthread_barrier_wait(&thread_barrier);
|
pthread_barrier_wait(&thread_barrier);
|
||||||
|
|
||||||
for (i = 0; i < targs->margs->loop_count; i++) {
|
for (i = 0; i < targs->margs->loop_count; i++) {
|
||||||
if (targs->margs->op == op_inc) {
|
if (targs->margs->op == op_cmpxchg) {
|
||||||
|
/* special case with special function */
|
||||||
|
cmpxchg_inc(targs->margs->type, targs->atomic);
|
||||||
|
} else if (targs->margs->op == op_inc) {
|
||||||
func_inc(targs->margs->type, targs->atomic);
|
func_inc(targs->margs->type, targs->atomic);
|
||||||
} else if (targs->margs->op == op_dec) {
|
} else if (targs->margs->op == op_dec) {
|
||||||
func_dec(targs->margs->type, targs->atomic);
|
func_dec(targs->margs->type, targs->atomic);
|
||||||
@@ -750,6 +767,7 @@ static int test_atomic_arithmetic_threaded(struct unit_module *m,
|
|||||||
case op_sub:
|
case op_sub:
|
||||||
case op_inc:
|
case op_inc:
|
||||||
case op_dec:
|
case op_dec:
|
||||||
|
case op_cmpxchg:
|
||||||
expected_val = args->start_val +
|
expected_val = args->start_val +
|
||||||
(args->loop_count * num_threads *
|
(args->loop_count * num_threads *
|
||||||
ATOMIC_OP_SIGN(args->op) * args->value);
|
ATOMIC_OP_SIGN(args->op) * args->value);
|
||||||
@@ -797,8 +815,14 @@ static int test_atomic_arithmetic_threaded(struct unit_module *m,
|
|||||||
|
|
||||||
exit:
|
exit:
|
||||||
pthread_barrier_destroy(&thread_barrier);
|
pthread_barrier_destroy(&thread_barrier);
|
||||||
|
|
||||||
|
if (args->type == NOT_ATOMIC) {
|
||||||
|
/* For the non-atomics, pass is fail and fail is pass */
|
||||||
|
return INVERTED_RESULT(ret);
|
||||||
|
} else {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Thread function for the test_atomic_arithmetic_and_test_threaded() test.
|
* Thread function for the test_atomic_arithmetic_and_test_threaded() test.
|
||||||
@@ -1386,20 +1410,26 @@ static struct atomic_test_args sub_and_test_64_arg = {
|
|||||||
.repeat_count = 5000, /* for threaded test */
|
.repeat_count = 5000, /* for threaded test */
|
||||||
};
|
};
|
||||||
struct atomic_test_args xchg_not_atomic_arg = {
|
struct atomic_test_args xchg_not_atomic_arg = {
|
||||||
|
.op = op_cmpxchg,
|
||||||
.type = NOT_ATOMIC,
|
.type = NOT_ATOMIC,
|
||||||
.start_val = 1,
|
.start_val = 1,
|
||||||
|
.value = 1,
|
||||||
.loop_count = 10000,
|
.loop_count = 10000,
|
||||||
.repeat_count = 2000, /* for threaded test */
|
.repeat_count = 10000, /* for threaded test */
|
||||||
};
|
};
|
||||||
struct atomic_test_args xchg_32_arg = {
|
struct atomic_test_args xchg_32_arg = {
|
||||||
|
.op = op_cmpxchg,
|
||||||
.type = ATOMIC_32,
|
.type = ATOMIC_32,
|
||||||
.start_val = 1,
|
.start_val = 1,
|
||||||
|
.value = 1,
|
||||||
.loop_count = 10000,
|
.loop_count = 10000,
|
||||||
.repeat_count = 2000, /* for threaded test */
|
.repeat_count = 10000, /* for threaded test */
|
||||||
};
|
};
|
||||||
struct atomic_test_args xchg_64_arg = {
|
struct atomic_test_args xchg_64_arg = {
|
||||||
|
.op = op_cmpxchg,
|
||||||
.type = ATOMIC_64,
|
.type = ATOMIC_64,
|
||||||
.start_val = INT_MAX,
|
.start_val = INT_MAX,
|
||||||
|
.value = 1,
|
||||||
.loop_count = 10000,
|
.loop_count = 10000,
|
||||||
.repeat_count = 2000, /* for threaded test */
|
.repeat_count = 2000, /* for threaded test */
|
||||||
};
|
};
|
||||||
@@ -1452,6 +1482,9 @@ struct unit_module_test atomic_tests[] = {
|
|||||||
UNIT_TEST(atomic_add_64_threaded, test_atomic_arithmetic_threaded, &add_64_arg, 0),
|
UNIT_TEST(atomic_add_64_threaded, test_atomic_arithmetic_threaded, &add_64_arg, 0),
|
||||||
UNIT_TEST(atomic_sub_32_threaded, test_atomic_arithmetic_threaded, &sub_32_arg, 0),
|
UNIT_TEST(atomic_sub_32_threaded, test_atomic_arithmetic_threaded, &sub_32_arg, 0),
|
||||||
UNIT_TEST(atomic_sub_64_threaded, test_atomic_arithmetic_threaded, &sub_64_arg, 0),
|
UNIT_TEST(atomic_sub_64_threaded, test_atomic_arithmetic_threaded, &sub_64_arg, 0),
|
||||||
|
UNIT_TEST(atomic_cmpxchg_not_atomic_threaded, test_atomic_arithmetic_threaded, &xchg_not_atomic_arg, 0),
|
||||||
|
UNIT_TEST(atomic_cmpxchg_32_threaded, test_atomic_arithmetic_threaded, &xchg_32_arg, 0),
|
||||||
|
UNIT_TEST(atomic_cmpxchg_64_threaded, test_atomic_arithmetic_threaded, &xchg_64_arg, 0),
|
||||||
|
|
||||||
/* Level 1 tests */
|
/* Level 1 tests */
|
||||||
UNIT_TEST(atomic_inc_and_test_not_atomic_threaded, test_atomic_arithmetic_and_test_threaded, &inc_and_test_not_atomic_arg, 1),
|
UNIT_TEST(atomic_inc_and_test_not_atomic_threaded, test_atomic_arithmetic_and_test_threaded, &inc_and_test_not_atomic_arg, 1),
|
||||||
|
|||||||
Reference in New Issue
Block a user