From: Christian König <deathsimple@xxxxxxxxxxx> To prevent deadlocks under extreme conditions. v2: rebase on top of new sa_manager patch Signed-off-by: Christian König <deathsimple@xxxxxxxxxxx> Reviewed-by: Jerome Glisse <jglisse@xxxxxxxxxx> --- 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 | 8 +++++++- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index fa4dc73..f18aa13 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -397,6 +397,7 @@ struct radeon_sa_manager { uint64_t gpu_addr; void *cpu_ptr; uint32_t domain; + void (*try_free)(struct radeon_device *); }; struct radeon_sa_bo; diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 96a2a81..1766671 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 2b71971..242c76f 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -159,7 +159,8 @@ static inline void * radeon_sa_bo_cpu_addr(struct radeon_sa_bo *sa_bo) 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 fc63ebb..0293342 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -208,7 +208,7 @@ int radeon_ib_pool_init(struct radeon_device *rdev) r = radeon_sa_bo_manager_init(rdev, &tmp, 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 f7b20b1..6541b0d 100644 --- a/drivers/gpu/drm/radeon/radeon_sa.c +++ b/drivers/gpu/drm/radeon/radeon_sa.c @@ -33,7 +33,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; @@ -45,6 +46,7 @@ int radeon_sa_bo_manager_init(struct radeon_device *rdev, sa_manager->ehole_size = size; sa_manager->ehole_offset = 0; 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, @@ -183,6 +185,10 @@ retry: /* failed to find something big enough, wait * for the biggest hole to increase in size */ + if (sa_manager->try_free) { + /* try to free something */ + sa_manager->try_free(rdev); + } r = wait_event_interruptible(sa_manager->queue, radeon_sa_bo_max_free(sa_manager, align) >= size); if (r) { -- 1.7.7.6 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel