summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
diff options
context:
space:
mode:
authorsujeet baranwal <sbaranwal@nvidia.com>2014-09-30 13:54:57 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:11:57 -0400
commit5febd08ae76cbd4042e53ad70f062cd491b7e8b6 (patch)
tree3815d03eaab78e1d249a8fafeec32a312ddc9de7 /drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
parent3d313d06570dcb28bba73247a2c0fc52bec56af0 (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.c73
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
32struct dbg_gpu_session_ops dbg_gpu_session_ops_gk20a = { 33struct 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,
359static int nvgpu_dbg_gpu_ioctl_smpc_ctxsw_mode(struct dbg_session_gk20a *dbg_s, 360static 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
363static 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
362long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd, 368long 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
708static 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}