diff options
author | Marcin Slusarz <marcin.slusarz@gmail.com> | 2011-03-09 08:22:19 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-03-14 02:35:16 -0400 |
commit | bd35fe5a7930bf83ed56422ea4e4b6471ee6f739 (patch) | |
tree | 1ff63be39ccd22175d4fa61683865664181fef38 /drivers/gpu/drm/nouveau/nouveau_fence.c | |
parent | 459ca7e5283914845d7139905ff58824d2b0cc85 (diff) |
drm/nouveau: fix __nouveau_fence_wait performance
Commit 21e86c1c8a844bf978f8fc431a59c9f5a578812d ("drm/nouveau: remove
cpu_writers lock") turned on lazy waits. Unfortunately
__nouveau_fence_wait was not optimized for this case and on HZ=100
kernel wasted up to 10 ms per call.
Depending on application, it led to 10-30% FPS regression.
Fix it.
Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com>
Signed-off-by: Francisco Jerez <currojerez@riseup.net>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_fence.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fence.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index a244702bb227..4b9f4493c9f9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c | |||
@@ -27,6 +27,9 @@ | |||
27 | #include "drmP.h" | 27 | #include "drmP.h" |
28 | #include "drm.h" | 28 | #include "drm.h" |
29 | 29 | ||
30 | #include <linux/ktime.h> | ||
31 | #include <linux/hrtimer.h> | ||
32 | |||
30 | #include "nouveau_drv.h" | 33 | #include "nouveau_drv.h" |
31 | #include "nouveau_ramht.h" | 34 | #include "nouveau_ramht.h" |
32 | #include "nouveau_dma.h" | 35 | #include "nouveau_dma.h" |
@@ -229,7 +232,8 @@ int | |||
229 | __nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) | 232 | __nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) |
230 | { | 233 | { |
231 | unsigned long timeout = jiffies + (3 * DRM_HZ); | 234 | unsigned long timeout = jiffies + (3 * DRM_HZ); |
232 | unsigned long sleep_time = jiffies + 1; | 235 | unsigned long sleep_time = NSEC_PER_MSEC / 1000; |
236 | ktime_t t; | ||
233 | int ret = 0; | 237 | int ret = 0; |
234 | 238 | ||
235 | while (1) { | 239 | while (1) { |
@@ -243,8 +247,13 @@ __nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) | |||
243 | 247 | ||
244 | __set_current_state(intr ? TASK_INTERRUPTIBLE | 248 | __set_current_state(intr ? TASK_INTERRUPTIBLE |
245 | : TASK_UNINTERRUPTIBLE); | 249 | : TASK_UNINTERRUPTIBLE); |
246 | if (lazy && time_after_eq(jiffies, sleep_time)) | 250 | if (lazy) { |
247 | schedule_timeout(1); | 251 | t = ktime_set(0, sleep_time); |
252 | schedule_hrtimeout(&t, HRTIMER_MODE_REL); | ||
253 | sleep_time *= 2; | ||
254 | if (sleep_time > NSEC_PER_MSEC) | ||
255 | sleep_time = NSEC_PER_MSEC; | ||
256 | } | ||
248 | 257 | ||
249 | if (intr && signal_pending(current)) { | 258 | if (intr && signal_pending(current)) { |
250 | ret = -ERESTARTSYS; | 259 | ret = -ERESTARTSYS; |