diff --git a/drivers/gpu/nvgpu/common/utils/string.c b/drivers/gpu/nvgpu/common/utils/string.c index 2cb50c691..eb6260d13 100644 --- a/drivers/gpu/nvgpu/common/utils/string.c +++ b/drivers/gpu/nvgpu/common/utils/string.c @@ -38,7 +38,7 @@ nvgpu_memcmp(const u8 *b1, const u8 *b2, size_t n) int nvgpu_strnadd_u32(char *dst, const u32 value, size_t size, u32 radix) { - int n; + u32 n; u32 v; char *p; u32 digit; @@ -47,20 +47,16 @@ int nvgpu_strnadd_u32(char *dst, const u32 value, size_t size, u32 radix) return 0; } - if (size > ((u64)(INT_MAX))) { - return 0; - } - /* how many digits do we need ? */ n = 0; v = value; do { - n = nvgpu_safe_add_s32(n, 1); + n = nvgpu_safe_add_u32(n, 1U); v = v / radix; } while (v > 0U); /* bail out if there is not room for '\0' */ - if (n >= (s32)size) { + if (n >= size) { return 0; } @@ -80,7 +76,7 @@ int nvgpu_strnadd_u32(char *dst, const u32 value, size_t size, u32 radix) } while (v > 0U); - return n; + return (int)n; } bool nvgpu_mem_is_word_aligned(struct gk20a *g, u8 *addr) diff --git a/drivers/gpu/nvgpu/include/nvgpu/string.h b/drivers/gpu/nvgpu/include/nvgpu/string.h index a2505cc12..22a1a27b1 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/string.h +++ b/drivers/gpu/nvgpu/include/nvgpu/string.h @@ -72,7 +72,8 @@ int nvgpu_memcmp(const u8 *b1, const u8 *b2, size_t n); * @param dst [in,out] Buffer to copy the value into. * @param value [in] Value to be added with the string. * @param size [in] Size available in the destination buffer. - * @param radix [in] Radix value to be used. + * @param radix [in] Radix value to be used. Should be in the range + * 2 - 16, both inclusive. * * @return Returns number of digits added to string (not including '\0') if * successful, else 0. diff --git a/userspace/units/enabled/nvgpu-enabled.c b/userspace/units/enabled/nvgpu-enabled.c index c861952ea..ac7f560a2 100644 --- a/userspace/units/enabled/nvgpu-enabled.c +++ b/userspace/units/enabled/nvgpu-enabled.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2021, 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"), @@ -108,6 +108,55 @@ int test_nvgpu_set_enabled(struct unit_module *m, return UNIT_SUCCESS; } +int test_nvgpu_enabled_bvec(struct unit_module *m, + struct gk20a *g, void *args) +{ + u32 n = 0; + + nvgpu_set_enabled(g, n, true); + if (!nvgpu_is_enabled(g, n)) { + g->enabled_flags = original_enabled_flags; + unit_return_fail(m, "enabled_flag not set for %u\n", n); + } + + n = NVGPU_MAX_ENABLED_BITS - 1; + nvgpu_set_enabled(g, n, true); + if (!nvgpu_is_enabled(g, n)) { + g->enabled_flags = original_enabled_flags; + unit_return_fail(m, "enabled_flag not set for %u\n", n); + } + + n = NVGPU_MAX_ENABLED_BITS/2; + nvgpu_set_enabled(g, n, true); + if (!nvgpu_is_enabled(g, n)) { + g->enabled_flags = original_enabled_flags; + unit_return_fail(m, "enabled_flag not set for %u\n", n); + } + + n = NVGPU_MAX_ENABLED_BITS; + nvgpu_set_enabled(g, n, true); + if (nvgpu_is_enabled(g, n)) { + g->enabled_flags = original_enabled_flags; + unit_return_fail(m, "enabled_flag set for %u\n", n); + } + + n = NVGPU_MAX_ENABLED_BITS + 1; + nvgpu_set_enabled(g, n, true); + if (nvgpu_is_enabled(g, n)) { + g->enabled_flags = original_enabled_flags; + unit_return_fail(m, "enabled_flag set for %u\n", n); + } + + n = UINT32_MAX; + nvgpu_set_enabled(g, n, true); + if (nvgpu_is_enabled(g, n)) { + g->enabled_flags = original_enabled_flags; + unit_return_fail(m, "enabled_flag set for %u\n", n); + } + + return UNIT_SUCCESS; +} + int test_nvgpu_free_enabled_flags(struct unit_module *m, struct gk20a *g, void *args) { @@ -124,8 +173,9 @@ struct unit_module_test enabled_tests[] = { UNIT_TEST(enabled_flags_false_check, test_nvgpu_enabled_flags_false_check, NULL, 0), UNIT_TEST(set_enabled, test_nvgpu_set_enabled, NULL, 0), + UNIT_TEST(bvec_enabled, test_nvgpu_enabled_bvec, NULL, 0), UNIT_TEST(free, test_nvgpu_free_enabled_flags, NULL, 0), }; -UNIT_MODULE(enabled, enabled_tests, UNIT_PRIO_NVGPU_TEST); \ No newline at end of file +UNIT_MODULE(enabled, enabled_tests, UNIT_PRIO_NVGPU_TEST); diff --git a/userspace/units/enabled/nvgpu-enabled.h b/userspace/units/enabled/nvgpu-enabled.h index 4ee4ec1f3..b7e260601 100644 --- a/userspace/units/enabled/nvgpu-enabled.h +++ b/userspace/units/enabled/nvgpu-enabled.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2021, 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"), @@ -101,6 +101,49 @@ int test_nvgpu_enabled_flags_false_check(struct unit_module *m, */ int test_nvgpu_set_enabled(struct unit_module *m, struct gk20a *g, void *args); +/** + * Test specification for: test_nvgpu_enabled_bvec + * + * Description: Boundary check for flag setting and checking. + * + * Test Type: Boundary value + * + * Targets: nvgpu_is_enabled, nvgpu_set_enabled + * + * Input: test_nvgpu_init_enabled_flags + * + * Equivalence classes: + * Variable: flag + * - Valid : { 0 - (NVGPU_MAX_ENABLED_BITS - 1) } + * - Invalid : { NVGPU_MAX_ENABLED_BITS - UINT32_MAX } + * + * Steps: + * - Set and check flag for bit position 0. The set API nvgpu_set_enabled + * should set the value and the check API nvgpu_is_enabled should return 1. + * - Set and check flag for bit position NVGPU_MAX_ENABLED_BITS - 1. The set + * API nvgpu_set_enabled should set the value and the check API + * nvgpu_is_enabled should return 1. + * - Set and check flag for bit position NVGPU_MAX_ENABLED_BITS/2. The set API + * nvgpu_set_enabled should set the value and the check API nvgpu_is_enabled + * should return 1. + * - Try to set and check flag for bit position NVGPU_MAX_ENABLED_BITS. The + * set API nvgpu_set_enabled should return without doing any operation and + * the check API nvgpu_is_enabled should return 0 indicating an error for + * flag boundary value. + * - Try to set and check flag for bit position NVGPU_MAX_ENABLED_BITS + 1. The + * set API nvgpu_set_enabled should return without doing any operation and + * the check API nvgpu_is_enabled should return 0 indicating an error for + * flag boundary value. + * - Try to set and check flag for bit position UINT32_MAX. The set API + * nvgpu_set_enabled should return without doing any operation and + * the check API nvgpu_is_enabled should return 0 indicating an error for + * flag boundary value. + * + * Output: Returns SUCCESS if the steps above were executed successfully. FAIL + * otherwise. + */ +int test_nvgpu_enabled_bvec(struct unit_module *m, struct gk20a *g, void *args); + /** * Test specification for: test_nvgpu_free_enabled_flags * diff --git a/userspace/units/interface/rbtree/rbtree.c b/userspace/units/interface/rbtree/rbtree.c index 9062542c5..ef8c8a2a2 100644 --- a/userspace/units/interface/rbtree/rbtree.c +++ b/userspace/units/interface/rbtree/rbtree.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2021, 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"), @@ -535,6 +535,193 @@ int test_unlink_corner_cases(struct unit_module *m, struct gk20a *g, void *args) return UNIT_SUCCESS; } +int test_search_bvec(struct unit_module *m, struct gk20a *g, void *args) +{ + struct nvgpu_rbtree_node *root = NULL; + struct nvgpu_rbtree_node *result1 = NULL; + struct nvgpu_rbtree_node *result2 = NULL; + struct nvgpu_rbtree_node *result3 = NULL; + struct nvgpu_rbtree_node *node1 = NULL; + struct nvgpu_rbtree_node *node2 = NULL; + u64 key_start_search = RED_BLACK_BVEC_KEY_MIN; + int status = UNIT_FAIL; + + fill_test_tree(m, &root); + if (check_rbtree(m, root) < 0) { + goto free_tree; + } + + node1 = (struct nvgpu_rbtree_node *) + malloc(sizeof(struct nvgpu_rbtree_node)); + node1->key_start = RED_BLACK_BVEC_KEY_MIN; + node1->key_end = RED_BLACK_BVEC_KEY_MIN + RANGE_SIZE; + nvgpu_rbtree_insert(node1, &root); + + node2 = (struct nvgpu_rbtree_node *) + malloc(sizeof(struct nvgpu_rbtree_node)); + node2->key_start = RED_BLACK_BVEC_KEY_MAX; + node2->key_end = RED_BLACK_BVEC_KEY_MAX; + nvgpu_rbtree_insert(node2, &root); + + if (check_rbtree(m, root) < 0) { + goto free_nodes; + } + + nvgpu_rbtree_search(key_start_search, &result1, root); + if (result1 == NULL) { + unit_err(m, "BVEC search failed for min value\n"); + goto free_nodes; + } + + nvgpu_rbtree_range_search(key_start_search, &result2, root); + if (result2 == NULL) { + unit_err(m, "BVEC range search failed\n"); + goto free_nodes; + } else if (result1 != result2) { + unit_err(m, + "BVEC range search did not find the expected result\n"); + goto free_nodes; + } + + nvgpu_rbtree_less_than_search(key_start_search, &result3, root); + if (result3 != NULL) { + unit_err(m, "BVEC less than search failed\n"); + goto free_nodes; + } + + result1 = NULL; + result2 = NULL; + result3 = NULL; + key_start_search = RED_BLACK_BVEC_KEY_MAX; + + nvgpu_rbtree_search(key_start_search, &result1, root); + if (result1 == NULL) { + unit_err(m, "BVEC search failed for max value\n"); + goto free_nodes; + } + + nvgpu_rbtree_range_search(key_start_search, &result2, root); + if (result2 != NULL) { + unit_err(m, "BVEC range search failed for max value\n"); + goto free_nodes; + } + + nvgpu_rbtree_less_than_search(key_start_search, &result3, root); + if (result3 == NULL) { + unit_err(m, "BVEC less than search failed for max value\n"); + goto free_nodes; + } + + result1 = NULL; + result2 = NULL; + result3 = NULL; + key_start_search = SEARCH_KEY; + + nvgpu_rbtree_search(key_start_search, &result1, root); + if (result1 == NULL) { + unit_err(m, "BVEC search failed for valid value\n"); + goto free_nodes; + } + + nvgpu_rbtree_range_search(key_start_search, &result2, root); + if (result2 == NULL) { + unit_err(m, "BVEC range search failed for valid value\n"); + goto free_nodes; + } + + nvgpu_rbtree_less_than_search(key_start_search, &result3, root); + if (result3 == NULL) { + unit_err(m, "BVEC less than search failed for valid value\n"); + goto free_nodes; + } + + status = UNIT_SUCCESS; + +free_nodes: + free(node1); + free(node2); +free_tree: + free_test_tree(m, root); + + return status; +} + +int test_enum_bvec(struct unit_module *m, struct gk20a *g, void *args) +{ + struct nvgpu_rbtree_node *root = NULL; + struct nvgpu_rbtree_node *node = NULL; + struct nvgpu_rbtree_node *node1 = NULL; + struct nvgpu_rbtree_node *node2 = NULL; + u64 key_start; + int status = UNIT_FAIL; + + fill_test_tree(m, &root); + if (check_rbtree(m, root) < 0) { + goto free_tree; + } + + key_start = initial_key_start[0]; + nvgpu_rbtree_enum_start(key_start, &node, root); + if (node == NULL) { + unit_err(m, "Enum for valid key returned NULL\n"); + goto free_nodes; + } + if (node->key_start != key_start) { + unit_err(m, "Enum mismatch for initial value\n"); + goto free_tree; + } + + node1 = (struct nvgpu_rbtree_node *) + malloc(sizeof(struct nvgpu_rbtree_node)); + node1->key_start = RED_BLACK_BVEC_KEY_MIN; + node1->key_end = RED_BLACK_BVEC_KEY_MIN + RANGE_SIZE; + nvgpu_rbtree_insert(node1, &root); + + node2 = (struct nvgpu_rbtree_node *) + malloc(sizeof(struct nvgpu_rbtree_node)); + node2->key_start = RED_BLACK_BVEC_KEY_MAX; + node2->key_end = RED_BLACK_BVEC_KEY_MAX; + nvgpu_rbtree_insert(node2, &root); + + if (check_rbtree(m, root) < 0) { + goto free_nodes; + } + + node = NULL; + key_start = RED_BLACK_BVEC_KEY_MIN; + nvgpu_rbtree_enum_start(key_start, &node, root); + if (node == NULL) { + unit_err(m, "Enum for min key returned NULL\n"); + goto free_nodes; + } + if (node->key_start != key_start) { + unit_err(m, "Enum mismatch for min value\n"); + goto free_nodes; + } + + node = NULL; + key_start = RED_BLACK_BVEC_KEY_MAX; + nvgpu_rbtree_enum_start(key_start, &node, root); + if (node == NULL) { + unit_err(m, "Enum for max key returned NULL\n"); + goto free_nodes; + } + if (node->key_start != key_start) { + unit_err(m, "Enum mismatch for max value\n"); + goto free_nodes; + } + + status = UNIT_SUCCESS; + +free_nodes: + free(node1); + free(node2); +free_tree: + free_test_tree(m, root); + + return status; +} + struct unit_module_test interface_rbtree_tests[] = { UNIT_TEST(insert, test_insert, NULL, 0), UNIT_TEST(search, test_search, NULL, 0), @@ -543,6 +730,8 @@ struct unit_module_test interface_rbtree_tests[] = { UNIT_TEST(enum_next, test_enum_next, NULL, 0), UNIT_TEST(search_less_than, test_search_less, NULL, 0), UNIT_TEST(unlink_corner_cases, test_unlink_corner_cases, NULL, 0), + UNIT_TEST(search_bvec, test_search_bvec, NULL, 0), + UNIT_TEST(search_bvec, test_enum_bvec, NULL, 0), }; UNIT_MODULE(interface_rbtree, interface_rbtree_tests, UNIT_PRIO_NVGPU_TEST); diff --git a/userspace/units/interface/rbtree/rbtree.h b/userspace/units/interface/rbtree/rbtree.h index 944409f83..2ec18ed0b 100644 --- a/userspace/units/interface/rbtree/rbtree.h +++ b/userspace/units/interface/rbtree/rbtree.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2021, 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"), @@ -95,6 +95,10 @@ u64 initial_key_start[] = {50, 30, 80, 100, 170, 10, 200, DUPLICATE_VALUE, #define RED_BLACK_VIOLATION_1 20 #define RED_BLACK_VIOLATION_2 320 + +#define RED_BLACK_BVEC_KEY_MIN 0 +#define RED_BLACK_BVEC_KEY_MAX UINT64_MAX + /** * Test specification for: test_insert * @@ -292,5 +296,81 @@ int test_search_less(struct unit_module *m, struct gk20a *g, void *args); int test_unlink_corner_cases(struct unit_module *m, struct gk20a *g, void *args); +/** + * Test specification for: test_search_bvec + * + * Description: Test to check the boundary values for nvgpu_rbtree_search, + * nvgpu_rbtree_range_search and nvgpu_rbtree_less_than_search. + * + * Test Type: Boundary value + * + * Targets: nvgpu_rbtree_search, nvgpu_rbtree_range_search, + * nvgpu_rbtree_less_than_search. + * + * Input: None + * + * Equivalence classes: + * Variable: key_start + * - Valid : { 0 - UINT64_MAX } + * Variable: key + * - Valid : { 0 - UINT64_MAX } + * Steps: + * - Create a test tree with known values. + * - Insert two new nodes with boundary key values. + * - Ensure that searching for min boundary value returns a valid result. + * - Ensure that range searching for min value returns a valid result. + * - Ensure that less than search for min value returns NULL. + * - Ensure that searching for max boundary value returns a valid result. + * - Ensure that range searching for max value returns NULL. + * - Ensure that less than search for max value returns a valid result. + * - Ensure that searching for a valid value in between min and max values + * returns a valid result. + * - Ensure that range searching for a valid value in between min and max + * returns a valid result. + * - Ensure that less than search for a valid value in between min and max + * returns a valid result. + * - Free the extra nodes allocated. + * - Free the test tree. + * + * Output: Returns PASS if the steps above were executed successfully. FAIL + * otherwise. + */ +int test_search_bvec(struct unit_module *m, struct gk20a *g, void *args); + +/** + * Test specification for: test_enum_bvec + * + * Description: Test to check the boundary values for nvgpu_rbtree_enum_start + * + * Test Type: Boundary value + * + * Targets: nvgpu_rbtree_enum_start + * + * Input: None + * + * Equivalence classes: + * Variable: key_start + * - Valid : { 0 - UINT64_MAX } + * + * Steps: + * - Create a test tree with known values. + * - Invoke nvgpu_rbtree_enum_start for a known key value in the tree. The API + * should return a valid node and the key_start value of the node should + * match the requested key value. + * - Insert two new nodes with boundary key values. + * - Invoke nvgpu_rbtree_enum_start for BVEC min key value in the tree. The API + * should return a valid node and the key_start value of the node should + * match the requested key value. + * - Invoke nvgpu_rbtree_enum_start for BVEC max key value in the tree. The API + * should return a valid node and the key_start value of the node should + * match the requested key value. + * - Free the extra nodes allocated. + * - Free the test tree. + * + * Output: Returns PASS if the steps above were executed successfully. FAIL + * otherwise. + */ +int test_enum_bvec(struct unit_module *m, struct gk20a *g, void *args); + /** }@ */ #endif /* UNIT_RBTREE_H */ diff --git a/userspace/units/interface/string/nvgpu-string.c b/userspace/units/interface/string/nvgpu-string.c index 906b5347e..0ab948e22 100644 --- a/userspace/units/interface/string/nvgpu-string.c +++ b/userspace/units/interface/string/nvgpu-string.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-2021, 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"), @@ -60,20 +60,38 @@ int test_memcpy_memcmp(struct unit_module *m, struct gk20a *g, void *args) int test_strnadd_u32(struct unit_module *m, struct gk20a *g, void *args) { - const size_t len = 10; + const size_t len = 40; char dest[len]; + const char *max_str = "11111111111111111111111111111111"; /* test invalid radices */ + unit_assert(nvgpu_strnadd_u32(dest, 10U, len, 0U) == 0, + return UNIT_FAIL); unit_assert(nvgpu_strnadd_u32(dest, 10U, len, 1U) == 0, return UNIT_FAIL); unit_assert(nvgpu_strnadd_u32(dest, 10U, len, 17U) == 0, return UNIT_FAIL); + unit_assert(nvgpu_strnadd_u32(dest, 10U, len, 100U) == 0, + return UNIT_FAIL); + unit_assert(nvgpu_strnadd_u32(dest, 10U, len, UINT32_MAX) == 0, + return UNIT_FAIL); + /* test insufficient space */ + unit_assert(nvgpu_strnadd_u32(dest, 1000U, 0, 10U) == 0, + return UNIT_FAIL); unit_assert(nvgpu_strnadd_u32(dest, 1000U, 2, 10U) == 0, return UNIT_FAIL); unit_assert(nvgpu_strnadd_u32(dest, 1000U, 4, 10U) == 0, return UNIT_FAIL); + unit_assert(nvgpu_strnadd_u32(dest, 1U, len, 2U) == 1, + return UNIT_FAIL); + unit_assert(strncmp(dest, "1", 4) == 0, return UNIT_FAIL); + + unit_assert(nvgpu_strnadd_u32(dest, 0xffffffff, len, 2U) == 32, + return UNIT_FAIL); + unit_assert(strncmp(dest, max_str, 32) == 0, return UNIT_FAIL); + unit_assert(nvgpu_strnadd_u32(dest, 1000U, len, 10U) == 4, return UNIT_FAIL); unit_assert(strncmp(dest, "1000", 4) == 0, return UNIT_FAIL); diff --git a/userspace/units/interface/string/nvgpu-string.h b/userspace/units/interface/string/nvgpu-string.h index 32f04b6b9..023da01a3 100644 --- a/userspace/units/interface/string/nvgpu-string.h +++ b/userspace/units/interface/string/nvgpu-string.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-2021, 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"), @@ -76,13 +76,25 @@ int test_memcpy_memcmp(struct unit_module *m, struct gk20a *g, void *args); * * Input: None. * + * Equivalence classes: + * Variable: radix + * - Valid: { 2 - 16 } + * - Invalid: { 0, 1, 17 - UINT32_MAX } + * * Steps: - * - Call nvgpu_strnadd_u32 with invalid radices. Verify 0 is returned. - * - Call nvgpu_strnadd_u32 with an insufficient string size for the requested. - * number. Verify 0 is returned. + * - Call nvgpu_strnadd_u32 with invalid radix 0. Verify 0 is returned. + * - Call nvgpu_strnadd_u32 with invalid radix 1. Verify 0 is returned. + * - Call nvgpu_strnadd_u32 with invalid radix 17. Verify 0 is returned. + * - Call nvgpu_strnadd_u32 with invalid radix 100. Verify 0 is returned. + * - Call nvgpu_strnadd_u32 with invalid radix UINT32_MAX. Verify 0 is + * returned. + * - Call nvgpu_strnadd_u32 with insufficient string sizes. Verify 0 is + * returned. + * - Call nvgpu_strnadd_u32 with a binary value of 10. Verify returned size + * is 4 and the string contains "1010". * - Call nvgpu_strnadd_u32 with a decimal value of 1000. Verify returned size * is 4 and the string contains "1000". - * - Call nvgpu_strnadd_u32 with a hexidecimal value of 0xdeadbeef. Verify + * - Call nvgpu_strnadd_u32 with a hexadecimal value of 0xdeadbeef. Verify * returned size is 8 and the string contains "deadbeef". * * Output: Returns PASS if expected result is met, FAIL otherwise.