OSDN Git Service

nouveau: fix some issues where buffer objects never get freed
authorBen Skeggs <skeggsb@gmail.com>
Thu, 5 Feb 2009 13:03:29 +0000 (23:03 +1000)
committerBen Skeggs <skeggsb@gmail.com>
Thu, 5 Feb 2009 13:17:05 +0000 (23:17 +1000)
libdrm/nouveau/nouveau_bo.c
libdrm/nouveau/nouveau_channel.c

index 0ab426d..6b9877f 100644 (file)
@@ -435,10 +435,18 @@ nouveau_bo_del(struct nouveau_bo **bo)
        }
 
        nouveau_bo_ufree(nvbo);
-       if (!nouveau_device(nvbo->base.device)->mm_enabled && nvbo->fence)
-               nouveau_fence_signal_cb(nvbo->fence, nouveau_bo_del_cb, nvbo);
-       else
+
+       if (!nouveau_device(nvbo->base.device)->mm_enabled && nvbo->fence) {
+               nouveau_fence_flush(nvbo->fence->channel);
+               if (nouveau_fence(nvbo->fence)->signalled) {
+                       nouveau_bo_del_cb(nvbo);
+               } else {
+                       nouveau_fence_signal_cb(nvbo->fence,
+                                               nouveau_bo_del_cb, nvbo);
+               }
+       } else {
                nouveau_bo_del_cb(nvbo);
+       }
 }
 
 int
@@ -786,7 +794,6 @@ nouveau_bo_busy(struct nouveau_bo *bo, uint32_t access)
        return 1;
 }
 
-#include <stdio.h>
 struct drm_nouveau_gem_pushbuf_bo *
 nouveau_bo_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo)
 {
index e0fb415..5de27dc 100644 (file)
@@ -150,6 +150,17 @@ nouveau_channel_free(struct nouveau_channel **chan)
        
        FIRE_RING(&nvchan->base);
 
+       if (!nvdev->mm_enabled) {
+               struct nouveau_fence *fence = NULL;
+
+               /* Make sure all buffer objects on delayed delete queue
+                * actually get freed.
+                */
+               nouveau_fence_new(&nvchan->base, &fence);
+               nouveau_fence_emit(fence);
+               nouveau_fence_wait(&fence);
+       }
+
        if (nvchan->notifier_block)
                drmUnmap(nvchan->notifier_block, nvchan->drm.notifier_size);