| From 7963f54317cc8034060e339fe7359cce37f1a45a Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com> |
| Date: Fri, 24 Mar 2017 19:01:09 +0900 |
| Subject: [PATCH] drm/radeon: Override fpfn for all VRAM placements in |
| radeon_evict_flags |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| commit ce4b4f228e51219b0b79588caf73225b08b5b779 upstream. |
| |
| We were accidentally only overriding the first VRAM placement. For BOs |
| with the RADEON_GEM_NO_CPU_ACCESS flag set, |
| radeon_ttm_placement_from_domain creates a second VRAM placment with |
| fpfn == 0. If VRAM is almost full, the first VRAM placement with |
| fpfn > 0 may not work, but the second one with fpfn == 0 always will |
| (the BO's current location trivially satisfies it). Because "moving" |
| the BO to its current location puts it back on the LRU list, this |
| results in an infinite loop. |
| |
| Fixes: 2a85aedd117c ("drm/radeon: Try evicting from CPU accessible to |
| inaccessible VRAM first") |
| Reported-by: Zachary Michaels <zmichaels@oblong.com> |
| Reported-and-Tested-by: Julien Isorce <jisorce@oblong.com> |
| Reviewed-by: Christian König <christian.koenig@amd.com> |
| Reviewed-by: Alex Deucher <alexander.deucher@amd.com> |
| Signed-off-by: Michel Dänzer <michel.daenzer@amd.com> |
| Signed-off-by: Alex Deucher <alexander.deucher@amd.com> |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c |
| index c2e0a1ccdfbc..4af206cd5373 100644 |
| --- a/drivers/gpu/drm/radeon/radeon_ttm.c |
| +++ b/drivers/gpu/drm/radeon/radeon_ttm.c |
| @@ -213,8 +213,8 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo, |
| rbo->placement.num_busy_placement = 0; |
| for (i = 0; i < rbo->placement.num_placement; i++) { |
| if (rbo->placements[i].flags & TTM_PL_FLAG_VRAM) { |
| - if (rbo->placements[0].fpfn < fpfn) |
| - rbo->placements[0].fpfn = fpfn; |
| + if (rbo->placements[i].fpfn < fpfn) |
| + rbo->placements[i].fpfn = fpfn; |
| } else { |
| rbo->placement.busy_placement = |
| &rbo->placements[i]; |
| -- |
| 2.12.0 |
| |