Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bd35fe5a authored by Marcin Slusarz's avatar Marcin Slusarz Committed by Ben Skeggs
Browse files

drm/nouveau: fix __nouveau_fence_wait performance



Commit 21e86c1c ("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: default avatarMarcin Slusarz <marcin.slusarz@gmail.com>
Signed-off-by: default avatarFrancisco Jerez <currojerez@riseup.net>
parent 459ca7e5
Loading
Loading
Loading
Loading
+12 −3
Original line number Original line Diff line number Diff line
@@ -27,6 +27,9 @@
#include "drmP.h"
#include "drmP.h"
#include "drm.h"
#include "drm.h"


#include <linux/ktime.h>
#include <linux/hrtimer.h>

#include "nouveau_drv.h"
#include "nouveau_drv.h"
#include "nouveau_ramht.h"
#include "nouveau_ramht.h"
#include "nouveau_dma.h"
#include "nouveau_dma.h"
@@ -229,7 +232,8 @@ int
__nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
__nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
{
{
	unsigned long timeout = jiffies + (3 * DRM_HZ);
	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;
	int ret = 0;


	while (1) {
	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
		__set_current_state(intr ? TASK_INTERRUPTIBLE
			: TASK_UNINTERRUPTIBLE);
			: TASK_UNINTERRUPTIBLE);
		if (lazy && time_after_eq(jiffies, sleep_time))
		if (lazy) {
			schedule_timeout(1);
			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)) {
		if (intr && signal_pending(current)) {
			ret = -ERESTARTSYS;
			ret = -ERESTARTSYS;