[PATCH] gpu: drm: amd: amdgpu: Fix calls to dev_{info,err}

Chen, Guchun Guchun.Chen at amd.com
Wed Aug 2 01:37:51 UTC 2023


[Public]

Hi Bert,

Thanks for your patch. However, I guess adding a dev member for printing purpose only does not introduce much benefit. So, instead, the culprit commits have been reverted.
https://patchwork.freedesktop.org/patch/550297/
https://patchwork.freedesktop.org/patch/550396/

Regards,
Guchun

> -----Original Message-----
> From: Bert Karwatzki <spasswolf at web.de>
> Sent: Monday, July 31, 2023 5:55 PM
> To: amd-gfx at lists.freedesktop.org
> Cc: SHANMUGAM, SRINIVASAN <SRINIVASAN.SHANMUGAM at amd.com>;
> Chen, Guchun <Guchun.Chen at amd.com>; Alex Deucher
> <alexdeucher at gmail.com>
> Subject: [PATCH] gpu: drm: amd: amdgpu: Fix calls to dev_{info,err}
>
> Commit b0bd0a92b8158ea9c809d885e0f0c21518bdbd14 introduced
> dev_{info,err} calls which failed (leading to a hang on boot) because of an
> incorrect usage of the container_of macro. This fixes the error by introducing
> a pointer to the device as an additional element in struct amdgpu_atpx and
> struct radeon_atpx.
>
> Fixes: https://gitlab.freedesktop.org/drm/amd/-/issues/2744
> Signed-off-by: Bert Karwatzki <spasswolf at web.de>
> ---
>  .../gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c  | 40 +++++++++----------
> drivers/gpu/drm/radeon/radeon_atpx_handler.c  | 30 +++++++-------
>  2 files changed, 32 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
> index 6f241c574665..29242ecec7b0 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
> @@ -37,6 +37,7 @@ struct amdgpu_atpx_functions {
>
>  struct amdgpu_atpx {
>       acpi_handle handle;
> +     struct device *dev;
>       struct amdgpu_atpx_functions functions;
>       bool is_hybrid;
>       bool dgpu_req_power_for_displays;
> @@ -104,22 +105,20 @@ void *amdgpu_atpx_get_dhandle(void)
>  /**
>   * amdgpu_atpx_call - call an ATPX method
>   *
> - * @handle: acpi handle
> + * @atpx: amdgpu atpx struct
>   * @function: the ATPX function to execute
>   * @params: ATPX function params
>   *
>   * Executes the requested ATPX function (all asics).
>   * Returns a pointer to the acpi output buffer.
>   */
> -static union acpi_object *amdgpu_atpx_call(acpi_handle handle, int
> function,
> +static union acpi_object *amdgpu_atpx_call(struct amdgpu_atpx *atpx,
> +int
> function,
>                                          struct acpi_buffer *params)
>  {
>       acpi_status status;
>       union acpi_object atpx_arg_elements[2];
>       struct acpi_object_list atpx_arg;
>       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
> -     struct acpi_device *adev = container_of(handle, struct acpi_device,
> handle);
> -     struct device *dev = &adev->dev;
>
>       atpx_arg.count = 2;
>       atpx_arg.pointer = &atpx_arg_elements[0]; @@ -137,11 +136,11
> @@ static union acpi_object *amdgpu_atpx_call(acpi_handle handle, int
> function,
>               atpx_arg_elements[1].integer.value = 0;
>       }
>
> -     status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer);
> +     status = acpi_evaluate_object(atpx->handle, NULL, &atpx_arg,
> &buffer);
>
>       /* Fail only if calling the method fails and ATPX is supported */
>       if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
> -             dev_err(dev, "failed to evaluate ATPX got %s\n",
> +             dev_err(atpx->dev, "failed to evaluate ATPX got %s\n",
>                       acpi_format_exception(status));
>               kfree(buffer.pointer);
>               return NULL;
> @@ -183,15 +182,13 @@ static void amdgpu_atpx_parse_functions(struct
> amdgpu_atpx_functions *f, u32 mas
>  static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx)  {
>       u32 valid_bits = 0;
> -     struct acpi_device *adev = container_of(atpx->handle, struct
> acpi_device, handle);
> -     struct device *dev = &adev->dev;
>
>       if (atpx->functions.px_params) {
>               union acpi_object *info;
>               struct atpx_px_params output;
>               size_t size;
>
> -             info = amdgpu_atpx_call(atpx->handle,
> ATPX_FUNCTION_GET_PX_PARAMETERS, NULL);
> +             info = amdgpu_atpx_call(atpx,
> ATPX_FUNCTION_GET_PX_PARAMETERS,
> NULL);
>               if (!info)
>                       return -EIO;
>
> @@ -199,7 +196,7 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx
> *atpx)
>
>               size = *(u16 *) info->buffer.pointer;
>               if (size < 10) {
> -                     dev_err(dev, "ATPX buffer is too small: %zu\n", size);
> +                     dev_err(atpx->dev, "ATPX buffer is too small: %zu\n",
> size);
>                       kfree(info);
>                       return -EINVAL;
>               }
> @@ -232,11 +229,11 @@ static int amdgpu_atpx_validate(struct
> amdgpu_atpx *atpx)
>       atpx->is_hybrid = false;
>       if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) {
>               if (amdgpu_atpx_priv.quirks &
> AMDGPU_PX_QUIRK_FORCE_ATPX) {
> -                     dev_info(dev, "ATPX Hybrid Graphics, forcing to
> ATPX\n");
> +                     dev_info(atpx->dev, "ATPX Hybrid Graphics, forcing
> to
> ATPX\n");
>                       atpx->functions.power_cntl = true;
>                       atpx->is_hybrid = false;
>               } else {
> -                     dev_info(dev, "ATPX Hybrid Graphics\n");
> +                     dev_info(atpx->dev, "ATPX Hybrid Graphics\n");
>                       /*
>                        * Disable legacy PM methods only when pcie port
> PM is usable,
>                        * otherwise the device might fail to power off or
> power on.
> @@ -269,10 +266,8 @@ static int amdgpu_atpx_verify_interface(struct
> amdgpu_atpx
> *atpx)
>       struct atpx_verify_interface output;
>       size_t size;
>       int err = 0;
> -     struct acpi_device *adev = container_of(atpx->handle, struct
> acpi_device, handle);
> -     struct device *dev = &adev->dev;
>
> -     info = amdgpu_atpx_call(atpx->handle,
> ATPX_FUNCTION_VERIFY_INTERFACE,
> NULL);
> +     info = amdgpu_atpx_call(atpx, ATPX_FUNCTION_VERIFY_INTERFACE,
> NULL);
>       if (!info)
>               return -EIO;
>
> @@ -280,7 +275,7 @@ static int amdgpu_atpx_verify_interface(struct
> amdgpu_atpx
> *atpx)
>
>       size = *(u16 *) info->buffer.pointer;
>       if (size < 8) {
> -             printk("ATPX buffer is too small: %zu\n", size);
> +             dev_err(atpx->dev, "ATPX buffer is too small: %zu\n", size);
>               err = -EINVAL;
>               goto out;
>       }
> @@ -289,7 +284,7 @@ static int amdgpu_atpx_verify_interface(struct
> amdgpu_atpx
> *atpx)
>       memcpy(&output, info->buffer.pointer, size);
>
>       /* TODO: check version? */
> -     dev_info(dev, "ATPX version %u, functions 0x%08x\n",
> +     dev_info(atpx->dev, "ATPX version %u, functions 0x%08x\n",
>                output.version, output.function_bits);
>
>       amdgpu_atpx_parse_functions(&atpx->functions,
> output.function_bits); @@ -320,7 +315,7 @@ static int
> amdgpu_atpx_set_discrete_state(struct amdgpu_atpx *atpx, u8 state)
>               input.dgpu_state = state;
>               params.length = input.size;
>               params.pointer = &input;
> -             info = amdgpu_atpx_call(atpx->handle,
> +             info = amdgpu_atpx_call(atpx,
>                                       ATPX_FUNCTION_POWER_CONTROL,
>                                       &params);
>               if (!info)
> @@ -356,7 +351,7 @@ static int amdgpu_atpx_switch_disp_mux(struct
> amdgpu_atpx *atpx, u16 mux_id)
>               input.mux = mux_id;
>               params.length = input.size;
>               params.pointer = &input;
> -             info = amdgpu_atpx_call(atpx->handle,
> +             info = amdgpu_atpx_call(atpx,
>
>       ATPX_FUNCTION_DISPLAY_MUX_CONTROL,
>                                       &params);
>               if (!info)
> @@ -388,7 +383,7 @@ static int amdgpu_atpx_switch_i2c_mux(struct
> amdgpu_atpx *atpx, u16 mux_id)
>               input.mux = mux_id;
>               params.length = input.size;
>               params.pointer = &input;
> -             info = amdgpu_atpx_call(atpx->handle,
> +             info = amdgpu_atpx_call(atpx,
>
>       ATPX_FUNCTION_I2C_MUX_CONTROL,
>                                       &params);
>               if (!info)
> @@ -420,7 +415,7 @@ static int amdgpu_atpx_switch_start(struct
> amdgpu_atpx *atpx, u16 mux_id)
>               input.mux = mux_id;
>               params.length = input.size;
>               params.pointer = &input;
> -             info = amdgpu_atpx_call(atpx->handle,
> +             info = amdgpu_atpx_call(atpx,
>
>       ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION,
>                                       &params);
>               if (!info)
> @@ -452,7 +447,7 @@ static int amdgpu_atpx_switch_end(struct
> amdgpu_atpx *atpx,
> u16 mux_id)
>               input.mux = mux_id;
>               params.length = input.size;
>               params.pointer = &input;
> -             info = amdgpu_atpx_call(atpx->handle,
> +             info = amdgpu_atpx_call(atpx,
>
>       ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION,
>                                       &params);
>               if (!info)
> @@ -533,6 +528,7 @@ static bool amdgpu_atpx_pci_probe_handle(struct
> pci_dev
> *pdev)
>       }
>       amdgpu_atpx_priv.dhandle = dhandle;
>       amdgpu_atpx_priv.atpx.handle = atpx_handle;
> +     amdgpu_atpx_priv.atpx.dev = &pdev->dev;
>       return true;
>  }
>
> diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
> b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
> index fb4d931fdf18..f6a005520b55 100644
> --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
> +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
> @@ -26,6 +26,7 @@ struct radeon_atpx_functions {
>
>  struct radeon_atpx {
>       acpi_handle handle;
> +     struct device *dev;
>       struct radeon_atpx_functions functions;
>       bool is_hybrid;
>       bool dgpu_req_power_for_displays;
> @@ -87,15 +88,13 @@ bool
> radeon_atpx_dgpu_req_power_for_displays(void) {
>   * Executes the requested ATPX function (all asics).
>   * Returns a pointer to the acpi output buffer.
>   */
> -static union acpi_object *radeon_atpx_call(acpi_handle handle, int function,
> +static union acpi_object *radeon_atpx_call(struct radeon_atpx *atpx,
> +int
> function,
>                                          struct acpi_buffer *params)
>  {
>       acpi_status status;
>       union acpi_object atpx_arg_elements[2];
>       struct acpi_object_list atpx_arg;
>       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
> -     struct acpi_device *adev = container_of(handle, struct acpi_device,
> handle);
> -     struct device *dev = &adev->dev;
>
>       atpx_arg.count = 2;
>       atpx_arg.pointer = &atpx_arg_elements[0]; @@ -113,11 +112,11
> @@ static union acpi_object *radeon_atpx_call(acpi_handle handle, int
> function,
>               atpx_arg_elements[1].integer.value = 0;
>       }
>
> -     status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer);
> +     status = acpi_evaluate_object(atpx->handle, NULL, &atpx_arg,
> &buffer);
>
>       /* Fail only if calling the method fails and ATPX is supported */
>       if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
> -             dev_err(dev, "failed to evaluate ATPX got %s\n",
> +             dev_err(atpx->dev, "failed to evaluate ATPX got %s\n",
>                       acpi_format_exception(status));
>               kfree(buffer.pointer);
>               return NULL;
> @@ -159,15 +158,13 @@ static void radeon_atpx_parse_functions(struct
> radeon_atpx_functions *f, u32 mas
>  static int radeon_atpx_validate(struct radeon_atpx *atpx)  {
>       u32 valid_bits = 0;
> -     struct acpi_device *adev = container_of(atpx->handle, struct
> acpi_device, handle);
> -     struct device *dev = &adev->dev;
>
>       if (atpx->functions.px_params) {
>               union acpi_object *info;
>               struct atpx_px_params output;
>               size_t size;
>
> -             info = radeon_atpx_call(atpx->handle,
> ATPX_FUNCTION_GET_PX_PARAMETERS, NULL);
> +             info = radeon_atpx_call(atpx,
> ATPX_FUNCTION_GET_PX_PARAMETERS,
> NULL);
>               if (!info)
>                       return -EIO;
>
> @@ -175,7 +172,7 @@ static int radeon_atpx_validate(struct radeon_atpx
> *atpx)
>
>               size = *(u16 *) info->buffer.pointer;
>               if (size < 10) {
> -                     dev_err(dev, "ATPX buffer is too small: %zu\n", size);
> +                     dev_err(atpx->dev, "ATPX buffer is too small: %zu\n",
> size);
>                       kfree(info);
>                       return -EINVAL;
>               }
> @@ -206,7 +203,7 @@ static int radeon_atpx_validate(struct radeon_atpx
> *atpx)
>
>       atpx->is_hybrid = false;
>       if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) {
> -             dev_info(dev, "ATPX Hybrid Graphics\n");
> +             dev_info(atpx->dev, "ATPX Hybrid Graphics\n");
>               /*
>                * Disable legacy PM methods only when pcie port PM is
> usable,
>                * otherwise the device might fail to power off or power on.
> @@ -235,7 +232,7 @@ static int radeon_atpx_verify_interface(struct
> radeon_atpx
> *atpx)
>       size_t size;
>       int err = 0;
>
> -     info = radeon_atpx_call(atpx->handle,
> ATPX_FUNCTION_VERIFY_INTERFACE,
> NULL);
> +     info = radeon_atpx_call(atpx, ATPX_FUNCTION_VERIFY_INTERFACE,
> NULL);
>       if (!info)
>               return -EIO;
>
> @@ -283,7 +280,7 @@ static int radeon_atpx_set_discrete_state(struct
> radeon_atpx *atpx, u8 state)
>               input.dgpu_state = state;
>               params.length = input.size;
>               params.pointer = &input;
> -             info = radeon_atpx_call(atpx->handle,
> +             info = radeon_atpx_call(atpx,
>                                       ATPX_FUNCTION_POWER_CONTROL,
>                                       &params);
>               if (!info)
> @@ -319,7 +316,7 @@ static int radeon_atpx_switch_disp_mux(struct
> radeon_atpx *atpx, u16 mux_id)
>               input.mux = mux_id;
>               params.length = input.size;
>               params.pointer = &input;
> -             info = radeon_atpx_call(atpx->handle,
> +             info = radeon_atpx_call(atpx,
>
>       ATPX_FUNCTION_DISPLAY_MUX_CONTROL,
>                                       &params);
>               if (!info)
> @@ -351,7 +348,7 @@ static int radeon_atpx_switch_i2c_mux(struct
> radeon_atpx *atpx, u16 mux_id)
>               input.mux = mux_id;
>               params.length = input.size;
>               params.pointer = &input;
> -             info = radeon_atpx_call(atpx->handle,
> +             info = radeon_atpx_call(atpx,
>
>       ATPX_FUNCTION_I2C_MUX_CONTROL,
>                                       &params);
>               if (!info)
> @@ -383,7 +380,7 @@ static int radeon_atpx_switch_start(struct
> radeon_atpx *atpx, u16 mux_id)
>               input.mux = mux_id;
>               params.length = input.size;
>               params.pointer = &input;
> -             info = radeon_atpx_call(atpx->handle,
> +             info = radeon_atpx_call(atpx,
>
>       ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION,
>                                       &params);
>               if (!info)
> @@ -415,7 +412,7 @@ static int radeon_atpx_switch_end(struct
> radeon_atpx *atpx,
> u16 mux_id)
>               input.mux = mux_id;
>               params.length = input.size;
>               params.pointer = &input;
> -             info = radeon_atpx_call(atpx->handle,
> +             info = radeon_atpx_call(atpx,
>
>       ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION,
>                                       &params);
>               if (!info)
> @@ -495,6 +492,7 @@ static bool radeon_atpx_pci_probe_handle(struct
> pci_dev
> *pdev)
>
>       radeon_atpx_priv.dhandle = dhandle;
>       radeon_atpx_priv.atpx.handle = atpx_handle;
> +     radeon_atpx_priv.atpx.dev = &pdev->dev;
>       return true;
>  }
>
> --
> 2.39.2
>
> If the introduction of new elements to {amdgpu,radeon}_atpx is to not
> wanted I think using pr_{info,err} instead of dev_{info_err} is fine here.
>
> Bert Karwatzki


More information about the amd-gfx mailing list