@@ -1482,7 +1482,9 @@ drm_gpuvm_bo_create(struct drm_gpuvm *gpuvm,
vm_bo->vm = drm_gpuvm_get(gpuvm);
vm_bo->obj = obj;
- drm_gem_object_get(obj);
+
+ if (!(gpuvm->flags & DRM_GPUVM_VA_WEAK_REF))
+ drm_gem_object_get(obj);
kref_init(&vm_bo->kref);
INIT_LIST_HEAD(&vm_bo->list.gpuva);
@@ -1504,6 +1506,7 @@ drm_gpuvm_bo_destroy(struct kref *kref)
const struct drm_gpuvm_ops *ops = gpuvm->ops;
struct drm_gem_object *obj = vm_bo->obj;
bool lock = !drm_gpuvm_resv_protected(gpuvm);
+ bool unref = !(gpuvm->flags & DRM_GPUVM_VA_WEAK_REF);
drm_gpuvm_bo_list_del(vm_bo, extobj, lock);
drm_gpuvm_bo_list_del(vm_bo, evict, lock);
@@ -1519,7 +1522,8 @@ drm_gpuvm_bo_destroy(struct kref *kref)
kfree(vm_bo);
drm_gpuvm_put(gpuvm);
- drm_gem_object_put(obj);
+ if (unref)
+ drm_gem_object_put(obj);
}
/**
@@ -205,10 +205,18 @@ enum drm_gpuvm_flags {
*/
DRM_GPUVM_RESV_PROTECTED = BIT(0),
+ /**
+ * @DRM_GPUVM_VA_WEAK_REF:
+ *
+ * Flag indicating that the &drm_gpuva (or more correctly, the
+ * &drm_gpuvm_bo) only holds a weak reference to the &drm_gem_object.
+ */
+ DRM_GPUVM_VA_WEAK_REF = BIT(1),
+
/**
* @DRM_GPUVM_USERBITS: user defined bits
*/
- DRM_GPUVM_USERBITS = BIT(1),
+ DRM_GPUVM_USERBITS = BIT(2),
};
/**
@@ -651,7 +659,7 @@ struct drm_gpuvm_bo {
/**
* @obj: The &drm_gem_object being mapped in @vm. This is a reference
- * counted pointer.
+ * counted pointer, unless the &DRM_GPUVM_VA_WEAK_REF flag is set.
*/
struct drm_gem_object *obj;