summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-10-30 19:21:02 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2014-10-31 08:45:09 +0000
commit9115406b651eb11779f37c4b048d55188b9d6e02 (patch)
tree3b86b2a0dbb7db2ddae6b9c1ee5596b76acb4b02
parent9d48d2817927bc2532953f09b6be2002c2086e1f (diff)
sna: Retire all requests when a bo is found to be not busy
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/kgem.c16
-rw-r--r--src/sna/kgem.h9
2 files changed, 23 insertions, 2 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 86810180..f1e426d7 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2551,6 +2551,7 @@ static bool __kgem_retire_rq(struct kgem *kgem, struct kgem_request *rq)
}
bo->domain = DOMAIN_NONE;
+ bo->gtt_dirty = false;
bo->rq = NULL;
if (bo->refcnt)
continue;
@@ -2703,6 +2704,21 @@ bool __kgem_ring_is_idle(struct kgem *kgem, int ring)
return true;
}
+void __kgem_retire_requests_upto(struct kgem *kgem, struct kgem_request *rq)
+{
+ struct list *requests = &kgem->requests[RQ_RING(rq) == I915_EXEC_BLT];
+ struct kgem_request *tmp;
+
+ rq = RQ(rq);
+ assert(rq != &kgem->static_request);
+
+ do {
+ tmp = list_first_entry(requests, struct kgem_request, list);
+ assert(tmp->ring == rq->ring);
+ __kgem_retire_rq(kgem, tmp);
+ } while (tmp != rq);
+}
+
#if 0
static void kgem_commit__check_reloc(struct kgem *kgem)
{
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index bea518f8..c77866f4 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -618,6 +618,7 @@ static inline bool kgem_bo_is_busy(struct kgem_bo *bo)
return bo->rq;
}
+void __kgem_retire_requests_upto(struct kgem *kgem, struct kgem_request *rq);
static inline bool __kgem_bo_is_busy(struct kgem *kgem, struct kgem_bo *bo)
{
DBG(("%s: handle=%d, domain: %d exec? %d, rq? %d\n", __FUNCTION__,
@@ -627,8 +628,12 @@ static inline bool __kgem_bo_is_busy(struct kgem *kgem, struct kgem_bo *bo)
if (bo->exec)
return true;
- if (bo->rq && !__kgem_busy(kgem, bo->handle))
- __kgem_bo_clear_busy(bo);
+ if (bo->rq && !__kgem_busy(kgem, bo->handle)) {
+ __kgem_retire_requests_upto(kgem, bo->rq);
+ assert(list_is_empty(&bo->request));
+ assert(bo->rq == NULL);
+ assert(bo->domain == DOMAIN_NONE);
+ }
return kgem_bo_is_busy(bo);
}