diff options
author | Monk Liu <Monk.Liu@amd.com> | 2017-09-15 02:35:09 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-09-26 15:14:13 -0400 |
commit | d59c026b7be1dd9ae00b54d1916a90775fe3bdda (patch) | |
tree | 20d3703306567c9bdf7685bb80868038b3491b30 /drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | |
parent | eb01abc7c4fd1faa26d0787f410894d9c704eb60 (diff) |
drm/amdgpu/sriov:fix memory leak after gpu reset
GPU reset will require all hw doing hw_init thus
ucode_init_bo will be invoked again, which lead to
memory leak
skip the fw_buf allocation during sriov gpu reset to avoid
memory leak.
Signed-off-by: Monk Liu <Monk.Liu@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 64 |
1 files changed, 32 insertions, 32 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index f306374ff654..65649026b836 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | |||
@@ -360,8 +360,6 @@ static int amdgpu_ucode_patch_jt(struct amdgpu_firmware_info *ucode, | |||
360 | int amdgpu_ucode_init_bo(struct amdgpu_device *adev) | 360 | int amdgpu_ucode_init_bo(struct amdgpu_device *adev) |
361 | { | 361 | { |
362 | struct amdgpu_bo **bo = &adev->firmware.fw_buf; | 362 | struct amdgpu_bo **bo = &adev->firmware.fw_buf; |
363 | uint64_t fw_mc_addr; | ||
364 | void *fw_buf_ptr = NULL; | ||
365 | uint64_t fw_offset = 0; | 363 | uint64_t fw_offset = 0; |
366 | int i, err; | 364 | int i, err; |
367 | struct amdgpu_firmware_info *ucode = NULL; | 365 | struct amdgpu_firmware_info *ucode = NULL; |
@@ -372,37 +370,39 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev) | |||
372 | return 0; | 370 | return 0; |
373 | } | 371 | } |
374 | 372 | ||
375 | err = amdgpu_bo_create(adev, adev->firmware.fw_size, PAGE_SIZE, true, | 373 | if (!amdgpu_sriov_vf(adev) || !adev->in_sriov_reset) { |
376 | amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT, | 374 | err = amdgpu_bo_create(adev, adev->firmware.fw_size, PAGE_SIZE, true, |
377 | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, | 375 | amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT, |
378 | NULL, NULL, 0, bo); | 376 | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, |
379 | if (err) { | 377 | NULL, NULL, 0, bo); |
380 | dev_err(adev->dev, "(%d) Firmware buffer allocate failed\n", err); | 378 | if (err) { |
381 | goto failed; | 379 | dev_err(adev->dev, "(%d) Firmware buffer allocate failed\n", err); |
382 | } | 380 | goto failed; |
381 | } | ||
383 | 382 | ||
384 | err = amdgpu_bo_reserve(*bo, false); | 383 | err = amdgpu_bo_reserve(*bo, false); |
385 | if (err) { | 384 | if (err) { |
386 | dev_err(adev->dev, "(%d) Firmware buffer reserve failed\n", err); | 385 | dev_err(adev->dev, "(%d) Firmware buffer reserve failed\n", err); |
387 | goto failed_reserve; | 386 | goto failed_reserve; |
388 | } | 387 | } |
389 | 388 | ||
390 | err = amdgpu_bo_pin(*bo, amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT, | 389 | err = amdgpu_bo_pin(*bo, amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT, |
391 | &fw_mc_addr); | 390 | &adev->firmware.fw_buf_mc); |
392 | if (err) { | 391 | if (err) { |
393 | dev_err(adev->dev, "(%d) Firmware buffer pin failed\n", err); | 392 | dev_err(adev->dev, "(%d) Firmware buffer pin failed\n", err); |
394 | goto failed_pin; | 393 | goto failed_pin; |
395 | } | 394 | } |
396 | 395 | ||
397 | err = amdgpu_bo_kmap(*bo, &fw_buf_ptr); | 396 | err = amdgpu_bo_kmap(*bo, &adev->firmware.fw_buf_ptr); |
398 | if (err) { | 397 | if (err) { |
399 | dev_err(adev->dev, "(%d) Firmware buffer kmap failed\n", err); | 398 | dev_err(adev->dev, "(%d) Firmware buffer kmap failed\n", err); |
400 | goto failed_kmap; | 399 | goto failed_kmap; |
401 | } | 400 | } |
402 | 401 | ||
403 | amdgpu_bo_unreserve(*bo); | 402 | amdgpu_bo_unreserve(*bo); |
403 | } | ||
404 | 404 | ||
405 | memset(fw_buf_ptr, 0, adev->firmware.fw_size); | 405 | memset(adev->firmware.fw_buf_ptr, 0, adev->firmware.fw_size); |
406 | 406 | ||
407 | /* | 407 | /* |
408 | * if SMU loaded firmware, it needn't add SMC, UVD, and VCE | 408 | * if SMU loaded firmware, it needn't add SMC, UVD, and VCE |
@@ -421,14 +421,14 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev) | |||
421 | ucode = &adev->firmware.ucode[i]; | 421 | ucode = &adev->firmware.ucode[i]; |
422 | if (ucode->fw) { | 422 | if (ucode->fw) { |
423 | header = (const struct common_firmware_header *)ucode->fw->data; | 423 | header = (const struct common_firmware_header *)ucode->fw->data; |
424 | amdgpu_ucode_init_single_fw(adev, ucode, fw_mc_addr + fw_offset, | 424 | amdgpu_ucode_init_single_fw(adev, ucode, adev->firmware.fw_buf_mc + fw_offset, |
425 | (void *)((uint8_t *)fw_buf_ptr + fw_offset)); | 425 | adev->firmware.fw_buf_ptr + fw_offset); |
426 | if (i == AMDGPU_UCODE_ID_CP_MEC1 && | 426 | if (i == AMDGPU_UCODE_ID_CP_MEC1 && |
427 | adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { | 427 | adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { |
428 | const struct gfx_firmware_header_v1_0 *cp_hdr; | 428 | const struct gfx_firmware_header_v1_0 *cp_hdr; |
429 | cp_hdr = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; | 429 | cp_hdr = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data; |
430 | amdgpu_ucode_patch_jt(ucode, fw_mc_addr + fw_offset, | 430 | amdgpu_ucode_patch_jt(ucode, adev->firmware.fw_buf_mc + fw_offset, |
431 | fw_buf_ptr + fw_offset); | 431 | adev->firmware.fw_buf_ptr + fw_offset); |
432 | fw_offset += ALIGN(le32_to_cpu(cp_hdr->jt_size) << 2, PAGE_SIZE); | 432 | fw_offset += ALIGN(le32_to_cpu(cp_hdr->jt_size) << 2, PAGE_SIZE); |
433 | } | 433 | } |
434 | fw_offset += ALIGN(ucode->ucode_size, PAGE_SIZE); | 434 | fw_offset += ALIGN(ucode->ucode_size, PAGE_SIZE); |