Commit 00a11f97 authored by Arunpravin Paneer Selvam's avatar Arunpravin Paneer Selvam Committed by Alex Deucher

drm/amdgpu: Enable seq64 manager and fix bugs

- Enable the seq64 mapping sequence.
- Fix wflinfo va conflict and other bugs.

v1:
  - The seq64 area needs to be included in the AMDGPU_VA_RESERVED_SIZE
    otherwise the areas will conflict with user space allocations (Alex)

  - It needs to be mapped read only in the user VM (Alex)

v2:
  - Instead of just one define for TOP/BOTTOM
    reserved space separate them into two (Christian)

  - Fix the CPU and VA calculations and while at it
    also cleanup error handling and kerneldoc (Christian)
Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarArunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
parent 059e7c6b
...@@ -30,7 +30,7 @@ uint64_t amdgpu_csa_vaddr(struct amdgpu_device *adev) ...@@ -30,7 +30,7 @@ uint64_t amdgpu_csa_vaddr(struct amdgpu_device *adev)
{ {
uint64_t addr = adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT; uint64_t addr = adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT;
addr -= AMDGPU_VA_RESERVED_SIZE; addr -= AMDGPU_VA_RESERVED_CSA_SIZE;
addr = amdgpu_gmc_sign_extend(addr); addr = amdgpu_gmc_sign_extend(addr);
return addr; return addr;
......
...@@ -709,10 +709,10 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, ...@@ -709,10 +709,10 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
uint64_t vm_size; uint64_t vm_size;
int r = 0; int r = 0;
if (args->va_address < AMDGPU_VA_RESERVED_SIZE) { if (args->va_address < AMDGPU_VA_RESERVED_BOTTOM) {
dev_dbg(dev->dev, dev_dbg(dev->dev,
"va_address 0x%llx is in reserved area 0x%llx\n", "va_address 0x%llx is in reserved area 0x%llx\n",
args->va_address, AMDGPU_VA_RESERVED_SIZE); args->va_address, AMDGPU_VA_RESERVED_BOTTOM);
return -EINVAL; return -EINVAL;
} }
...@@ -728,7 +728,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, ...@@ -728,7 +728,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
args->va_address &= AMDGPU_GMC_HOLE_MASK; args->va_address &= AMDGPU_GMC_HOLE_MASK;
vm_size = adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE; vm_size = adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE;
vm_size -= AMDGPU_VA_RESERVED_SIZE; vm_size -= AMDGPU_VA_RESERVED_TOP;
if (args->va_address + args->map_size > vm_size) { if (args->va_address + args->map_size > vm_size) {
dev_dbg(dev->dev, dev_dbg(dev->dev,
"va_address 0x%llx is in top reserved area 0x%llx\n", "va_address 0x%llx is in top reserved area 0x%llx\n",
......
...@@ -894,14 +894,14 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) ...@@ -894,14 +894,14 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
dev_info->ids_flags |= AMDGPU_IDS_FLAGS_CONFORMANT_TRUNC_COORD; dev_info->ids_flags |= AMDGPU_IDS_FLAGS_CONFORMANT_TRUNC_COORD;
vm_size = adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE; vm_size = adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE;
vm_size -= AMDGPU_VA_RESERVED_SIZE; vm_size -= AMDGPU_VA_RESERVED_TOP;
/* Older VCE FW versions are buggy and can handle only 40bits */ /* Older VCE FW versions are buggy and can handle only 40bits */
if (adev->vce.fw_version && if (adev->vce.fw_version &&
adev->vce.fw_version < AMDGPU_VCE_FW_53_45) adev->vce.fw_version < AMDGPU_VCE_FW_53_45)
vm_size = min(vm_size, 1ULL << 40); vm_size = min(vm_size, 1ULL << 40);
dev_info->virtual_address_offset = AMDGPU_VA_RESERVED_SIZE; dev_info->virtual_address_offset = AMDGPU_VA_RESERVED_BOTTOM;
dev_info->virtual_address_max = dev_info->virtual_address_max =
min(vm_size, AMDGPU_GMC_HOLE_START); min(vm_size, AMDGPU_GMC_HOLE_START);
...@@ -1379,6 +1379,10 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) ...@@ -1379,6 +1379,10 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
goto error_vm; goto error_vm;
} }
r = amdgpu_seq64_map(adev, &fpriv->vm, &fpriv->seq64_va);
if (r)
goto error_vm;
mutex_init(&fpriv->bo_list_lock); mutex_init(&fpriv->bo_list_lock);
idr_init_base(&fpriv->bo_list_handles, 1); idr_init_base(&fpriv->bo_list_handles, 1);
......
...@@ -1398,7 +1398,7 @@ int amdgpu_mes_self_test(struct amdgpu_device *adev) ...@@ -1398,7 +1398,7 @@ int amdgpu_mes_self_test(struct amdgpu_device *adev)
goto error_fini; goto error_fini;
} }
ctx_data.meta_data_gpu_addr = AMDGPU_VA_RESERVED_SIZE; ctx_data.meta_data_gpu_addr = AMDGPU_VA_RESERVED_BOTTOM;
r = amdgpu_mes_ctx_map_meta_data(adev, vm, &ctx_data); r = amdgpu_mes_ctx_map_meta_data(adev, vm, &ctx_data);
if (r) { if (r) {
DRM_ERROR("failed to map ctx meta data\n"); DRM_ERROR("failed to map ctx meta data\n");
......
...@@ -35,14 +35,29 @@ ...@@ -35,14 +35,29 @@
* counters and VM updates. It has maximum count of 32768 64 bit slots. * counters and VM updates. It has maximum count of 32768 64 bit slots.
*/ */
/**
* amdgpu_seq64_get_va_base - Get the seq64 va base address
*
* @adev: amdgpu_device pointer
*
* Returns:
* va base address on success
*/
static inline u64 amdgpu_seq64_get_va_base(struct amdgpu_device *adev)
{
u64 addr = adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT;
addr -= AMDGPU_VA_RESERVED_TOP;
return addr;
}
/** /**
* amdgpu_seq64_map - Map the seq64 memory to VM * amdgpu_seq64_map - Map the seq64 memory to VM
* *
* @adev: amdgpu_device pointer * @adev: amdgpu_device pointer
* @vm: vm pointer * @vm: vm pointer
* @bo_va: bo_va pointer * @bo_va: bo_va pointer
* @seq64_addr: seq64 vaddr start address
* @size: seq64 pool size
* *
* Map the seq64 memory to the given VM. * Map the seq64 memory to the given VM.
* *
...@@ -50,11 +65,11 @@ ...@@ -50,11 +65,11 @@
* 0 on success or a negative error code on failure * 0 on success or a negative error code on failure
*/ */
int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm, int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct amdgpu_bo_va **bo_va, u64 seq64_addr, struct amdgpu_bo_va **bo_va)
uint32_t size)
{ {
struct amdgpu_bo *bo; struct amdgpu_bo *bo;
struct drm_exec exec; struct drm_exec exec;
u64 seq64_addr;
int r; int r;
bo = adev->seq64.sbo; bo = adev->seq64.sbo;
...@@ -77,9 +92,9 @@ int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm, ...@@ -77,9 +92,9 @@ int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm,
goto error; goto error;
} }
r = amdgpu_vm_bo_map(adev, *bo_va, seq64_addr, 0, size, seq64_addr = amdgpu_seq64_get_va_base(adev);
AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE | r = amdgpu_vm_bo_map(adev, *bo_va, seq64_addr, 0, AMDGPU_VA_RESERVED_SEQ64_SIZE,
AMDGPU_PTE_EXECUTABLE); AMDGPU_PTE_READABLE);
if (r) { if (r) {
DRM_ERROR("failed to do bo_map on userq sem, err=%d\n", r); DRM_ERROR("failed to do bo_map on userq sem, err=%d\n", r);
amdgpu_vm_bo_del(adev, *bo_va); amdgpu_vm_bo_del(adev, *bo_va);
...@@ -144,31 +159,25 @@ void amdgpu_seq64_unmap(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv) ...@@ -144,31 +159,25 @@ void amdgpu_seq64_unmap(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv)
* amdgpu_seq64_alloc - Allocate a 64 bit memory * amdgpu_seq64_alloc - Allocate a 64 bit memory
* *
* @adev: amdgpu_device pointer * @adev: amdgpu_device pointer
* @gpu_addr: allocated gpu VA start address * @va: VA to access the seq in process address space
* @cpu_addr: allocated cpu VA start address * @cpu_addr: CPU address to access the seq
* *
* Alloc a 64 bit memory from seq64 pool. * Alloc a 64 bit memory from seq64 pool.
* *
* Returns: * Returns:
* 0 on success or a negative error code on failure * 0 on success or a negative error code on failure
*/ */
int amdgpu_seq64_alloc(struct amdgpu_device *adev, u64 *gpu_addr, int amdgpu_seq64_alloc(struct amdgpu_device *adev, u64 *va, u64 **cpu_addr)
u64 **cpu_addr)
{ {
unsigned long bit_pos; unsigned long bit_pos;
u32 offset;
bit_pos = find_first_zero_bit(adev->seq64.used, adev->seq64.num_sem); bit_pos = find_first_zero_bit(adev->seq64.used, adev->seq64.num_sem);
if (bit_pos >= adev->seq64.num_sem)
return -ENOSPC;
if (bit_pos < adev->seq64.num_sem) { __set_bit(bit_pos, adev->seq64.used);
__set_bit(bit_pos, adev->seq64.used); *va = bit_pos * sizeof(u64) + amdgpu_seq64_get_va_base(adev);
offset = bit_pos << 6; /* convert to qw offset */ *cpu_addr = bit_pos + adev->seq64.cpu_base_addr;
} else {
return -EINVAL;
}
*gpu_addr = offset + AMDGPU_SEQ64_VADDR_START;
*cpu_addr = offset + adev->seq64.cpu_base_addr;
return 0; return 0;
} }
...@@ -177,20 +186,17 @@ int amdgpu_seq64_alloc(struct amdgpu_device *adev, u64 *gpu_addr, ...@@ -177,20 +186,17 @@ int amdgpu_seq64_alloc(struct amdgpu_device *adev, u64 *gpu_addr,
* amdgpu_seq64_free - Free the given 64 bit memory * amdgpu_seq64_free - Free the given 64 bit memory
* *
* @adev: amdgpu_device pointer * @adev: amdgpu_device pointer
* @gpu_addr: gpu start address to be freed * @va: gpu start address to be freed
* *
* Free the given 64 bit memory from seq64 pool. * Free the given 64 bit memory from seq64 pool.
*
*/ */
void amdgpu_seq64_free(struct amdgpu_device *adev, u64 gpu_addr) void amdgpu_seq64_free(struct amdgpu_device *adev, u64 va)
{ {
u32 offset; unsigned long bit_pos;
offset = gpu_addr - AMDGPU_SEQ64_VADDR_START;
offset >>= 6; bit_pos = (va - amdgpu_seq64_get_va_base(adev)) / sizeof(u64);
if (offset < adev->seq64.num_sem) if (bit_pos < adev->seq64.num_sem)
__clear_bit(offset, adev->seq64.used); __clear_bit(bit_pos, adev->seq64.used);
} }
/** /**
...@@ -229,7 +235,7 @@ int amdgpu_seq64_init(struct amdgpu_device *adev) ...@@ -229,7 +235,7 @@ int amdgpu_seq64_init(struct amdgpu_device *adev)
* AMDGPU_MAX_SEQ64_SLOTS * sizeof(u64) * 8 = AMDGPU_MAX_SEQ64_SLOTS * AMDGPU_MAX_SEQ64_SLOTS * sizeof(u64) * 8 = AMDGPU_MAX_SEQ64_SLOTS
* 64bit slots * 64bit slots
*/ */
r = amdgpu_bo_create_kernel(adev, AMDGPU_SEQ64_SIZE, r = amdgpu_bo_create_kernel(adev, AMDGPU_VA_RESERVED_SEQ64_SIZE,
PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT, PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
&adev->seq64.sbo, NULL, &adev->seq64.sbo, NULL,
(void **)&adev->seq64.cpu_base_addr); (void **)&adev->seq64.cpu_base_addr);
...@@ -238,7 +244,7 @@ int amdgpu_seq64_init(struct amdgpu_device *adev) ...@@ -238,7 +244,7 @@ int amdgpu_seq64_init(struct amdgpu_device *adev)
return r; return r;
} }
memset(adev->seq64.cpu_base_addr, 0, AMDGPU_SEQ64_SIZE); memset(adev->seq64.cpu_base_addr, 0, AMDGPU_VA_RESERVED_SEQ64_SIZE);
adev->seq64.num_sem = AMDGPU_MAX_SEQ64_SLOTS; adev->seq64.num_sem = AMDGPU_MAX_SEQ64_SLOTS;
memset(&adev->seq64.used, 0, sizeof(adev->seq64.used)); memset(&adev->seq64.used, 0, sizeof(adev->seq64.used));
......
...@@ -25,10 +25,9 @@ ...@@ -25,10 +25,9 @@
#ifndef __AMDGPU_SEQ64_H__ #ifndef __AMDGPU_SEQ64_H__
#define __AMDGPU_SEQ64_H__ #define __AMDGPU_SEQ64_H__
#define AMDGPU_SEQ64_SIZE (2ULL << 20) #include "amdgpu_vm.h"
#define AMDGPU_MAX_SEQ64_SLOTS (AMDGPU_SEQ64_SIZE / (sizeof(u64) * 8))
#define AMDGPU_SEQ64_VADDR_OFFSET 0x50000 #define AMDGPU_MAX_SEQ64_SLOTS (AMDGPU_VA_RESERVED_SEQ64_SIZE / sizeof(u64))
#define AMDGPU_SEQ64_VADDR_START (AMDGPU_VA_RESERVED_SIZE + AMDGPU_SEQ64_VADDR_OFFSET)
struct amdgpu_seq64 { struct amdgpu_seq64 {
struct amdgpu_bo *sbo; struct amdgpu_bo *sbo;
...@@ -42,7 +41,7 @@ int amdgpu_seq64_init(struct amdgpu_device *adev); ...@@ -42,7 +41,7 @@ int amdgpu_seq64_init(struct amdgpu_device *adev);
int amdgpu_seq64_alloc(struct amdgpu_device *adev, u64 *gpu_addr, u64 **cpu_addr); int amdgpu_seq64_alloc(struct amdgpu_device *adev, u64 *gpu_addr, u64 **cpu_addr);
void amdgpu_seq64_free(struct amdgpu_device *adev, u64 gpu_addr); void amdgpu_seq64_free(struct amdgpu_device *adev, u64 gpu_addr);
int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm, int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct amdgpu_bo_va **bo_va, u64 seq64_addr, uint32_t size); struct amdgpu_bo_va **bo_va);
void amdgpu_seq64_unmap(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv); void amdgpu_seq64_unmap(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv);
#endif #endif
......
...@@ -358,7 +358,7 @@ static int setup_umsch_mm_test(struct amdgpu_device *adev, ...@@ -358,7 +358,7 @@ static int setup_umsch_mm_test(struct amdgpu_device *adev,
memset(test->ring_data_cpu_addr, 0, sizeof(struct umsch_mm_test_ring_data)); memset(test->ring_data_cpu_addr, 0, sizeof(struct umsch_mm_test_ring_data));
test->ring_data_gpu_addr = AMDGPU_VA_RESERVED_SIZE; test->ring_data_gpu_addr = AMDGPU_VA_RESERVED_BOTTOM;
r = map_ring_data(adev, test->vm, test->ring_data_obj, &test->bo_va, r = map_ring_data(adev, test->vm, test->ring_data_obj, &test->bo_va,
test->ring_data_gpu_addr, sizeof(struct umsch_mm_test_ring_data)); test->ring_data_gpu_addr, sizeof(struct umsch_mm_test_ring_data));
if (r) if (r)
......
...@@ -136,7 +136,11 @@ struct amdgpu_mem_stats; ...@@ -136,7 +136,11 @@ struct amdgpu_mem_stats;
#define AMDGPU_IS_MMHUB1(x) ((x) >= AMDGPU_MMHUB1_START && (x) < AMDGPU_MAX_VMHUBS) #define AMDGPU_IS_MMHUB1(x) ((x) >= AMDGPU_MMHUB1_START && (x) < AMDGPU_MAX_VMHUBS)
/* Reserve 2MB at top/bottom of address space for kernel use */ /* Reserve 2MB at top/bottom of address space for kernel use */
#define AMDGPU_VA_RESERVED_SIZE (2ULL << 20) #define AMDGPU_VA_RESERVED_CSA_SIZE (2ULL << 20)
#define AMDGPU_VA_RESERVED_SEQ64_SIZE (2ULL << 20)
#define AMDGPU_VA_RESERVED_BOTTOM (2ULL << 20)
#define AMDGPU_VA_RESERVED_TOP (AMDGPU_VA_RESERVED_SEQ64_SIZE + \
AMDGPU_VA_RESERVED_CSA_SIZE)
/* See vm_update_mode */ /* See vm_update_mode */
#define AMDGPU_VM_USE_CPU_FOR_GFX (1 << 0) #define AMDGPU_VM_USE_CPU_FOR_GFX (1 << 0)
......
...@@ -435,9 +435,10 @@ static void gmc_v6_0_set_prt(struct amdgpu_device *adev, bool enable) ...@@ -435,9 +435,10 @@ static void gmc_v6_0_set_prt(struct amdgpu_device *adev, bool enable)
WREG32(mmVM_PRT_CNTL, tmp); WREG32(mmVM_PRT_CNTL, tmp);
if (enable) { if (enable) {
uint32_t low = AMDGPU_VA_RESERVED_SIZE >> AMDGPU_GPU_PAGE_SHIFT; uint32_t low = AMDGPU_VA_RESERVED_BOTTOM >>
AMDGPU_GPU_PAGE_SHIFT;
uint32_t high = adev->vm_manager.max_pfn - uint32_t high = adev->vm_manager.max_pfn -
(AMDGPU_VA_RESERVED_SIZE >> AMDGPU_GPU_PAGE_SHIFT); (AMDGPU_VA_RESERVED_TOP >> AMDGPU_GPU_PAGE_SHIFT);
WREG32(mmVM_PRT_APERTURE0_LOW_ADDR, low); WREG32(mmVM_PRT_APERTURE0_LOW_ADDR, low);
WREG32(mmVM_PRT_APERTURE1_LOW_ADDR, low); WREG32(mmVM_PRT_APERTURE1_LOW_ADDR, low);
......
...@@ -563,9 +563,10 @@ static void gmc_v7_0_set_prt(struct amdgpu_device *adev, bool enable) ...@@ -563,9 +563,10 @@ static void gmc_v7_0_set_prt(struct amdgpu_device *adev, bool enable)
WREG32(mmVM_PRT_CNTL, tmp); WREG32(mmVM_PRT_CNTL, tmp);
if (enable) { if (enable) {
uint32_t low = AMDGPU_VA_RESERVED_SIZE >> AMDGPU_GPU_PAGE_SHIFT; uint32_t low = AMDGPU_VA_RESERVED_BOTTOM >>
AMDGPU_GPU_PAGE_SHIFT;
uint32_t high = adev->vm_manager.max_pfn - uint32_t high = adev->vm_manager.max_pfn -
(AMDGPU_VA_RESERVED_SIZE >> AMDGPU_GPU_PAGE_SHIFT); (AMDGPU_VA_RESERVED_TOP >> AMDGPU_GPU_PAGE_SHIFT);
WREG32(mmVM_PRT_APERTURE0_LOW_ADDR, low); WREG32(mmVM_PRT_APERTURE0_LOW_ADDR, low);
WREG32(mmVM_PRT_APERTURE1_LOW_ADDR, low); WREG32(mmVM_PRT_APERTURE1_LOW_ADDR, low);
......
...@@ -777,9 +777,10 @@ static void gmc_v8_0_set_prt(struct amdgpu_device *adev, bool enable) ...@@ -777,9 +777,10 @@ static void gmc_v8_0_set_prt(struct amdgpu_device *adev, bool enable)
WREG32(mmVM_PRT_CNTL, tmp); WREG32(mmVM_PRT_CNTL, tmp);
if (enable) { if (enable) {
uint32_t low = AMDGPU_VA_RESERVED_SIZE >> AMDGPU_GPU_PAGE_SHIFT; uint32_t low = AMDGPU_VA_RESERVED_BOTTOM >>
AMDGPU_GPU_PAGE_SHIFT;
uint32_t high = adev->vm_manager.max_pfn - uint32_t high = adev->vm_manager.max_pfn -
(AMDGPU_VA_RESERVED_SIZE >> AMDGPU_GPU_PAGE_SHIFT); (AMDGPU_VA_RESERVED_TOP >> AMDGPU_GPU_PAGE_SHIFT);
WREG32(mmVM_PRT_APERTURE0_LOW_ADDR, low); WREG32(mmVM_PRT_APERTURE0_LOW_ADDR, low);
WREG32(mmVM_PRT_APERTURE1_LOW_ADDR, low); WREG32(mmVM_PRT_APERTURE1_LOW_ADDR, low);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment