summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2015-12-21 04:51:49 -0500
committerTerje Bergstrom <tbergstrom@nvidia.com>2016-04-19 11:07:45 -0400
commitb63c4bced5b01e2aef477ecfca784848e2a2cd3a (patch)
tree4309e72334876236efc29fd57bda6f49599c7732 /drivers
parentdfac8ce70464413c0e3748634c57d49950e71933 (diff)
gpu: nvgpu: IOCTL to suspend/resume context
Add below IOCTL to suspend/resume a context NVGPU_DBG_GPU_IOCTL_SUSPEND_RESUME_CONTEXTS: Suspend sequence : - disable ctxsw - loop through list of channels - if channel is ctx resident, suspend all SMs - otherwise, disable channel/TSG - enable ctxsw Resume sequence : - disable ctxsw - loop through list of channels - if channel is ctx resident, resume all SMs - otherwise, enable channel/TSG - enable ctxsw Bug 200156699 Change-Id: Iacf1bf7877b67ddf87cc6891c37c758a4644b014 Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/1120332 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c81
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h3
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c118
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.h9
-rw-r--r--drivers/gpu/nvgpu/gm20b/gr_gm20b.c1
5 files changed, 181 insertions, 31 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
index 34685416..afc1517b 100644
--- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
@@ -780,6 +780,42 @@ err_free:
780 return err; 780 return err;
781} 781}
782 782
783static int
784nvgpu_dbg_gpu_ioctl_suspend_resume_contexts(struct dbg_session_gk20a *dbg_s,
785 struct nvgpu_dbg_gpu_suspend_resume_contexts_args *args)
786{
787 struct gk20a *g = dbg_s->g;
788 int err = 0;
789 int ctx_resident_ch_fd = -1;
790
791 err = gk20a_busy(g->dev);
792 if (err)
793 return err;
794
795 switch (args->action) {
796 case NVGPU_DBG_GPU_SUSPEND_ALL_CONTEXTS:
797 err = g->ops.gr.suspend_contexts(g, dbg_s,
798 &ctx_resident_ch_fd);
799 break;
800
801 case NVGPU_DBG_GPU_RESUME_ALL_CONTEXTS:
802 err = gr_gk20a_resume_contexts(g, dbg_s,
803 &ctx_resident_ch_fd);
804 break;
805 }
806
807 if (ctx_resident_ch_fd < 0) {
808 args->is_resident_context = 0;
809 } else {
810 args->is_resident_context = 1;
811 args->resident_context_fd = ctx_resident_ch_fd;
812 }
813
814 gk20a_idle(g->dev);
815
816 return err;
817}
818
783long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd, 819long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd,
784 unsigned long arg) 820 unsigned long arg)
785{ 821{
@@ -897,6 +933,11 @@ long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd,
897 (struct nvgpu_dbg_gpu_unbind_channel_args *)buf); 933 (struct nvgpu_dbg_gpu_unbind_channel_args *)buf);
898 break; 934 break;
899 935
936 case NVGPU_DBG_GPU_IOCTL_SUSPEND_RESUME_CONTEXTS:
937 err = nvgpu_dbg_gpu_ioctl_suspend_resume_contexts(dbg_s,
938 (struct nvgpu_dbg_gpu_suspend_resume_contexts_args *)buf);
939 break;
940
900 default: 941 default:
901 gk20a_err(dev_from_gk20a(g), 942 gk20a_err(dev_from_gk20a(g),
902 "unrecognized dbg gpu ioctl cmd: 0x%x", 943 "unrecognized dbg gpu ioctl cmd: 0x%x",
@@ -1222,7 +1263,6 @@ static int nvgpu_dbg_gpu_ioctl_suspend_resume_sm(
1222{ 1263{
1223 struct gk20a *g = get_gk20a(dbg_s->dev); 1264 struct gk20a *g = get_gk20a(dbg_s->dev);
1224 struct channel_gk20a *ch; 1265 struct channel_gk20a *ch;
1225 bool ch_is_curr_ctx;
1226 int err = 0, action = args->mode; 1266 int err = 0, action = args->mode;
1227 1267
1228 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, "action: %d", args->mode); 1268 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, "action: %d", args->mode);
@@ -1234,10 +1274,6 @@ static int nvgpu_dbg_gpu_ioctl_suspend_resume_sm(
1234 mutex_lock(&g->dbg_sessions_lock); 1274 mutex_lock(&g->dbg_sessions_lock);
1235 1275
1236 /* Suspend GPU context switching */ 1276 /* Suspend GPU context switching */
1237 /* Disable channel switching.
1238 * at that point the hardware state can be inspected to
1239 * determine if the context we're interested in is current.
1240 */
1241 err = gr_gk20a_disable_ctxsw(g); 1277 err = gr_gk20a_disable_ctxsw(g);
1242 if (err) { 1278 if (err) {
1243 gk20a_err(dev_from_gk20a(g), "unable to stop gr ctxsw"); 1279 gk20a_err(dev_from_gk20a(g), "unable to stop gr ctxsw");
@@ -1245,40 +1281,23 @@ static int nvgpu_dbg_gpu_ioctl_suspend_resume_sm(
1245 goto clean_up; 1281 goto clean_up;
1246 } 1282 }
1247 1283
1248 /* find out whether the current channel is resident */ 1284 switch (action) {
1249 ch_is_curr_ctx = gk20a_is_channel_ctx_resident(ch); 1285 case NVGPU_DBG_GPU_SUSPEND_ALL_SMS:
1250 1286 gr_gk20a_suspend_context(ch);
1251 if (ch_is_curr_ctx) { 1287 break;
1252 switch (action) {
1253 case NVGPU_DBG_GPU_SUSPEND_ALL_SMS:
1254 gk20a_suspend_all_sms(g, 0, false);
1255 break;
1256
1257 case NVGPU_DBG_GPU_RESUME_ALL_SMS:
1258 gk20a_resume_all_sms(g);
1259 break;
1260 }
1261 } else {
1262 switch (action) {
1263 case NVGPU_DBG_GPU_SUSPEND_ALL_SMS:
1264 /* Disable the channel */
1265 channel_gk20a_disable(ch);
1266 break;
1267 1288
1268 case NVGPU_DBG_GPU_RESUME_ALL_SMS: 1289 case NVGPU_DBG_GPU_RESUME_ALL_SMS:
1269 /* Enable the channel */ 1290 gr_gk20a_resume_context(ch);
1270 channel_gk20a_enable(ch); 1291 break;
1271 break;
1272 }
1273 } 1292 }
1274 1293
1275 /* Resume GPU context switching */
1276 err = gr_gk20a_enable_ctxsw(g); 1294 err = gr_gk20a_enable_ctxsw(g);
1277 if (err) 1295 if (err)
1278 gk20a_err(dev_from_gk20a(g), "unable to restart ctxsw!\n"); 1296 gk20a_err(dev_from_gk20a(g), "unable to restart ctxsw!\n");
1279 1297
1280 clean_up: 1298clean_up:
1281 mutex_unlock(&g->dbg_sessions_lock); 1299 mutex_unlock(&g->dbg_sessions_lock);
1300
1282 return err; 1301 return err;
1283} 1302}
1284 1303
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index b03e779b..5c397ad8 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -248,6 +248,9 @@ struct gpu_ops {
248 sm_error_state); 248 sm_error_state);
249 int (*clear_sm_error_state)(struct gk20a *g, 249 int (*clear_sm_error_state)(struct gk20a *g,
250 struct channel_gk20a *ch, u32 sm_id); 250 struct channel_gk20a *ch, u32 sm_id);
251 int (*suspend_contexts)(struct gk20a *g,
252 struct dbg_session_gk20a *dbg_s,
253 int *ctx_resident_ch_fd);
251 } gr; 254 } gr;
252 const char *name; 255 const char *name;
253 struct { 256 struct {
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index 4c88751e..3354c05e 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -8458,6 +8458,123 @@ static void gr_gk20a_get_access_map(struct gk20a *g,
8458 *num_entries = ARRAY_SIZE(wl_addr_gk20a); 8458 *num_entries = ARRAY_SIZE(wl_addr_gk20a);
8459} 8459}
8460 8460
8461/*
8462 * gr_gk20a_suspend_context()
8463 * This API should be called with dbg_session lock held
8464 * and ctxsw disabled
8465 * Returns bool value indicating if context was resident
8466 * or not
8467 */
8468bool gr_gk20a_suspend_context(struct channel_gk20a *ch)
8469{
8470 struct gk20a *g = ch->g;
8471 bool ctx_resident = false;
8472
8473 if (gk20a_is_channel_ctx_resident(ch)) {
8474 gk20a_suspend_all_sms(g, 0, false);
8475 ctx_resident = true;
8476 } else {
8477 gk20a_disable_channel_tsg(g, ch);
8478 }
8479
8480 return ctx_resident;
8481}
8482
8483bool gr_gk20a_resume_context(struct channel_gk20a *ch)
8484{
8485 struct gk20a *g = ch->g;
8486 bool ctx_resident = false;
8487
8488 if (gk20a_is_channel_ctx_resident(ch)) {
8489 gk20a_resume_all_sms(g);
8490 ctx_resident = true;
8491 } else {
8492 gk20a_enable_channel_tsg(g, ch);
8493 }
8494
8495 return ctx_resident;
8496}
8497
8498int gr_gk20a_suspend_contexts(struct gk20a *g,
8499 struct dbg_session_gk20a *dbg_s,
8500 int *ctx_resident_ch_fd)
8501{
8502 int local_ctx_resident_ch_fd = -1;
8503 bool ctx_resident;
8504 struct channel_gk20a *ch;
8505 struct dbg_session_channel_data *ch_data;
8506 int err = 0;
8507
8508 mutex_lock(&g->dbg_sessions_lock);
8509
8510 err = gr_gk20a_disable_ctxsw(g);
8511 if (err) {
8512 gk20a_err(dev_from_gk20a(g), "unable to stop gr ctxsw");
8513 goto clean_up;
8514 }
8515
8516 mutex_lock(&dbg_s->ch_list_lock);
8517
8518 list_for_each_entry(ch_data, &dbg_s->ch_list, ch_entry) {
8519 ch = g->fifo.channel + ch_data->chid;
8520
8521 ctx_resident = gr_gk20a_suspend_context(ch);
8522 if (ctx_resident)
8523 local_ctx_resident_ch_fd = ch_data->channel_fd;
8524 }
8525
8526 mutex_unlock(&dbg_s->ch_list_lock);
8527
8528 err = gr_gk20a_enable_ctxsw(g);
8529 if (err)
8530 gk20a_err(dev_from_gk20a(g), "unable to restart ctxsw!\n");
8531
8532 *ctx_resident_ch_fd = local_ctx_resident_ch_fd;
8533
8534clean_up:
8535 mutex_unlock(&g->dbg_sessions_lock);
8536
8537 return err;
8538}
8539
8540int gr_gk20a_resume_contexts(struct gk20a *g,
8541 struct dbg_session_gk20a *dbg_s,
8542 int *ctx_resident_ch_fd)
8543{
8544 int local_ctx_resident_ch_fd = -1;
8545 bool ctx_resident;
8546 struct channel_gk20a *ch;
8547 int err = 0;
8548 struct dbg_session_channel_data *ch_data;
8549
8550 mutex_lock(&g->dbg_sessions_lock);
8551
8552 err = gr_gk20a_disable_ctxsw(g);
8553 if (err) {
8554 gk20a_err(dev_from_gk20a(g), "unable to stop gr ctxsw");
8555 goto clean_up;
8556 }
8557
8558 list_for_each_entry(ch_data, &dbg_s->ch_list, ch_entry) {
8559 ch = g->fifo.channel + ch_data->chid;
8560
8561 ctx_resident = gr_gk20a_resume_context(ch);
8562 if (ctx_resident)
8563 local_ctx_resident_ch_fd = ch_data->channel_fd;
8564 }
8565
8566 err = gr_gk20a_enable_ctxsw(g);
8567 if (err)
8568 gk20a_err(dev_from_gk20a(g), "unable to restart ctxsw!\n");
8569
8570 *ctx_resident_ch_fd = local_ctx_resident_ch_fd;
8571
8572clean_up:
8573 mutex_unlock(&g->dbg_sessions_lock);
8574
8575 return err;
8576}
8577
8461void gk20a_init_gr_ops(struct gpu_ops *gops) 8578void gk20a_init_gr_ops(struct gpu_ops *gops)
8462{ 8579{
8463 gops->gr.access_smpc_reg = gr_gk20a_access_smpc_reg; 8580 gops->gr.access_smpc_reg = gr_gk20a_access_smpc_reg;
@@ -8522,4 +8639,5 @@ void gk20a_init_gr_ops(struct gpu_ops *gops)
8522 gops->gr.record_sm_error_state = gk20a_gr_record_sm_error_state; 8639 gops->gr.record_sm_error_state = gk20a_gr_record_sm_error_state;
8523 gops->gr.update_sm_error_state = gk20a_gr_update_sm_error_state; 8640 gops->gr.update_sm_error_state = gk20a_gr_update_sm_error_state;
8524 gops->gr.clear_sm_error_state = gk20a_gr_clear_sm_error_state; 8641 gops->gr.clear_sm_error_state = gk20a_gr_clear_sm_error_state;
8642 gops->gr.suspend_contexts = gr_gk20a_suspend_contexts;
8525} 8643}
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h
index 22ff1351..3417610f 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h
@@ -614,4 +614,13 @@ int gr_gk20a_get_ctx_id(struct gk20a *g,
614 614
615u32 gk20a_mask_hww_warp_esr(u32 hww_warp_esr); 615u32 gk20a_mask_hww_warp_esr(u32 hww_warp_esr);
616 616
617bool gr_gk20a_suspend_context(struct channel_gk20a *ch);
618bool gr_gk20a_resume_context(struct channel_gk20a *ch);
619int gr_gk20a_suspend_contexts(struct gk20a *g,
620 struct dbg_session_gk20a *dbg_s,
621 int *ctx_resident_ch_fd);
622int gr_gk20a_resume_contexts(struct gk20a *g,
623 struct dbg_session_gk20a *dbg_s,
624 int *ctx_resident_ch_fd);
625
617#endif /*__GR_GK20A_H__*/ 626#endif /*__GR_GK20A_H__*/
diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
index 204a90f3..9d269365 100644
--- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
@@ -1397,4 +1397,5 @@ void gm20b_init_gr(struct gpu_ops *gops)
1397 gops->gr.record_sm_error_state = gm20b_gr_record_sm_error_state; 1397 gops->gr.record_sm_error_state = gm20b_gr_record_sm_error_state;
1398 gops->gr.update_sm_error_state = gm20b_gr_update_sm_error_state; 1398 gops->gr.update_sm_error_state = gm20b_gr_update_sm_error_state;
1399 gops->gr.clear_sm_error_state = gm20b_gr_clear_sm_error_state; 1399 gops->gr.clear_sm_error_state = gm20b_gr_clear_sm_error_state;
1400 gops->gr.suspend_contexts = gr_gk20a_suspend_contexts;
1400} 1401}