From f80dccb543c7bb90d29dacbdca49bd7377f28030 Mon Sep 17 00:00:00 2001 From: Antony Clince Alex Date: Tue, 18 May 2021 11:01:58 +0000 Subject: [PATCH] gpu: nvgpu: report gpc_tpc_mask in physical order At present, there is an inconsistency in the order in which gpc_tpc masks are reported to the userspace. Both gpc and tpc masks are reported using physical-ids. However, the gpc_tpc_masks array is ordered by logical gpc-ids and not physical-ids. This creates a mismatch between the gpc reported as enabled in the gpc_mask and its corresponding gpc_tpc_mask. Introduce field "gpc_tpc_mask_physical" which stores the gpc_tpc_masks in physical order and update NVGPU_GPU_IOCTL_GET_TPC_MASKS to return this field. Bug 200665942 Change-Id: I63aa83414a59676b7e7d36b6deb527e2f3c04cff Signed-off-by: Antony Clince Alex Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2531114 Tested-by: mobile promotions Reviewed-by: mobile promotions --- drivers/gpu/nvgpu/common/gr/gr_config.c | 29 ++++++++++++++- drivers/gpu/nvgpu/common/gr/gr_config_priv.h | 10 ++++-- drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.c | 11 ++++-- drivers/gpu/nvgpu/include/nvgpu/gr/config.h | 36 +++++++++++++++++-- .../gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h | 1 + drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c | 2 +- 6 files changed, 80 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/nvgpu/common/gr/gr_config.c b/drivers/gpu/nvgpu/common/gr/gr_config.c index 2b3ccdb63..90c4a9b96 100644 --- a/drivers/gpu/nvgpu/common/gr/gr_config.c +++ b/drivers/gpu/nvgpu/common/gr/gr_config.c @@ -241,6 +241,7 @@ static bool gr_config_alloc_struct_mem(struct gk20a *g, max_gpc_cnt = nvgpu_safe_mult_u64((size_t)config->max_gpc_count, sizeof(u32)); config->gpc_tpc_count = nvgpu_kzalloc(g, gpc_size); config->gpc_tpc_mask = nvgpu_kzalloc(g, max_gpc_cnt); + config->gpc_tpc_mask_physical = nvgpu_kzalloc(g, max_gpc_cnt); #ifdef CONFIG_NVGPU_GRAPHICS if (!nvgpu_is_enabled(g, NVGPU_SUPPORT_MIG)) { config->max_zcull_per_gpc_count = nvgpu_get_litter_value(g, @@ -327,6 +328,7 @@ struct nvgpu_gr_config *nvgpu_gr_config_init(struct gk20a *g) u32 cur_gr_instance = nvgpu_gr_get_cur_instance_id(g); u32 gpc_index; u32 gpc_phys_id; + u32 gpc_id; int err; config = nvgpu_kzalloc(g, sizeof(*config)); @@ -385,8 +387,21 @@ struct nvgpu_gr_config *nvgpu_gr_config_init(struct gk20a *g) */ gpc_phys_id = nvgpu_grmgr_get_gr_gpc_phys_id(g, cur_gr_instance, gpc_index); + + /* + * The gpc_tpc_mask_physical masks are ordered by gpc_id. + * Where gpc_id = gpc_logical_id when MIG=true, else + * gpc_physical_id. + */ + gpc_id = gpc_phys_id; + if (nvgpu_is_enabled(g, NVGPU_SUPPORT_MIG)) { + gpc_id = nvgpu_grmgr_get_gr_gpc_logical_id(g, + cur_gr_instance, gpc_index); + } config->gpc_tpc_mask[gpc_index] = g->ops.gr.config.get_gpc_tpc_mask(g, config, gpc_phys_id); + config->gpc_tpc_mask_physical[gpc_id] = + g->ops.gr.config.get_gpc_tpc_mask(g, config, gpc_phys_id); } config->ppc_count = 0; @@ -759,13 +774,25 @@ u32 *nvgpu_gr_config_get_base_mask_gpc_tpc(struct nvgpu_gr_config *config) return config->gpc_tpc_mask; } +u32 *nvgpu_gr_config_get_gpc_tpc_mask_physical_base(struct nvgpu_gr_config *config) +{ + return config->gpc_tpc_mask_physical; +} + u32 nvgpu_gr_config_get_gpc_tpc_mask(struct nvgpu_gr_config *config, u32 gpc_index) { - nvgpu_assert(gpc_index < nvgpu_gr_config_get_gpc_count(config)); + nvgpu_assert(gpc_index < nvgpu_gr_config_get_max_gpc_count(config)); return config->gpc_tpc_mask[gpc_index]; } +u32 nvgpu_gr_config_get_gpc_tpc_mask_physical(struct nvgpu_gr_config *config, + u32 gpc_index) +{ + nvgpu_assert(gpc_index < nvgpu_gr_config_get_max_gpc_count(config)); + return config->gpc_tpc_mask_physical[gpc_index]; +} + void nvgpu_gr_config_set_gpc_tpc_mask(struct nvgpu_gr_config *config, u32 gpc_index, u32 val) { diff --git a/drivers/gpu/nvgpu/common/gr/gr_config_priv.h b/drivers/gpu/nvgpu/common/gr/gr_config_priv.h index df7415041..6bff3f08d 100644 --- a/drivers/gpu/nvgpu/common/gr/gr_config_priv.h +++ b/drivers/gpu/nvgpu/common/gr/gr_config_priv.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"), @@ -128,9 +128,15 @@ struct nvgpu_gr_config { /** * Array to hold mask of TPCs per GPC. - * Array is indexed by GPC index. + * Array is indexed by GPC logical index. */ u32 *gpc_tpc_mask; + /** + * Array to hold mask of TPCs per GPC. + * Array is indexed by GPC physical-id in non-MIG(legacy) mode and by + * logical-id in MIG mode. + */ + u32 *gpc_tpc_mask_physical; /** * 2-D array to hold mask of TPCs attached to a PES unit * in a GPC. diff --git a/drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.c b/drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.c index 7cc8295bb..f184ab22f 100644 --- a/drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.c +++ b/drivers/gpu/nvgpu/common/vgpu/gr/gr_vgpu.c @@ -259,8 +259,11 @@ static int vgpu_gr_init_gr_config(struct gk20a *g, struct nvgpu_gr *gr) goto cleanup; } - config->gpc_tpc_mask = nvgpu_kzalloc(g, config->gpc_count * sizeof(u32)); - if (!config->gpc_tpc_mask) { + config->gpc_tpc_mask = nvgpu_kzalloc(g, + config->max_gpc_count * sizeof(u32)); + config->gpc_tpc_mask_physical = nvgpu_kzalloc(g, + config->max_gpc_count * sizeof(u32)); + if (!config->gpc_tpc_mask || !config->gpc_tpc_mask_physical) { goto cleanup; } @@ -288,7 +291,7 @@ static int vgpu_gr_init_gr_config(struct gk20a *g, struct nvgpu_gr *gr) #endif config->tpc_count = 0; - for (gpc_index = 0; gpc_index < config->gpc_count; gpc_index++) { + for (gpc_index = 0; gpc_index < config->max_gpc_count; gpc_index++) { config->gpc_tpc_count[gpc_index] = priv->constants.gpc_tpc_count[gpc_index]; @@ -298,6 +301,8 @@ static int vgpu_gr_init_gr_config(struct gk20a *g, struct nvgpu_gr *gr) gr->config->gpc_tpc_mask[gpc_index] = g->ops.gr.config.get_gpc_tpc_mask(g, g->gr->config, gpc_index); + gr->config->gpc_tpc_mask_physical[gpc_index] = + priv->constants.gpc_tpc_mask_physical[gpc_index]; } } diff --git a/drivers/gpu/nvgpu/include/nvgpu/gr/config.h b/drivers/gpu/nvgpu/include/nvgpu/gr/config.h index cba151d49..15a2eedd0 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gr/config.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gr/config.h @@ -238,7 +238,21 @@ u32 nvgpu_gr_config_get_pes_tpc_count(struct nvgpu_gr_config *config, u32 *nvgpu_gr_config_get_base_mask_gpc_tpc(struct nvgpu_gr_config *config); /** - * @brief Get TPC mask for given GPC. + * @brief Get base address of array that stores mask of TPCs in GPC. + * + * @param config [in] Pointer to GR configuration struct. + * + * Get base address of array that stores mask of TPCs in GPC, ordered + * in physical-id when in non-MIG(legacy) mode and by logical-id when in + * MIG mode. + * + * @return base address of array that stores mask of TPCs in GPC. + */ +u32 *nvgpu_gr_config_get_gpc_tpc_mask_physical_base( + struct nvgpu_gr_config *config); + +/** + * @brief Get TPC mask for given logical GPC index. * * @param config [in] Pointer to GR configuration struct. * @param gpc_index [in] Valid GPC index. @@ -247,13 +261,31 @@ u32 *nvgpu_gr_config_get_base_mask_gpc_tpc(struct nvgpu_gr_config *config); * Each set bit indicates TPC with that index is available, otherwise * the TPC is considered floorswept. * GPC index must be less than value returned by - * #nvgpu_gr_config_get_gpc_count(), otherwise an assert is raised. + * #nvgpu_gr_config_get_max_gpc_count(), otherwise an assert is raised. * * @return mask of TPCs for given GPC. */ u32 nvgpu_gr_config_get_gpc_tpc_mask(struct nvgpu_gr_config *config, u32 gpc_index); +/** + * @brief Get TPC mask for given physical GPC index. + * + * @param config [in] Pointer to GR configuration struct. + * @param gpc_index [in] Valid GPC physical id. + * + * This function returns mask of TPCs for given GPC index, which will be + * the physical-id in non-MIG(legacy) mode and logical-id in MIG mode. + * Each set bit indicates TPC with that index is available, otherwise + * the TPC is considered floorswept. + * GPC index must be less than value returned by + * #nvgpu_gr_config_get_max_gpc_count(), otherwise an assert is raised. + * + * @return mask of TPCs for given GPC. + */ +u32 nvgpu_gr_config_get_gpc_tpc_mask_physical(struct nvgpu_gr_config *config, + u32 gpc_index); + /** * @brief Set TPC mask for given GPC. * diff --git a/drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h b/drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h index 6f2309aed..bcd32d3a8 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h +++ b/drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h @@ -483,6 +483,7 @@ struct tegra_vgpu_constants_params { * TEGRA_VGPU_MAX_TPC_COUNT_PER_GPC */ u16 gpc_tpc_mask[TEGRA_VGPU_MAX_GPC_COUNT]; + u16 gpc_tpc_mask_physical[TEGRA_VGPU_MAX_GPC_COUNT]; u16 gpc_ppc_count[TEGRA_VGPU_MAX_GPC_COUNT]; u32 pes_tpc_count[TEGRA_VGPU_MAX_PES_COUNT_PER_GPC * TEGRA_VGPU_MAX_GPC_COUNT]; diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c index 5da765089..ee8398e9e 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c @@ -717,7 +717,7 @@ static int gk20a_ctrl_get_tpc_masks(struct gk20a *g, struct nvgpu_gr_config *gr_ err = copy_to_user((void __user *)(uintptr_t) args->mask_buf_addr, - nvgpu_gr_config_get_base_mask_gpc_tpc(gr_config), + nvgpu_gr_config_get_gpc_tpc_mask_physical_base(gr_config), write_size); }