diff options
author | sujeet baranwal <sbaranwal@nvidia.com> | 2014-09-30 13:54:57 -0400 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-03-18 15:11:57 -0400 |
commit | 5febd08ae76cbd4042e53ad70f062cd491b7e8b6 (patch) | |
tree | 3815d03eaab78e1d249a8fafeec32a312ddc9de7 /drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | |
parent | 3d313d06570dcb28bba73247a2c0fc52bec56af0 (diff) |
gpu: kernel support for suspending/resuming SMs
Kernel support for allowing a GPU debugger to suspend and resume
SMs. Invocation of "suspend" on a given channel will suspend all
SMs if the channel is resident, else remove the channel form the
runlist. Similarly, "resume" will either resume all SMs if the
channel was resident, or re-enable the channel in the runlist.
Change-Id: I3b4ae21dc1b91c1059c828ec6db8125f8a0ce194
Signed-off-by: sujeet baranwal <sbaranwal@nvidia.com>
Signed-off-by: Mayank Kaushik <mkaushik@nvidia.com>
Reviewed-on: http://git-master/r/552115
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c index 94486064..39941aae 100644 --- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "dbg_gpu_gk20a.h" | 28 | #include "dbg_gpu_gk20a.h" |
29 | #include "regops_gk20a.h" | 29 | #include "regops_gk20a.h" |
30 | #include "hw_therm_gk20a.h" | 30 | #include "hw_therm_gk20a.h" |
31 | #include "hw_gr_gk20a.h" | ||
31 | 32 | ||
32 | struct dbg_gpu_session_ops dbg_gpu_session_ops_gk20a = { | 33 | struct dbg_gpu_session_ops dbg_gpu_session_ops_gk20a = { |
33 | .exec_reg_ops = exec_regops_gk20a, | 34 | .exec_reg_ops = exec_regops_gk20a, |
@@ -359,6 +360,11 @@ static int nvgpu_ioctl_powergate_gk20a(struct dbg_session_gk20a *dbg_s, | |||
359 | static int nvgpu_dbg_gpu_ioctl_smpc_ctxsw_mode(struct dbg_session_gk20a *dbg_s, | 360 | static int nvgpu_dbg_gpu_ioctl_smpc_ctxsw_mode(struct dbg_session_gk20a *dbg_s, |
360 | struct nvgpu_dbg_gpu_smpc_ctxsw_mode_args *args); | 361 | struct nvgpu_dbg_gpu_smpc_ctxsw_mode_args *args); |
361 | 362 | ||
363 | static int nvgpu_dbg_gpu_ioctl_suspend_resume_sm( | ||
364 | struct dbg_session_gk20a *dbg_s, | ||
365 | struct nvgpu_dbg_gpu_suspend_resume_all_sms_args *args); | ||
366 | |||
367 | |||
362 | long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd, | 368 | long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd, |
363 | unsigned long arg) | 369 | unsigned long arg) |
364 | { | 370 | { |
@@ -418,8 +424,13 @@ long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd, | |||
418 | (struct nvgpu_dbg_gpu_smpc_ctxsw_mode_args *)buf); | 424 | (struct nvgpu_dbg_gpu_smpc_ctxsw_mode_args *)buf); |
419 | break; | 425 | break; |
420 | 426 | ||
427 | case NVGPU_DBG_GPU_IOCTL_SUSPEND_RESUME_ALL_SMS: | ||
428 | err = nvgpu_dbg_gpu_ioctl_suspend_resume_sm(dbg_s, | ||
429 | (struct nvgpu_dbg_gpu_suspend_resume_all_sms_args *)buf); | ||
430 | break; | ||
431 | |||
421 | default: | 432 | default: |
422 | dev_dbg(dev_from_gk20a(g), | 433 | gk20a_err(dev_from_gk20a(g), |
423 | "unrecognized dbg gpu ioctl cmd: 0x%x", | 434 | "unrecognized dbg gpu ioctl cmd: 0x%x", |
424 | cmd); | 435 | cmd); |
425 | err = -ENOTTY; | 436 | err = -ENOTTY; |
@@ -693,3 +704,63 @@ static int nvgpu_dbg_gpu_ioctl_smpc_ctxsw_mode(struct dbg_session_gk20a *dbg_s, | |||
693 | mutex_unlock(&g->dbg_sessions_lock); | 704 | mutex_unlock(&g->dbg_sessions_lock); |
694 | return err; | 705 | return err; |
695 | } | 706 | } |
707 | |||
708 | static int nvgpu_dbg_gpu_ioctl_suspend_resume_sm( | ||
709 | struct dbg_session_gk20a *dbg_s, | ||
710 | struct nvgpu_dbg_gpu_suspend_resume_all_sms_args *args) | ||
711 | { | ||
712 | struct gk20a *g = get_gk20a(dbg_s->pdev); | ||
713 | struct channel_gk20a *ch = dbg_s->ch; | ||
714 | bool ch_is_curr_ctx; | ||
715 | int err = 0, action = args->mode; | ||
716 | |||
717 | mutex_lock(&g->dbg_sessions_lock); | ||
718 | |||
719 | /* Suspend GPU context switching */ | ||
720 | /* Disable channel switching. | ||
721 | * at that point the hardware state can be inspected to | ||
722 | * determine if the context we're interested in is current. | ||
723 | */ | ||
724 | err = gr_gk20a_disable_ctxsw(g); | ||
725 | if (err) { | ||
726 | gk20a_err(dev_from_gk20a(g), "unable to stop gr ctxsw"); | ||
727 | /* this should probably be ctx-fatal... */ | ||
728 | goto clean_up; | ||
729 | } | ||
730 | |||
731 | /* find out whether the current channel is resident */ | ||
732 | ch_is_curr_ctx = gk20a_is_channel_ctx_resident(ch); | ||
733 | |||
734 | if (ch_is_curr_ctx) { | ||
735 | switch (action) { | ||
736 | case NVGPU_DBG_GPU_SUSPEND_ALL_SMS: | ||
737 | gk20a_suspend_all_sms(g); | ||
738 | break; | ||
739 | |||
740 | case NVGPU_DBG_GPU_RESUME_ALL_SMS: | ||
741 | gk20a_resume_all_sms(g); | ||
742 | break; | ||
743 | } | ||
744 | } else { | ||
745 | switch (action) { | ||
746 | case NVGPU_DBG_GPU_SUSPEND_ALL_SMS: | ||
747 | /* Disable the channel */ | ||
748 | channel_gk20a_disable(ch); | ||
749 | break; | ||
750 | |||
751 | case NVGPU_DBG_GPU_RESUME_ALL_SMS: | ||
752 | /* Enable the channel */ | ||
753 | channel_gk20a_enable(ch); | ||
754 | break; | ||
755 | } | ||
756 | } | ||
757 | |||
758 | /* Resume GPU context switching */ | ||
759 | err = gr_gk20a_enable_ctxsw(g); | ||
760 | if (err) | ||
761 | gk20a_err(dev_from_gk20a(g), "unable to restart ctxsw!\n"); | ||
762 | |||
763 | clean_up: | ||
764 | mutex_unlock(&g->dbg_sessions_lock); | ||
765 | return err; | ||
766 | } | ||