summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Fleury <tfleury@nvidia.com>2017-01-25 19:59:31 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-03-09 13:44:55 -0500
commit6c35cebdcb2d14741385cfe051577882a806cdb8 (patch)
tree80c0e8f0519dc253839a1aa7c8fe6e7da7ad336a
parentbc47d822298b9f3b2f93a384a7780a3763fee495 (diff)
gpu: nvgpu: vgpu: suspend/resume contexts
Add ability to suspend/resume contexts for a debug session (NVGPU_DBG_GPU_IOCTL_SUSPEND_RESUME_CONTEXTS), in virtualized case: - added hal function to resume contexts. - added vgpu support for suspend contexts, i.e. build a list of channel ids, and send TEGRA_VGPU_CMD_SUSPEND_CONTEXTS - added vgpu support for resume contexts, i.e. build a list of channel ids, and send TEGRA_VGPU_CMD_RESUME_CONTEXTS Bug 1791111 Change-Id: Icc1c00d94a94dab6384ac263fb811c00fa4b07bf Signed-off-by: Thomas Fleury <tfleury@nvidia.com> Reviewed-on: http://git-master/r/1294761 (cherry picked from commit d17a38eda312ffa92ce92e5bafc30727a8b76c4e) Reviewed-on: http://git-master/r/1299059 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Cory Perry <cperry@nvidia.com> Tested-by: Cory Perry <cperry@nvidia.com> Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c2
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h3
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c1
-rw-r--r--drivers/gpu/nvgpu/gm20b/gr_gm20b.c1
-rw-r--r--drivers/gpu/nvgpu/vgpu/fifo_vgpu.c6
-rw-r--r--drivers/gpu/nvgpu/vgpu/gr_vgpu.c79
-rw-r--r--include/linux/tegra_vgpu.h10
7 files changed, 100 insertions, 2 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
index 0a0aada7..6a32d727 100644
--- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
@@ -777,7 +777,7 @@ nvgpu_dbg_gpu_ioctl_suspend_resume_contexts(struct dbg_session_gk20a *dbg_s,
777 break; 777 break;
778 778
779 case NVGPU_DBG_GPU_RESUME_ALL_CONTEXTS: 779 case NVGPU_DBG_GPU_RESUME_ALL_CONTEXTS:
780 err = gr_gk20a_resume_contexts(g, dbg_s, 780 err = g->ops.gr.resume_contexts(g, dbg_s,
781 &ctx_resident_ch_fd); 781 &ctx_resident_ch_fd);
782 break; 782 break;
783 } 783 }
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 8ce682e3..e55753fe 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -309,6 +309,9 @@ struct gpu_ops {
309 int (*suspend_contexts)(struct gk20a *g, 309 int (*suspend_contexts)(struct gk20a *g,
310 struct dbg_session_gk20a *dbg_s, 310 struct dbg_session_gk20a *dbg_s,
311 int *ctx_resident_ch_fd); 311 int *ctx_resident_ch_fd);
312 int (*resume_contexts)(struct gk20a *g,
313 struct dbg_session_gk20a *dbg_s,
314 int *ctx_resident_ch_fd);
312 int (*set_preemption_mode)(struct channel_gk20a *ch, 315 int (*set_preemption_mode)(struct channel_gk20a *ch,
313 u32 graphics_preempt_mode, 316 u32 graphics_preempt_mode,
314 u32 compute_preempt_mode); 317 u32 compute_preempt_mode);
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index e695f02e..3ab63862 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -9304,6 +9304,7 @@ void gk20a_init_gr_ops(struct gpu_ops *gops)
9304 gops->gr.update_sm_error_state = gk20a_gr_update_sm_error_state; 9304 gops->gr.update_sm_error_state = gk20a_gr_update_sm_error_state;
9305 gops->gr.clear_sm_error_state = gk20a_gr_clear_sm_error_state; 9305 gops->gr.clear_sm_error_state = gk20a_gr_clear_sm_error_state;
9306 gops->gr.suspend_contexts = gr_gk20a_suspend_contexts; 9306 gops->gr.suspend_contexts = gr_gk20a_suspend_contexts;
9307 gops->gr.resume_contexts = gr_gk20a_resume_contexts;
9307 gops->gr.get_preemption_mode_flags = gr_gk20a_get_preemption_mode_flags; 9308 gops->gr.get_preemption_mode_flags = gr_gk20a_get_preemption_mode_flags;
9308 gops->gr.program_active_tpc_counts = gr_gk20a_program_active_tpc_counts; 9309 gops->gr.program_active_tpc_counts = gr_gk20a_program_active_tpc_counts;
9309 gops->gr.program_sm_id_numbering = gr_gk20a_program_sm_id_numbering; 9310 gops->gr.program_sm_id_numbering = gr_gk20a_program_sm_id_numbering;
diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
index de3f879a..5b5fa82c 100644
--- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
@@ -1589,6 +1589,7 @@ void gm20b_init_gr(struct gpu_ops *gops)
1589 gops->gr.update_sm_error_state = gm20b_gr_update_sm_error_state; 1589 gops->gr.update_sm_error_state = gm20b_gr_update_sm_error_state;
1590 gops->gr.clear_sm_error_state = gm20b_gr_clear_sm_error_state; 1590 gops->gr.clear_sm_error_state = gm20b_gr_clear_sm_error_state;
1591 gops->gr.suspend_contexts = gr_gk20a_suspend_contexts; 1591 gops->gr.suspend_contexts = gr_gk20a_suspend_contexts;
1592 gops->gr.resume_contexts = gr_gk20a_resume_contexts;
1592 gops->gr.get_preemption_mode_flags = gr_gm20b_get_preemption_mode_flags; 1593 gops->gr.get_preemption_mode_flags = gr_gm20b_get_preemption_mode_flags;
1593 gops->gr.fuse_override = gm20b_gr_fuse_override; 1594 gops->gr.fuse_override = gm20b_gr_fuse_override;
1594 gops->gr.init_sm_id_table = gr_gk20a_init_sm_id_table; 1595 gops->gr.init_sm_id_table = gr_gk20a_init_sm_id_table;
diff --git a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c
index 027a92fc..0655ea15 100644
--- a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c
+++ b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c
@@ -405,6 +405,7 @@ int vgpu_init_fifo_support(struct gk20a *g)
405static int vgpu_fifo_preempt_channel(struct gk20a *g, u32 hw_chid) 405static int vgpu_fifo_preempt_channel(struct gk20a *g, u32 hw_chid)
406{ 406{
407 struct fifo_gk20a *f = &g->fifo; 407 struct fifo_gk20a *f = &g->fifo;
408 struct channel_gk20a *ch = &f->channel[hw_chid];
408 struct tegra_vgpu_cmd_msg msg; 409 struct tegra_vgpu_cmd_msg msg;
409 struct tegra_vgpu_channel_config_params *p = 410 struct tegra_vgpu_channel_config_params *p =
410 &msg.params.channel_config; 411 &msg.params.channel_config;
@@ -412,9 +413,12 @@ static int vgpu_fifo_preempt_channel(struct gk20a *g, u32 hw_chid)
412 413
413 gk20a_dbg_fn(""); 414 gk20a_dbg_fn("");
414 415
416 if (!atomic_read(&ch->bound))
417 return 0;
418
415 msg.cmd = TEGRA_VGPU_CMD_CHANNEL_PREEMPT; 419 msg.cmd = TEGRA_VGPU_CMD_CHANNEL_PREEMPT;
416 msg.handle = vgpu_get_handle(g); 420 msg.handle = vgpu_get_handle(g);
417 p->handle = f->channel[hw_chid].virt_ctx; 421 p->handle = ch->virt_ctx;
418 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); 422 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
419 423
420 if (err || msg.ret) { 424 if (err || msg.ret) {
diff --git a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c
index 5c637d25..7ffe96fe 100644
--- a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c
+++ b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c
@@ -1085,6 +1085,83 @@ static int vgpu_gr_clear_sm_error_state(struct gk20a *g,
1085 return 0; 1085 return 0;
1086} 1086}
1087 1087
1088static int vgpu_gr_suspend_resume_contexts(struct gk20a *g,
1089 struct dbg_session_gk20a *dbg_s,
1090 int *ctx_resident_ch_fd, u32 cmd)
1091{
1092 struct dbg_session_channel_data *ch_data;
1093 struct tegra_vgpu_cmd_msg *msg;
1094 struct tegra_vgpu_suspend_resume_contexts *p;
1095 size_t size_out = offsetof(struct tegra_vgpu_cmd_msg,
1096 params.suspend_contexts.chids);
1097 size_t size_in;
1098 size_t n;
1099 int channel_fd = -1;
1100 int err = 0;
1101
1102 mutex_lock(&g->dbg_sessions_lock);
1103 mutex_lock(&dbg_s->ch_list_lock);
1104
1105 n = 0;
1106 list_for_each_entry(ch_data, &dbg_s->ch_list, ch_entry)
1107 n++;
1108
1109 size_in = size_out + n * sizeof(u16);
1110
1111 msg = kmalloc(size_in, GFP_KERNEL);
1112 if (!msg)
1113 return -ENOMEM;
1114
1115 msg->cmd = cmd;
1116 msg->handle = vgpu_get_handle(g);
1117 p = &msg->params.suspend_contexts;
1118 p->num_channels = n;
1119 n = 0;
1120 list_for_each_entry(ch_data, &dbg_s->ch_list, ch_entry) {
1121 p->chids[n++] = (u16)ch_data->chid;
1122 }
1123
1124 err = vgpu_comm_sendrecv(msg, size_in, size_out);
1125 if (err || msg->ret) {
1126 err = -ENOMEM;
1127 goto fail;
1128 }
1129
1130 if (p->resident_chid != (u16)~0) {
1131 list_for_each_entry(ch_data, &dbg_s->ch_list, ch_entry) {
1132 if (ch_data->chid == p->resident_chid) {
1133 channel_fd = ch_data->channel_fd;
1134 break;
1135 }
1136 }
1137 }
1138
1139fail:
1140 mutex_unlock(&dbg_s->ch_list_lock);
1141 mutex_unlock(&g->dbg_sessions_lock);
1142
1143 *ctx_resident_ch_fd = channel_fd;
1144 kfree(msg);
1145
1146 return err;
1147}
1148
1149static int vgpu_gr_suspend_contexts(struct gk20a *g,
1150 struct dbg_session_gk20a *dbg_s,
1151 int *ctx_resident_ch_fd)
1152{
1153 return vgpu_gr_suspend_resume_contexts(g, dbg_s,
1154 ctx_resident_ch_fd, TEGRA_VGPU_CMD_SUSPEND_CONTEXTS);
1155}
1156
1157static int vgpu_gr_resume_contexts(struct gk20a *g,
1158 struct dbg_session_gk20a *dbg_s,
1159 int *ctx_resident_ch_fd)
1160{
1161 return vgpu_gr_suspend_resume_contexts(g, dbg_s,
1162 ctx_resident_ch_fd, TEGRA_VGPU_CMD_RESUME_CONTEXTS);
1163}
1164
1088void vgpu_gr_handle_sm_esr_event(struct gk20a *g, 1165void vgpu_gr_handle_sm_esr_event(struct gk20a *g,
1089 struct tegra_vgpu_sm_esr_info *info) 1166 struct tegra_vgpu_sm_esr_info *info)
1090{ 1167{
@@ -1133,6 +1210,8 @@ void vgpu_init_gr_ops(struct gpu_ops *gops)
1133 gops->gr.update_smpc_ctxsw_mode = vgpu_gr_update_smpc_ctxsw_mode; 1210 gops->gr.update_smpc_ctxsw_mode = vgpu_gr_update_smpc_ctxsw_mode;
1134 gops->gr.update_hwpm_ctxsw_mode = vgpu_gr_update_hwpm_ctxsw_mode; 1211 gops->gr.update_hwpm_ctxsw_mode = vgpu_gr_update_hwpm_ctxsw_mode;
1135 gops->gr.clear_sm_error_state = vgpu_gr_clear_sm_error_state; 1212 gops->gr.clear_sm_error_state = vgpu_gr_clear_sm_error_state;
1213 gops->gr.suspend_contexts = vgpu_gr_suspend_contexts;
1214 gops->gr.resume_contexts = vgpu_gr_resume_contexts;
1136 gops->gr.dump_gr_regs = NULL; 1215 gops->gr.dump_gr_regs = NULL;
1137 gops->gr.set_boosted_ctx = NULL; 1216 gops->gr.set_boosted_ctx = NULL;
1138 gops->gr.update_boosted_ctx = NULL; 1217 gops->gr.update_boosted_ctx = NULL;
diff --git a/include/linux/tegra_vgpu.h b/include/linux/tegra_vgpu.h
index 4f1c7926..9ecc44a7 100644
--- a/include/linux/tegra_vgpu.h
+++ b/include/linux/tegra_vgpu.h
@@ -99,6 +99,8 @@ enum {
99 TEGRA_VGPU_CMD_CHANNEL_CYCLESTATS_SNAPSHOT = 63, 99 TEGRA_VGPU_CMD_CHANNEL_CYCLESTATS_SNAPSHOT = 63,
100 TEGRA_VGPU_CMD_TSG_OPEN = 64, 100 TEGRA_VGPU_CMD_TSG_OPEN = 64,
101 TEGRA_VGPU_CMD_GET_GPU_LOAD = 65, 101 TEGRA_VGPU_CMD_GET_GPU_LOAD = 65,
102 TEGRA_VGPU_CMD_SUSPEND_CONTEXTS = 66,
103 TEGRA_VGPU_CMD_RESUME_CONTEXTS = 67,
102}; 104};
103 105
104struct tegra_vgpu_connect_params { 106struct tegra_vgpu_connect_params {
@@ -454,6 +456,12 @@ struct tegra_vgpu_gpu_load_params {
454 u32 load; 456 u32 load;
455}; 457};
456 458
459struct tegra_vgpu_suspend_resume_contexts {
460 u32 num_channels;
461 u16 resident_chid;
462 u16 chids[];
463};
464
457struct tegra_vgpu_cmd_msg { 465struct tegra_vgpu_cmd_msg {
458 u32 cmd; 466 u32 cmd;
459 int ret; 467 int ret;
@@ -500,6 +508,8 @@ struct tegra_vgpu_cmd_msg {
500 struct tegra_vgpu_constants_params constants; 508 struct tegra_vgpu_constants_params constants;
501 struct tegra_vgpu_channel_cyclestats_snapshot_params cyclestats_snapshot; 509 struct tegra_vgpu_channel_cyclestats_snapshot_params cyclestats_snapshot;
502 struct tegra_vgpu_gpu_load_params gpu_load; 510 struct tegra_vgpu_gpu_load_params gpu_load;
511 struct tegra_vgpu_suspend_resume_contexts suspend_contexts;
512 struct tegra_vgpu_suspend_resume_contexts resume_contexts;
503 char padding[192]; 513 char padding[192];
504 } params; 514 } params;
505}; 515};