On the A+A VF the hypervisor reports each VF's VRAM address in the ACPI SRAT table, and that address is stored in aper_base. The XGMI node segment does not describe the VF, so physical_node_id * node_segment_size is not a valid VRAM starting address.
gmc_v12_0_vram_gtt_location() and amdgpu_virt_resume() still added that offset on top of aper_base, which moved the SPM PDB0 system PTEs off the VF's HBM. Leave vram_base_offset at aper_base on both paths. Size PDB0 from the VF's local VRAM and place GART after that window, aligned to 8GB. That alignment is one PDB0 entry when vmid0_page_table_block_size is 12, and it applies to every PDB0 placement. v2: - Explain that the SRAT address is already the VF VRAM base and must not be adjusted by the XGMI node segment. Signed-off-by: Zhigang Luo <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 12 +++++++++--- drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 22 ++++++++++++++++------ drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c | 6 ++++-- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 9326f811c500..7a664b7b1ba3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4677,9 +4677,15 @@ static inline int amdgpu_virt_resume(struct amdgpu_device *adev) dev_info(adev->dev, "xgmi node, old id %d, new id %d\n", prev_physical_node_id, adev->gmc.xgmi.physical_node_id); - adev->vm_manager.vram_base_offset = adev->gfxhub.funcs->get_mc_fb_offset(adev); - adev->vm_manager.vram_base_offset += - adev->gmc.xgmi.physical_node_id * adev->gmc.xgmi.node_segment_size; + if (amdgpu_virt_vram_is_spm(adev)) { + adev->vm_manager.vram_base_offset = adev->gmc.aper_base; + } else { + adev->vm_manager.vram_base_offset = + adev->gfxhub.funcs->get_mc_fb_offset(adev); + adev->vm_manager.vram_base_offset += + adev->gmc.xgmi.physical_node_id * + adev->gmc.xgmi.node_segment_size; + } return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index f76da74abfec..96075db3b9ac 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -42,6 +42,8 @@ #include <drm/ttm/ttm_tt.h> static const u64 four_gb = 0x100000000ULL; +/* PDB0 block size 12 covers one 8GB entry. */ +static const u64 eight_gb = 0x200000000ULL; bool amdgpu_gmc_is_pdb0_enabled(struct amdgpu_device *adev) { @@ -60,7 +62,8 @@ int amdgpu_gmc_pdb0_alloc(struct amdgpu_device *adev) { int r; struct amdgpu_bo_param bp; - u64 vram_size = adev->gmc.xgmi.node_segment_size * adev->gmc.xgmi.num_physical_nodes; + u64 vram_size = amdgpu_virt_vram_is_spm(adev) ? adev->gmc.mc_vram_size : + adev->gmc.xgmi.node_segment_size * adev->gmc.xgmi.num_physical_nodes; uint32_t pde0_page_shift = adev->gmc.vmid0_page_table_block_size + 21; uint32_t npdes = (vram_size + (1ULL << pde0_page_shift) - 1) >> pde0_page_shift; @@ -261,16 +264,21 @@ void amdgpu_gmc_sysvm_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc u64 hive_vram_end = mc->xgmi.node_segment_size * mc->xgmi.num_physical_nodes - 1; mc->vram_start = mc->xgmi.node_segment_size * mc->xgmi.physical_node_id; mc->vram_end = mc->vram_start + mc->xgmi.node_segment_size - 1; - /* node_segment_size may not 4GB aligned on SRIOV, align up is needed. */ - mc->gart_start = ALIGN(hive_vram_end + 1, four_gb); + /* Round up to a PDB0 entry so GART starts on the page-table PDE. */ + mc->gart_start = ALIGN(hive_vram_end + 1, eight_gb); mc->gart_end = mc->gart_start + mc->gart_size - 1; - if (amdgpu_virt_xgmi_migrate_enabled(adev)) { + if (amdgpu_virt_xgmi_migrate_enabled(adev) || + amdgpu_virt_vram_is_spm(adev)) { /* set mc->vram_start to 0 to switch the returned GPU address of * amdgpu_bo_create_reserved() from FB aperture to GART aperture. */ mc->vram_start = 0; mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; mc->visible_vram_size = min(mc->visible_vram_size, mc->real_vram_size); + if (amdgpu_virt_vram_is_spm(adev)) { + mc->gart_start = ALIGN(mc->vram_end + 1, eight_gb); + mc->gart_end = mc->gart_start + mc->gart_size - 1; + } } else { mc->fb_start = hive_vram_start; mc->fb_end = hive_vram_end; @@ -1269,7 +1277,8 @@ void amdgpu_gmc_init_pdb0(struct amdgpu_device *adev) uint64_t flags = adev->gart.gart_pte_flags; //TODO it is UC. explore NC/RW? /* Each PDE0 (used as PTE) covers (2^vmid0_page_table_block_size)*2M */ - u64 vram_size = adev->gmc.xgmi.node_segment_size * adev->gmc.xgmi.num_physical_nodes; + u64 vram_size = amdgpu_virt_vram_is_spm(adev) ? adev->gmc.mc_vram_size : + adev->gmc.xgmi.node_segment_size * adev->gmc.xgmi.num_physical_nodes; u64 pde0_page_size = (1ULL<<adev->gmc.vmid0_page_table_block_size)<<21; u64 vram_addr, vram_end; u64 gart_ptb_gpu_pa = amdgpu_gmc_vram_pa(adev, adev->gart.bo); @@ -1287,7 +1296,8 @@ void amdgpu_gmc_init_pdb0(struct amdgpu_device *adev) flags |= AMDGPU_PDE_PTE_FLAG(adev); vram_addr = adev->vm_manager.vram_base_offset; - if (!amdgpu_virt_xgmi_migrate_enabled(adev)) + if (!amdgpu_virt_xgmi_migrate_enabled(adev) && + !amdgpu_virt_vram_is_spm(adev)) vram_addr -= adev->gmc.xgmi.physical_node_id * adev->gmc.xgmi.node_segment_size; vram_end = vram_addr + vram_size; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c index cd276a138e10..e37c84f10709 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c @@ -734,8 +734,10 @@ static void gmc_v12_0_vram_gtt_location(struct amdgpu_device *adev, adev->vm_manager.vram_base_offset = adev->mmhub.funcs->get_mc_fb_offset(adev); } - adev->vm_manager.vram_base_offset += - adev->gmc.xgmi.physical_node_id * adev->gmc.xgmi.node_segment_size; + if (!amdgpu_virt_vram_is_spm(adev)) + adev->vm_manager.vram_base_offset += + adev->gmc.xgmi.physical_node_id * + adev->gmc.xgmi.node_segment_size; } /** -- 2.43.0
