mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 09:57:08 +03:00
gpu: nvgpu: add UT for timers unit
Add unit test cases for timers unit. Jira NVGPU-2655 Change-Id: Ie3f3001dc8b89cdd13cde3d4c326f2481dabd425 Signed-off-by: ajesh <akv@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2179108 GVS: Gerrit_Virtual_Submit Reviewed-by: Alex Waterman <alexw@nvidia.com> Reviewed-by: Vaibhav Kachore <vkachore@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
@@ -43,6 +43,7 @@ NV_REPOSITORY_COMPONENTS += userspace/units/posix/sizes
|
|||||||
NV_REPOSITORY_COMPONENTS += userspace/units/init
|
NV_REPOSITORY_COMPONENTS += userspace/units/init
|
||||||
NV_REPOSITORY_COMPONENTS += userspace/units/posix/thread
|
NV_REPOSITORY_COMPONENTS += userspace/units/posix/thread
|
||||||
NV_REPOSITORY_COMPONENTS += userspace/units/posix/cond
|
NV_REPOSITORY_COMPONENTS += userspace/units/posix/cond
|
||||||
|
NV_REPOSITORY_COMPONENTS += userspace/units/posix/timers
|
||||||
NV_REPOSITORY_COMPONENTS += userspace/units/interface/bsearch
|
NV_REPOSITORY_COMPONENTS += userspace/units/interface/bsearch
|
||||||
NV_REPOSITORY_COMPONENTS += userspace/units/interface/lock
|
NV_REPOSITORY_COMPONENTS += userspace/units/interface/lock
|
||||||
NV_REPOSITORY_COMPONENTS += userspace/units/interface/atomic
|
NV_REPOSITORY_COMPONENTS += userspace/units/interface/atomic
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ nvgpu_gr_config_set_sm_info_sm_index
|
|||||||
nvgpu_gr_config_get_sm_info_sm_index
|
nvgpu_gr_config_get_sm_info_sm_index
|
||||||
nvgpu_gr_config_set_gpc_tpc_mask
|
nvgpu_gr_config_set_gpc_tpc_mask
|
||||||
nvgpu_gr_config_get_gpc_tpc_mask
|
nvgpu_gr_config_get_gpc_tpc_mask
|
||||||
|
nvgpu_hr_timestamp
|
||||||
nvgpu_can_busy
|
nvgpu_can_busy
|
||||||
nvgpu_channel_alloc_inst
|
nvgpu_channel_alloc_inst
|
||||||
nvgpu_channel_cleanup_sw
|
nvgpu_channel_cleanup_sw
|
||||||
@@ -123,6 +124,9 @@ nvgpu_cond_signal_interruptible
|
|||||||
nvgpu_cond_signal_locked
|
nvgpu_cond_signal_locked
|
||||||
nvgpu_cond_timedwait
|
nvgpu_cond_timedwait
|
||||||
nvgpu_cond_unlock
|
nvgpu_cond_unlock
|
||||||
|
nvgpu_current_time_ms
|
||||||
|
nvgpu_current_time_ns
|
||||||
|
nvgpu_current_time_us
|
||||||
nvgpu_detect_chip
|
nvgpu_detect_chip
|
||||||
nvgpu_dma_alloc
|
nvgpu_dma_alloc
|
||||||
nvgpu_dma_alloc_get_fault_injection
|
nvgpu_dma_alloc_get_fault_injection
|
||||||
@@ -197,6 +201,7 @@ nvgpu_mm_get_available_big_page_sizes
|
|||||||
nvgpu_mm_get_default_big_page_size
|
nvgpu_mm_get_default_big_page_size
|
||||||
nvgpu_mm_setup_hw
|
nvgpu_mm_setup_hw
|
||||||
nvgpu_mm_suspend
|
nvgpu_mm_suspend
|
||||||
|
nvgpu_msleep
|
||||||
nvgpu_mutex_acquire
|
nvgpu_mutex_acquire
|
||||||
nvgpu_mutex_destroy
|
nvgpu_mutex_destroy
|
||||||
nvgpu_mutex_init
|
nvgpu_mutex_init
|
||||||
@@ -248,6 +253,9 @@ nvgpu_readl
|
|||||||
nvgpu_readl_impl
|
nvgpu_readl_impl
|
||||||
nvgpu_runlist_construct_locked
|
nvgpu_runlist_construct_locked
|
||||||
nvgpu_rwsem_init
|
nvgpu_rwsem_init
|
||||||
|
nvgpu_timeout_expired_msg_impl
|
||||||
|
nvgpu_timeout_init
|
||||||
|
nvgpu_timeout_peek_expired
|
||||||
nvgpu_tsg_abort
|
nvgpu_tsg_abort
|
||||||
nvgpu_tsg_bind_channel
|
nvgpu_tsg_bind_channel
|
||||||
nvgpu_tsg_check_and_get_from_id
|
nvgpu_tsg_check_and_get_from_id
|
||||||
@@ -282,8 +290,10 @@ nvgpu_thread_is_running
|
|||||||
nvgpu_thread_should_stop
|
nvgpu_thread_should_stop
|
||||||
nvgpu_thread_stop
|
nvgpu_thread_stop
|
||||||
nvgpu_thread_stop_graceful
|
nvgpu_thread_stop_graceful
|
||||||
|
nvgpu_udelay
|
||||||
nvgpu_userd_init_slabs
|
nvgpu_userd_init_slabs
|
||||||
nvgpu_usermode_writel
|
nvgpu_usermode_writel
|
||||||
|
nvgpu_usleep_range
|
||||||
nvgpu_vfree_impl
|
nvgpu_vfree_impl
|
||||||
nvgpu_vm_area_alloc
|
nvgpu_vm_area_alloc
|
||||||
nvgpu_vm_area_free
|
nvgpu_vm_area_free
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ UNITS := \
|
|||||||
$(UNIT_SRC)/posix/sizes \
|
$(UNIT_SRC)/posix/sizes \
|
||||||
$(UNIT_SRC)/posix/thread \
|
$(UNIT_SRC)/posix/thread \
|
||||||
$(UNIT_SRC)/posix/cond \
|
$(UNIT_SRC)/posix/cond \
|
||||||
|
$(UNIT_SRC)/posix/timers \
|
||||||
$(UNIT_SRC)/pramin \
|
$(UNIT_SRC)/pramin \
|
||||||
$(UNIT_SRC)/init \
|
$(UNIT_SRC)/init \
|
||||||
$(UNIT_SRC)/interface/bsearch \
|
$(UNIT_SRC)/interface/bsearch \
|
||||||
|
|||||||
26
userspace/units/posix/timers/Makefile
Normal file
26
userspace/units/posix/timers/Makefile
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Copyright (c) 2019, 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"),
|
||||||
|
# to deal in the Software without restriction, including without limitation
|
||||||
|
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
# and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
# Software is furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
|
||||||
|
OBJS = posix-timers.o
|
||||||
|
MODULE = posix-timers
|
||||||
|
|
||||||
|
include ../../Makefile.units
|
||||||
35
userspace/units/posix/timers/Makefile.interface.tmk
Normal file
35
userspace/units/posix/timers/Makefile.interface.tmk
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||||
|
#
|
||||||
|
# Copyright (c) 2019, 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"),
|
||||||
|
# to deal in the Software without restriction, including without limitation
|
||||||
|
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
# and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
# Software is furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
# tmake for SW Mobile component makefile
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
NVGPU_UNIT_NAME=posix-timers
|
||||||
|
|
||||||
|
include $(NV_COMPONENT_DIR)/../../Makefile.units.common.interface.tmk
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# indent-tabs-mode: t
|
||||||
|
# tab-width: 8
|
||||||
|
# End:
|
||||||
|
# vi: set tabstop=8 noexpandtab:
|
||||||
35
userspace/units/posix/timers/Makefile.tmk
Normal file
35
userspace/units/posix/timers/Makefile.tmk
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
################################### tell Emacs this is a -*- makefile-gmake -*-
|
||||||
|
#
|
||||||
|
# Copyright (c) 2019, 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"),
|
||||||
|
# to deal in the Software without restriction, including without limitation
|
||||||
|
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
# and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
# Software is furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
# tmake for SW Mobile component makefile
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
NVGPU_UNIT_NAME=posix-timers
|
||||||
|
|
||||||
|
include $(NV_COMPONENT_DIR)/../../Makefile.units.common.tmk
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# indent-tabs-mode: t
|
||||||
|
# tab-width: 8
|
||||||
|
# End:
|
||||||
|
# vi: set tabstop=8 noexpandtab:
|
||||||
345
userspace/units/posix/timers/posix-timers.c
Normal file
345
userspace/units/posix/timers/posix-timers.c
Normal file
@@ -0,0 +1,345 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <unit/io.h>
|
||||||
|
#include <unit/unit.h>
|
||||||
|
|
||||||
|
#include <nvgpu/timers.h>
|
||||||
|
#include "posix-timers.h"
|
||||||
|
|
||||||
|
struct test_timer_args {
|
||||||
|
bool counter_timer;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct test_timer_args init_args = {
|
||||||
|
.counter_timer = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TEST_TIMER_COUNT 10
|
||||||
|
|
||||||
|
/* The value should be kept below 999 since it is used to calculate
|
||||||
|
* the duration paramater to usleep. This will ensure that the duration
|
||||||
|
* value passed to usleep is less than 1000000.
|
||||||
|
*/
|
||||||
|
#define TEST_TIMER_DURATION 10
|
||||||
|
|
||||||
|
static struct nvgpu_timeout test_timeout;
|
||||||
|
|
||||||
|
int test_timer_init(struct unit_module *m,
|
||||||
|
struct gk20a *g, void *args)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned int duration;
|
||||||
|
unsigned long flags;
|
||||||
|
struct test_timer_args *test_args = (struct test_timer_args *)args;
|
||||||
|
|
||||||
|
if (test_args->counter_timer == true) {
|
||||||
|
duration = TEST_TIMER_COUNT;
|
||||||
|
flags = NVGPU_TIMER_RETRY_TIMER;
|
||||||
|
} else {
|
||||||
|
duration = TEST_TIMER_DURATION;
|
||||||
|
flags = NVGPU_TIMER_CPU_TIMER;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = nvgpu_timeout_init(g, &test_timeout,
|
||||||
|
duration,
|
||||||
|
flags);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
unit_return_fail(m, "Timer init failed %d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (test_timeout.g != g) {
|
||||||
|
unit_return_fail(m, "Timer g struct mismatch %d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (test_timeout.flags != flags) {
|
||||||
|
unit_return_fail(m, "Timer flags mismatch %d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return UNIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_timer_init_err(struct unit_module *m,
|
||||||
|
struct gk20a *g, void *args)
|
||||||
|
{
|
||||||
|
int ret, i;
|
||||||
|
|
||||||
|
for (i = 0; i < 12; i++) {
|
||||||
|
memset(&test_timeout, 0, sizeof(struct nvgpu_timeout));
|
||||||
|
/* nvgpu_tiemout_init accepts only BIT(0), BIT(8), and BIT(9) as
|
||||||
|
* valid flag bits. So ret should be EINVAL */
|
||||||
|
ret = nvgpu_timeout_init(g, &test_timeout, 10, (1 << i));
|
||||||
|
|
||||||
|
if ((i == 0) || (i == 8) || (i == 9)) {
|
||||||
|
if (ret != 0) {
|
||||||
|
unit_return_fail(m,
|
||||||
|
"Timer init failed %d\n",
|
||||||
|
ret);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ret != -EINVAL) {
|
||||||
|
unit_return_fail(m,
|
||||||
|
"Timer init with invalid flag %d\n",
|
||||||
|
ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BIT(0), BIT(8) and BIT(9) set. Return value should be 0 */
|
||||||
|
ret = nvgpu_timeout_init(g, &test_timeout, 10, 0x301);
|
||||||
|
if (ret != 0) {
|
||||||
|
unit_return_fail(m,"Timer init failed with flag 0x301\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BIT(8) and BIT(9) set. Return value should be 0 */
|
||||||
|
ret = nvgpu_timeout_init(g, &test_timeout, 10, 0x300);
|
||||||
|
if (ret != 0) {
|
||||||
|
unit_return_fail(m,"Timer init failed with flag 0x300\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BIT(0) and BIT(8) set. Return value should be 0 */
|
||||||
|
ret = nvgpu_timeout_init(g, &test_timeout, 10, 0x101);
|
||||||
|
if (ret != 0) {
|
||||||
|
unit_return_fail(m,"Timer init failed with flag 0x101\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BIT(0) and BIT(9) set. Return value should be 0 */
|
||||||
|
ret = nvgpu_timeout_init(g, &test_timeout, 10, 0x201);
|
||||||
|
if (ret != 0) {
|
||||||
|
unit_return_fail(m,"Timer init failed with flag 0x201\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BIT(0), BIT(7) and BIT(9) set. Return value should be -EINVAL */
|
||||||
|
ret = nvgpu_timeout_init(g, &test_timeout, 10, 0x281);
|
||||||
|
if (ret != -EINVAL) {
|
||||||
|
unit_return_fail(m,"Timer init failed with flag 0x281\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BIT(5), BIT(7) and BIT(9) set. Return value should be -EINVAL */
|
||||||
|
ret = nvgpu_timeout_init(g, &test_timeout, 10, 0x2A0);
|
||||||
|
if (ret != -EINVAL) {
|
||||||
|
unit_return_fail(m,"Timer init failed with flag 0x2A0\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BIT(1), BIT(2) and BIT(3) set. Return value should be -EINVAL */
|
||||||
|
ret = nvgpu_timeout_init(g, &test_timeout, 10, 0x00E);
|
||||||
|
if (ret != -EINVAL) {
|
||||||
|
unit_return_fail(m,"Timer init failed with flag 0x00E\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BIT(1) to BIT(7) set. Return value should be -EINVAL */
|
||||||
|
ret = nvgpu_timeout_init(g, &test_timeout, 10, 0x07E);
|
||||||
|
if (ret != -EINVAL) {
|
||||||
|
unit_return_fail(m,"Timer init failed with flag 0x07E\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All bits set. Return value should be -EINVAL */
|
||||||
|
ret = nvgpu_timeout_init(g, &test_timeout, 10, 0xFFFFFFFFFFFFFFFF);
|
||||||
|
if (ret != -EINVAL) {
|
||||||
|
unit_return_fail(m,"Timer init failed with flag all 1s\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return UNIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_timer_counter(struct unit_module *m,
|
||||||
|
struct gk20a *g, void *args)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
memset(&test_timeout, 0, sizeof(struct nvgpu_timeout));
|
||||||
|
|
||||||
|
ret = nvgpu_timeout_init(g, &test_timeout,
|
||||||
|
TEST_TIMER_COUNT,
|
||||||
|
NVGPU_TIMER_RETRY_TIMER);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
unit_return_fail(m, "Timer init failed %d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
usleep(1);
|
||||||
|
} while (nvgpu_timeout_expired(&test_timeout) == 0);
|
||||||
|
|
||||||
|
if (!nvgpu_timeout_peek_expired(&test_timeout)) {
|
||||||
|
unit_return_fail(m, "Counter mismatch %d\n",
|
||||||
|
test_timeout.retries.attempted);
|
||||||
|
}
|
||||||
|
|
||||||
|
return UNIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_timer_duration(struct unit_module *m,
|
||||||
|
struct gk20a *g, void *args)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
memset(&test_timeout, 0, sizeof(struct nvgpu_timeout));
|
||||||
|
|
||||||
|
ret = nvgpu_timeout_init(g, &test_timeout,
|
||||||
|
TEST_TIMER_DURATION,
|
||||||
|
NVGPU_TIMER_CPU_TIMER);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
unit_return_fail(m, "Timer init failed %d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sleep for TEST_TIMER_DURATION */
|
||||||
|
usleep((TEST_TIMER_DURATION * 1000));
|
||||||
|
|
||||||
|
do {
|
||||||
|
usleep(10);
|
||||||
|
ret = nvgpu_timeout_expired(&test_timeout);
|
||||||
|
|
||||||
|
} while (ret == 0);
|
||||||
|
|
||||||
|
if (ret != -ETIMEDOUT) {
|
||||||
|
unit_return_fail(m, "Duration timer not expired %d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nvgpu_timeout_peek_expired(&test_timeout)) {
|
||||||
|
unit_return_fail(m, "Duration failure\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return UNIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_timer_delay(struct unit_module *m,
|
||||||
|
struct gk20a *g, void *args)
|
||||||
|
{
|
||||||
|
signed long ts_before, ts_after, delay;
|
||||||
|
|
||||||
|
ts_before = nvgpu_current_time_us();
|
||||||
|
nvgpu_udelay(5000);
|
||||||
|
ts_after = nvgpu_current_time_us();
|
||||||
|
|
||||||
|
delay = ts_after - ts_before;
|
||||||
|
delay /= 1000;
|
||||||
|
|
||||||
|
if (delay < 5) {
|
||||||
|
unit_return_fail(m,
|
||||||
|
"Delay Duration incorrect\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ts_before = nvgpu_current_time_us();
|
||||||
|
nvgpu_usleep_range(5000, 10000);
|
||||||
|
ts_after = nvgpu_current_time_us();
|
||||||
|
|
||||||
|
delay = ts_after - ts_before;
|
||||||
|
delay /= 1000;
|
||||||
|
|
||||||
|
if (delay < 5) {
|
||||||
|
unit_return_fail(m,
|
||||||
|
"Delay Duration incorrect\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return UNIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_timer_msleep(struct unit_module *m,
|
||||||
|
struct gk20a *g, void *args)
|
||||||
|
{
|
||||||
|
signed long ts_before, ts_after, delay;
|
||||||
|
|
||||||
|
delay = 0;
|
||||||
|
|
||||||
|
ts_before = nvgpu_current_time_ms();
|
||||||
|
nvgpu_msleep(5);
|
||||||
|
ts_after = nvgpu_current_time_ms();
|
||||||
|
|
||||||
|
delay = ts_after - ts_before;
|
||||||
|
|
||||||
|
if (delay < 5) {
|
||||||
|
unit_return_fail(m, "Sleep Duration incorrect\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return UNIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_timer_hrtimestamp(struct unit_module *m,
|
||||||
|
struct gk20a *g, void *args)
|
||||||
|
{
|
||||||
|
unsigned long cycles_read, cycles_bkp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
cycles_read = 0;
|
||||||
|
cycles_bkp = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 50; i++) {
|
||||||
|
cycles_read = nvgpu_hr_timestamp();
|
||||||
|
|
||||||
|
if (cycles_read < cycles_bkp) {
|
||||||
|
unit_return_fail(m,
|
||||||
|
"HR cycle value error %ld < %ld\n",
|
||||||
|
cycles_read, cycles_bkp);
|
||||||
|
}
|
||||||
|
|
||||||
|
cycles_bkp = cycles_read;
|
||||||
|
usleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return UNIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_timer_compare(struct unit_module *m,
|
||||||
|
struct gk20a *g, void *args)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
signed long time_ms, time_ns;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
time_ms = 0;
|
||||||
|
time_ns = 0;
|
||||||
|
|
||||||
|
while (i < 10) {
|
||||||
|
time_ms = nvgpu_current_time_ms();
|
||||||
|
time_ns = nvgpu_current_time_ns();
|
||||||
|
|
||||||
|
time_ns /= 1000000;
|
||||||
|
|
||||||
|
if (time_ns < time_ms) {
|
||||||
|
unit_return_fail(m,
|
||||||
|
"Err, ms and ns mismatch\n");
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
usleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return UNIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct unit_module_test posix_timers_tests[] = {
|
||||||
|
UNIT_TEST(init, test_timer_init, &init_args, 0),
|
||||||
|
UNIT_TEST(init_err, test_timer_init_err, NULL, 0),
|
||||||
|
UNIT_TEST(counter, test_timer_counter, NULL, 0),
|
||||||
|
UNIT_TEST(duration, test_timer_duration, NULL, 0),
|
||||||
|
UNIT_TEST(delay, test_timer_delay, NULL, 0),
|
||||||
|
UNIT_TEST(msleep, test_timer_msleep, NULL, 0),
|
||||||
|
UNIT_TEST(hr_cycles, test_timer_hrtimestamp, NULL, 0),
|
||||||
|
UNIT_TEST(compare, test_timer_compare, NULL, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
UNIT_MODULE(posix_timers, posix_timers_tests, UNIT_PRIO_POSIX_TEST);
|
||||||
260
userspace/units/posix/timers/posix-timers.h
Normal file
260
userspace/units/posix/timers/posix-timers.h
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup SWUTS-posix-timers
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* Software Unit Test Specification for posix-timers
|
||||||
|
*/
|
||||||
|
#ifndef __UNIT_POSIX_TIMERS_H__
|
||||||
|
#define __UNIT_POSIX_TIMERS_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test specification for test_timer_init
|
||||||
|
*
|
||||||
|
* Description: Test the timer initialization routine.
|
||||||
|
*
|
||||||
|
* Test Type: Feature based.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* 1) The type of timer to be tested is passed as an argument to the test.
|
||||||
|
* 2) Global defines for flag and duration values.
|
||||||
|
* 3) Global nvgpu_timeout structure instance.
|
||||||
|
*
|
||||||
|
* Steps:
|
||||||
|
* 1) Check for the type of timer to be tested.
|
||||||
|
* 2) Populate the flags and duration values depending on the timer type.
|
||||||
|
* 3) Invoke the timer init function.
|
||||||
|
* 4) Check the return value for errors.
|
||||||
|
* 5) Check the internal parameters in nvgpu_timeout structure to ensure
|
||||||
|
* proper initialisation.
|
||||||
|
*
|
||||||
|
* Output:
|
||||||
|
* The test returns PASS if the return value from timer init function
|
||||||
|
* indicates success and the internal parameter values in nvgpu_timeout
|
||||||
|
* structure is initialised as per the passed arguments.
|
||||||
|
* Test returns FAIL if timer init function fails or if any of the
|
||||||
|
* parameters inside the nvgpu_timeout struct is not initialised properly.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int test_timer_init(struct unit_module *m,
|
||||||
|
struct gk20a *g, void *args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test specification for test_timer_init_err
|
||||||
|
*
|
||||||
|
* Description: Test the timer initialisation routine error path.
|
||||||
|
*
|
||||||
|
* Test Type: Boundary Value analysis.
|
||||||
|
*
|
||||||
|
* Inputs:
|
||||||
|
* 1) Global nvgpu_timeout structure instance.
|
||||||
|
*
|
||||||
|
* Steps:
|
||||||
|
* 1) Invoke timer initialisation routine in loop with different value for
|
||||||
|
* flags parameter for each invocation.
|
||||||
|
* 2) Check for the corresponding return value. The timer initialisation
|
||||||
|
* function should return error for invalid flag values and return success
|
||||||
|
* for valid flag values.
|
||||||
|
*
|
||||||
|
* Output:
|
||||||
|
* The test returns PASS if the initialisation routine returns an appropriate
|
||||||
|
* return value as per the flag value passed for each invocation.
|
||||||
|
* The test returns FAIL if the initialisation routine does not return the
|
||||||
|
* expected value for a particular flag for any of the invocation.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int test_timer_init_err(struct unit_module *m,
|
||||||
|
struct gk20a *g, void *args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test specification for test_timer_counter
|
||||||
|
*
|
||||||
|
* Description: Test the counter based timer functionality.
|
||||||
|
*
|
||||||
|
* Test Type: Feature based.
|
||||||
|
*
|
||||||
|
* Input:
|
||||||
|
* 1) Global nvgpu_timeout structure instance.
|
||||||
|
* 2) Global defines for flag and duration parameters.
|
||||||
|
*
|
||||||
|
* Steps:
|
||||||
|
* 1) Reset the global nvgpu_timeout structure with all 0s.
|
||||||
|
* 2) Initialise the timeout structure.
|
||||||
|
* 3) Check the return value for error.
|
||||||
|
* 4) Loop and check for the timer expiry. Sleep is introduced
|
||||||
|
* between each loop.
|
||||||
|
* 5) Confirm the status of the timer expiry by verifying the
|
||||||
|
* counter value.
|
||||||
|
*
|
||||||
|
* Output:
|
||||||
|
* Test returns PASS if the timer expires after the programmed
|
||||||
|
* counter value.
|
||||||
|
* Test returns FAIL if the initialisation routine returns error or
|
||||||
|
* timer expires before the programmed counter value is reached.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int test_timer_counter(struct unit_module *m,
|
||||||
|
struct gk20a *g, void *args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test specification for test_timer_duration
|
||||||
|
*
|
||||||
|
* Description: Test the duration based timer functionality.
|
||||||
|
*
|
||||||
|
* Test Type: Feature based.
|
||||||
|
*
|
||||||
|
* Input:
|
||||||
|
* 1) Global nvgpu_timeout structure instance.
|
||||||
|
* 2) Global defines for flag and duration parameters.
|
||||||
|
*
|
||||||
|
* Steps:
|
||||||
|
* 1) Reset the global nvgpu_timeout structure to all 0s.
|
||||||
|
* 2) Initialise the timeout structure.
|
||||||
|
* 3) Check the return value for error.
|
||||||
|
* 4) Sleep for the required duration + 500ms to ensure the timer expires.
|
||||||
|
* 5) Check for the timer status.
|
||||||
|
* 6) Reconfirm the timer status.
|
||||||
|
*
|
||||||
|
* Output:
|
||||||
|
* Test returns PASS if the timer expires after the programmed
|
||||||
|
* duration.
|
||||||
|
* Test returns FAIL if the initialisation routine returns error or if
|
||||||
|
* the timer does not expire even after the programmed duration.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int test_timer_duration(struct unit_module *m,
|
||||||
|
struct gk20a *g, void *args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test specification for test_timer_delay
|
||||||
|
*
|
||||||
|
* Description: Test the delay functionality.
|
||||||
|
*
|
||||||
|
* Test Type: Feature based.
|
||||||
|
*
|
||||||
|
* Input: None.
|
||||||
|
*
|
||||||
|
* Steps:
|
||||||
|
* 1) Get the current time in us.
|
||||||
|
* 2) Delay the execution using nvpgu_udelay function.
|
||||||
|
* 3) Get the time after the delay function is executed.
|
||||||
|
* 4) Calculate the difference between both timestamps.
|
||||||
|
* 5) Convert it into msec.
|
||||||
|
* 6) If the difference is less than the duration for which the
|
||||||
|
* delay was requested, return fail.
|
||||||
|
* 7) Continue steps 1-6 for the wrapper api nvgpu_usleep_range
|
||||||
|
* which internally uses nvgpu_udelay itself.
|
||||||
|
*
|
||||||
|
* Output:
|
||||||
|
* Test returns PASS if the delay function actually delays the execution
|
||||||
|
* for required amount of time. It also returns PASS if there is a
|
||||||
|
* reordering of instructions resulting in the test check being invalid
|
||||||
|
* and the test is skipped by returning PASS.
|
||||||
|
* Test returns FAIL if the delay function returns before the required
|
||||||
|
* duration.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int test_timer_delay(struct unit_module *m,
|
||||||
|
struct gk20a *g, void *args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test specification for test_timer_msleep
|
||||||
|
*
|
||||||
|
* Description: Test the sleep functionality.
|
||||||
|
*
|
||||||
|
* Test Type: Feature based.
|
||||||
|
*
|
||||||
|
* Input: None.
|
||||||
|
*
|
||||||
|
* Steps:
|
||||||
|
* 1) Get the current time in ms.
|
||||||
|
* 2) Call sleep function for 5ms.
|
||||||
|
* 3) Get the time after the sleep call.
|
||||||
|
* 4) Calculate the difference between both the timestamps.
|
||||||
|
* 5) Compare the difference to deduce the test result.
|
||||||
|
*
|
||||||
|
* Output:
|
||||||
|
* Test returns PASS if the sleep function is completed for required duration.
|
||||||
|
* Test returns FAIL if the sleep function returns before the requested
|
||||||
|
* duration.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int test_timer_msleep(struct unit_module *m,
|
||||||
|
struct gk20a *g, void *args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test specification for test_timer_hrtimestamp
|
||||||
|
*
|
||||||
|
* Description: Test the high resolution counter based functionalities.
|
||||||
|
*
|
||||||
|
* Test Type: Feature based.
|
||||||
|
*
|
||||||
|
* Input: None.
|
||||||
|
*
|
||||||
|
* Steps:
|
||||||
|
* 1) Initialise two counter variables to 0.
|
||||||
|
* 2) Read the value of HR counter into one of the counter variables.
|
||||||
|
* 3) Compare the value of read counter value with the bkp counter value.
|
||||||
|
* 4) If read counter variable is less than the previously read counter value
|
||||||
|
* return fail.
|
||||||
|
* 5) Store the read counter value in bkp counter value.
|
||||||
|
* 6) Suspend execution by calling usleep.
|
||||||
|
* 7) Loop steps 1 - 6 for multiple times.
|
||||||
|
*
|
||||||
|
* Output:
|
||||||
|
* Test returns PASS if for every read of HR counter, the value returned is
|
||||||
|
* either greater than or equal to the previous value.
|
||||||
|
* Test returns FAIL if any of the subsequent read of HR counter returns
|
||||||
|
* a value less than the previous value.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int test_timer_hrtimestamp(struct unit_module *m,
|
||||||
|
struct gk20a *g, void *args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test specification for test_timer_compare
|
||||||
|
*
|
||||||
|
* Description: Compare the timers in various resoutions.
|
||||||
|
*
|
||||||
|
* Test Type: Feature based.
|
||||||
|
*
|
||||||
|
* Input: None.
|
||||||
|
*
|
||||||
|
* Steps:
|
||||||
|
* 1) Initialise two timestamp variables.
|
||||||
|
* 2) Read the time in ms and store in one timestamp variable.
|
||||||
|
* 3) Read the time in ns and store in the second timestamp variable.
|
||||||
|
* 4) Do the necessary conversion to make both timers in same resolution.
|
||||||
|
* 5) Compare the timer values to determine the test results.
|
||||||
|
*
|
||||||
|
* Output:
|
||||||
|
* Test returns PASS if various timer resolutions match each other.
|
||||||
|
* Test returns FAIL if various timer resolutions does not match with
|
||||||
|
* each other.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int test_timer_compare(struct unit_module *m,
|
||||||
|
struct gk20a *g, void *args);
|
||||||
|
|
||||||
|
#endif /* __UNIT_POSIX_TIMERS_H__ */
|
||||||
Reference in New Issue
Block a user