summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-12-18 19:26:38 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2011-12-18 19:46:08 +0000
commitfed8d145c148bfa8a8a29f4088902377f9a10440 (patch)
treecbf9a70eb5770d31bcb5230b0eb091be55239b32
parent2a98dabcabf25067abcda60f233656e19e83493a (diff)
sna: Use a safe iterator whilst searching for inactive linear bo
As we may free a purged bo whilst iterating, we need to keep the next bo as a local member. Include the debugging that led to this find. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/kgem.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index f95b5b2e..fba0693b 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -46,6 +46,8 @@
static inline void _list_del(struct list *list)
{
+ assert(list->prev->next == list);
+ assert(list->next->prev == list);
__list_del(list->prev, list->next);
}
@@ -821,6 +823,10 @@ bool kgem_retire(struct kgem *kgem)
DBG(("%s\n", __FUNCTION__));
list_for_each_entry_safe(bo, next, &kgem->flushing, request) {
+ assert(bo->refcnt == 0);
+ assert(bo->rq == &_kgem_static_request);
+ assert(bo->exec == NULL);
+
if (kgem_busy(kgem, bo->handle))
break;
@@ -829,7 +835,6 @@ bool kgem_retire(struct kgem *kgem)
if (kgem_bo_set_purgeable(kgem, bo)) {
bo->needs_flush = false;
bo->domain = DOMAIN_NONE;
- assert(bo->rq == &_kgem_static_request);
bo->rq = NULL;
list_move(&bo->list, inactive(kgem, bo->size));
list_del(&bo->request);
@@ -1449,11 +1454,15 @@ void kgem_cleanup_cache(struct kgem *kgem)
static struct kgem_bo *
search_linear_cache(struct kgem *kgem, unsigned int size, bool use_active)
{
- struct kgem_bo *bo;
+ struct kgem_bo *bo, *next;
struct list *cache;
cache = use_active ? active(kgem, size): inactive(kgem, size);
- list_for_each_entry(bo, cache, list) {
+ list_for_each_entry_safe(bo, next, cache, list) {
+ assert(bo->refcnt == 0);
+ assert(bo->reusable);
+ assert(!!bo->rq == !!use_active);
+
if (size > bo->size)
continue;
@@ -1485,8 +1494,6 @@ search_linear_cache(struct kgem *kgem, unsigned int size, bool use_active)
DBG((" %s: found handle=%d (size=%d) in linear %s cache\n",
__FUNCTION__, bo->handle, bo->size,
use_active ? "active" : "inactive"));
- assert(bo->refcnt == 0);
- assert(bo->reusable);
assert(use_active || bo->domain != DOMAIN_GPU);
//assert(use_active || !kgem_busy(kgem, bo->handle));
return bo;