mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 02:22:34 +03:00
nvgpu: gpu: simplify waiting logic for interrupt handler
The atomic counter in interrupt handler can overflow and result in calling of BUG() which will crash the process. The equivalent functionality can be implemented with just setting an atomic variable at start of handler and resetting at end of handler. The wait can be longer in case there is constant interrupts coming but ultimately it will end. Generally the wait path is not time critical so it should not be an issue. Also, fix the unit tests for mc. Change-Id: I9b8a236f72e057e89a969d2e98d4d3f9be81b379 Signed-off-by: shashank singh <shashsingh@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2247819 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-misra <svc-mobile-misra@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit
This commit is contained in:
committed by
Alex Waterman
parent
bd5604bba7
commit
d34bad0a27
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2019, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2014-2020, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -47,7 +47,7 @@ irqreturn_t nvgpu_intr_stall(struct gk20a *g)
|
||||
}
|
||||
#endif
|
||||
|
||||
nvgpu_atomic_inc(&g->mc.hw_irq_stall_count);
|
||||
nvgpu_atomic_set(&g->mc.sw_irq_stall_pending, 1);
|
||||
|
||||
#ifdef CONFIG_NVGPU_TRACE
|
||||
trace_mc_gk20a_intr_stall_done(g->name);
|
||||
@@ -58,19 +58,16 @@ irqreturn_t nvgpu_intr_stall(struct gk20a *g)
|
||||
|
||||
irqreturn_t nvgpu_intr_thread_stall(struct gk20a *g)
|
||||
{
|
||||
int hw_irq_count;
|
||||
|
||||
nvgpu_log(g, gpu_dbg_intr, "interrupt thread launched");
|
||||
|
||||
#ifdef CONFIG_NVGPU_TRACE
|
||||
trace_mc_gk20a_intr_thread_stall(g->name);
|
||||
#endif
|
||||
|
||||
hw_irq_count = nvgpu_atomic_read(&g->mc.hw_irq_stall_count);
|
||||
g->ops.mc.isr_stall(g);
|
||||
nvgpu_mc_intr_stall_resume(g);
|
||||
/* sync handled irq counter before re-enabling interrupts */
|
||||
nvgpu_atomic_set(&g->mc.sw_irq_stall_last_handled, hw_irq_count);
|
||||
nvgpu_atomic_set(&g->mc.sw_irq_stall_pending, 0);
|
||||
nvgpu_mc_intr_stall_resume(g);
|
||||
|
||||
nvgpu_cond_broadcast(&g->mc.sw_irq_stall_last_handled_cond);
|
||||
|
||||
@@ -84,7 +81,6 @@ irqreturn_t nvgpu_intr_thread_stall(struct gk20a *g)
|
||||
irqreturn_t nvgpu_intr_nonstall(struct gk20a *g)
|
||||
{
|
||||
u32 non_stall_intr_val;
|
||||
u32 hw_irq_count;
|
||||
int ops_old, ops_new, ops = 0;
|
||||
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
||||
|
||||
@@ -103,6 +99,7 @@ irqreturn_t nvgpu_intr_nonstall(struct gk20a *g)
|
||||
}
|
||||
#endif
|
||||
|
||||
nvgpu_atomic_set(&g->mc.sw_irq_nonstall_pending, 1);
|
||||
ops = g->ops.mc.isr_nonstall(g);
|
||||
if (ops) {
|
||||
do {
|
||||
@@ -114,10 +111,8 @@ irqreturn_t nvgpu_intr_nonstall(struct gk20a *g)
|
||||
queue_work(l->nonstall_work_queue, &l->nonstall_fn_work);
|
||||
}
|
||||
|
||||
hw_irq_count = nvgpu_atomic_inc_return(&g->mc.hw_irq_nonstall_count);
|
||||
|
||||
/* sync handled irq counter before re-enabling interrupts */
|
||||
nvgpu_atomic_set(&g->mc.sw_irq_nonstall_last_handled, hw_irq_count);
|
||||
nvgpu_atomic_set(&g->mc.sw_irq_nonstall_pending, 0);
|
||||
|
||||
nvgpu_mc_intr_nonstall_resume(g);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user