On 2017å¹´12æ??14æ?¥ 17:35, Christian König wrote: > Am 14.12.2017 um 10:22 schrieb Chunming Zhou: >> v2: >>   remove SUBPTB member >> v3: >>   remove last_level, use AMDGPU_VM_PTB directly instead. >> >> Change-Id: Ic1f39d3bc853e9e4259d3e03a22920eda822eec5 >> Signed-off-by: Chunming Zhou <david1.zhou at amd.com> > > Reviewed-by: Christian König <christian.koenig at amd.com> Thanks, pushed just now, you can rebase yours now. The vmpt level looks really clear:) Regards, David Zhou > >> --- >>  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 69 >> ++++++++++++++++++++++++---------- >>  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 11 ++++++ >>  2 files changed, 61 insertions(+), 19 deletions(-) >> >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c >> index 709587d8a77f..564e1b1962f1 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c >> @@ -148,12 +148,23 @@ struct amdgpu_prt_cb { >>  static unsigned amdgpu_vm_level_shift(struct amdgpu_device *adev, >>                        unsigned level) >>  { >> -   if (level != adev->vm_manager.num_level) >> -       return 9 * (adev->vm_manager.num_level - level - 1) + >> +   unsigned shift = 0xff; >> + >> +   switch (level) { >> +   case AMDGPU_VM_PDB2: >> +   case AMDGPU_VM_PDB1: >> +   case AMDGPU_VM_PDB0: >> +       shift = 9 * (AMDGPU_VM_PDB0 - level) + >>              adev->vm_manager.block_size; >> -   else >> -       /* For the page tables on the leaves */ >> -       return 0; >> +       break; >> +   case AMDGPU_VM_PTB: >> +       shift = 0; >> +       break; >> +   default: >> +       dev_err(adev->dev, "the level%d isn't supported.\n", level); >> +   } >> + >> +   return shift; >>  } >>   /** >> @@ -166,12 +177,13 @@ static unsigned amdgpu_vm_level_shift(struct >> amdgpu_device *adev, >>  static unsigned amdgpu_vm_num_entries(struct amdgpu_device *adev, >>                        unsigned level) >>  { >> -   unsigned shift = amdgpu_vm_level_shift(adev, 0); >> +   unsigned shift = amdgpu_vm_level_shift(adev, >> +                          adev->vm_manager.root_level); >>  -   if (level == 0) >> +   if (level == adev->vm_manager.root_level) >>          /* For the root directory */ >>          return round_up(adev->vm_manager.max_pfn, 1 << shift) >> >> shift; >> -   else if (level != adev->vm_manager.num_level) >> +   else if (level != AMDGPU_VM_PTB) >>          /* Everything in between */ >>          return 512; >>      else >> @@ -343,7 +355,7 @@ static int amdgpu_vm_alloc_levels(struct >> amdgpu_device *adev, >>       if (vm->pte_support_ats) { >>          init_value = AMDGPU_PTE_DEFAULT_ATC; >> -       if (level != adev->vm_manager.num_level) >> +       if (level != AMDGPU_VM_PTB) >>              init_value |= AMDGPU_PDE_PTE; >>       } >> @@ -385,7 +397,7 @@ static int amdgpu_vm_alloc_levels(struct >> amdgpu_device *adev, >>              spin_unlock(&vm->status_lock); >>          } >>  -       if (level < adev->vm_manager.num_level) { >> +       if (level < AMDGPU_VM_PTB) { >>              uint64_t sub_saddr = (pt_idx == from) ? saddr : 0; >>              uint64_t sub_eaddr = (pt_idx == to) ? eaddr : >>                  ((1 << shift) - 1); >> @@ -431,7 +443,8 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev, >>      saddr /= AMDGPU_GPU_PAGE_SIZE; >>      eaddr /= AMDGPU_GPU_PAGE_SIZE; >>  -   return amdgpu_vm_alloc_levels(adev, vm, &vm->root, saddr, >> eaddr, 0); >> +   return amdgpu_vm_alloc_levels(adev, vm, &vm->root, saddr, eaddr, >> +                     adev->vm_manager.root_level); >>  } >>   /** >> @@ -1091,6 +1104,7 @@ static void amdgpu_vm_update_pde(struct >> amdgpu_pte_update_params *params, >>      for (level = 0, pbo = parent->base.bo->parent; pbo; ++level) >>          pbo = pbo->parent; >>  +   level += params->adev->vm_manager.root_level; >>      pt = amdgpu_bo_gpu_offset(bo); >>      flags = AMDGPU_PTE_VALID; >>      amdgpu_gart_get_vm_pde(params->adev, level, &pt, &flags); >> @@ -1247,7 +1261,8 @@ int amdgpu_vm_update_directories(struct >> amdgpu_device *adev, >>      return 0; >>   error: >> -   amdgpu_vm_invalidate_level(adev, vm, &vm->root, 0); >> +   amdgpu_vm_invalidate_level(adev, vm, &vm->root, >> +                  adev->vm_manager.root_level); >>      amdgpu_job_free(job); >>      return r; >>  } >> @@ -1266,7 +1281,7 @@ void amdgpu_vm_get_entry(struct >> amdgpu_pte_update_params *p, uint64_t addr, >>               struct amdgpu_vm_pt **entry, >>               struct amdgpu_vm_pt **parent) >>  { >> -   unsigned level = 0; >> +   unsigned level = p->adev->vm_manager.root_level; >>       *parent = NULL; >>      *entry = &p->vm->root; >> @@ -1278,7 +1293,7 @@ void amdgpu_vm_get_entry(struct >> amdgpu_pte_update_params *p, uint64_t addr, >>          addr &= (1ULL << shift) - 1; >>      } >>  -   if (level != p->adev->vm_manager.num_level) >> +   if (level != AMDGPU_VM_PTB) >>          *entry = NULL; >>  } >>  @@ -1320,7 +1335,7 @@ static void >> amdgpu_vm_handle_huge_pages(struct amdgpu_pte_update_params *p, >>          return; >>      entry->huge = !!(flags & AMDGPU_PDE_PTE); >>  -   amdgpu_gart_get_vm_pde(p->adev, p->adev->vm_manager.num_level >> - 1, >> +   amdgpu_gart_get_vm_pde(p->adev, AMDGPU_VM_PDB0, >>                     &dst, &flags); >>       if (use_cpu_update) { >> @@ -1636,7 +1651,8 @@ static int amdgpu_vm_bo_update_mapping(struct >> amdgpu_device *adev, >>   error_free: >>      amdgpu_job_free(job); >> -   amdgpu_vm_invalidate_level(adev, vm, &vm->root, 0); >> +   amdgpu_vm_invalidate_level(adev, vm, &vm->root, >> +                  adev->vm_manager.root_level); >>      return r; >>  } >>  @@ -2552,7 +2568,19 @@ void amdgpu_vm_adjust_size(struct >> amdgpu_device *adev, uint32_t vm_size, >>          tmp >>= amdgpu_vm_block_size - 9; >>      tmp = DIV_ROUND_UP(fls64(tmp) - 1, 9) - 1; >>      adev->vm_manager.num_level = min(max_level, (unsigned)tmp); >> - >> +   switch (adev->vm_manager.num_level) { >> +   case 3: >> +       adev->vm_manager.root_level = AMDGPU_VM_PDB2; >> +       break; >> +   case 2: >> +       adev->vm_manager.root_level = AMDGPU_VM_PDB1; >> +       break; >> +   case 1: >> +       adev->vm_manager.root_level = AMDGPU_VM_PDB0; >> +       break; >> +   default: >> +       dev_err(adev->dev, "VMPT only supports 2~4+1 levels\n"); >> +   } >>      /* block size depends on vm size and hw setup*/ >>      if (amdgpu_vm_block_size != -1) >>          adev->vm_manager.block_size = >> @@ -2646,7 +2674,9 @@ int amdgpu_vm_init(struct amdgpu_device *adev, >> struct amdgpu_vm *vm, >>          flags |= (AMDGPU_GEM_CREATE_NO_CPU_ACCESS | >>                  AMDGPU_GEM_CREATE_SHADOW); >>  -   r = amdgpu_bo_create(adev, amdgpu_vm_bo_size(adev, 0), align, >> true, >> +   r = amdgpu_bo_create(adev, >> +                amdgpu_vm_bo_size(adev, adev->vm_manager.root_level), >> +                align, true, >>                   AMDGPU_GEM_DOMAIN_VRAM, >>                   flags, >>                   NULL, NULL, init_pde_value, &vm->root.base.bo); >> @@ -2782,7 +2812,8 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, >> struct amdgpu_vm *vm) >>      if (r) { >>          dev_err(adev->dev, "Leaking page tables because BO >> reservation failed\n"); >>      } else { >> -       amdgpu_vm_free_levels(adev, &vm->root, 0); >> +       amdgpu_vm_free_levels(adev, &vm->root, >> +                     adev->vm_manager.root_level); >>          amdgpu_bo_unreserve(root); >>      } >>      amdgpu_bo_unref(&root); >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h >> index e52bf980669f..1056484de0e3 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h >> @@ -120,6 +120,16 @@ struct amdgpu_bo_list_entry; >>  #define AMDGPU_VM_USE_CPU_FOR_GFX (1 << 0) >>  #define AMDGPU_VM_USE_CPU_FOR_COMPUTE (1 << 1) >>  +/* VMPT level enumerate, and the hiberachy is: >> + * PDB2->PDB1->PDB0->PTB >> + */ >> +enum amdgpu_vm_level { >> +   AMDGPU_VM_PDB2, >> +   AMDGPU_VM_PDB1, >> +   AMDGPU_VM_PDB0, >> +   AMDGPU_VM_PTB >> +}; >> + >>  /* base structure for tracking BO usage in a VM */ >>  struct amdgpu_vm_bo_base { >>      /* constant after initialization */ >> @@ -236,6 +246,7 @@ struct amdgpu_vm_manager { >>      uint32_t               num_level; >>      uint32_t               block_size; >>      uint32_t               fragment_size; >> +   enum amdgpu_vm_level           root_level; >>      /* vram base address for page table entry */ >>      u64                   vram_base_offset; >>      /* vm pte handling */ >