[PATCH] drm/amd/pm: add delay to avoid unintened shutdown due to hotspot temperature spark
Alex Deucher
alexdeucher at gmail.com
Tue May 16 13:07:56 UTC 2023
On Mon, May 15, 2023 at 10:52 PM Evan Quan <evan.quan at amd.com> wrote:
>
> There will be a double check for the hotspot temperature on delay
> expired. This can avoid unintended shutdown due to hotspot temperature
> spark.
>
> Signed-off-by: Evan Quan <evan.quan at amd.com>
> --
> v1->v2:
> - add the proper millidegree Celsius to degree Celsius transform
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 +
> drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 14 ++++++++
> drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 34 +++++++++++++++++++
> drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 2 ++
> .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 9 ++---
> .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 9 ++---
Can you extend this to the older powerplay code as well?
> 6 files changed, 55 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 39192eba3ff8..4cd873659365 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -243,6 +243,7 @@ extern int amdgpu_num_kcq;
> #define AMDGPU_VCNFW_LOG_SIZE (32 * 1024)
> extern int amdgpu_vcnfw_log;
> extern int amdgpu_sg_display;
> +extern uint amdgpu_ctf_delay;
>
> #define AMDGPU_VM_MAX_NUM_CTX 4096
> #define AMDGPU_SG_THRESHOLD (256*1024*1024)
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index 749eeb9a2976..6c699fefdf92 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -198,6 +198,7 @@ int amdgpu_smartshift_bias;
> int amdgpu_use_xgmi_p2p = 1;
> int amdgpu_vcnfw_log;
> int amdgpu_sg_display = -1; /* auto */
> +uint amdgpu_ctf_delay = 50; /* in ms */
>
> static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work);
>
> @@ -973,6 +974,19 @@ MODULE_PARM_DESC(smu_pptable_id,
> "specify pptable id to be used (-1 = auto(default) value, 0 = use pptable from vbios, > 0 = soft pptable id)");
> module_param_named(smu_pptable_id, amdgpu_smu_pptable_id, int, 0444);
>
> +/**
> + * DOC: ctf_delay (uint)
> + * On SW CTF triggerred, to protect the chip from over-heated and possible damage, we usually
> + * trigger a system shutdown. However, considering there may be a hotspot temperature spark
> + * momentarily hitting the SW CTF setting point, a delay is added to avoid unintended shutdown.
> + * On the delay expired, the shutdown will be performed if the hotspot temp is still
> + * bigger than the SW CTF setting. Otherwise, nothing will be done.
> + * The default setting for the delay is 50ms.
> + */
> +MODULE_PARM_DESC(ctf_delay,
> + "the delay(default 50ms) enforced before real action taken on ctf triggerred");
> +module_param_named(ctf_delay, amdgpu_ctf_delay, uint, 0444);
I think we can probably drop this. I don't see a need for users to
adjust this and it could be bad for the hardware if it gets set too
long.
> +
> /* These devices are not supported by amdgpu.
> * They are supported by the mach64, r128, radeon drivers
> */
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> index 3c860939031e..71153b335ad9 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
> @@ -24,6 +24,7 @@
>
> #include <linux/firmware.h>
> #include <linux/pci.h>
> +#include <linux/reboot.h>
>
> #include "amdgpu.h"
> #include "amdgpu_smu.h"
> @@ -1070,6 +1071,34 @@ static void smu_interrupt_work_fn(struct work_struct *work)
> smu->ppt_funcs->interrupt_work(smu);
> }
>
> +static void smu_swctf_delayed_work_handler(struct work_struct *work)
> +{
> + struct smu_context *smu =
> + container_of(work, struct smu_context, swctf_delayed_work.work);
> + struct smu_temperature_range *range =
> + &smu->thermal_range;
> + struct amdgpu_device *adev = smu->adev;
> + uint32_t hotspot_tmp, size;
> +
> + /*
> + * If the hotspot temperature is confirmed as below SW CTF setting point
> + * after the delay enforced, nothing will be done.
> + * Otherwise, a graceful shutdown will be performed to prevent further damage.
> + */
> + if (smu->ppt_funcs->read_sensor &&
> + !smu->ppt_funcs->read_sensor(smu,
> + AMDGPU_PP_SENSOR_HOTSPOT_TEMP,
> + &hotspot_tmp,
> + &size) &&
> + range->software_shutdown_temp &&
> + hotspot_tmp / 1000 < range->software_shutdown_temp)
> + return;
> +
> + dev_emerg(adev->dev, "ERROR: GPU over temperature range(SW CTF) detected!\n");
> + dev_emerg(adev->dev, "ERROR: System is going to shutdown due to GPU SW CTF!\n");
> + orderly_poweroff(true);
> +}
> +
> static int smu_sw_init(void *handle)
> {
> struct amdgpu_device *adev = (struct amdgpu_device *)handle;
> @@ -1358,6 +1387,9 @@ static int smu_smc_hw_setup(struct smu_context *smu)
> return ret;
> }
>
> + INIT_DELAYED_WORK(&smu->swctf_delayed_work,
> + smu_swctf_delayed_work_handler);
> +
> ret = smu_enable_thermal_alert(smu);
> if (ret) {
> dev_err(adev->dev, "Failed to enable thermal alert!\n");
> @@ -1592,6 +1624,8 @@ static int smu_smc_hw_cleanup(struct smu_context *smu)
> return ret;
> }
>
> + cancel_delayed_work_sync(&smu->swctf_delayed_work);
> +
> ret = smu_disable_dpms(smu);
> if (ret) {
> dev_err(adev->dev, "Fail to disable dpm features!\n");
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
> index 4ce394903c07..18101ec0ae6e 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
> +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
> @@ -573,6 +573,8 @@ struct smu_context
> u32 debug_param_reg;
> u32 debug_msg_reg;
> u32 debug_resp_reg;
> +
> + struct delayed_work swctf_delayed_work;
> };
>
> struct i2c_adapter;
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
> index e1ef88ee1ed3..4c3c682bf7a0 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
> @@ -1412,13 +1412,8 @@ static int smu_v11_0_irq_process(struct amdgpu_device *adev,
> if (client_id == SOC15_IH_CLIENTID_THM) {
> switch (src_id) {
> case THM_11_0__SRCID__THM_DIG_THERM_L2H:
> - dev_emerg(adev->dev, "ERROR: GPU over temperature range(SW CTF) detected!\n");
> - /*
> - * SW CTF just occurred.
> - * Try to do a graceful shutdown to prevent further damage.
> - */
> - dev_emerg(adev->dev, "ERROR: System is going to shutdown due to GPU SW CTF!\n");
> - orderly_poweroff(true);
> + schedule_delayed_work(&smu->swctf_delayed_work,
> + msecs_to_jiffies(amdgpu_ctf_delay));
> break;
> case THM_11_0__SRCID__THM_DIG_THERM_H2L:
> dev_emerg(adev->dev, "ERROR: GPU under temperature range detected\n");
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
> index 0bc0a6e97b5a..a5447119d5f5 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
> @@ -1377,13 +1377,8 @@ static int smu_v13_0_irq_process(struct amdgpu_device *adev,
> if (client_id == SOC15_IH_CLIENTID_THM) {
> switch (src_id) {
> case THM_11_0__SRCID__THM_DIG_THERM_L2H:
> - dev_emerg(adev->dev, "ERROR: GPU over temperature range(SW CTF) detected!\n");
> - /*
> - * SW CTF just occurred.
> - * Try to do a graceful shutdown to prevent further damage.
> - */
> - dev_emerg(adev->dev, "ERROR: System is going to shutdown due to GPU SW CTF!\n");
> - orderly_poweroff(true);
> + schedule_delayed_work(&smu->swctf_delayed_work,
> + msecs_to_jiffies(amdgpu_ctf_delay));
> break;
> case THM_11_0__SRCID__THM_DIG_THERM_H2L:
> dev_emerg(adev->dev, "ERROR: GPU under temperature range detected\n");
> --
> 2.34.1
>
More information about the amd-gfx
mailing list