diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index e3c4940..fc0ddf6 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -230,6 +230,7 @@ struct radeon_bo_list { unsigned rdomain; unsigned wdomain; u32 tiling_flags; + bool list_reserved; }; /* diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 65590a0..8def608 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -83,7 +83,7 @@ int radeon_cs_parser_relocs(struct radeon_cs_parser *p) p->relocs[i].flags = r->flags; INIT_LIST_HEAD(&p->relocs[i].lobj.list); radeon_bo_list_add_object(&p->relocs[i].lobj, - &p->validated); + &p->validated); } } return radeon_bo_list_validate(&p->validated, p->ib->fence); @@ -191,7 +191,7 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) if (error) { radeon_bo_list_unvalidate(&parser->validated, - parser->ib->fence); + parser->ib->fence); } else { radeon_bo_list_unreserve(&parser->validated); } diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index af77168..5c74336 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -102,8 +102,10 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, } *bo_ptr = NULL; bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); - if (bo == NULL) + if (bo == NULL) { + DRM_ERROR("failed to allocate radeon bo\n"); return -ENOMEM; + } bo->rdev = rdev; bo->gobj = gobj; bo->surface_reg = -1; @@ -274,6 +276,7 @@ void radeon_bo_fini(struct radeon_device *rdev) void radeon_bo_list_add_object(struct radeon_bo_list *lobj, struct list_head *head) { + WARN_ON(lobj->list_reserved == true); if (lobj->wdomain) { list_add(&lobj->list, head); } else { @@ -290,6 +293,7 @@ int radeon_bo_list_reserve(struct list_head *head) r = radeon_bo_reserve(lobj->bo, false); if (unlikely(r != 0)) return r; + lobj->list_reserved = true; } return 0; } @@ -300,8 +304,11 @@ void radeon_bo_list_unreserve(struct list_head *head) list_for_each_entry(lobj, head, list) { /* only unreserve object we successfully reserved */ - if (radeon_bo_is_reserved(lobj->bo)) + // if (radeon_bo_is_reserved(lobj->bo)) + if (lobj->list_reserved == true) { radeon_bo_unreserve(lobj->bo); + lobj->list_reserved = false; + } } } @@ -493,14 +500,18 @@ int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved, void radeon_bo_move_notify(struct ttm_buffer_object *bo, struct ttm_mem_reg *mem) { - struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo); + struct radeon_bo *rbo; if (!radeon_ttm_bo_is_radeon_bo(bo)) return; + rbo = container_of(bo, struct radeon_bo, tbo); radeon_bo_check_tiling(rbo, 0, 1); } void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo) { - struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo); + struct radeon_bo *rbo; + if (!radeon_ttm_bo_is_radeon_bo(bo)) + return; + rbo = container_of(bo, struct radeon_bo, tbo); radeon_bo_check_tiling(rbo, 0, 0); } diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index f6b69c2..cd73aa3 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -59,18 +59,14 @@ static inline unsigned radeon_mem_type_to_domain(u32 mem_type) * * Returns: * -EBUSY: buffer is busy and @no_wait is true - * -ERESTART: A wait for the buffer to become unreserved was interrupted by * a signal. Release all buffer reservations and return to user-space. */ static inline int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait) { int r; -retry: r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0); if (unlikely(r != 0)) { - if (r == -ERESTART) - goto retry; dev_err(bo->rdev->dev, "%p reserve failed\n", bo); return r; } @@ -125,11 +121,8 @@ static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, { int r; -retry: r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0); if (unlikely(r != 0)) { - if (r == -ERESTART) - goto retry; dev_err(bo->rdev->dev, "%p reserve failed for wait\n", bo); return r; } @@ -140,8 +133,6 @@ retry: r = ttm_bo_wait(&bo->tbo, true, true, no_wait); spin_unlock(&bo->tbo.lock); ttm_bo_unreserve(&bo->tbo); - if (unlikely(r == -ERESTART)) - goto retry; return r; } diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 7b853e8..e2aa808 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -314,6 +314,7 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo, r = ttm_bo_mem_space(bo, &placement, &tmp_mem, interruptible, no_wait); if (unlikely(r)) { + DRM_ERROR("failed to allocate GTT space for GTT moving 1\n"); return r; } @@ -366,6 +367,7 @@ static int radeon_move_ram_vram(struct ttm_buffer_object *bo, placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT; r = ttm_bo_mem_space(bo, &placement, &tmp_mem, interruptible, no_wait); if (unlikely(r)) { + DRM_ERROR("failed to allocate GTT space for GTT moving 2\n"); return r; } r = ttm_bo_move_ttm(bo, true, no_wait, &tmp_mem); diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 4cd4007..17cc899 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -267,7 +267,6 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo, return 0; } -EXPORT_SYMBOL(ttm_bo_reserve); static void ttm_bo_ref_bug(struct kref *list_kref) { @@ -283,6 +282,8 @@ int ttm_bo_reserve(struct ttm_buffer_object *bo, int ret; spin_lock(&glob->lru_lock); + WARN_ON(!list_empty(&bo->ddestroy)); + ret = ttm_bo_reserve_locked(bo, interruptible, no_wait, use_sequence, sequence); if (likely(ret == 0)) @@ -294,6 +295,7 @@ int ttm_bo_reserve(struct ttm_buffer_object *bo, return ret; } +EXPORT_SYMBOL(ttm_bo_reserve); void ttm_bo_unreserve(struct ttm_buffer_object *bo) { @@ -455,7 +457,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) struct ttm_bo_global *glob = bo->glob; struct ttm_bo_driver *driver = bdev->driver; int ret; - + int test; spin_lock(&bo->lock); (void) ttm_bo_wait(bo, false, false, !remove_all); @@ -465,6 +467,11 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) spin_unlock(&bo->lock); spin_lock(&glob->lru_lock); + test = atomic_read(&bo->reserved); + if (test) { + printk("%s: bo %p reserved %d %ld\n", __func__, bo, test, bo->num_pages); + } + ret = ttm_bo_reserve_locked(bo, false, false, false, 0); BUG_ON(ret); if (bo->ttm) @@ -589,6 +596,8 @@ static void ttm_bo_release(struct kref *kref) container_of(kref, struct ttm_buffer_object, kref); struct ttm_bo_device *bdev = bo->bdev; + WARN_ON(atomic_read(&bo->reserved)); + if (likely(bo->vm_node != NULL)) { rb_erase(&bo->vm_rb, &bdev->addr_space_rb); drm_mm_put_block(bo->vm_node); @@ -606,6 +615,7 @@ void ttm_bo_unref(struct ttm_buffer_object **p_bo) struct ttm_bo_device *bdev = bo->bdev; *p_bo = NULL; + write_lock(&bdev->vm_lock); kref_put(&bo->kref, ttm_bo_release); write_unlock(&bdev->vm_lock); @@ -1569,8 +1579,10 @@ static void ttm_bo_vm_insert_rb(struct ttm_buffer_object *bo) cur = &parent->rb_left; else if (offset > cur_offset) cur = &parent->rb_right; - else + else { + printk("cur offset %x\n", offset); BUG(); + } } rb_link_node(&bo->vm_rb, parent, cur); @@ -1595,8 +1607,10 @@ static int ttm_bo_setup_vm(struct ttm_buffer_object *bo) retry_pre_get: ret = drm_mm_pre_get(&bdev->addr_space_mm); - if (unlikely(ret != 0)) + if (unlikely(ret != 0)) { + printk(KERN_ERR "drm_mm pre get failed for bo %p\n", bo); return ret; + } write_lock(&bdev->vm_lock); bo->vm_node = drm_mm_search_free(&bdev->addr_space_mm, @@ -1604,6 +1618,7 @@ retry_pre_get: if (unlikely(bo->vm_node == NULL)) { ret = -ENOMEM; + printk(KERN_ERR "failure to allocate vm node space for bo %p\n", bo); goto out_unlock; } @@ -1768,7 +1783,7 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink) * to re-check that nobody removed us from the swap-list while * we slept. */ - + WARN_ON(!list_empty(&bo->ddestroy)); ret = ttm_bo_reserve_locked(bo, false, true, false, 0); if (unlikely(ret == -EBUSY)) { spin_unlock(&glob->lru_lock);