diff options
Diffstat (limited to 'drivers/gpu/nvgpu/vgpu/gr_vgpu.c')
-rw-r--r-- | drivers/gpu/nvgpu/vgpu/gr_vgpu.c | 49 |
1 files changed, 27 insertions, 22 deletions
diff --git a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c index dd515f41..42af9ee1 100644 --- a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c | |||
@@ -1100,41 +1100,47 @@ static int vgpu_gr_suspend_resume_contexts(struct gk20a *g, | |||
1100 | int *ctx_resident_ch_fd, u32 cmd) | 1100 | int *ctx_resident_ch_fd, u32 cmd) |
1101 | { | 1101 | { |
1102 | struct dbg_session_channel_data *ch_data; | 1102 | struct dbg_session_channel_data *ch_data; |
1103 | struct tegra_vgpu_cmd_msg *msg; | 1103 | struct tegra_vgpu_cmd_msg msg; |
1104 | struct tegra_vgpu_suspend_resume_contexts *p; | 1104 | struct tegra_vgpu_suspend_resume_contexts *p; |
1105 | size_t size_out = offsetof(struct tegra_vgpu_cmd_msg, | ||
1106 | params.suspend_contexts.chids); | ||
1107 | size_t size_in; | ||
1108 | size_t n; | 1105 | size_t n; |
1109 | int channel_fd = -1; | 1106 | int channel_fd = -1; |
1110 | int err = 0; | 1107 | int err = 0; |
1108 | void *handle = NULL; | ||
1109 | u16 *oob; | ||
1110 | size_t oob_size; | ||
1111 | 1111 | ||
1112 | nvgpu_mutex_acquire(&g->dbg_sessions_lock); | 1112 | nvgpu_mutex_acquire(&g->dbg_sessions_lock); |
1113 | nvgpu_mutex_acquire(&dbg_s->ch_list_lock); | 1113 | nvgpu_mutex_acquire(&dbg_s->ch_list_lock); |
1114 | 1114 | ||
1115 | handle = tegra_gr_comm_oob_get_ptr(TEGRA_GR_COMM_CTX_CLIENT, | ||
1116 | tegra_gr_comm_get_server_vmid(), TEGRA_VGPU_QUEUE_CMD, | ||
1117 | (void **)&oob, &oob_size); | ||
1118 | if (!handle) { | ||
1119 | err = -EINVAL; | ||
1120 | goto done; | ||
1121 | } | ||
1122 | |||
1115 | n = 0; | 1123 | n = 0; |
1116 | list_for_each_entry(ch_data, &dbg_s->ch_list, ch_entry) | 1124 | list_for_each_entry(ch_data, &dbg_s->ch_list, ch_entry) |
1117 | n++; | 1125 | n++; |
1118 | 1126 | ||
1119 | size_in = size_out + n * sizeof(u16); | 1127 | if (oob_size < n * sizeof(u16)) { |
1120 | 1128 | err = -ENOMEM; | |
1121 | msg = nvgpu_kmalloc(g, size_in); | 1129 | goto done; |
1122 | if (!msg) | 1130 | } |
1123 | return -ENOMEM; | ||
1124 | 1131 | ||
1125 | msg->cmd = cmd; | 1132 | msg.cmd = cmd; |
1126 | msg->handle = vgpu_get_handle(g); | 1133 | msg.handle = vgpu_get_handle(g); |
1127 | p = &msg->params.suspend_contexts; | 1134 | p = &msg.params.suspend_contexts; |
1128 | p->num_channels = n; | 1135 | p->num_channels = n; |
1129 | n = 0; | 1136 | n = 0; |
1130 | list_for_each_entry(ch_data, &dbg_s->ch_list, ch_entry) { | 1137 | list_for_each_entry(ch_data, &dbg_s->ch_list, ch_entry) |
1131 | p->chids[n++] = (u16)ch_data->chid; | 1138 | oob[n++] = (u16)ch_data->chid; |
1132 | } | ||
1133 | 1139 | ||
1134 | err = vgpu_comm_sendrecv(msg, size_in, size_out); | 1140 | err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); |
1135 | if (err || msg->ret) { | 1141 | if (err || msg.ret) { |
1136 | err = -ENOMEM; | 1142 | err = -ENOMEM; |
1137 | goto fail; | 1143 | goto done; |
1138 | } | 1144 | } |
1139 | 1145 | ||
1140 | if (p->resident_chid != (u16)~0) { | 1146 | if (p->resident_chid != (u16)~0) { |
@@ -1146,13 +1152,12 @@ static int vgpu_gr_suspend_resume_contexts(struct gk20a *g, | |||
1146 | } | 1152 | } |
1147 | } | 1153 | } |
1148 | 1154 | ||
1149 | fail: | 1155 | done: |
1156 | if (handle) | ||
1157 | tegra_gr_comm_oob_put_ptr(handle); | ||
1150 | nvgpu_mutex_release(&dbg_s->ch_list_lock); | 1158 | nvgpu_mutex_release(&dbg_s->ch_list_lock); |
1151 | nvgpu_mutex_release(&g->dbg_sessions_lock); | 1159 | nvgpu_mutex_release(&g->dbg_sessions_lock); |
1152 | |||
1153 | *ctx_resident_ch_fd = channel_fd; | 1160 | *ctx_resident_ch_fd = channel_fd; |
1154 | nvgpu_kfree(g, msg); | ||
1155 | |||
1156 | return err; | 1161 | return err; |
1157 | } | 1162 | } |
1158 | 1163 | ||