diff options
author | Thomas Fleury <tfleury@nvidia.com> | 2017-01-25 19:59:31 -0500 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-03-09 13:44:55 -0500 |
commit | 6c35cebdcb2d14741385cfe051577882a806cdb8 (patch) | |
tree | 80c0e8f0519dc253839a1aa7c8fe6e7da7ad336a /drivers/gpu/nvgpu | |
parent | bc47d822298b9f3b2f93a384a7780a3763fee495 (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>
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/gr_gm20b.c | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/vgpu/fifo_vgpu.c | 6 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/vgpu/gr_vgpu.c | 79 |
6 files changed, 90 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) | |||
405 | static int vgpu_fifo_preempt_channel(struct gk20a *g, u32 hw_chid) | 405 | static 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 | ||
1088 | static 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 | |||
1139 | fail: | ||
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 | |||
1149 | static 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 | |||
1157 | static 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 | |||
1088 | void vgpu_gr_handle_sm_esr_event(struct gk20a *g, | 1165 | void 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; |