On Mon, Jun 8, 2026 at 5:14 AM Ruoyu Wang <[email protected]> wrote:
>
> r600_parse_extended_power_table() uses manual kfree() calls for some
> early allocation failures, but the freed pointers are left in the
> dynamic power-management state. If device teardown later calls
> r600_free_extended_power_table(), those stale pointers can be freed
> again.
>
> Use the common extended power table cleanup helper for those early
> failure paths as well, and clear each pointer after freeing it so
> repeated cleanup stays safe.
>
> Signed-off-by: Ruoyu Wang <[email protected]>

Applied.  Thanks!

> ---
>  drivers/gpu/drm/radeon/r600_dpm.c | 21 +++++++++++++++------
>  1 file changed, 15 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/r600_dpm.c 
> b/drivers/gpu/drm/radeon/r600_dpm.c
> index 83f1ae31cbdbc..9755e717ca8bb 100644
> --- a/drivers/gpu/drm/radeon/r600_dpm.c
> +++ b/drivers/gpu/drm/radeon/r600_dpm.c
> @@ -932,7 +932,7 @@ int r600_parse_extended_power_table(struct radeon_device 
> *rdev)
>                         ret = 
> r600_parse_clk_voltage_dep_table(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
>                                                                dep_table);
>                         if (ret) {
> -                               
> kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries);
> +                               r600_free_extended_power_table(rdev);
>                                 return ret;
>                         }
>                 }
> @@ -943,8 +943,7 @@ int r600_parse_extended_power_table(struct radeon_device 
> *rdev)
>                         ret = 
> r600_parse_clk_voltage_dep_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
>                                                                dep_table);
>                         if (ret) {
> -                               
> kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries);
> -                               
> kfree(rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk.entries);
> +                               r600_free_extended_power_table(rdev);
>                                 return ret;
>                         }
>                 }
> @@ -955,9 +954,7 @@ int r600_parse_extended_power_table(struct radeon_device 
> *rdev)
>                         ret = 
> r600_parse_clk_voltage_dep_table(&rdev->pm.dpm.dyn_state.mvdd_dependency_on_mclk,
>                                                                dep_table);
>                         if (ret) {
> -                               
> kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries);
> -                               
> kfree(rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk.entries);
> -                               
> kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk.entries);
> +                               r600_free_extended_power_table(rdev);
>                                 return ret;
>                         }
>                 }
> @@ -1296,17 +1293,29 @@ void r600_free_extended_power_table(struct 
> radeon_device *rdev)
>         struct radeon_dpm_dynamic_state *dyn_state = &rdev->pm.dpm.dyn_state;
>
>         kfree(dyn_state->vddc_dependency_on_sclk.entries);
> +       dyn_state->vddc_dependency_on_sclk.entries = NULL;
>         kfree(dyn_state->vddci_dependency_on_mclk.entries);
> +       dyn_state->vddci_dependency_on_mclk.entries = NULL;
>         kfree(dyn_state->vddc_dependency_on_mclk.entries);
> +       dyn_state->vddc_dependency_on_mclk.entries = NULL;
>         kfree(dyn_state->mvdd_dependency_on_mclk.entries);
> +       dyn_state->mvdd_dependency_on_mclk.entries = NULL;
>         kfree(dyn_state->cac_leakage_table.entries);
> +       dyn_state->cac_leakage_table.entries = NULL;
>         kfree(dyn_state->phase_shedding_limits_table.entries);
> +       dyn_state->phase_shedding_limits_table.entries = NULL;
>         kfree(dyn_state->ppm_table);
> +       dyn_state->ppm_table = NULL;
>         kfree(dyn_state->cac_tdp_table);
> +       dyn_state->cac_tdp_table = NULL;
>         kfree(dyn_state->vce_clock_voltage_dependency_table.entries);
> +       dyn_state->vce_clock_voltage_dependency_table.entries = NULL;
>         kfree(dyn_state->uvd_clock_voltage_dependency_table.entries);
> +       dyn_state->uvd_clock_voltage_dependency_table.entries = NULL;
>         kfree(dyn_state->samu_clock_voltage_dependency_table.entries);
> +       dyn_state->samu_clock_voltage_dependency_table.entries = NULL;
>         kfree(dyn_state->acp_clock_voltage_dependency_table.entries);
> +       dyn_state->acp_clock_voltage_dependency_table.entries = NULL;
>  }
>
>  enum radeon_pcie_gen r600_get_pcie_gen_support(struct radeon_device *rdev,
> --
> 2.51.0
>

Reply via email to