sna: Tweak deletion of used buffers
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 31 Oct 2013 10:32:46 +0000 (10:32 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 31 Oct 2013 13:35:37 +0000 (13:35 +0000)
Make sure we never unwind a used buffer.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
src/sna/gen6_common.c
src/sna/kgem.c
src/sna/kgem.h
src/sna/sna_accel.c

index 38af859..8789109 100644 (file)
@@ -69,4 +69,3 @@ void gen6_render_retire(struct kgem *kgem)
                sna->render.vertex_index = 0;
        }
 }
-
index 7c0ad11..4c66917 100644 (file)
@@ -2357,6 +2357,7 @@ static void kgem_commit(struct kgem *kgem)
 
                if (!bo->refcnt && !bo->reusable) {
                        assert(!bo->snoop);
+                       assert(!bo->proxy);
                        kgem_bo_free(kgem, bo);
                        continue;
                }
@@ -2451,8 +2452,8 @@ static void kgem_finish_buffers(struct kgem *kgem)
                        if (!DBG_NO_UPLOAD_ACTIVE &&
                            used + PAGE_SIZE <= bytes(&bo->base) &&
                            (kgem->has_llc || bo->mmapped == MMAPPED_GTT || bo->base.snoop)) {
-                               DBG(("%s: retaining upload buffer (%d/%d)\n",
-                                    __FUNCTION__, bo->used, bytes(&bo->base)));
+                               DBG(("%s: retaining upload buffer (%d/%d): used=%d, refcnt=%d\n",
+                                    __FUNCTION__, bo->used, bytes(&bo->base), used, bo->base.refcnt));
                                bo->used = used;
                                if (bo->base.refcnt == 1) {
                                        list_move(&bo->base.list,
@@ -4634,17 +4635,22 @@ void _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
             __FUNCTION__, bo->handle, bo->proxy != NULL));
 
        if (bo->proxy) {
+               assert(!bo->reusable);
+               kgem_bo_binding_free(kgem, bo);
+
+               assert(list_is_empty(&bo->list));
                _list_del(&bo->vma);
                _list_del(&bo->request);
-               if (bo->io && bo->exec == NULL && bo->domain == DOMAIN_CPU)
+
+               if (bo->io && bo->domain == DOMAIN_CPU)
                        _kgem_bo_delete_buffer(kgem, bo);
+
                kgem_bo_unref(kgem, bo->proxy);
-               kgem_bo_binding_free(kgem, bo);
-               free(bo);
-               return;
-       }
 
-       __kgem_bo_destroy(kgem, bo);
+               *(struct kgem_bo **)bo = __kgem_freed_bo;
+               __kgem_freed_bo = bo;
+       } else
+               __kgem_bo_destroy(kgem, bo);
 }
 
 static void __kgem_flush(struct kgem *kgem, struct kgem_bo *bo)
@@ -4993,6 +4999,7 @@ uint32_t kgem_add_reloc(struct kgem *kgem,
                                bo->rq = MAKE_REQUEST(kgem->next_request,
                                                      kgem->ring);
                                bo->exec = &_kgem_dummy_exec;
+                               bo->domain = DOMAIN_GPU;
                        }
 
                        if (read_write_domain & 0x7fff && !bo->gpu_dirty)
@@ -5505,7 +5512,7 @@ struct kgem_bo *kgem_create_proxy(struct kgem *kgem,
        bo->proxy = kgem_bo_reference(target);
        bo->delta = offset;
 
-       if (target->exec) {
+       if (target->exec && !bo->io) {
                list_move_tail(&bo->request, &kgem->next_request->buffers);
                bo->exec = &_kgem_dummy_exec;
        }
index 77edfc8..e2bb4f9 100644 (file)
@@ -370,8 +370,10 @@ static inline void kgem_set_mode(struct kgem *kgem,
        kgem_submit(kgem);
 #endif
 
-       if (kgem->nreloc && bo->exec == NULL && kgem_ring_is_idle(kgem, kgem->ring))
+       if (kgem->nreloc && bo->exec == NULL && kgem_ring_is_idle(kgem, kgem->ring)) {
+               DBG(("%s: flushing before new bo\n", __FUNCTION__));
                _kgem_submit(kgem);
+       }
 
        if (kgem->mode == mode)
                return;
index 7d45065..93231db 100644 (file)
@@ -4264,6 +4264,7 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
                DBG(("%s: discarding cached upload proxy\n", __FUNCTION__));
                sna_pixmap_free_gpu(sna, priv);
        }
+       assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL);
 
        if (priv->cow || priv->move_to_gpu) {
                DBG(("%s: no, has COW or pending move-to-gpu\n", __FUNCTION__));