Using the kernel zone memory size to determine the size of the GART table introduced a regression on systems with a large amount of system memory. On a system with 512GB RAM, driver initialisation would fail as there are more GART entries than there are GPU pages to map to them. With 256GB RAM, the table would barely fit, but no other allocations are possible. Restrict the size of the GART such that it will occupy at maximum half of the pages available to the GPU. Fixes: a693e050 ("drm/amdgpu: use the kernel zone memory size as the max remote memory in amdgpu") Signed-off-by: Russell Currey <ruscur@xxxxxxxxxx> --- I don't know much about GPUs, restricting this to less than half might make more sense. --- drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | 21 +++++++++++++++------ drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 21 +++++++++++++++------ drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 21 +++++++++++++++------ 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c index b13c8aa..f8bbb17 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c @@ -264,6 +264,7 @@ static int gmc_v6_0_mc_init(struct amdgpu_device *adev) u32 tmp; int chansize, numchan; + u64 max_gtt_entries; tmp = RREG32(MC_ARB_RAMCFG); if (tmp & CHANSIZE_OVERRIDE) { @@ -313,13 +314,21 @@ static int gmc_v6_0_mc_init(struct amdgpu_device *adev) adev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; adev->mc.visible_vram_size = adev->mc.aper_size; - /* unless the user had overridden it, set the gart - * size equal to the 1024 or vram, whichever is larger. - */ - if (amdgpu_gart_size == -1) - adev->mc.gtt_size = amdgpu_ttm_get_gtt_mem_size(adev); - else + /* unless the user had overridden it, set the GART size proportional + * to system memory, but no more than half of the GPU pages. */ + if (amdgpu_gart_size == -1) { + /* a table entry is 8 GPU pages */ + max_gtt_entries = amdgpu_ttm_get_gtt_mem_size(adev) / + (AMDGPU_GPU_PAGE_SIZE / 8); + + if (max_gtt_entries > adev->mc.visible_vram_size / 2) + adev->mc.gtt_size = (adev->mc.visible_vram_size / 2) * + AMDGPU_GPU_PAGE_SIZE / 8; + else + adev->mc.gtt_size = amdgpu_ttm_get_gtt_mem_size(adev); + } else { adev->mc.gtt_size = (uint64_t)amdgpu_gart_size << 20; + } gmc_v6_0_vram_gtt_location(adev, &adev->mc); diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index aa0c4b9..276a662 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -329,6 +329,7 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev) { u32 tmp; int chansize, numchan; + u64 max_gtt_entries; /* Get VRAM informations */ tmp = RREG32(mmMC_ARB_RAMCFG); @@ -381,13 +382,21 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev) if (adev->mc.visible_vram_size > adev->mc.real_vram_size) adev->mc.visible_vram_size = adev->mc.real_vram_size; - /* unless the user had overridden it, set the gart - * size equal to the 1024 or vram, whichever is larger. - */ - if (amdgpu_gart_size == -1) - adev->mc.gtt_size = amdgpu_ttm_get_gtt_mem_size(adev); - else + /* unless the user had overridden it, set the GART size proportional + * to system memory, but no more than half of the GPU pages. */ + if (amdgpu_gart_size == -1) { + /* a table entry is 8 GPU pages */ + max_gtt_entries = amdgpu_ttm_get_gtt_mem_size(adev) / + (AMDGPU_GPU_PAGE_SIZE / 8); + + if (max_gtt_entries > adev->mc.visible_vram_size / 2) + adev->mc.gtt_size = (adev->mc.visible_vram_size / 2) * + AMDGPU_GPU_PAGE_SIZE / 8; + else + adev->mc.gtt_size = amdgpu_ttm_get_gtt_mem_size(adev); + } else { adev->mc.gtt_size = (uint64_t)amdgpu_gart_size << 20; + } gmc_v7_0_vram_gtt_location(adev, &adev->mc); diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index a16b220..460100a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -416,6 +416,7 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev) { u32 tmp; int chansize, numchan; + u64 max_gtt_entries; /* Get VRAM informations */ tmp = RREG32(mmMC_ARB_RAMCFG); @@ -468,13 +469,21 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev) if (adev->mc.visible_vram_size > adev->mc.real_vram_size) adev->mc.visible_vram_size = adev->mc.real_vram_size; - /* unless the user had overridden it, set the gart - * size equal to the 1024 or vram, whichever is larger. - */ - if (amdgpu_gart_size == -1) - adev->mc.gtt_size = amdgpu_ttm_get_gtt_mem_size(adev); - else + /* unless the user had overridden it, set the GART size proportional + * to system memory, but no more than half of the GPU pages. */ + if (amdgpu_gart_size == -1) { + /* a table entry is 8 GPU pages */ + max_gtt_entries = amdgpu_ttm_get_gtt_mem_size(adev) / + (AMDGPU_GPU_PAGE_SIZE / 8); + + if (max_gtt_entries > adev->mc.visible_vram_size / 2) + adev->mc.gtt_size = (adev->mc.visible_vram_size / 2) * + AMDGPU_GPU_PAGE_SIZE / 8; + else + adev->mc.gtt_size = amdgpu_ttm_get_gtt_mem_size(adev); + } else { adev->mc.gtt_size = (uint64_t)amdgpu_gart_size << 20; + } gmc_v8_0_vram_gtt_location(adev, &adev->mc); -- 2.10.2 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel