NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
        gpuobj->dev = dev;
        gpuobj->flags = flags;
-       gpuobj->refcount = 1;
+       kref_init(&gpuobj->refcount);
        gpuobj->size = size;
 
        list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
 nouveau_gpuobj_late_takedown(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_gpuobj *gpuobj = NULL;
-       struct list_head *entry, *tmp;
-
-       NV_DEBUG(dev, "\n");
-
-       list_for_each_safe(entry, tmp, &dev_priv->gpuobj_list) {
-               gpuobj = list_entry(entry, struct nouveau_gpuobj, list);
 
-               NV_ERROR(dev, "gpuobj %p still exists at takedown, refs=%d\n",
-                        gpuobj, gpuobj->refcount);
-
-               gpuobj->refcount = 1;
-               nouveau_gpuobj_ref(NULL, &gpuobj);
-       }
+       BUG_ON(!list_empty(&dev_priv->gpuobj_list));
 }
 
-static int
-nouveau_gpuobj_del(struct nouveau_gpuobj *gpuobj)
+static void
+nouveau_gpuobj_del(struct kref *ref)
 {
+       struct nouveau_gpuobj *gpuobj =
+               container_of(ref, struct nouveau_gpuobj, refcount);
        struct drm_device *dev = gpuobj->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_engine *engine = &dev_priv->engine;
        list_del(&gpuobj->list);
 
        kfree(gpuobj);
-       return 0;
 }
 
 void
 nouveau_gpuobj_ref(struct nouveau_gpuobj *ref, struct nouveau_gpuobj **ptr)
 {
        if (ref)
-               ref->refcount++;
+               kref_get(&ref->refcount);
 
-       if (*ptr && --(*ptr)->refcount == 0)
-               nouveau_gpuobj_del(*ptr);
+       if (*ptr)
+               kref_put(&(*ptr)->refcount, nouveau_gpuobj_del);
 
        *ptr = ref;
 }
        NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
        gpuobj->dev = dev;
        gpuobj->flags = flags;
-       gpuobj->refcount = 1;
+       kref_init(&gpuobj->refcount);
        gpuobj->size  = size;
        gpuobj->pinst = pinst;
        gpuobj->cinst = 0xdeadbeef;
        gpuobj->dev = chan->dev;
        gpuobj->engine = NVOBJ_ENGINE_SW;
        gpuobj->class = class;
-       gpuobj->refcount = 1;
+       kref_init(&gpuobj->refcount);
        gpuobj->cinst = 0x40;
 
        list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);