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 <tzimmerm...@suse.de>
---
 drivers/gpu/drm/nouveau/nouveau_bo.c | 43 +++++++++++++++++++---------
 drivers/gpu/drm/nouveau/nouveau_bo.h |  2 ++
 2 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 56dcd25db1ce2..4a7c002a325a4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -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;
 }
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h 
b/drivers/gpu/drm/nouveau/nouveau_bo.h
index e9dfab6a81560..4e891752c2551 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.h
@@ -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 *);
-- 
2.43.2

Reply via email to