diff options
author | Shashank Singh <shashsingh@nvidia.com> | 2017-12-28 01:22:14 -0500 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-03-12 12:13:00 -0400 |
commit | db089a73a586b34e6266504925b29eea8628673e (patch) | |
tree | 6006c525d7046a75974f26ad65f0f4cfee3da768 | |
parent | 02956adcd35507dde5db3a3b006a5c6a06334733 (diff) |
gpu: nvgpu: add refcounting for ctxsw disable/enable
ctxsw disable could be called recursively for RM server. Suspend
contexts disables ctxsw at the beginning, then call tsg disable and
preempt. If preempt timeout happens, it goes to recovery path, which
will try to disable ctxsw again. More details on Bug 200331110.
Jira VQRM-2982
Change-Id: I4659c842ae73ed59be51ae65b25366f24abcaf22
Signed-off-by: Shashank Singh <shashsingh@nvidia.com>
Signed-off-by: Richard Zhao <rizhao@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1671716
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Sourab Gupta <sourabg@nvidia.com>
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/driver_common.c | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 31 |
4 files changed, 29 insertions, 7 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/driver_common.c b/drivers/gpu/nvgpu/common/linux/driver_common.c index 9029366f..695bb307 100644 --- a/drivers/gpu/nvgpu/common/linux/driver_common.c +++ b/drivers/gpu/nvgpu/common/linux/driver_common.c | |||
@@ -62,6 +62,7 @@ static void nvgpu_init_vars(struct gk20a *g) | |||
62 | nvgpu_mutex_init(&g->client_lock); | 62 | nvgpu_mutex_init(&g->client_lock); |
63 | nvgpu_mutex_init(&g->poweron_lock); | 63 | nvgpu_mutex_init(&g->poweron_lock); |
64 | nvgpu_mutex_init(&g->poweroff_lock); | 64 | nvgpu_mutex_init(&g->poweroff_lock); |
65 | nvgpu_mutex_init(&g->ctxsw_disable_lock); | ||
65 | 66 | ||
66 | l->regs_saved = l->regs; | 67 | l->regs_saved = l->regs; |
67 | l->bar1_saved = l->bar1; | 68 | l->bar1_saved = l->bar1; |
diff --git a/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c b/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c index 1e5efa38..6f040603 100644 --- a/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c +++ b/drivers/gpu/nvgpu/common/linux/vgpu/vgpu_linux.c | |||
@@ -76,6 +76,7 @@ static void vgpu_init_vars(struct gk20a *g, struct gk20a_platform *platform) | |||
76 | 76 | ||
77 | nvgpu_mutex_init(&g->poweron_lock); | 77 | nvgpu_mutex_init(&g->poweron_lock); |
78 | nvgpu_mutex_init(&g->poweroff_lock); | 78 | nvgpu_mutex_init(&g->poweroff_lock); |
79 | nvgpu_mutex_init(&g->ctxsw_disable_lock); | ||
79 | l->regs_saved = l->regs; | 80 | l->regs_saved = l->regs; |
80 | l->bar1_saved = l->bar1; | 81 | l->bar1_saved = l->bar1; |
81 | 82 | ||
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 3442861c..4ebdb6a4 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -1191,6 +1191,9 @@ struct gk20a { | |||
1191 | 1191 | ||
1192 | nvgpu_atomic_t usage_count; | 1192 | nvgpu_atomic_t usage_count; |
1193 | 1193 | ||
1194 | struct nvgpu_mutex ctxsw_disable_lock; | ||
1195 | int ctxsw_disable_count; | ||
1196 | |||
1194 | struct nvgpu_ref refcount; | 1197 | struct nvgpu_ref refcount; |
1195 | 1198 | ||
1196 | const char *name; | 1199 | const char *name; |
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 61975106..8a3f98af 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c | |||
@@ -616,22 +616,39 @@ static int gr_gk20a_ctrl_ctxsw(struct gk20a *g, u32 fecs_method, u32 *ret) | |||
616 | .cond.fail = GR_IS_UCODE_OP_EQUAL }, true); | 616 | .cond.fail = GR_IS_UCODE_OP_EQUAL }, true); |
617 | } | 617 | } |
618 | 618 | ||
619 | /* Stop processing (stall) context switches at FECS. | 619 | /* Stop processing (stall) context switches at FECS. */ |
620 | * The caller must hold the dbg_sessions_lock, else if mutliple stop methods | ||
621 | * are sent to the ucode in sequence, it can get into an undefined state. */ | ||
622 | int gr_gk20a_disable_ctxsw(struct gk20a *g) | 620 | int gr_gk20a_disable_ctxsw(struct gk20a *g) |
623 | { | 621 | { |
622 | int err = 0; | ||
623 | |||
624 | gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, ""); | 624 | gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, ""); |
625 | return gr_gk20a_ctrl_ctxsw(g, | 625 | |
626 | gr_fecs_method_push_adr_stop_ctxsw_v(), NULL); | 626 | nvgpu_mutex_acquire(&g->ctxsw_disable_lock); |
627 | g->ctxsw_disable_count++; | ||
628 | if (g->ctxsw_disable_count == 1) | ||
629 | err = gr_gk20a_ctrl_ctxsw(g, | ||
630 | gr_fecs_method_push_adr_stop_ctxsw_v(), NULL); | ||
631 | nvgpu_mutex_release(&g->ctxsw_disable_lock); | ||
632 | |||
633 | return err; | ||
627 | } | 634 | } |
628 | 635 | ||
629 | /* Start processing (continue) context switches at FECS */ | 636 | /* Start processing (continue) context switches at FECS */ |
630 | int gr_gk20a_enable_ctxsw(struct gk20a *g) | 637 | int gr_gk20a_enable_ctxsw(struct gk20a *g) |
631 | { | 638 | { |
639 | int err = 0; | ||
640 | |||
632 | gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, ""); | 641 | gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, ""); |
633 | return gr_gk20a_ctrl_ctxsw(g, | 642 | |
634 | gr_fecs_method_push_adr_start_ctxsw_v(), NULL); | 643 | nvgpu_mutex_acquire(&g->ctxsw_disable_lock); |
644 | g->ctxsw_disable_count--; | ||
645 | WARN_ON(g->ctxsw_disable_count < 0); | ||
646 | if (g->ctxsw_disable_count == 0) | ||
647 | err = gr_gk20a_ctrl_ctxsw(g, | ||
648 | gr_fecs_method_push_adr_start_ctxsw_v(), NULL); | ||
649 | nvgpu_mutex_release(&g->ctxsw_disable_lock); | ||
650 | |||
651 | return err; | ||
635 | } | 652 | } |
636 | 653 | ||
637 | int gr_gk20a_halt_pipe(struct gk20a *g) | 654 | int gr_gk20a_halt_pipe(struct gk20a *g) |