Skip to content

Commit

Permalink
Merge tag 'drm-fixes-for-v4.7-rc3' of git://people.freedesktop.org/~a…
Browse files Browse the repository at this point in the history
…irlied/linux

Pull drm fixes from Dave Airlie:
 "This weeks instalment of fixes:

  amdgpu:
     Lots of memory leak and firmware leak fixes

  nouveau:
     Collection of display fixes, KASAN fixes

  vc4:
     vblank/pageflipping fixes

  fsl-dcu:
     Regmap cache fix

  omap:
     Unused variable warning fix.

  Nothing too surprising so far"

* tag 'drm-fixes-for-v4.7-rc3' of git://people.freedesktop.org/~airlied/linux: (46 commits)
  drm/amdgpu: fix warning with powerplay disabled.
  drm/amd/powerplay: delete useless code as pptable changed in vbios.
  drm/amd/powerplay: fix bug visit array out of bounds
  drm/amdgpu: fix smu ucode memleak (v2)
  drm/amdgpu: add release firmware for cgs
  drm/amdgpu: fix tonga smu_fini mem leak
  drm/amdgpu: fix fiji smu fini mem leak
  drm/amdgpu: fix cik sdma ucode memleak
  drm/amdgpu: fix sdma24 ucode mem leak
  drm/amdgpu: fix sdma3 ucode mem leak
  drm/amdgpu: fix uvd fini mem leak
  drm/amdgpu: fix gfx 7 ucode mem leak
  drm/amdgpu: fix gfx8 ucode mem leak
  drm/amdgpu: fix missing free wb for cond_exec
  drm/amdgpu: fix memleak in pptable_init
  drm/amdgpu: fix mem leak in atombios
  drm/amdgpu: fix mem leak in pplib/hwmgr
  drm/amdgpu: fix mem leak in smumgr
  drm/amdgpu: add pipeline sync while vmid switch in same ctx
  drm/amdgpu: vBIOS post only call when mem_size zero
  ...
  • Loading branch information
Linus Torvalds committed Jun 10, 2016
2 parents f758bbd + 7ff6977 commit 00da900
Show file tree
Hide file tree
Showing 62 changed files with 439 additions and 185 deletions.
4 changes: 3 additions & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,7 @@ struct amdgpu_ring {
unsigned cond_exe_offs;
u64 cond_exe_gpu_addr;
volatile u32 *cond_exe_cpu_addr;
int vmid;
};

/*
Expand Down Expand Up @@ -936,7 +937,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring,
unsigned vm_id, uint64_t pd_addr,
uint32_t gds_base, uint32_t gds_size,
uint32_t gws_base, uint32_t gws_size,
uint32_t oa_base, uint32_t oa_size);
uint32_t oa_base, uint32_t oa_size,
bool vmid_switch);
void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id);
uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr);
int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
Expand Down
12 changes: 12 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,17 @@ static uint32_t fw_type_convert(struct cgs_device *cgs_device, uint32_t fw_type)
return result;
}

static int amdgpu_cgs_rel_firmware(struct cgs_device *cgs_device, enum cgs_ucode_id type)
{
CGS_FUNC_ADEV;
if ((CGS_UCODE_ID_SMU == type) || (CGS_UCODE_ID_SMU_SK == type)) {
release_firmware(adev->pm.fw);
return 0;
}
/* cannot release other firmware because they are not created by cgs */
return -EINVAL;
}

static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
enum cgs_ucode_id type,
struct cgs_firmware_info *info)
Expand Down Expand Up @@ -1125,6 +1136,7 @@ static const struct cgs_ops amdgpu_cgs_ops = {
amdgpu_cgs_pm_query_clock_limits,
amdgpu_cgs_set_camera_voltages,
amdgpu_cgs_get_firmware_info,
amdgpu_cgs_rel_firmware,
amdgpu_cgs_set_powergating_state,
amdgpu_cgs_set_clockgating_state,
amdgpu_cgs_get_active_displays_info,
Expand Down
12 changes: 9 additions & 3 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,8 +827,10 @@ static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg)
*/
static void amdgpu_atombios_fini(struct amdgpu_device *adev)
{
if (adev->mode_info.atom_context)
if (adev->mode_info.atom_context) {
kfree(adev->mode_info.atom_context->scratch);
kfree(adev->mode_info.atom_context->iio);
}
kfree(adev->mode_info.atom_context);
adev->mode_info.atom_context = NULL;
kfree(adev->mode_info.atom_card_info);
Expand Down Expand Up @@ -1325,6 +1327,11 @@ static int amdgpu_fini(struct amdgpu_device *adev)
adev->ip_block_status[i].valid = false;
}

for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
if (adev->ip_blocks[i].funcs->late_fini)
adev->ip_blocks[i].funcs->late_fini((void *)adev);
}

return 0;
}

Expand Down Expand Up @@ -1513,8 +1520,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
amdgpu_atombios_has_gpu_virtualization_table(adev);

