To prevent deadlocks under extreme conditions. Signed-off-by: Christian König <deathsimple@xxxxxxxxxxx> --- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_gart.c | 2 +- drivers/gpu/drm/radeon/radeon_object.h | 3 ++- drivers/gpu/drm/radeon/radeon_ring.c | 2 +- drivers/gpu/drm/radeon/radeon_sa.c | 15 ++++++++++++--- 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index e71dc67..4f7e941 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -389,6 +389,7 @@ struct radeon_sa_manager { uint64_t gpu_addr; void *cpu_ptr; uint32_t domain; + void (*try_free)(struct radeon_device *); }; /* sub-allocation buffer */ diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 7af4ff9..fba3884 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c @@ -291,7 +291,7 @@ int radeon_vm_manager_init(struct radeon_device *rdev) /* mark first vm as always in use, it's the system one */ r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, rdev->vm_manager.max_pfn * 8, - RADEON_GEM_DOMAIN_VRAM); + RADEON_GEM_DOMAIN_VRAM, NULL); if (r) { dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", (rdev->vm_manager.max_pfn * 8) >> 10); diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index 85f33d9..08505ed 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -148,7 +148,8 @@ extern struct radeon_bo_va *radeon_bo_va(struct radeon_bo *rbo, */ extern int radeon_sa_bo_manager_init(struct radeon_device *rdev, struct radeon_sa_manager *sa_manager, - unsigned size, u32 domain); + unsigned size, u32 domain, + void (*try_free)(struct radeon_device *rdev)); extern void radeon_sa_bo_manager_fini(struct radeon_device *rdev, struct radeon_sa_manager *sa_manager); extern int radeon_sa_bo_manager_start(struct radeon_device *rdev, diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index ccee74f..ae28129 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -216,7 +216,7 @@ int radeon_ib_pool_init(struct radeon_device *rdev) r = radeon_sa_bo_manager_init(rdev, &rdev->ib_pool.sa_manager, RADEON_IB_POOL_SIZE*64*1024, - RADEON_GEM_DOMAIN_GTT); + RADEON_GEM_DOMAIN_GTT, NULL); if (r) { return r; } diff --git a/drivers/gpu/drm/radeon/radeon_sa.c b/drivers/gpu/drm/radeon/radeon_sa.c index 92ab7b4..9d3e70a 100644 --- a/drivers/gpu/drm/radeon/radeon_sa.c +++ b/drivers/gpu/drm/radeon/radeon_sa.c @@ -34,7 +34,8 @@ int radeon_sa_bo_manager_init(struct radeon_device *rdev, struct radeon_sa_manager *sa_manager, - unsigned size, u32 domain) + unsigned size, u32 domain, + void (*try_free)(struct radeon_device *rdev)) { int r; @@ -43,6 +44,7 @@ int radeon_sa_bo_manager_init(struct radeon_device *rdev, sa_manager->size = size; sa_manager->biggest_hole = &sa_manager->sa_bo; sa_manager->domain = domain; + sa_manager->try_free = try_free; INIT_LIST_HEAD(&sa_manager->sa_bo); r = radeon_bo_create(rdev, size, RADEON_GPU_PAGE_SIZE, true, @@ -224,8 +226,15 @@ int radeon_sa_bo_new(struct radeon_device *rdev, } if (block) { - /* failed to find something big enough, wait - for the biggest hole to increase in size */ + /* failed to find something big enough */ + if (sa_manager->try_free) { + /* try to free something */ + spin_unlock_irq(&sa_manager->queue.lock); + sa_manager->try_free(rdev); + spin_lock_irq(&sa_manager->queue.lock); + } + + /* and wait for the biggest hole to increase in size */ r = wait_event_interruptible_locked_irq(sa_manager->queue, radeon_sa_bo_min_free(sa_manager, align) >= size ); -- 1.7.5.4 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel