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:
Terje Bergstrom
2017-05-16 13:59:31 -07:00
committed by mobile promotions
parent 9db45cf037
commit ee25b33ca4
4 changed files with 56 additions and 22 deletions

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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)

View File

@@ -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__ */