/* Post card if necessary */
if (!amdgpu_card_posted(adev) ||
adev->virtualization.supports_sr_iov) {
if (!amdgpu_card_posted(adev)) {
if (!adev->bios) {
dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n");
return -EINVAL;
Expand Down
9 changes: 7 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
bool skip_preamble, need_ctx_switch;
unsigned patch_offset = ~0;
struct amdgpu_vm *vm;
int vmid = 0, old_vmid = ring->vmid;
struct fence *hwf;
uint64_t ctx;

Expand All @@ -135,9 +136,11 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
if (job) {
vm = job->vm;
ctx = job->ctx;
vmid = job->vm_id;
} else {
vm = NULL;
ctx = 0;
vmid = 0;
}

if (!ring->ready) {
Expand All @@ -163,7 +166,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
r = amdgpu_vm_flush(ring, job->vm_id, job->vm_pd_addr,
job->gds_base, job->gds_size,
job->gws_base, job->gws_size,
job->oa_base, job->oa_size);
job->oa_base, job->oa_size,
(ring->current_ctx == ctx) && (old_vmid != vmid));
if (r) {
amdgpu_ring_undo(ring);
return r;
Expand All @@ -180,14 +184,14 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
need_ctx_switch = ring->current_ctx != ctx;
for (i = 0; i < num_ibs; ++i) {
ib = &ibs[i];

/* drop preamble IBs if we don't have a context switch */
if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && skip_preamble)
continue;

amdgpu_ring_emit_ib(ring, ib, job ? job->vm_id : 0,
need_ctx_switch);
need_ctx_switch = false;
ring->vmid = vmid;
}

if (ring->funcs->emit_hdp_invalidate)
Expand All @@ -198,6 +202,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
dev_err(adev->dev, "failed to emit fence (%d)\n", r);
if (job && job->vm_id)
amdgpu_vm_reset_id(adev, job->vm_id);
ring->vmid = old_vmid;
amdgpu_ring_undo(ring);
return r;
}
Expand Down
24 changes: 17 additions & 7 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,6 @@ static int amdgpu_pp_sw_fini(void *handle)
if (ret)
return ret;

#ifdef CONFIG_DRM_AMD_POWERPLAY
if (adev->pp_enabled) {
amdgpu_pm_sysfs_fini(adev);
amd_powerplay_fini(adev->powerplay.pp_handle);
}
#endif

return ret;
}

Expand Down Expand Up @@ -223,6 +216,22 @@ static int amdgpu_pp_hw_fini(void *handle)
return ret;
}

static void amdgpu_pp_late_fini(void *handle)
{
#ifdef CONFIG_DRM_AMD_POWERPLAY
struct amdgpu_device *adev = (struct amdgpu_device *)handle;

if (adev->pp_enabled) {
amdgpu_pm_sysfs_fini(adev);
amd_powerplay_fini(adev->powerplay.pp_handle);
}

if (adev->powerplay.ip_funcs->late_fini)
adev->powerplay.ip_funcs->late_fini(
adev->powerplay.pp_handle);
#endif
}

static int amdgpu_pp_suspend(void *handle)
{
int ret = 0;
Expand Down Expand Up @@ -311,6 +320,7 @@ const struct amd_ip_funcs amdgpu_pp_ip_funcs = {
.sw_fini = amdgpu_pp_sw_fini,
.hw_init = amdgpu_pp_hw_init,
.hw_fini = amdgpu_pp_hw_fini,
.late_fini = amdgpu_pp_late_fini,
.suspend = amdgpu_pp_suspend,
.resume = amdgpu_pp_resume,
.is_idle = amdgpu_pp_is_idle,
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring)
ring->ring = NULL;
ring->ring_obj = NULL;

amdgpu_wb_free(ring->adev, ring->cond_exe_offs);
amdgpu_wb_free(ring->adev, ring->fence_offs);
amdgpu_wb_free(ring->adev, ring->rptr_offs);
amdgpu_wb_free(ring->adev, ring->wptr_offs);
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ int amdgpu_sa_bo_manager_start(struct amdgpu_device *adev,
return r;
}
r = amdgpu_bo_kmap(sa_manager->bo, &sa_manager->cpu_ptr);
memset(sa_manager->cpu_ptr, 0, sa_manager->size);
amdgpu_bo_unreserve(sa_manager->bo);
return r;
}
Expand Down
19 changes: 10 additions & 9 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,19 +253,20 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev)
{
int r;

if (adev->uvd.vcpu_bo == NULL)
return 0;
kfree(adev->uvd.saved_bo);

amd_sched_entity_fini(&adev->uvd.ring.sched, &adev->uvd.entity);

r = amdgpu_bo_reserve(adev->uvd.vcpu_bo, false);
if (!r) {
amdgpu_bo_kunmap(adev->uvd.vcpu_bo);
amdgpu_bo_unpin(adev->uvd.vcpu_bo);
amdgpu_bo_unreserve(adev->uvd.vcpu_bo);
}
if (adev->uvd.vcpu_bo) {
r = amdgpu_bo_reserve(adev->uvd.vcpu_bo, false);
if (!r) {
amdgpu_bo_kunmap(adev->uvd.vcpu_bo);
amdgpu_bo_unpin(adev->uvd.vcpu_bo);
amdgpu_bo_unreserve(adev->uvd.vcpu_bo);
}

amdgpu_bo_unref(&adev->uvd.vcpu_bo);
amdgpu_bo_unref(&adev->uvd.vcpu_bo);
}

amdgpu_ring_fini(&adev->uvd.ring);

Expand Down
6 changes: 3 additions & 3 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring,
unsigned vm_id, uint64_t pd_addr,
uint32_t gds_base, uint32_t gds_size,
uint32_t gws_base, uint32_t gws_size,
uint32_t oa_base, uint32_t oa_size)
uint32_t oa_base, uint32_t oa_size,
bool vmid_switch)
{
struct amdgpu_device *adev = ring->adev;
struct amdgpu_vm_id *id = &adev->vm_manager.ids[vm_id];
Expand All @@ -312,8 +313,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring,
int r;

if (ring->funcs->emit_pipeline_sync && (
pd_addr != AMDGPU_VM_NO_FLUSH || gds_switch_needed ||
ring->type == AMDGPU_RING_TYPE_COMPUTE))
pd_addr != AMDGPU_VM_NO_FLUSH || gds_switch_needed || vmid_switch))
amdgpu_ring_emit_pipeline_sync(ring);

