aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshaoyunl <Shaoyun.Liu@amd.com>2018-07-11 22:32:49 -0400
committerOded Gabbay <oded.gabbay@gmail.com>2018-07-11 22:32:49 -0400
commitb97dfa27ef3ad3eddd2cb97a3b6a140d7037827a (patch)
treea8df9ac8dfc2d082435a6252792f01760412ebb5
parent101fee63cbb0a3df9e54aaafbfad0ab5821a34e6 (diff)
drm/amdgpu: save vm fault information for amdkfd
amdgpu save the vm fault related information for KFD usage and keep the copy until KFD read it. Signed-off-by: shaoyun liu <shaoyun.liu@amd.com> Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com> Acked-by: Christian König <christian.koenig@amd.com> Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c14
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c33
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c33
-rw-r--r--drivers/gpu/drm/amd/include/kgd_kfd_interface.h20
8 files changed, 105 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
index a8418a3f4e9d..3dc76d9b4d12 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -183,6 +183,9 @@ int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_dev *kgd,
183int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info, 183int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info,
184 struct dma_fence **ef); 184 struct dma_fence **ef);
185 185
186int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd,
187 struct kfd_vm_fault_info *info);
188
186void amdgpu_amdkfd_gpuvm_init_mem_limits(void); 189void amdgpu_amdkfd_gpuvm_init_mem_limits(void);
187void amdgpu_amdkfd_unreserve_system_memory_limit(struct amdgpu_bo *bo); 190void amdgpu_amdkfd_unreserve_system_memory_limit(struct amdgpu_bo *bo);
188 191
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
index ea79908dac4c..befc7c48b1cf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
@@ -216,6 +216,7 @@ static const struct kfd2kgd_calls kfd2kgd = {
216 .invalidate_tlbs = invalidate_tlbs, 216 .invalidate_tlbs = invalidate_tlbs,
217 .invalidate_tlbs_vmid = invalidate_tlbs_vmid, 217 .invalidate_tlbs_vmid = invalidate_tlbs_vmid,
218 .submit_ib = amdgpu_amdkfd_submit_ib, 218 .submit_ib = amdgpu_amdkfd_submit_ib,
219 .get_vm_fault_info = amdgpu_amdkfd_gpuvm_get_vm_fault_info
219}; 220};
220 221
221struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void) 222struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
index 19dd665e7307..c68ef85f7753 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
@@ -176,6 +176,7 @@ static const struct kfd2kgd_calls kfd2kgd = {
176 .invalidate_tlbs = invalidate_tlbs, 176 .invalidate_tlbs = invalidate_tlbs,
177 .invalidate_tlbs_vmid = invalidate_tlbs_vmid, 177 .invalidate_tlbs_vmid = invalidate_tlbs_vmid,
178 .submit_ib = amdgpu_amdkfd_submit_ib, 178 .submit_ib = amdgpu_amdkfd_submit_ib,
179 .get_vm_fault_info = amdgpu_amdkfd_gpuvm_get_vm_fault_info
179}; 180};
180 181
181struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void) 182struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index fa38a960ce00..8a707d8bbb1c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -1621,6 +1621,20 @@ bo_reserve_failed:
1621 return ret; 1621 return ret;
1622} 1622}
1623 1623
1624int amdgpu_amdkfd_gpuvm_get_vm_fault_info(struct kgd_dev *kgd,
1625 struct kfd_vm_fault_info *mem)
1626{
1627 struct amdgpu_device *adev;
1628
1629 adev = (struct amdgpu_device *)kgd;
1630 if (atomic_read(&adev->gmc.vm_fault_info_updated) == 1) {
1631 *mem = *adev->gmc.vm_fault_info;
1632 mb();
1633 atomic_set(&adev->gmc.vm_fault_info_updated, 0);
1634 }
1635 return 0;
1636}
1637
1624/* Evict a userptr BO by stopping the queues if necessary 1638/* Evict a userptr BO by stopping the queues if necessary
1625 * 1639 *
1626 * Runs in MMU notifier, may be in RECLAIM_FS context. This means it 1640 * Runs in MMU notifier, may be in RECLAIM_FS context. This means it
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
index 6cb4948233cb..bb5a47a45790 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
@@ -105,6 +105,8 @@ struct amdgpu_gmc {
105 /* protects concurrent invalidation */ 105 /* protects concurrent invalidation */
106 spinlock_t invalidate_lock; 106 spinlock_t invalidate_lock;
107 bool translate_further; 107 bool translate_further;
108 struct kfd_vm_fault_info *vm_fault_info;
109 atomic_t vm_fault_info_updated;
108 110
109 const struct amdgpu_gmc_funcs *gmc_funcs; 111 const struct amdgpu_gmc_funcs *gmc_funcs;
110}; 112};
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
index 10920f0bd85f..36dc367c4b45 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
@@ -28,6 +28,7 @@
28#include "cik.h" 28#include "cik.h"
29#include "gmc_v7_0.h" 29#include "gmc_v7_0.h"
30#include "amdgpu_ucode.h" 30#include "amdgpu_ucode.h"
31#include "amdgpu_amdkfd.h"
31 32
32#include "bif/bif_4_1_d.h" 33#include "bif/bif_4_1_d.h"
33#include "bif/bif_4_1_sh_mask.h" 34#include "bif/bif_4_1_sh_mask.h"
@@ -1078,6 +1079,12 @@ static int gmc_v7_0_sw_init(void *handle)
1078 adev->vm_manager.vram_base_offset = 0; 1079 adev->vm_manager.vram_base_offset = 0;
1079 } 1080 }
1080 1081
1082 adev->gmc.vm_fault_info = kmalloc(sizeof(struct kfd_vm_fault_info),
1083 GFP_KERNEL);
1084 if (!adev->gmc.vm_fault_info)
1085 return -ENOMEM;
1086 atomic_set(&adev->gmc.vm_fault_info_updated, 0);
1087
1081 return 0; 1088 return 0;
1082} 1089}
1083 1090
@@ -1087,6 +1094,7 @@ static int gmc_v7_0_sw_fini(void *handle)
1087 1094
1088 amdgpu_gem_force_release(adev); 1095 amdgpu_gem_force_release(adev);
1089 amdgpu_vm_manager_fini(adev); 1096 amdgpu_vm_manager_fini(adev);
1097 kfree(adev->gmc.vm_fault_info);
1090 gmc_v7_0_gart_fini(adev); 1098 gmc_v7_0_gart_fini(adev);
1091 amdgpu_bo_fini(adev); 1099 amdgpu_bo_fini(adev);
1092 release_firmware(adev->gmc.fw); 1100 release_firmware(adev->gmc.fw);
@@ -1276,7 +1284,7 @@ static int gmc_v7_0_process_interrupt(struct amdgpu_device *adev,
1276 struct amdgpu_irq_src *source, 1284 struct amdgpu_irq_src *source,
1277 struct amdgpu_iv_entry *entry) 1285 struct amdgpu_iv_entry *entry)
1278{ 1286{
1279 u32 addr, status, mc_client; 1287 u32 addr, status, mc_client, vmid;
1280 1288
1281 addr = RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_ADDR); 1289 addr = RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_ADDR);
1282 status = RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_STATUS); 1290 status = RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_STATUS);
@@ -1301,6 +1309,29 @@ static int gmc_v7_0_process_interrupt(struct amdgpu_device *adev,
1301 entry->pasid); 1309 entry->pasid);
1302 } 1310 }
1303 1311
1312 vmid = REG_GET_FIELD(status, VM_CONTEXT1_PROTECTION_FAULT_STATUS,
1313 VMID);
1314 if (amdgpu_amdkfd_is_kfd_vmid(adev, vmid)
1315 && !atomic_read(&adev->gmc.vm_fault_info_updated)) {
1316 struct kfd_vm_fault_info *info = adev->gmc.vm_fault_info;
1317 u32 protections = REG_GET_FIELD(status,
1318 VM_CONTEXT1_PROTECTION_FAULT_STATUS,
1319 PROTECTIONS);
1320
1321 info->vmid = vmid;
1322 info->mc_id = REG_GET_FIELD(status,
1323 VM_CONTEXT1_PROTECTION_FAULT_STATUS,
1324 MEMORY_CLIENT_ID);
1325 info->status = status;
1326 info->page_addr = addr;
1327 info->prot_valid = protections & 0x7 ? true : false;
1328 info->prot_read = protections & 0x8 ? true : false;
1329 info->prot_write = protections & 0x10 ? true : false;
1330 info->prot_exec = protections & 0x20 ? true : false;
1331 mb();
1332 atomic_set(&adev->gmc.vm_fault_info_updated, 1);
1333 }
1334
1304 return 0; 1335 return 0;
1305} 1336}
1306 1337
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
index 75f3ffb2891e..70fc97b59b4f 100644
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
@@ -26,6 +26,7 @@
26#include "amdgpu.h" 26#include "amdgpu.h"
27#include "gmc_v8_0.h" 27#include "gmc_v8_0.h"
28#include "amdgpu_ucode.h" 28#include "amdgpu_ucode.h"
29#include "amdgpu_amdkfd.h"
29 30
30#include "gmc/gmc_8_1_d.h" 31#include "gmc/gmc_8_1_d.h"
31#include "gmc/gmc_8_1_sh_mask.h" 32#include "gmc/gmc_8_1_sh_mask.h"
@@ -1182,6 +1183,12 @@ static int gmc_v8_0_sw_init(void *handle)
1182 adev->vm_manager.vram_base_offset = 0; 1183 adev->vm_manager.vram_base_offset = 0;
1183 } 1184 }
1184 1185
1186 adev->gmc.vm_fault_info = kmalloc(sizeof(struct kfd_vm_fault_info),
1187 GFP_KERNEL);
1188 if (!adev->gmc.vm_fault_info)
1189 return -ENOMEM;
1190 atomic_set(&adev->gmc.vm_fault_info_updated, 0);
1191
1185 return 0; 1192 return 0;
1186} 1193}
1187 1194
@@ -1191,6 +1198,7 @@ static int gmc_v8_0_sw_fini(void *handle)
1191 1198
1192 amdgpu_gem_force_release(adev); 1199 amdgpu_gem_force_release(adev);
1193 amdgpu_vm_manager_fini(adev); 1200 amdgpu_vm_manager_fini(adev);
1201 kfree(adev->gmc.vm_fault_info);
1194 gmc_v8_0_gart_fini(adev); 1202 gmc_v8_0_gart_fini(adev);
1195 amdgpu_bo_fini(adev); 1203 amdgpu_bo_fini(adev);
1196 release_firmware(adev->gmc.fw); 1204 release_firmware(adev->gmc.fw);
@@ -1426,7 +1434,7 @@ static int gmc_v8_0_process_interrupt(struct amdgpu_device *adev,
1426 struct amdgpu_irq_src *source, 1434 struct amdgpu_irq_src *source,
1427 struct amdgpu_iv_entry *entry) 1435 struct amdgpu_iv_entry *entry)
1428{ 1436{
1429 u32 addr, status, mc_client; 1437 u32 addr, status, mc_client, vmid;
1430 1438
1431 if (amdgpu_sriov_vf(adev)) { 1439 if (amdgpu_sriov_vf(adev)) {
1432 dev_err(adev->dev, "GPU fault detected: %d 0x%08x\n", 1440 dev_err(adev->dev, "GPU fault detected: %d 0x%08x\n",
@@ -1463,6 +1471,29 @@ static int gmc_v8_0_process_interrupt(struct amdgpu_device *adev,
1463 entry->pasid); 1471 entry->pasid);
1464 } 1472 }
1465 1473
1474 vmid = REG_GET_FIELD(status, VM_CONTEXT1_PROTECTION_FAULT_STATUS,
1475 VMID);
1476 if (amdgpu_amdkfd_is_kfd_vmid(adev, vmid)
1477 && !atomic_read(&adev->gmc.vm_fault_info_updated)) {
1478 struct kfd_vm_fault_info *info = adev->gmc.vm_fault_info;
1479 u32 protections = REG_GET_FIELD(status,
1480 VM_CONTEXT1_PROTECTION_FAULT_STATUS,
1481 PROTECTIONS);
1482
1483 info->vmid = vmid;
1484 info->mc_id = REG_GET_FIELD(status,
1485 VM_CONTEXT1_PROTECTION_FAULT_STATUS,
1486 MEMORY_CLIENT_ID);
1487 info->status = status;
1488 info->page_addr = addr;
1489 info->prot_valid = protections & 0x7 ? true : false;
1490 info->prot_read = protections & 0x8 ? true : false;
1491 info->prot_write = protections & 0x10 ? true : false;
1492 info->prot_exec = protections & 0x20 ? true : false;
1493 mb();
1494 atomic_set(&adev->gmc.vm_fault_info_updated, 1);
1495 }
1496
1466 return 0; 1497 return 0;
1467} 1498}
1468 1499
diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
index 5733fbee07f7..28b11d105288 100644
--- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
@@ -47,6 +47,17 @@ enum kfd_preempt_type {
47 KFD_PREEMPT_TYPE_WAVEFRONT_RESET, 47 KFD_PREEMPT_TYPE_WAVEFRONT_RESET,
48}; 48};
49 49
50struct kfd_vm_fault_info {
51 uint64_t page_addr;
52 uint32_t vmid;
53 uint32_t mc_id;
54 uint32_t status;
55 bool prot_valid;
56 bool prot_read;
57 bool prot_write;
58 bool prot_exec;
59};
60
50struct kfd_cu_info { 61struct kfd_cu_info {
51 uint32_t num_shader_engines; 62 uint32_t num_shader_engines;
52 uint32_t num_shader_arrays_per_engine; 63 uint32_t num_shader_arrays_per_engine;
@@ -259,6 +270,12 @@ struct tile_config {
259 * IB to the corresponding ring (ring type). The IB is executed with the 270 * IB to the corresponding ring (ring type). The IB is executed with the
260 * specified VMID in a user mode context. 271 * specified VMID in a user mode context.
261 * 272 *
273 * @get_vm_fault_info: Return information about a recent VM fault on
274 * GFXv7 and v8. If multiple VM faults occurred since the last call of
275 * this function, it will return information about the first of those
276 * faults. On GFXv9 VM fault information is fully contained in the IH
277 * packet and this function is not needed.
278 *
262 * This structure contains function pointers to services that the kgd driver 279 * This structure contains function pointers to services that the kgd driver
263 * provides to amdkfd driver. 280 * provides to amdkfd driver.
264 * 281 *
@@ -374,6 +391,9 @@ struct kfd2kgd_calls {
374 int (*submit_ib)(struct kgd_dev *kgd, enum kgd_engine_type engine, 391 int (*submit_ib)(struct kgd_dev *kgd, enum kgd_engine_type engine,
375 uint32_t vmid, uint64_t gpu_addr, 392 uint32_t vmid, uint64_t gpu_addr,
376 uint32_t *ib_cmd, uint32_t ib_len); 393 uint32_t *ib_cmd, uint32_t ib_len);
394
395 int (*get_vm_fault_info)(struct kgd_dev *kgd,
396 struct kfd_vm_fault_info *info);
377}; 397};
378 398
379/** 399/**