gpu: nvgpu: Modify common.top for better coverage

Following changes are done to common.top code and UT:

1.Change return type for device_info_parse_enum to void as it can never
return non-zero value.
   - This is a private HAL and is only called by get_device_info HAL.
   - It gets called only for table entry with entry type = enum.
   - So there is no error path left.
This helps remove unnecessary branches and get better branch coverage

2. Check if the data parsing function pointers are not NULL before
parsing the device tree. Return error if there are no functions
to interpret the device_info table registers. Add checks for same in
unit test test_get_device_info().

JIRA NVGPU-2204

Change-Id: I8833da7aa58b070d19b50ee17f64362f301bd792
Signed-off-by: tkudav <tkudav@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2269603
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
tkudav
2019-12-27 17:23:15 +05:30
committed by Alex Waterman
parent 95c09bdddd
commit cb8003d9e0
7 changed files with 32 additions and 41 deletions

View File

@@ -110,18 +110,12 @@ int gm20b_get_device_info(struct gk20a *g, struct nvgpu_device_info *dev_info,
if (top_device_info_type_enum_v(entry_engine) == engine_type) { if (top_device_info_type_enum_v(entry_engine) == engine_type) {
dev_info->engine_type = engine_type; dev_info->engine_type = engine_type;
if (g->ops.top.device_info_parse_enum != NULL) { if (g->ops.top.device_info_parse_enum != NULL) {
ret = g->ops.top.device_info_parse_enum(g, g->ops.top.device_info_parse_enum(g,
entry_enum, entry_enum,
&dev_info->engine_id, &dev_info->engine_id,
&dev_info->runlist_id, &dev_info->runlist_id,
&dev_info->intr_id, &dev_info->intr_id,
&dev_info->reset_id); &dev_info->reset_id);
if (ret != 0) {
nvgpu_err(g,
"Error parsing Enum Entry 0x%x",
entry_enum);
return ret;
}
} }
if (g->ops.top.device_info_parse_data != NULL) { if (g->ops.top.device_info_parse_data != NULL) {
ret = g->ops.top.device_info_parse_data(g, ret = g->ops.top.device_info_parse_data(g,

View File

@@ -30,7 +30,7 @@
struct gk20a; struct gk20a;
struct nvgpu_device_info; struct nvgpu_device_info;
int gm20b_device_info_parse_enum(struct gk20a *g, u32 table_entry, void gm20b_device_info_parse_enum(struct gk20a *g, u32 table_entry,
u32 *engine_id, u32 *runlist_id, u32 *engine_id, u32 *runlist_id,
u32 *intr_id, u32 *reset_id); u32 *intr_id, u32 *reset_id);
#ifdef CONFIG_NVGPU_HAL_NON_FUSA #ifdef CONFIG_NVGPU_HAL_NON_FUSA

View File

@@ -28,7 +28,7 @@
#include <nvgpu/hw/gm20b/hw_top_gm20b.h> #include <nvgpu/hw/gm20b/hw_top_gm20b.h>
int gm20b_device_info_parse_enum(struct gk20a *g, u32 table_entry, void gm20b_device_info_parse_enum(struct gk20a *g, u32 table_entry,
u32 *engine_id, u32 *runlist_id, u32 *engine_id, u32 *runlist_id,
u32 *intr_id, u32 *reset_id) u32 *intr_id, u32 *reset_id)
{ {
@@ -66,7 +66,6 @@ int gm20b_device_info_parse_enum(struct gk20a *g, u32 table_entry,
} }
nvgpu_log_info(g, "Reset_id: %u", *reset_id); nvgpu_log_info(g, "Reset_id: %u", *reset_id);
return 0;
} }
bool gm20b_is_engine_gr(struct gk20a *g, u32 engine_type) bool gm20b_is_engine_gr(struct gk20a *g, u32 engine_type)

View File

@@ -65,32 +65,21 @@ static int gp10b_check_device_match(struct gk20a *g,
&& (top_device_info_data_inst_id_v(entry_data) == && (top_device_info_data_inst_id_v(entry_data) ==
inst_id)) { inst_id)) {
dev_info->engine_type = engine_type; dev_info->engine_type = engine_type;
if (g->ops.top.device_info_parse_enum != NULL) { g->ops.top.device_info_parse_enum(g,
ret = g->ops.top.device_info_parse_enum(g,
entry_enum, entry_enum,
&dev_info->engine_id, &dev_info->engine_id,
&dev_info->runlist_id, &dev_info->runlist_id,
&dev_info->intr_id, &dev_info->intr_id,
&dev_info->reset_id); &dev_info->reset_id);
if (ret != 0) { ret = g->ops.top.device_info_parse_data(g,
nvgpu_err(g,
"Error parsing Enum Entry 0x%x",
entry_data);
return ret;
}
}
if (g->ops.top.device_info_parse_data != NULL) {
ret = g->ops.top.device_info_parse_data(g,
entry_data, entry_data,
&dev_info->inst_id, &dev_info->inst_id,
&dev_info->pri_base, &dev_info->pri_base,
&dev_info->fault_id); &dev_info->fault_id);
if (ret != 0) { if (ret != 0) {
nvgpu_err(g, nvgpu_err(g, "Error parsing Data Entry 0x%x",
"Error parsing Data Entry 0x%x", entry_data);
entry_data); return ret;
return ret;
}
} }
} }
@@ -114,6 +103,12 @@ int gp10b_get_device_info(struct gk20a *g, struct nvgpu_device_info *dev_info,
return -EINVAL; return -EINVAL;
} }
if ((g->ops.top.device_info_parse_enum == NULL) ||
(g->ops.top.device_info_parse_data == NULL)) {
nvgpu_err(g, "Dev_info parsing functions ptrs not set.");
return -EINVAL;
}
for (i = 0; i < max_info_entries; i++) { for (i = 0; i < max_info_entries; i++) {
table_entry = nvgpu_readl(g, top_device_info_r(i)); table_entry = nvgpu_readl(g, top_device_info_r(i));
entry = top_device_info_entry_v(table_entry); entry = top_device_info_entry_v(table_entry);

View File

@@ -286,7 +286,7 @@ struct gops_top {
/** /**
* HALs used within "Top" unit. Private HALs. * HALs used within "Top" unit. Private HALs.
*/ */
int (*device_info_parse_enum)(struct gk20a *g, void (*device_info_parse_enum)(struct gk20a *g,
u32 table_entry, u32 table_entry,
u32 *engine_id, u32 *runlist_id, u32 *engine_id, u32 *runlist_id,
u32 *intr_id, u32 *reset_id); u32 *intr_id, u32 *reset_id);

View File

@@ -131,7 +131,6 @@ int test_device_info_parse_enum(struct unit_module *m, struct gk20a *g,
void *args) void *args)
{ {
int ret = UNIT_SUCCESS; int ret = UNIT_SUCCESS;
int val = 0;
u32 engine_id = 0U; u32 engine_id = 0U;
u32 runlist_id = 0U; u32 runlist_id = 0U;
u32 intr_id = 0U; u32 intr_id = 0U;
@@ -149,15 +148,10 @@ int test_device_info_parse_enum(struct unit_module *m, struct gk20a *g,
table_entry = 0x10228C3E; table_entry = 0x10228C3E;
/* Call top.device_info_parse_enum to parse the above table entry */ /* Call top.device_info_parse_enum to parse the above table entry */
val = g->ops.top.device_info_parse_enum(g, table_entry, &engine_id, g->ops.top.device_info_parse_enum(g, table_entry, &engine_id,
&runlist_id, &intr_id, &runlist_id, &intr_id,
&reset_id); &reset_id);
if (val != 0) {
unit_err(m, "Call to top.device_info_parse_enum() failed.\n");
ret = UNIT_FAIL;
}
/* Verify if the parsed data is as expected */ /* Verify if the parsed data is as expected */
if (engine_id != 4U) { if (engine_id != 4U) {
unit_err(m, unit_err(m,
@@ -190,15 +184,10 @@ int test_device_info_parse_enum(struct unit_module *m, struct gk20a *g,
table_entry = 0x10228C02; table_entry = 0x10228C02;
/* Call top.device_info_parse_enum to parse the above table entry */ /* Call top.device_info_parse_enum to parse the above table entry */
val = g->ops.top.device_info_parse_enum(g, table_entry, &engine_id, g->ops.top.device_info_parse_enum(g, table_entry, &engine_id,
&runlist_id, &intr_id, &runlist_id, &intr_id,
&reset_id); &reset_id);
if (val != 0) {
unit_err(m, "Call to top.device_info_parse_enum() failed.\n");
ret = UNIT_FAIL;
}
/* Verify if the parsed data is as expected */ /* Verify if the parsed data is as expected */
if (engine_id != U32_MAX) { if (engine_id != U32_MAX) {
unit_err(m, unit_err(m,
@@ -543,6 +532,16 @@ int test_get_device_info(struct unit_module *m, struct gk20a *g, void *args)
ret = UNIT_FAIL; ret = UNIT_FAIL;
} }
/* Call top.get_device_info with NULL function pointers */
g->ops.top.device_info_parse_enum = NULL;
g->ops.top.device_info_parse_data = NULL;
val = g->ops.top.get_device_info(g, &dev_info_1, engine_type, inst_id);
if (val != -EINVAL) {
unit_err(m,
"get_device_info() failed to handle NULL function pointers.\n");
ret = UNIT_FAIL;
}
return ret; return ret;
} }

View File

@@ -353,6 +353,10 @@ int test_get_num_engine_type_entries(struct unit_module *m, struct gk20a *g,
* Steps: * Steps:
* - The device_info table is setup during test_top_setup(). * - The device_info table is setup during test_top_setup().
* - The device_info table is initialized to have one copy engine entry. * - The device_info table is initialized to have one copy engine entry.
* - Set device_info_parse_enum() and device_info_parse_data() HAL to NULL.
* Call get_device_info HAL and check if it returns -EINVAL when the data
* parsing function pointers are not initialized.
* - Initialize the device_info_parse_enum and device_info_parse_data HAL.
* - Call get_device_info HAL to parse copy engine related data. * - Call get_device_info HAL to parse copy engine related data.
* - Here, we just make sure the call returns success; we do not check the * - Here, we just make sure the call returns success; we do not check the
* parsed values as we have separate tests for verifying enum and data * parsed values as we have separate tests for verifying enum and data