if (ring->funcs->emit_vm_flush &&
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/ci_dpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -6221,6 +6221,9 @@ static int ci_dpm_sw_fini(void *handle)
ci_dpm_fini(adev);
mutex_unlock(&adev->pm.mutex);

release_firmware(adev->pm.fw);
adev->pm.fw = NULL;

return 0;
}

Expand Down
22 changes: 20 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/cik_sdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ MODULE_FIRMWARE("radeon/mullins_sdma1.bin");

u32 amdgpu_cik_gpu_check_soft_reset(struct amdgpu_device *adev);


static void cik_sdma_free_microcode(struct amdgpu_device *adev)
{
int i;
for (i = 0; i < adev->sdma.num_instances; i++) {
release_firmware(adev->sdma.instance[i].fw);
adev->sdma.instance[i].fw = NULL;
}
}

/*
* sDMA - System DMA
* Starting with CIK, the GPU has new asynchronous
Expand Down Expand Up @@ -419,6 +429,8 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev)
/* Initialize the ring buffer's read and write pointers */
WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0);
WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0);
WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0);
WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0);

/* set the wb address whether it's enabled or not */
WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i],
Expand Down Expand Up @@ -446,7 +458,12 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev)
WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl);

ring->ready = true;
}

cik_sdma_enable(adev, true);

for (i = 0; i < adev->sdma.num_instances; i++) {
ring = &adev->sdma.instance[i].ring;
r = amdgpu_ring_test_ring(ring);
if (r) {
ring->ready = false;
Expand Down Expand Up @@ -529,8 +546,8 @@ static int cik_sdma_start(struct amdgpu_device *adev)
if (r)
return r;

/* unhalt the MEs */
cik_sdma_enable(adev, true);
/* halt the engine before programing */
cik_sdma_enable(adev, false);

/* start the gfx rings and rlc compute queues */
r = cik_sdma_gfx_resume(adev);
Expand Down Expand Up @@ -998,6 +1015,7 @@ static int cik_sdma_sw_fini(void *handle)
for (i = 0; i < adev->sdma.num_instances; i++)
amdgpu_ring_fini(&adev->sdma.instance[i].ring);

cik_sdma_free_microcode(adev);
return 0;
}

Expand Down
5 changes: 5 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/fiji_dpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ static int fiji_dpm_sw_init(void *handle)

static int fiji_dpm_sw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;

release_firmware(adev->pm.fw);
adev->pm.fw = NULL;

return 0;
}

Expand Down
17 changes: 17 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,22 @@ static int gfx_v7_0_init_microcode(struct amdgpu_device *adev)
return err;
}

static void gfx_v7_0_free_microcode(struct amdgpu_device *adev)
{
release_firmware(adev->gfx.pfp_fw);
adev->gfx.pfp_fw = NULL;
release_firmware(adev->gfx.me_fw);
adev->gfx.me_fw = NULL;
release_firmware(adev->gfx.ce_fw);
adev->gfx.ce_fw = NULL;
release_firmware(adev->gfx.mec_fw);
adev->gfx.mec_fw = NULL;
release_firmware(adev->gfx.mec2_fw);
adev->gfx.mec2_fw = NULL;
release_firmware(adev->gfx.rlc_fw);
adev->gfx.rlc_fw = NULL;
}

/**
* gfx_v7_0_tiling_mode_table_init - init the hw tiling table
*
Expand Down Expand Up @@ -4489,6 +4505,7 @@ static int gfx_v7_0_sw_fini(void *handle)
gfx_v7_0_cp_compute_fini(adev);
gfx_v7_0_rlc_fini(adev);
gfx_v7_0_mec_fini(adev);
gfx_v7_0_free_microcode(adev);

return 0;
}
Expand Down
Loading

0 comments on commit 00da900

Please sign in to comment.