From bd35fe5a7930bf83ed56422ea4e4b6471ee6f739 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Wed, 9 Mar 2011 14:22:19 +0100 Subject: [PATCH] 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 Signed-off-by: Francisco Jerez --- drivers/gpu/drm/nouveau/nouveau_fence.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index a244702..4b9f449 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -27,6 +27,9 @@ #include "drmP.h" #include "drm.h" +#include +#include + #include "nouveau_drv.h" #include "nouveau_ramht.h" #include "nouveau_dma.h" @@ -229,7 +232,8 @@ int __nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) { unsigned long timeout = jiffies + (3 * DRM_HZ); - unsigned long sleep_time = jiffies + 1; + unsigned long sleep_time = NSEC_PER_MSEC / 1000; + ktime_t t; int ret = 0; while (1) { @@ -243,8 +247,13 @@ __nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) __set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); - if (lazy && time_after_eq(jiffies, sleep_time)) - schedule_timeout(1); + if (lazy) { + t = ktime_set(0, sleep_time); + schedule_hrtimeout(&t, HRTIMER_MODE_REL); + sleep_time *= 2; + if (sleep_time > NSEC_PER_MSEC) + sleep_time = NSEC_PER_MSEC; + } if (intr && signal_pending(current)) { ret = -ERESTARTSYS; -- 2.7.4