Commit 2a238b09 authored by Kun Liu's avatar Kun Liu Committed by Alex Deucher
Browse files

drm/amd/pm: fix BUG: scheduling while atomic



atomic scheduling will be triggered in interrupt handler for
AC/DC mode switch as following backtrace.
Call Trace:
 <IRQ>
 dump_stack_lvl
 __schedule_bug
 __schedule
 schedule
 schedule_preempt_disabled
 __mutex_lock
 smu_cmn_send_smc_msg_with_param
 smu_v13_0_irq_process
 amdgpu_irq_dispatch
 amdgpu_ih_process
 amdgpu_irq_handler
 __handle_irq_event_percpu
 handle_irq_event
 handle_edge_irq
 __common_interrupt
 common_interrupt
 </IRQ>
 <TASK>
 asm_common_interrupt

Reviewed-by: default avatarLijo Lazar <lijo.lazar@amd.com>
Reviewed-by: default avatarKenneth Feng <kenneth.feng@amd.com>
Signed-off-by: default avatarKun Liu <Kun.Liu2@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 03cc84b1)
Cc: stable@vger.kernel.org
parent a993d319
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -303,5 +303,7 @@ int smu_v13_0_set_wbrf_exclusion_ranges(struct smu_context *smu,
int smu_v13_0_get_boot_freq_by_index(struct smu_context *smu,
				     enum smu_clk_type clk_type,
				     uint32_t *value);

void smu_v13_0_interrupt_work(struct smu_context *smu);
#endif
#endif
+6 −6
Original line number Diff line number Diff line
@@ -1320,9 +1320,9 @@ static int smu_v13_0_set_irq_state(struct amdgpu_device *adev,
	return 0;
}

static int smu_v13_0_ack_ac_dc_interrupt(struct smu_context *smu)
void smu_v13_0_interrupt_work(struct smu_context *smu)
{
	return smu_cmn_send_smc_msg(smu,
	smu_cmn_send_smc_msg(smu,
			     SMU_MSG_ReenableAcDcInterrupt,
			     NULL);
}
@@ -1377,12 +1377,12 @@ static int smu_v13_0_irq_process(struct amdgpu_device *adev,
			switch (ctxid) {
			case SMU_IH_INTERRUPT_CONTEXT_ID_AC:
				dev_dbg(adev->dev, "Switched to AC mode!\n");
				smu_v13_0_ack_ac_dc_interrupt(smu);
				schedule_work(&smu->interrupt_work);
				adev->pm.ac_power = true;
				break;
			case SMU_IH_INTERRUPT_CONTEXT_ID_DC:
				dev_dbg(adev->dev, "Switched to DC mode!\n");
				smu_v13_0_ack_ac_dc_interrupt(smu);
				schedule_work(&smu->interrupt_work);
				adev->pm.ac_power = false;
				break;
			case SMU_IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING:
+1 −0
Original line number Diff line number Diff line
@@ -3219,6 +3219,7 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
	.is_asic_wbrf_supported = smu_v13_0_0_wbrf_support_check,
	.enable_uclk_shadow = smu_v13_0_enable_uclk_shadow,
	.set_wbrf_exclusion_ranges = smu_v13_0_set_wbrf_exclusion_ranges,
	.interrupt_work = smu_v13_0_interrupt_work,
};

void smu_v13_0_0_set_ppt_funcs(struct smu_context *smu)
+1 −0
Original line number Diff line number Diff line
@@ -2797,6 +2797,7 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = {
	.is_asic_wbrf_supported = smu_v13_0_7_wbrf_support_check,
	.enable_uclk_shadow = smu_v13_0_enable_uclk_shadow,
	.set_wbrf_exclusion_ranges = smu_v13_0_set_wbrf_exclusion_ranges,
	.interrupt_work = smu_v13_0_interrupt_work,
};

void smu_v13_0_7_set_ppt_funcs(struct smu_context *smu)