From 6b90684ceec6c32aed7491a059b3972b1f1be5f4 Mon Sep 17 00:00:00 2001 From: Thomas Fleury Date: Sat, 30 Dec 2017 13:04:19 -0800 Subject: gpu: nvgpu: vgpu: get virtual SMs mapping On gv11b we can have multiple SMs per TPC. Add sm_per_tpc in vgpu constants to properly dimension the virtual SM to TPC/GPC mapping in virtualization case. Use TEGRA_VGPU_CMD_GET_SMS_MAPPING to query current mapping. Bug 2039676 Change-Id: I817be18f9a28cfb9bd8af207d7d6341a2ec3994b Signed-off-by: Thomas Fleury Reviewed-on: https://git-master.nvidia.com/r/1631203 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/linux/vgpu/gr_vgpu.c | 65 ++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/nvgpu/common/linux/vgpu/gr_vgpu.c') diff --git a/drivers/gpu/nvgpu/common/linux/vgpu/gr_vgpu.c b/drivers/gpu/nvgpu/common/linux/vgpu/gr_vgpu.c index fa2010cd..a0662956 100644 --- a/drivers/gpu/nvgpu/common/linux/vgpu/gr_vgpu.c +++ b/drivers/gpu/nvgpu/common/linux/vgpu/gr_vgpu.c @@ -1,7 +1,7 @@ /* * Virtualized GPU Graphics * - * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-2018, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -610,6 +610,7 @@ static int vgpu_gr_init_gr_config(struct gk20a *g, struct gr_gk20a *gr) { struct vgpu_priv_data *priv = vgpu_get_priv_data(g); u32 gpc_index; + u32 sm_per_tpc; int err = -ENOMEM; gk20a_dbg_fn(""); @@ -628,8 +629,10 @@ static int vgpu_gr_init_gr_config(struct gk20a *g, struct gr_gk20a *gr) if (!gr->gpc_tpc_mask) goto cleanup; + sm_per_tpc = priv->constants.sm_per_tpc; gr->sm_to_cluster = nvgpu_kzalloc(g, gr->gpc_count * gr->max_tpc_per_gpc_count * + sm_per_tpc * sizeof(struct sm_info)); if (!gr->sm_to_cluster) goto cleanup; @@ -1215,3 +1218,63 @@ void vgpu_gr_handle_sm_esr_event(struct gk20a *g, nvgpu_mutex_release(&g->dbg_sessions_lock); } + +int vgpu_gr_init_sm_id_table(struct gk20a *g) +{ + struct tegra_vgpu_cmd_msg msg = {}; + struct tegra_vgpu_vsms_mapping_params *p = &msg.params.vsms_mapping; + struct tegra_vgpu_vsms_mapping_entry *entry; + struct vgpu_priv_data *priv = vgpu_get_priv_data(g); + struct sm_info *sm_info; + int err; + struct gr_gk20a *gr = &g->gr; + size_t oob_size; + void *handle = NULL; + u32 sm_id; + u32 max_sm; + + msg.cmd = TEGRA_VGPU_CMD_GET_VSMS_MAPPING; + msg.handle = vgpu_get_handle(g); + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + err = err ? err : msg.ret; + if (err) { + nvgpu_err(g, "get vsms mapping failed err %d", err); + return err; + } + + handle = tegra_gr_comm_oob_get_ptr(TEGRA_GR_COMM_CTX_CLIENT, + tegra_gr_comm_get_server_vmid(), + TEGRA_VGPU_QUEUE_CMD, + (void **)&entry, &oob_size); + if (!handle) + return -EINVAL; + + max_sm = gr->gpc_count * + gr->max_tpc_per_gpc_count * + priv->constants.sm_per_tpc; + if (p->num_sm > max_sm) + return -EINVAL; + + if ((p->num_sm * sizeof(*entry)) > oob_size) + return -EINVAL; + + gr->no_of_sm = p->num_sm; + for (sm_id = 0; sm_id < p->num_sm; sm_id++, entry++) { + sm_info = &gr->sm_to_cluster[sm_id]; + sm_info->tpc_index = entry->tpc_index; + sm_info->gpc_index = entry->gpc_index; + sm_info->sm_index = entry->sm_index; + sm_info->global_tpc_index = entry->global_tpc_index; + } + tegra_gr_comm_oob_put_ptr(handle); + + return 0; +} + +int vgpu_gr_init_fs_state(struct gk20a *g) +{ + if (!g->ops.gr.init_sm_id_table) + return -EINVAL; + + return g->ops.gr.init_sm_id_table(g); +} -- cgit v1.2.2