gpu: nvgpu: add more tests for cond unit

Add more tests as part of unit tests for condition variables.

Jira NVGPU-4478

Change-Id: I6256727b2174759a71fb1a3fecd18dde5dcdd9cd
Signed-off-by: ajesh <akv@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2274149
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Philip Elcan <pelcan@nvidia.com>
Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
Reviewed-by: Shashank Singh <shashsingh@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
ajesh
2020-01-06 12:12:33 +05:30
committed by Alex Waterman
parent 50af902b71
commit f22f08cdc9
2 changed files with 187 additions and 11 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -29,6 +29,7 @@
#include <nvgpu/cond.h>
#include <nvgpu/thread.h>
#include <nvgpu/timers.h>
#include "posix-cond.h"
@@ -338,6 +339,72 @@ int test_cond_init_destroy(struct unit_module *m,
return UNIT_SUCCESS;
}
int test_cond_bug(struct unit_module *m,
struct gk20a *g, void *args)
{
int ret;
memset(&test_cond, 0, sizeof(struct nvgpu_cond));
if(!EXPECT_BUG(nvgpu_cond_signal(NULL))) {
unit_return_fail(m, "BUG not called for NULL cond var\n");
}
if(!EXPECT_BUG(nvgpu_cond_signal(&test_cond))) {
unit_return_fail(m,
"BUG not called for uninitialized cond var\n");
}
if(!EXPECT_BUG(nvgpu_cond_signal_interruptible(NULL))) {
unit_return_fail(m, "BUG not called for NULL cond var\n");
}
if(!EXPECT_BUG(nvgpu_cond_signal_interruptible(&test_cond))) {
unit_return_fail(m,
"BUG not called for uninitialized cond var\n");
}
if(!EXPECT_BUG(nvgpu_cond_destroy(NULL))) {
unit_return_fail(m, "BUG not called for NULL cond var\n");
}
if(!EXPECT_BUG(nvgpu_cond_signal_locked(NULL))) {
unit_return_fail(m, "BUG not called for NULL cond var\n");
}
if(!EXPECT_BUG(nvgpu_cond_signal_locked(&test_cond))) {
unit_return_fail(m,
"BUG not called for uninitialized cond var\n");
}
ret = nvgpu_cond_broadcast(NULL);
if (ret != -EINVAL) {
unit_return_fail(m, "NULL cond var not handled\n");
}
ret = nvgpu_cond_broadcast(&test_cond);
if (ret != -EINVAL) {
unit_return_fail(m, "Uninitialized cond var not handled\n");
}
ret = nvgpu_cond_broadcast_interruptible(NULL);
if (ret != -EINVAL) {
unit_return_fail(m, "NULL cond var not handled\n");
}
ret = nvgpu_cond_broadcast_interruptible(&test_cond);
if (ret != -EINVAL) {
unit_return_fail(m, "Uninitialized cond var not handled\n");
}
ret = nvgpu_cond_broadcast_locked(&test_cond);
if (ret != -EINVAL) {
unit_return_fail(m, "Uninitialized cond var not handled\n");
}
return UNIT_SUCCESS;
}
int test_cond_signal(struct unit_module *m,
struct gk20a *g, void *args)
{
@@ -423,8 +490,51 @@ int test_cond_signal(struct unit_module *m,
return UNIT_SUCCESS;
}
int test_cond_timeout(struct unit_module *m,
struct gk20a *g, void *args)
{
int ret;
unsigned int timeout;
signed long ts_before, ts_after, delay;
memset(&test_cond, 0, sizeof(struct nvgpu_cond));
timeout = 10;
ret = nvgpu_cond_init(&test_cond);
if (ret != 0) {
unit_return_fail(m, "Cond init failed\n");
}
ts_before = nvgpu_current_time_us();
nvgpu_cond_lock(&test_cond);
ret = nvgpu_cond_timedwait(&test_cond, &timeout);
if (ret != ETIMEDOUT) {
nvgpu_cond_unlock(&test_cond);
nvgpu_cond_destroy(&test_cond);
unit_return_fail(m, "Cond timed wait return error %d\n", ret);
}
ts_after = nvgpu_current_time_us();
delay = ts_after - ts_before;
delay /= 1000;
if (delay < 10) {
nvgpu_cond_unlock(&test_cond);
nvgpu_cond_destroy(&test_cond);
unit_return_fail(m,
"Timed wait Duration incorrect\n");
}
nvgpu_cond_unlock(&test_cond);
nvgpu_cond_destroy(&test_cond);
return UNIT_SUCCESS;
}
struct unit_module_test posix_cond_tests[] = {
UNIT_TEST(init, test_cond_init_destroy, NULL, 0),
UNIT_TEST(bug_cond, test_cond_bug, NULL, 0),
UNIT_TEST(wait_signal, test_cond_signal, &signal_normal, 0),
UNIT_TEST(wait_signal_int, test_cond_signal, &signal_int, 0),
UNIT_TEST(wait_signal_locked, test_cond_signal, &signal_locked, 0),
@@ -435,6 +545,7 @@ struct unit_module_test posix_cond_tests[] = {
UNIT_TEST(wait_condition, test_cond_signal, &condition_wait, 0),
UNIT_TEST(wait_condition_int, test_cond_signal, &condition_wait_int, 0),
UNIT_TEST(wait_condition_locked, test_cond_signal, &condition_wait_locked, 0),
UNIT_TEST(wait_timeout, test_cond_timeout, NULL, 0),
};
UNIT_MODULE(posix_cond, posix_cond_tests, UNIT_PRIO_POSIX_TEST);

View File

@@ -53,7 +53,7 @@
* struct nvgpu_cond
*
* Output:
* The test returns PASS if cond variable initiaisation and cleanup functions
* The test returns PASS if cond variable initialization and cleanup functions
* returns expected success values and internal variables in cond variable
* structure is initialised with proper values.
* The test returns FAIL if either initialisation or cleanup routine fails.
@@ -64,6 +64,37 @@
int test_cond_init_destroy(struct unit_module *m,
struct gk20a *g, void *args);
/**
* Test specification for test_cond_bug
*
* Description: Test NULL and uninitialized cond vars.
*
* Test Type: Feature, Error injection
*
* Inputs:
* 1) Global instance of struct nvgpu_cond.
*
* Steps:
* 1) Call the condition variable functions with NULL as input parameter.
* 2) Make sure that all the called functions either invoke BUG or return
* an error value for NULL value as input parameter.
* 3) Call the condition variable function with uninitialized condition
* variable as input parameter.
* 4) Make sure that all the called functions either invokes BUG or returns
* an error value for uninitialized condition variable passed as input
* parameter.
*
* Output:
* The test returns PASS if all the NULL and uninitialized input parameters
* are handled by the condition variable functions by either calling BUG or by
* returning an error value.
* The test returns FAIL if any of the NULL or uninitialized condition variable
* passed as input parameter is not handled as expected.
*
*/
int test_cond_bug(struct unit_module *m,
struct gk20a *g, void *args);
/**
* Test specification for test_cond_signal
*
@@ -106,16 +137,16 @@ int test_cond_init_destroy(struct unit_module *m,
* - Main Thread:
* 1) Main thread resets the global variables test_code, test_cond
* and test_data.
* 2) Initialise the condition variabe by calling nvgpu_cond_init.
* 2) Initialise the condition variable by calling nvgpu_cond_init.
* 3) Return failure if the init function returns error.
* 4) Copy the test args into global structure instance of unit_test_cond_data.
* 4) Copy the test args into global instance of unit_test_cond_data.
* 5) Reset global variables read_status and bcst_read_status to 0.
* 6) Create the read thread.
* 7) Cleanup the initialised cond variable and return failure if read thread
* creation fails.
* 7) Cleanup the initialised cond variable and return failure if read
* thread creation fails.
* 8) Create the write thread.
* 9) Cleanup the initialised cond variable, cancel the read thread and return
* failure if write thread creation fails.
* 9) Cleanup the initialised cond variable, cancel the read thread and
* return failure if write thread creation fails.
* 10) Wait for both read and write thread to exit using pthread_join.
* 11) Check for global variable read_status and return FAIL if the value
* indicates an error.
@@ -131,7 +162,8 @@ int test_cond_init_destroy(struct unit_module *m,
* 5) Return from the thread handler.
*
* - Write Thread:
* 1) Wait on global variable read_wait to be true before proceeding further.
* 1) Wait on global variable read_wait to be true before proceeding
* further.
* 2) Update the global array test_code with a defined value.
* 3) Reset read_wait to 0.
* 4) Signal the condition variable.
@@ -157,7 +189,7 @@ int test_cond_init_destroy(struct unit_module *m,
*
* e) Wait and Broadcast
* In broadcast test cases an extra read thread is created by the main
* thread. Both the read threads will get blocked on the codition variable.
* thread. Both the read threads will get blocked on the condition variable.
* The write thread has to broadcast the signal, which should bring both
* the read threads out of blocked state. The main thread needs to wait for
* the extra read thread also to exit in this case.
@@ -185,10 +217,43 @@ int test_cond_init_destroy(struct unit_module *m,
* Output:
* All the tests return PASS if the condition variable is properly signalled
* by the write thread and further verification of shared data shows a
* succesful update from write thread with a predefined value.
* successful update from write thread with a predefined value.
* The tests return FAIL, if any of the above conditions are not met.
*
*/
int test_cond_signal(struct unit_module *m,
struct gk20a *g, void *args);
/**
* Test specification for test_cond_timeout
*
* Description: Test time out for a condition variable wait.
*
* Test Type: Feature, Error injection
*
* Inputs:
* 1) Global instance of struct nvgpu_cond.
*
* Steps:
* 1) Initialize the condition variable.
* 2) Call the function nvgpu_cond_timedwait with a timeout value.
* 3) Check the return value from the function nvgpu_cond_timedwait. If the
* return value is not ETIMEDOUT, unlock the mutex associated with the
* condition variable then destroy the condition variable and return fail.
* 4) If the return value is ETIMEDOUT, check the actual duration of timed
* wait. If it is less than the requested timeout value, unlock the mutex
* associated with the condition variable then destroy the condition
* variable and return FAIL.
* 5) Unlock the mutex associated with the condition variable then destroy the
* condition variable and return pass.
*
* Output:
* The test returns PASS if the nvgpu_cond_timedwait function returns
* ETIMEDOUT error.
* The test returns FAIL if the return value from nvgpu_cond_timedwait function
* is not ETIMEDOUT.
*
*/
int test_cond_timeout(struct unit_module *m,
struct gk20a *g, void *args);
#endif /* __UNIT_POSIX_COND_H__ */