summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2017-05-16 16:59:31 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-05-24 15:14:03 -0400
commitee25b33ca4aafbbab6e9b7cd963f9011a59037cd (patch)
tree80f10d0027de77ea23a5c6b71c46b7da61c61102
parent9db45cf0376c6de8d71cc8087d0ec76dff72c00b (diff)
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>
-rw-r--r--drivers/gpu/nvgpu/common/linux/ioctl_channel.c8
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c10
-rw-r--r--drivers/gpu/nvgpu/gk20a/fence_gk20a.c9
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/linux/cond.h51
4 files changed, 56 insertions, 22 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_channel.c b/drivers/gpu/nvgpu/common/linux/ioctl_channel.c
index 4d4d1690..c7adb76c 100644
--- a/drivers/gpu/nvgpu/common/linux/ioctl_channel.c
+++ b/drivers/gpu/nvgpu/common/linux/ioctl_channel.c
@@ -392,7 +392,6 @@ static int gk20a_channel_wait_semaphore(struct channel_gk20a *ch,
392 void *data; 392 void *data;
393 u32 *semaphore; 393 u32 *semaphore;
394 int ret = 0; 394 int ret = 0;
395 long remain;
396 395
397 /* do not wait if channel has timed out */ 396 /* do not wait if channel has timed out */
398 if (ch->has_timedout) 397 if (ch->has_timedout)
@@ -413,16 +412,11 @@ static int gk20a_channel_wait_semaphore(struct channel_gk20a *ch,
413 412
414 semaphore = data + (offset & ~PAGE_MASK); 413 semaphore = data + (offset & ~PAGE_MASK);
415 414
416 remain = NVGPU_COND_WAIT_INTERRUPTIBLE( 415 ret = NVGPU_COND_WAIT_INTERRUPTIBLE(
417 &ch->semaphore_wq, 416 &ch->semaphore_wq,
418 *semaphore == payload || ch->has_timedout, 417 *semaphore == payload || ch->has_timedout,
419 timeout); 418 timeout);
420 419
421 if (remain == 0 && *semaphore != payload)
422 ret = -ETIMEDOUT;
423 else if (remain < 0)
424 ret = remain;
425
426 dma_buf_kunmap(dmabuf, offset >> PAGE_SHIFT, data); 420 dma_buf_kunmap(dmabuf, offset >> PAGE_SHIFT, data);
427cleanup_put: 421cleanup_put:
428 dma_buf_put(dmabuf); 422 dma_buf_put(dmabuf);
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index 6cb77d67..4ee1ab43 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -409,7 +409,7 @@ static void gk20a_wait_until_counter_is_N(
409 if (NVGPU_COND_WAIT( 409 if (NVGPU_COND_WAIT(
410 c, 410 c,
411 atomic_read(counter) == wait_value, 411 atomic_read(counter) == wait_value,
412 msecs_to_jiffies(5000)) > 0) 412 5000) == 0)
413 break; 413 break;
414 414
415 nvgpu_warn(ch->g, 415 nvgpu_warn(ch->g,
@@ -1798,14 +1798,14 @@ static int gk20a_channel_poll_worker(void *arg)
1798 1798
1799 start_wait = jiffies; 1799 start_wait = jiffies;
1800 while (!nvgpu_thread_should_stop(&worker->poll_task)) { 1800 while (!nvgpu_thread_should_stop(&worker->poll_task)) {
1801 bool got_events; 1801 int ret;
1802 1802
1803 got_events = NVGPU_COND_WAIT( 1803 ret = NVGPU_COND_WAIT(
1804 &worker->wq, 1804 &worker->wq,
1805 __gk20a_channel_worker_pending(g, get), 1805 __gk20a_channel_worker_pending(g, get),
1806 timeout) > 0; 1806 jiffies_to_msecs(timeout)) > 0;
1807 1807
1808 if (got_events) 1808 if (ret == 0)
1809 gk20a_channel_worker_process(g, &get); 1809 gk20a_channel_worker_process(g, &get);
1810 1810
1811 if (jiffies - start_wait >= timeout) { 1811 if (jiffies - start_wait >= timeout) {
diff --git a/drivers/gpu/nvgpu/gk20a/fence_gk20a.c b/drivers/gpu/nvgpu/gk20a/fence_gk20a.c
index 3964c37d..7c5d33c7 100644
--- a/drivers/gpu/nvgpu/gk20a/fence_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fence_gk20a.c
@@ -203,20 +203,13 @@ void gk20a_init_fence(struct gk20a_fence *f,
203 203
204static int nvgpu_semaphore_fence_wait(struct gk20a_fence *f, long timeout) 204static int nvgpu_semaphore_fence_wait(struct gk20a_fence *f, long timeout)
205{ 205{
206 long remain;
207
208 if (!nvgpu_semaphore_is_acquired(f->semaphore)) 206 if (!nvgpu_semaphore_is_acquired(f->semaphore))
209 return 0; 207 return 0;
210 208
211 remain = NVGPU_COND_WAIT_INTERRUPTIBLE( 209 return NVGPU_COND_WAIT_INTERRUPTIBLE(
212 f->semaphore_wq, 210 f->semaphore_wq,
213 !nvgpu_semaphore_is_acquired(f->semaphore), 211 !nvgpu_semaphore_is_acquired(f->semaphore),
214 timeout); 212 timeout);
215 if (remain == 0 && nvgpu_semaphore_is_acquired(f->semaphore))
216 return -ETIMEDOUT;
217 else if (remain < 0)
218 return remain;
219 return 0;
220} 213}
221 214
222static bool nvgpu_semaphore_fence_is_expired(struct gk20a_fence *f) 215static bool nvgpu_semaphore_fence_is_expired(struct gk20a_fence *f)
diff --git a/drivers/gpu/nvgpu/include/nvgpu/linux/cond.h b/drivers/gpu/nvgpu/include/nvgpu/linux/cond.h
index 3eb52861..01ca5291 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/linux/cond.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/linux/cond.h
@@ -24,10 +24,57 @@ struct nvgpu_cond {
24 wait_queue_head_t wq; 24 wait_queue_head_t wq;
25}; 25};
26 26
27/**
28 * NVGPU_COND_WAIT - Wait for a condition to be true
29 *
30 * @c - The condition variable to sleep on
31 * @condition - The condition that needs to be true
32 * @timeout_ms - Timeout in milliseconds, or 0 for infinite wait
33 *
34 * Wait for a condition to become true. Returns -ETIMEOUT if
35 * the wait timed out with condition false.
36 */
27#define NVGPU_COND_WAIT(c, condition, timeout_ms) \ 37#define NVGPU_COND_WAIT(c, condition, timeout_ms) \
28 wait_event_timeout((c)->wq, condition, timeout_ms) 38({\
39 int ret = 0; \
40 long _timeout_ms = timeout_ms;\
41 if (_timeout_ms > 0) { \
42 long _ret = wait_event_timeout((c)->wq, condition, \
43 msecs_to_jiffies(_timeout_ms)); \
44 if (_ret == 0) \
45 ret = -ETIMEDOUT; \
46 } else { \
47 wait_event((c)->wq, condition); \
48 } \
49 ret;\
50})
29 51
52/**
53 * NVGPU_COND_WAIT_INTERRUPTIBLE - Wait for a condition to be true
54 *
55 * @c - The condition variable to sleep on
56 * @condition - The condition that needs to be true
57 * @timeout_ms - Timeout in milliseconds, or 0 for infinite wait
58 *
59 * Wait for a condition to become true. Returns -ETIMEOUT if
60 * the wait timed out with condition false or -ERESTARTSYS on
61 * signal.
62 */
30#define NVGPU_COND_WAIT_INTERRUPTIBLE(c, condition, timeout_ms) \ 63#define NVGPU_COND_WAIT_INTERRUPTIBLE(c, condition, timeout_ms) \
31 wait_event_interruptible_timeout((c)->wq, condition, timeout_ms) 64({ \
65 int ret = 0; \
66 long _timeout_ms = timeout_ms;\
67 if (_timeout_ms > 0) { \
68 long _ret = wait_event_interruptible_timeout((c)->wq, condition, \
69 msecs_to_jiffies(_timeout_ms)); \
70 if (_ret == 0) \
71 ret = -ETIMEDOUT; \
72 else if (_ret == -ERESTARTSYS) \
73 ret = -ERESTARTSYS; \
74 } else { \
75 wait_event_interruptible((c)->wq, condition); \
76 } \
77 ret; \
78})
32 79
33#endif /* __NVGPU_LOCK_LINUX_H__ */ 80#endif /* __NVGPU_LOCK_LINUX_H__ */