mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 10:34:43 +03:00
gpu: nvgpu: Proper timeout for NVGPU_COND_WAIT
The timeout parameter to NVGPU_COND_WAIT() was passed directly to wait_event_timeout(), which takes jiffies. Also allows zero timeout to disable timeout. The return value of NVGPU_COND_WAIT() was defined in a way specific to how Linux wait_event_() calls work. Replace that with proper error reporting and change the callers to check against error codes. JIRA NVGPU-14 Change-Id: Idbd2c8fbbef7589c3ca4f4c5732852bc71217515 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/1484927 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
9db45cf037
commit
ee25b33ca4
@@ -392,7 +392,6 @@ static int gk20a_channel_wait_semaphore(struct channel_gk20a *ch,
|
||||
void *data;
|
||||
u32 *semaphore;
|
||||
int ret = 0;
|
||||
long remain;
|
||||
|
||||
/* do not wait if channel has timed out */
|
||||
if (ch->has_timedout)
|
||||
@@ -413,16 +412,11 @@ static int gk20a_channel_wait_semaphore(struct channel_gk20a *ch,
|
||||
|
||||
semaphore = data + (offset & ~PAGE_MASK);
|
||||
|
||||
remain = NVGPU_COND_WAIT_INTERRUPTIBLE(
|
||||
ret = NVGPU_COND_WAIT_INTERRUPTIBLE(
|
||||
&ch->semaphore_wq,
|
||||
*semaphore == payload || ch->has_timedout,
|
||||
timeout);
|
||||
|
||||
if (remain == 0 && *semaphore != payload)
|
||||
ret = -ETIMEDOUT;
|
||||
else if (remain < 0)
|
||||
ret = remain;
|
||||
|
||||
dma_buf_kunmap(dmabuf, offset >> PAGE_SHIFT, data);
|
||||
cleanup_put:
|
||||
dma_buf_put(dmabuf);
|
||||
|
||||
@@ -409,7 +409,7 @@ static void gk20a_wait_until_counter_is_N(
|
||||
if (NVGPU_COND_WAIT(
|
||||
c,
|
||||
atomic_read(counter) == wait_value,
|
||||
msecs_to_jiffies(5000)) > 0)
|
||||
5000) == 0)
|
||||
break;
|
||||
|
||||
nvgpu_warn(ch->g,
|
||||
@@ -1798,14 +1798,14 @@ static int gk20a_channel_poll_worker(void *arg)
|
||||
|
||||
start_wait = jiffies;
|
||||
while (!nvgpu_thread_should_stop(&worker->poll_task)) {
|
||||
bool got_events;
|
||||
int ret;
|
||||
|
||||
got_events = NVGPU_COND_WAIT(
|
||||
ret = NVGPU_COND_WAIT(
|
||||
&worker->wq,
|
||||
__gk20a_channel_worker_pending(g, get),
|
||||
timeout) > 0;
|
||||
jiffies_to_msecs(timeout)) > 0;
|
||||
|
||||
if (got_events)
|
||||
if (ret == 0)
|
||||
gk20a_channel_worker_process(g, &get);
|
||||
|
||||
if (jiffies - start_wait >= timeout) {
|
||||
|
||||
@@ -203,20 +203,13 @@ void gk20a_init_fence(struct gk20a_fence *f,
|
||||
|
||||
static int nvgpu_semaphore_fence_wait(struct gk20a_fence *f, long timeout)
|
||||
{
|
||||
long remain;
|
||||
|
||||
if (!nvgpu_semaphore_is_acquired(f->semaphore))
|
||||
return 0;
|
||||
|
||||
remain = NVGPU_COND_WAIT_INTERRUPTIBLE(
|
||||
return NVGPU_COND_WAIT_INTERRUPTIBLE(
|
||||
f->semaphore_wq,
|
||||
!nvgpu_semaphore_is_acquired(f->semaphore),
|
||||
timeout);
|
||||
if (remain == 0 && nvgpu_semaphore_is_acquired(f->semaphore))
|
||||
return -ETIMEDOUT;
|
||||
else if (remain < 0)
|
||||
return remain;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool nvgpu_semaphore_fence_is_expired(struct gk20a_fence *f)
|
||||
|
||||
@@ -24,10 +24,57 @@ struct nvgpu_cond {
|
||||
wait_queue_head_t wq;
|
||||
};
|
||||
|
||||
/**
|
||||
* NVGPU_COND_WAIT - Wait for a condition to be true
|
||||
*
|
||||
* @c - The condition variable to sleep on
|
||||
* @condition - The condition that needs to be true
|
||||
* @timeout_ms - Timeout in milliseconds, or 0 for infinite wait
|
||||
*
|
||||
* Wait for a condition to become true. Returns -ETIMEOUT if
|
||||
* the wait timed out with condition false.
|
||||
*/
|
||||
#define NVGPU_COND_WAIT(c, condition, timeout_ms) \
|
||||
wait_event_timeout((c)->wq, condition, timeout_ms)
|
||||
({\
|
||||
int ret = 0; \
|
||||
long _timeout_ms = timeout_ms;\
|
||||
if (_timeout_ms > 0) { \
|
||||
long _ret = wait_event_timeout((c)->wq, condition, \
|
||||
msecs_to_jiffies(_timeout_ms)); \
|
||||
if (_ret == 0) \
|
||||
ret = -ETIMEDOUT; \
|
||||
} else { \
|
||||
wait_event((c)->wq, condition); \
|
||||
} \
|
||||
ret;\
|
||||
})
|
||||
|
||||
/**
|
||||
* NVGPU_COND_WAIT_INTERRUPTIBLE - Wait for a condition to be true
|
||||
*
|
||||
* @c - The condition variable to sleep on
|
||||
* @condition - The condition that needs to be true
|
||||
* @timeout_ms - Timeout in milliseconds, or 0 for infinite wait
|
||||
*
|
||||
* Wait for a condition to become true. Returns -ETIMEOUT if
|
||||
* the wait timed out with condition false or -ERESTARTSYS on
|
||||
* signal.
|
||||
*/
|
||||
#define NVGPU_COND_WAIT_INTERRUPTIBLE(c, condition, timeout_ms) \
|
||||
wait_event_interruptible_timeout((c)->wq, condition, timeout_ms)
|
||||
({ \
|
||||
int ret = 0; \
|
||||
long _timeout_ms = timeout_ms;\
|
||||
if (_timeout_ms > 0) { \
|
||||
long _ret = wait_event_interruptible_timeout((c)->wq, condition, \
|
||||
msecs_to_jiffies(_timeout_ms)); \
|
||||
if (_ret == 0) \
|
||||
ret = -ETIMEDOUT; \
|
||||
else if (_ret == -ERESTARTSYS) \
|
||||
ret = -ERESTARTSYS; \
|
||||
} else { \
|
||||
wait_event_interruptible((c)->wq, condition); \
|
||||
} \
|
||||
ret; \
|
||||
})
|
||||
|
||||
#endif /* __NVGPU_LOCK_LINUX_H__ */
|
||||
|
||||
Reference in New Issue
Block a user