drm/nouveau: Provide nouveau_bo_{pin,unpin}_locked()
authorThomas Zimmermann <tzimmermann@suse.de>
Tue, 27 Feb 2024 10:14:52 +0000 (11:14 +0100)
committerThomas Zimmermann <tzimmermann@suse.de>
Mon, 11 Mar 2024 12:33:50 +0000 (13:33 +0100)
Implement pinning without locking in nouveau_bo_pin_locked(). Keep
nouveau_bo_pin() for acquiring the buffer object's reservation lock.
The new helper will be useful for implementing the GEM pin callback
with correct semantics. Same for unpin.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> # virtio-gpu
Acked-by: Christian König <christian.koenig@amd.com>
Acked-by: Zack Rusin <zack.rusin@broadcom.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240227113853.8464-6-tzimmermann@suse.de
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/nouveau/nouveau_bo.h

index 56dcd25db1ce2c79b8a6be7c0ea684838e74e655..4a7c002a325a4757f61fd8e94b161f6dfdb82a36 100644 (file)
@@ -467,17 +467,14 @@ nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t domain,
        set_placement_range(nvbo, domain);
 }
 
-int
-nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t domain, bool contig)
+int nouveau_bo_pin_locked(struct nouveau_bo *nvbo, uint32_t domain, bool contig)
 {
        struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
        struct ttm_buffer_object *bo = &nvbo->bo;
        bool force = false, evict = false;
-       int ret;
+       int ret = 0;
 
-       ret = ttm_bo_reserve(bo, false, false, NULL);
-       if (ret)
-               return ret;
+       dma_resv_assert_held(bo->base.resv);
 
        if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA &&
            domain == NOUVEAU_GEM_DOMAIN_VRAM && contig) {
@@ -540,20 +537,15 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t domain, bool contig)
 out:
        if (force && ret)
                nvbo->contig = false;
-       ttm_bo_unreserve(bo);
        return ret;
 }
 
-int
-nouveau_bo_unpin(struct nouveau_bo *nvbo)
+void nouveau_bo_unpin_locked(struct nouveau_bo *nvbo)
 {
        struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
        struct ttm_buffer_object *bo = &nvbo->bo;
-       int ret;
 
-       ret = ttm_bo_reserve(bo, false, false, NULL);
-       if (ret)
-               return ret;
+       dma_resv_assert_held(bo->base.resv);
 
        ttm_bo_unpin(&nvbo->bo);
        if (!nvbo->bo.pin_count) {
@@ -568,8 +560,33 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo)
                        break;
                }
        }
+}
+
+int nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t domain, bool contig)
+{
+       struct ttm_buffer_object *bo = &nvbo->bo;
+       int ret;
 
+       ret = ttm_bo_reserve(bo, false, false, NULL);
+       if (ret)
+               return ret;
+       ret = nouveau_bo_pin_locked(nvbo, domain, contig);
+       ttm_bo_unreserve(bo);
+
+       return ret;
+}
+
+int nouveau_bo_unpin(struct nouveau_bo *nvbo)
+{
+       struct ttm_buffer_object *bo = &nvbo->bo;
+       int ret;
+
+       ret = ttm_bo_reserve(bo, false, false, NULL);
+       if (ret)
+               return ret;
+       nouveau_bo_unpin_locked(nvbo);
        ttm_bo_unreserve(bo);
+
        return 0;
 }
 
index e9dfab6a81560e5f68371363ce676008f1b8b901..4e891752c255139d464e62913e3eb7d6d31c0ad7 100644 (file)
@@ -85,6 +85,8 @@ int  nouveau_bo_new(struct nouveau_cli *, u64 size, int align, u32 domain,
                    u32 tile_mode, u32 tile_flags, struct sg_table *sg,
                    struct dma_resv *robj,
                    struct nouveau_bo **);
+int  nouveau_bo_pin_locked(struct nouveau_bo *nvbo, uint32_t domain, bool contig);
+void nouveau_bo_unpin_locked(struct nouveau_bo *nvbo);
 int  nouveau_bo_pin(struct nouveau_bo *, u32 flags, bool contig);
 int  nouveau_bo_unpin(struct nouveau_bo *);
 int  nouveau_bo_map(struct nouveau_bo *);