diff options
author | Marcin Slusarz <marcin.slusarz@gmail.com> | 2011-03-09 14:22:19 +0100 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-03-14 16:35:16 +1000 |
commit | bd35fe5a7930bf83ed56422ea4e4b6471ee6f739 (patch) | |
tree | 1ff63be39ccd22175d4fa61683865664181fef38 /drivers/gpu/drm | |
parent | 459ca7e5283914845d7139905ff58824d2b0cc85 (diff) | |
download | lwn-bd35fe5a7930bf83ed56422ea4e4b6471ee6f739.tar.gz lwn-bd35fe5a7930bf83ed56422ea4e4b6471ee6f739.zip |
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')
-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 @@ #include "drmP.h" #include "drm.h" +#include <linux/ktime.h> +#include <linux/hrtimer.h> + #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; |