gpu: nvgpu: create timed wait functions for stall and nonstall interrupts completion

In order to process stalling interrupts during TSG unbind, we need a API
to wait for the stalling interrupts to complete within certain duration.

Prepare these APIs for stalling and non-stalling interrupts.

Bug 200711183

Change-Id: I0b7a64c0f3761bbd0ca0843aea28a591ed23739f
Signed-off-by: Sagar Kamble <skamble@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2521970
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
Sagar Kamble
2021-04-28 12:30:52 +05:30
committed by mobile promotions
parent 89ec2afbd4
commit 6672914980
2 changed files with 66 additions and 14 deletions

View File

@@ -28,17 +28,35 @@
#include <nvgpu/nvgpu_init.h>
#include <nvgpu/trace.h>
void nvgpu_wait_for_deferred_interrupts(struct gk20a *g)
int nvgpu_wait_for_stall_interrupts(struct gk20a *g, u32 timeout)
{
/* wait until all stalling irqs are handled */
NVGPU_COND_WAIT(&g->mc.sw_irq_stall_last_handled_cond,
return NVGPU_COND_WAIT(&g->mc.sw_irq_stall_last_handled_cond,
nvgpu_atomic_read(&g->mc.sw_irq_stall_pending) == 0,
0U);
timeout);
}
int nvgpu_wait_for_nonstall_interrupts(struct gk20a *g, u32 timeout)
{
/* wait until all non-stalling irqs are handled */
NVGPU_COND_WAIT(&g->mc.sw_irq_nonstall_last_handled_cond,
return NVGPU_COND_WAIT(&g->mc.sw_irq_nonstall_last_handled_cond,
nvgpu_atomic_read(&g->mc.sw_irq_nonstall_pending) == 0,
0U);
timeout);
}
void nvgpu_wait_for_deferred_interrupts(struct gk20a *g)
{
int ret;
ret = nvgpu_wait_for_stall_interrupts(g, 0U);
if (ret != 0) {
nvgpu_err(g, "wait for stall interrupts failed %d", ret);
}
ret = nvgpu_wait_for_nonstall_interrupts(g, 0U);
if (ret != 0) {
nvgpu_err(g, "wait for nonstall interrupts failed %d", ret);
}
}
void nvgpu_mc_intr_mask(struct gk20a *g)

View File

@@ -325,7 +325,7 @@ struct nvgpu_mc {
* One of the condition variables needed to keep track of deferred
* interrupts.
* The condition variable that is signalled upon handling of the
* stalling interrupt. Function #nvgpu_wait_for_deferred_interrupts
* stalling interrupt. Function #nvgpu_wait_for_stall_interrupts
* waits on this condition variable.
*/
struct nvgpu_cond sw_irq_stall_last_handled_cond;
@@ -341,7 +341,7 @@ struct nvgpu_mc {
* One of the condition variables needed to keep track of deferred
* interrupts.
* The condition variable that is signalled upon handling of the
* non-stalling interrupt. Function #nvgpu_wait_for_deferred_interrupts
* non-stalling interrupt. Function #nvgpu_wait_for_nonstall_interrupts
* waits on this condition variable.
*/
struct nvgpu_cond sw_irq_nonstall_last_handled_cond;
@@ -361,6 +361,45 @@ struct nvgpu_mc {
/** @endcond DOXYGEN_SHOULD_SKIP_THIS */
};
/**
* @brief Wait for the stalling interrupts to complete.
*
* @param g [in] The GPU driver struct.
* @param timeout [in] Timeout
*
* Steps:
* - Get the stalling interrupts atomic count.
* - Wait for #timeout duration on the condition variable
* #sw_irq_stall_last_handled_cond until #sw_irq_stall_last_handled
* becomes greater than or equal to previously read stalling
* interrupt atomic count.
*
* @retval 0 if wait completes successfully.
* @retval -ETIMEDOUT if wait completes without stalling interrupts
* completing.
*/
int nvgpu_wait_for_stall_interrupts(struct gk20a *g, u32 timeout);
/**
* @brief Wait for the non-stalling interrupts to complete.
*
* @param g [in] The GPU driver struct.
* @param timeout [in] Timeout
*
* Steps:
* - Get the non-stalling interrupts atomic count.
* - Wait for #timeout duration on the condition variable
* #sw_irq_nonstall_last_handled_cond until #sw_irq_nonstall_last_handled
* becomes greater than or equal to previously read non-stalling
* interrupt atomic count.
*
* @retval 0 if wait completes successfully.
* @retval -ETIMEDOUT if wait completes without nonstalling interrupts
* completing.
*/
int nvgpu_wait_for_nonstall_interrupts(struct gk20a *g, u32 timeout);
/**
* @brief Wait for the interrupts to complete.
*
@@ -370,13 +409,8 @@ struct nvgpu_mc {
* to wait until all scheduled interrupt handlers have completed. This is
* because the interrupt handlers could access data structures after freeing.
* Steps:
* - Get the stalling and non-stalling interrupts atomic count.
* - Wait on the condition variable #sw_irq_stall_last_handled_cond until
* #sw_irq_stall_last_handled becomes greater than or equal to previously
* read stalling interrupt atomic count.
* - Wait on the condition variable #sw_irq_nonstall_last_handled_cond until
* #sw_irq_nonstall_last_handled becomes greater than or equal to previously
* read non-stalling interrupt atomic count.
* - Wait for stalling interrupts to complete with timeout disabled.
* - Wait for non-stalling interrupts to complete with timeout disabled.
*/
void nvgpu_wait_for_deferred_interrupts(struct gk20a *g);