On Thu, Sep 17, 2026 at 08:19:50PM +0200, Christian König wrote:
>
>
> On 9/10/26 05:02, Matthew Brost wrote:
> > On Thu, Sep 03, 2026 at 03:28:05PM +0200, Christian König wrote:
> >> Remove the embedded dma_resv (_resv) from struct drm_gem_object and use
> >> dynamically allocated reservations instead. This change aligns with the
> >> new reference counted dma_resv infrastructure and reduces the size of
> >> drm_gem_object.
> >>
> >> In drm_gem_private_object_init(), when no external resv is provided,
> >> allocate a new dma_resv using dma_resv_alloc() instead of initializing
> >> the embedded _resv field. This allows proper error handling if the
> >> allocation fails, returning -ENOMEM to the caller.
> >>
> >> The corresponding cleanup in drm_gem_private_object_fini() is simplified
> >> to only put the resv pointer, removing the redundant put on _resv.
> >>
> >> For TTM buffer objects, add an individual_resv field to track the
> >> dynamically allocated reservation object for proper cleanup during
> >> destruction. This ensures we can distinguish between shared and
> >> individual reservations when freeing resources.
> >>
> >> This change builds on the previous work to make
> >> drm_gem_private_object_init()
> >> return an error code, now utilizing that capability to handle allocation
> >> failures properly.
> >>
> >> Signed-off-by: Christian König <[email protected]>
> >> Assisted-by: Claude:Sonnet 4
> >> ---
> >> .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 2 +-
> >> drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 12 ++---
> >> drivers/gpu/drm/drm_gem.c | 9 ++--
> >> drivers/gpu/drm/i915/gem/i915_gem_object.c | 1 -
> >> drivers/gpu/drm/nouveau/nouveau_bo.c | 3 --
> >> .../gpu/drm/ttm/tests/ttm_bo_validate_test.c | 2 +-
> >> drivers/gpu/drm/ttm/ttm_bo.c | 26 ++++++-----
> >> drivers/gpu/drm/ttm/ttm_bo_util.c | 44 +++++++++++++------
> >> drivers/gpu/drm/xe/xe_bo.c | 8 ++--
> >> include/drm/drm_gem.h | 9 ----
> >> include/drm/ttm/ttm_bo.h | 2 +
> >> 11 files changed, 65 insertions(+), 53 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> >> index 20831dbebc31..a168083edab2 100644
> >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> >> @@ -397,7 +397,7 @@ static int amdgpu_amdkfd_remove_eviction_fence(struct
> >> amdgpu_bo *bo,
> >> */
> >> void amdgpu_amdkfd_remove_all_eviction_fences(struct amdgpu_bo *bo)
> >> {
> >> - struct dma_resv *resv = &bo->tbo.base._resv;
> >> + struct dma_resv *resv = bo->tbo.individual_resv;
> >> struct dma_fence *fence, *stub;
> >> struct dma_resv_iter cursor;
> >>
> >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> >> index 6c5182d54f7d..026821f6da7c 100644
> >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
> >> @@ -1319,7 +1319,7 @@ void amdgpu_bo_release_notify(struct
> >> ttm_buffer_object *bo)
> >> * So when this locking here fails something is wrong with the reference
> >> * counting.
> >> */
> >> - if (WARN_ON_ONCE(!dma_resv_trylock(&bo->base._resv)))
> >> + if (WARN_ON_ONCE(!dma_resv_trylock(bo->individual_resv)))
> >> return;
> >>
> >> amdgpu_amdkfd_remove_all_eviction_fences(abo);
> >> @@ -1329,22 +1329,22 @@ void amdgpu_bo_release_notify(struct
> >> ttm_buffer_object *bo)
> >> adev->in_suspend || drm_dev_is_unplugged(adev_to_drm(adev)))
> >> goto out;
> >>
> >> - r = dma_resv_reserve_fences(&bo->base._resv, 1);
> >> + r = dma_resv_reserve_fences(bo->individual_resv, 1);
> >> if (r)
> >> goto out;
> >>
> >> r = amdgpu_ttm_clear_buffer(amdgpu_ttm_next_clear_entity(adev),
> >> - abo, &bo->base._resv, &fence,
> >> - false,
> >> AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE);
> >> + abo, bo->individual_resv, &fence, false,
> >> + AMDGPU_KERNEL_JOB_ID_CLEAR_ON_RELEASE);
> >> if (WARN_ON(r))
> >> goto out;
> >>
> >> amdgpu_vram_mgr_set_cleared(bo->resource);
> >> - dma_resv_add_fence(&bo->base._resv, fence, DMA_RESV_USAGE_KERNEL);
> >> + dma_resv_add_fence(bo->individual_resv, fence, DMA_RESV_USAGE_KERNEL);
> >> dma_fence_put(fence);
> >>
> >> out:
> >> - dma_resv_unlock(&bo->base._resv);
> >> + dma_resv_unlock(bo->individual_resv);
> >> }
> >>
> >> /**
> >> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> >> index d2ce18bbddea..480391df556d 100644
> >> --- a/drivers/gpu/drm/drm_gem.c
> >> +++ b/drivers/gpu/drm/drm_gem.c
> >> @@ -235,9 +235,11 @@ int drm_gem_private_object_init(struct drm_device
> >> *dev,
> >> obj->handle_count = 0;
> >> obj->size = size;
> >> mutex_init(&obj->gpuva.lock);
> >> - dma_resv_init(&obj->_resv);
> >> - if (!obj->resv)
> >> - obj->resv = dma_resv_get(&obj->_resv);
> >> + if (!obj->resv) {
> >> + obj->resv = dma_resv_alloc();
> >> + if (!obj->resv)
> >> + return -ENOMEM;
> >> + }
> >>
> >> drm_gem_gpuva_init(obj);
> >>
> >> @@ -259,7 +261,6 @@ void drm_gem_private_object_fini(struct drm_gem_object
> >> *obj)
> >> WARN_ON(obj->dma_buf);
> >>
> >> dma_resv_put(obj->resv);
> >> - dma_resv_put(&obj->_resv);
> >> mutex_destroy(&obj->gpuva.lock);
> >> }
> >> EXPORT_SYMBOL(drm_gem_private_object_fini);
> >> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c
> >> b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> >> index 3f37b0cbb70f..1c73f15d0315 100644
> >> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
> >> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> >> @@ -90,7 +90,6 @@ struct drm_i915_gem_object *i915_gem_object_alloc(void)
> >> void i915_gem_object_free(struct drm_i915_gem_object *obj)
> >> {
> >> dma_resv_put(obj->base.resv);
> >> - dma_resv_put(&obj->base._resv);
> >> return kmem_cache_free(slab_objects, obj);
> >> }
> >>
> >> diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c
> >> b/drivers/gpu/drm/nouveau/nouveau_bo.c
> >> index 67c9d32f4f27..65e1f0c2f984 100644
> >> --- a/drivers/gpu/drm/nouveau/nouveau_bo.c
> >> +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
> >> @@ -159,8 +159,6 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
> >> drm_gem_object_put(nvbo->r_obj);
> >>
> >> drm_gem_object_release(&bo->base);
> >> - } else {
> >> - dma_resv_put(&bo->base._resv);
> >> }
> >>
> >> kfree(nvbo);
> >> @@ -385,7 +383,6 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int
> >> align,
> >> return PTR_ERR(nvbo);
> >>
> >> nvbo->bo.base.size = size;
> >> - dma_resv_init(&nvbo->bo.base._resv);
> >> drm_vma_node_reset(&nvbo->bo.base.vma_node);
> >>
> >> /* This must be called before ttm_bo_init_reserved(). Subsequent
> >> diff --git a/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c
> >> b/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c
> >> index e0ecadccccf8..4559352e7115 100644
> >> --- a/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c
> >> +++ b/drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c
> >> @@ -640,7 +640,7 @@ static void
> >> ttm_bo_validate_no_placement_not_signaled(struct kunit *test)
> >> KUNIT_EXPECT_EQ(test, ctx.bytes_moved, 0);
> >>
> >> if (bo->type != ttm_bo_type_sg)
> >> - KUNIT_ASSERT_PTR_EQ(test, bo->base.resv, &bo->base._resv);
> >> + KUNIT_ASSERT_PTR_EQ(test, bo->base.resv, &bo->individual_resv);
> >>
> >> /* Make sure we have an idle object at this point */
> >> dma_resv_wait_timeout(bo->base.resv, usage, false,
> >> MAX_SCHEDULE_TIMEOUT);
> >> diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
> >> index 999c24251fb7..ecb5f55a0dd1 100644
> >> --- a/drivers/gpu/drm/ttm/ttm_bo.c
> >> +++ b/drivers/gpu/drm/ttm/ttm_bo.c
> >> @@ -193,13 +193,13 @@ static int ttm_bo_individualize_resv(struct
> >> ttm_buffer_object *bo)
> >> {
> >> int r;
> >>
> >> - if (bo->base.resv == &bo->base._resv)
> >> + if (bo->base.resv == bo->individual_resv)
> >> return 0;
> >>
> >> - BUG_ON(!dma_resv_trylock(&bo->base._resv));
> >> + BUG_ON(!dma_resv_trylock(bo->individual_resv));
> >>
> >> - r = dma_resv_copy_fences(&bo->base._resv, bo->base.resv);
> >> - dma_resv_unlock(&bo->base._resv);
> >> + r = dma_resv_copy_fences(bo->individual_resv, bo->base.resv);
> >> + dma_resv_unlock(bo->individual_resv);
> >> if (r)
> >> return r;
> >>
> >> @@ -209,7 +209,7 @@ static int ttm_bo_individualize_resv(struct
> >> ttm_buffer_object *bo)
> >> * the resv object while holding the lru_lock.
> >> */
> >> spin_lock(&bo->bdev->lru_lock);
> >> - drm_gem_object_set_resv(&bo->base, &bo->base._resv);
> >> + drm_gem_object_set_resv(&bo->base, bo->individual_resv);
> >> spin_unlock(&bo->bdev->lru_lock);
> >> }
> >>
> >> @@ -218,7 +218,7 @@ static int ttm_bo_individualize_resv(struct
> >> ttm_buffer_object *bo)
> >>
> >> static void ttm_bo_flush_all_fences(struct ttm_buffer_object *bo)
> >> {
> >> - struct dma_resv *resv = &bo->base._resv;
> >> + struct dma_resv *resv = bo->individual_resv;
> >> struct dma_resv_iter cursor;
> >> struct dma_fence *fence;
> >>
> >> @@ -238,8 +238,8 @@ static void ttm_bo_delayed_delete(struct work_struct
> >> *work)
> >>
> >> bo = container_of(work, typeof(*bo), delayed_delete);
> >>
> >> - dma_resv_wait_timeout(&bo->base._resv, DMA_RESV_USAGE_BOOKKEEP, false,
> >> - MAX_SCHEDULE_TIMEOUT);
> >> + dma_resv_wait_timeout(bo->individual_resv, DMA_RESV_USAGE_BOOKKEEP,
> >> + false, MAX_SCHEDULE_TIMEOUT);
> >> dma_resv_lock(bo->base.resv, NULL);
> >> ttm_bo_cleanup_memtype_use(bo);
> >> dma_resv_unlock(bo->base.resv);
> >> @@ -273,7 +273,7 @@ static void ttm_bo_release(struct kref *kref)
> >> drm_vma_offset_remove(bdev->vma_manager, &bo->base.vma_node);
> >> ttm_mem_io_free(bdev, bo->resource);
> >>
> >> - if (!dma_resv_test_signaled(&bo->base._resv,
> >> + if (!dma_resv_test_signaled(bo->individual_resv,
> >> DMA_RESV_USAGE_BOOKKEEP) ||
> >> (want_init_on_free() && (bo->ttm != NULL)) ||
> >> bo->type == ttm_bo_type_sg ||
> >> @@ -316,6 +316,8 @@ static void ttm_bo_release(struct kref *kref)
> >> }
> >>
> >> atomic_dec(&ttm_glob.bo_count);
> >> + dma_resv_put(bo->individual_resv);
> >> + bo->individual_resv = NULL;
> >
> > individual_resv is set to NULL.
> >
> >> bo->destroy(bo);
> >
> > vfunc ->destroy() called and this the only call site.
> >
> >> }
> >>
> >> @@ -1197,7 +1199,11 @@ int ttm_bo_init_reserved(struct ttm_device *bdev,
> >> struct ttm_buffer_object *bo,
> >> bo->pin_count = 0;
> >> bo->sg = sg;
> >> bo->bulk_move = NULL;
> >> - drm_gem_object_set_resv(&bo->base, resv ?: &bo->base._resv);
> >> +
> >> + /* Save the original resv object before overwriting it */
> >> + bo->individual_resv = dma_resv_get(bo->base.resv);
> >> + if (resv)
> >> + drm_gem_object_set_resv(&bo->base, resv);
> >> atomic_inc(&ttm_glob.bo_count);
> >>
> >> /*
> >> diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c
> >> b/drivers/gpu/drm/ttm/ttm_bo_util.c
> >> index e080ce60933e..e39448a5015e 100644
> >> --- a/drivers/gpu/drm/ttm/ttm_bo_util.c
> >> +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
> >> @@ -208,7 +208,7 @@ static void ttm_transfered_destroy(struct
> >> ttm_buffer_object *bo)
> >
> > This is the vfunc ->destroy() for transfer destroys.
> >
> >>
> >> fbo = container_of(bo, struct ttm_transfer_obj, base);
> >> dma_resv_put(fbo->base.base.resv);
> >> - dma_resv_put(&fbo->base.base._resv);
> >> + dma_resv_put(fbo->base.individual_resv);
> >
> > fbo->base.individual_resv should always be NULL per above comments.
> >
> > Not functionally incorrect as dma_resv_put has a NULL check, but this
> > confused me in my analysis of the refcounting.
> >
> > Can we either delete this or WARN_ON_ONCE(fbo->base.individual_resv) to
> > future proof this?
>
> Good point, I just though better save than sorry here but that is indeed not
> needed.
>
> Any other comments/reviews on that series? If not I'm going to send it out
> once more to a wider audience.
>
Overall, this looks good to me, and it actually addresses a couple of
memory-safety issues in Xe by ensuring that the shared dma-resv does not
disappear underneath BOs that are sharing the VM's dma-resv. Once this
lands, I think we can drop those workarounds.
Getting all the way through this review is still on my backlog, but I'll
try to finish it over the next couple of days.
In the meantime, I would resend the series so Sashiko can take another
run at it. For some reason, the latest version didn'tt get a Sashiko
run. Sashiko is very good at spotting memory-safety issues, and if
the review comes back reasonably clean, I would lean toward merging the
next revision and if there is any fallout in bugs we will have several
months to close on any issues before it gets into a release.
Matt
> Thanks,
> Christian.
>
> >
> > Otherwise Xe, TTM, and DRM changes LGTM.
> >
> > Matt
> >
> >> ttm_bo_put(fbo->bo);
> >> kfree(fbo);
> >> }
> >> @@ -238,12 +238,23 @@ static int ttm_buffer_object_transfer(struct
> >> ttm_buffer_object *bo,
> >> if (!fbo)
> >> return -ENOMEM;
> >>
> >> - fbo->base = *bo;
> >>
> >> /**
> >> * Fix up members that we shouldn't copy directly:
> >> * TODO: Explicit member copy would probably be better here.
> >> */
> >> + fbo->base = *bo;
> >> +
> >> + fbo->base.individual_resv = dma_resv_alloc();
> >> + if (!fbo->base.individual_resv) {
> >> + ret = -ENOMEM;
> >> + goto error_free;
> >> + }
> >> +
> >> + if (bo->type != ttm_bo_type_sg)
> >> + fbo->base.base.resv = dma_resv_get(fbo->base.individual_resv);
> >> + else
> >> + dma_resv_get(fbo->base.base.resv);
> >>
> >> atomic_inc(&ttm_glob.bo_count);
> >> drm_vma_node_reset(&fbo->base.base.vma_node);
> >> @@ -251,19 +262,16 @@ static int ttm_buffer_object_transfer(struct
> >> ttm_buffer_object *bo,
> >> kref_init(&fbo->base.kref);
> >> fbo->base.destroy = &ttm_transfered_destroy;
> >> fbo->base.pin_count = 0;
> >> - if (bo->type != ttm_bo_type_sg)
> >> - fbo->base.base.resv = &fbo->base.base._resv;
> >>
> >> - dma_resv_init(&fbo->base.base._resv);
> >> fbo->base.base.dev = NULL;
> >> - ret = dma_resv_trylock(&fbo->base.base._resv);
> >> + ret = dma_resv_trylock(fbo->base.individual_resv);
> >> WARN_ON(!ret);
> >>
> >> - ret = dma_resv_reserve_fences(&fbo->base.base._resv,
> >> TTM_NUM_MOVE_FENCES);
> >> + ret = dma_resv_reserve_fences(fbo->base.individual_resv,
> >> + TTM_NUM_MOVE_FENCES);
> >> if (ret) {
> >> - dma_resv_unlock(&fbo->base.base._resv);
> >> - kfree(fbo);
> >> - return ret;
> >> + dma_resv_unlock(fbo->base.individual_resv);
> >> + goto error_unref;
> >> }
> >>
> >> if (fbo->base.resource) {
> >> @@ -281,6 +289,14 @@ static int ttm_buffer_object_transfer(struct
> >> ttm_buffer_object *bo,
> >>
> >> *new_obj = &fbo->base;
> >> return 0;
> >> +
> >> +error_unref:
> >> + dma_resv_put(fbo->base.individual_resv);
> >> + dma_resv_put(fbo->base.base.resv);
> >> +
> >> +error_free:
> >> + kfree(fbo);
> >> + return ret;
> >> }
> >>
> >> /**
> >> @@ -618,7 +634,7 @@ static int ttm_bo_move_to_ghost(struct
> >> ttm_buffer_object *bo,
> >> if (ret)
> >> return ret;
> >>
> >> - dma_resv_add_fence(&ghost_obj->base._resv, fence,
> >> + dma_resv_add_fence(ghost_obj->individual_resv, fence,
> >> DMA_RESV_USAGE_KERNEL);
> >>
> >> /**
> >> @@ -632,7 +648,7 @@ static int ttm_bo_move_to_ghost(struct
> >> ttm_buffer_object *bo,
> >> else
> >> bo->ttm = NULL;
> >>
> >> - dma_resv_unlock(&ghost_obj->base._resv);
> >> + dma_resv_unlock(ghost_obj->individual_resv);
> >> ttm_bo_put(ghost_obj);
> >> return 0;
> >> }
> >> @@ -802,14 +818,14 @@ int ttm_bo_pipeline_gutting(struct ttm_buffer_object
> >> *bo)
> >> if (ret)
> >> goto error_destroy_tt;
> >>
> >> - ret = dma_resv_copy_fences(&ghost->base._resv, bo->base.resv);
> >> + ret = dma_resv_copy_fences(ghost->individual_resv, bo->base.resv);
> >> /* Last resort, wait for the BO to be idle when we are OOM */
> >> if (ret) {
> >> dma_resv_wait_timeout(bo->base.resv, DMA_RESV_USAGE_BOOKKEEP,
> >> false, MAX_SCHEDULE_TIMEOUT);
> >> }
> >>
> >> - dma_resv_unlock(&ghost->base._resv);
> >> + dma_resv_unlock(ghost->individual_resv);
> >> ttm_bo_put(ghost);
> >> bo->ttm = ttm;
> >> return 0;
> >> diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
> >> index 6df7ef07ec0b..422fe4bddf00 100644
> >> --- a/drivers/gpu/drm/xe/xe_bo.c
> >> +++ b/drivers/gpu/drm/xe/xe_bo.c
> >> @@ -1660,7 +1660,7 @@ static bool xe_ttm_bo_lock_in_destructor(struct
> >> ttm_buffer_object *ttm_bo)
> >> * always succeed here, as long as we hold the lru lock.
> >> */
> >> spin_lock(&ttm_bo->bdev->lru_lock);
> >> - locked = dma_resv_trylock(&ttm_bo->base._resv);
> >> + locked = dma_resv_trylock(ttm_bo->individual_resv);
> >> spin_unlock(&ttm_bo->bdev->lru_lock);
> >> xe_assert(xe, locked);
> >>
> >> @@ -1689,14 +1689,14 @@ static void xe_ttm_bo_release_notify(struct
> >> ttm_buffer_object *ttm_bo)
> >> * TODO: Don't do this for external bos once we scrub them after
> >> * unbind.
> >> */
> >> - dma_resv_for_each_fence(&cursor, &ttm_bo->base._resv,
> >> + dma_resv_for_each_fence(&cursor, ttm_bo->individual_resv,
> >> DMA_RESV_USAGE_BOOKKEEP, fence) {
> >> if (xe_fence_is_xe_preempt(fence) &&
> >> !dma_fence_is_signaled(fence)) {
> >> if (!replacement)
> >> replacement = dma_fence_get_stub();
> >>
> >> - dma_resv_replace_fences(&ttm_bo->base._resv,
> >> + dma_resv_replace_fences(ttm_bo->individual_resv,
> >> fence->context,
> >> replacement,
> >> DMA_RESV_USAGE_BOOKKEEP);
> >> @@ -1704,7 +1704,7 @@ static void xe_ttm_bo_release_notify(struct
> >> ttm_buffer_object *ttm_bo)
> >> }
> >> dma_fence_put(replacement);
> >>
> >> - dma_resv_unlock(&ttm_bo->base._resv);
> >> + dma_resv_unlock(ttm_bo->individual_resv);
> >> }
> >>
> >> static void xe_ttm_bo_delete_mem_notify(struct ttm_buffer_object *ttm_bo)
> >> diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
> >> index f889232e8525..8aed680bfca2 100644
> >> --- a/include/drm/drm_gem.h
> >> +++ b/include/drm/drm_gem.h
> >> @@ -385,15 +385,6 @@ struct drm_gem_object {
> >> */
> >> struct dma_resv *resv;
> >>
> >> - /**
> >> - * @_resv:
> >> - *
> >> - * A reservation object for this GEM object.
> >> - *
> >> - * This is unused for imported GEM objects.
> >> - */
> >> - struct dma_resv _resv;
> >> -
> >> /**
> >> * @gpuva: Fields used by GPUVM to manage mappings pointing to this GEM
> >> object.
> >> *
> >> diff --git a/include/drm/ttm/ttm_bo.h b/include/drm/ttm/ttm_bo.h
> >> index 32791c4db2a9..f132caa9647f 100644
> >> --- a/include/drm/ttm/ttm_bo.h
> >> +++ b/include/drm/ttm/ttm_bo.h
> >> @@ -77,6 +77,7 @@ enum ttm_bo_type {
> >> * @bdev: Pointer to the buffer object device structure.
> >> * @type: The bo type.
> >> * @page_alignment: Page alignment.
> >> + * @individual_resv: Individual resv for destruction
> >> * @destroy: Destruction function. If NULL, kfree is used.
> >> * @kref: Reference count of this buffer object. When this refcount
> >> reaches
> >> * zero, the object is destroyed or put on the delayed delete list.
> >> @@ -107,6 +108,7 @@ struct ttm_buffer_object {
> >> struct ttm_device *bdev;
> >> enum ttm_bo_type type;
> >> uint32_t page_alignment;
> >> + struct dma_resv *individual_resv;
> >> void (*destroy) (struct ttm_buffer_object *);
> >>
> >> /*
> >> --
> >> 2.43.0
> >>
>