summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorMarcin Slusarz <marcin.slusarz@gmail.com>2011-03-09 14:22:19 +0100
committerBen Skeggs <bskeggs@redhat.com>2011-03-14 16:35:16 +1000
commitbd35fe5a7930bf83ed56422ea4e4b6471ee6f739 (patch)
tree1ff63be39ccd22175d4fa61683865664181fef38 /drivers/gpu/drm
parent459ca7e5283914845d7139905ff58824d2b0cc85 (diff)
downloadlwn-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.c15
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;