r600g: add bo busy backoff.

When we go to do a lot of bos in one draw like constant bufs we need
to avoid bouncing off the busy ioctl, this mitigates by backing off
on busy bos for a short amount of times.
diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h
index 76a7ba9..285a192 100644
--- a/src/gallium/winsys/r600/drm/r600_priv.h
+++ b/src/gallium/winsys/r600/drm/r600_priv.h
@@ -66,6 +66,8 @@
 	void				*data;
 	struct list_head		fencedlist;
 	boolean				shared;
+	int64_t				last_busy;
+	boolean				set_busy;
 };
 
 struct r600_bo {
diff --git a/src/gallium/winsys/r600/drm/radeon_bo.c b/src/gallium/winsys/r600/drm/radeon_bo.c
index 97138f9..42a23f0 100644
--- a/src/gallium/winsys/r600/drm/radeon_bo.c
+++ b/src/gallium/winsys/r600/drm/radeon_bo.c
@@ -32,6 +32,7 @@
 #include "r600_priv.h"
 #include "xf86drm.h"
 #include "radeon_drm.h"
+#include "util/u_time.h"
 
 static int radeon_bo_fixed_map(struct radeon *radeon, struct radeon_bo *bo)
 {
@@ -170,14 +171,23 @@
 	return ret;
 }
 
+#define BO_BUSY_BACKOFF 10000
+
 int radeon_bo_busy(struct radeon *radeon, struct radeon_bo *bo, uint32_t *domain)
 {
 	struct drm_radeon_gem_busy args;
 	int ret;
+	int64_t now;
 
+	now = os_time_get();
 	if (LIST_IS_EMPTY(&bo->fencedlist) && !bo->shared)
 		return 0;
 
+	if (bo->set_busy && (now - bo->last_busy < BO_BUSY_BACKOFF))
+		return -EBUSY;
+
+	bo->set_busy = FALSE;
+
 	memset(&args, 0, sizeof(args));
 	args.handle = bo->handle;
 	args.domain = 0;
@@ -190,6 +200,9 @@
 		LIST_FOR_EACH_ENTRY_SAFE(entry, tent, &bo->fencedlist, fencedlist) {
 			LIST_DELINIT(&entry->fencedlist);
 		}
+	} else {
+		bo->set_busy = TRUE;
+		bo->last_busy = now;
 	}
 	*domain = args.domain;
 	return ret;