AMD General

> -----Original Message-----
> From: Lazar, Lijo <[email protected]>
> Sent: Friday, June 26, 2026 7:37 PM
> To: Yang, Stanley <[email protected]>; [email protected]
> Subject: Re: [PATCH 1/1] drm/amdgpu/ras: Resum RAS IP hw init during nps
> dynamic switch
>
>
>
> On 26-Jun-26 3:56 PM, Yang, Stanley wrote:
> > AMD General
> >
> >> -----Original Message-----
> >> From: Lazar, Lijo <[email protected]>
> >> Sent: Friday, June 26, 2026 5:44 PM
> >> To: Yang, Stanley <[email protected]>;
> >> [email protected]
> >> Subject: Re: [PATCH 1/1] drm/amdgpu/ras: Resum RAS IP hw init during
> >> nps dynamic switch
> >>
> >>
> >>
> >> On 26-Jun-26 2:04 PM, Yang, Stanley wrote:
> >>> AMD General
> >>>
> >>>> -----Original Message-----
> >>>> From: Lazar, Lijo <[email protected]>
> >>>> Sent: Friday, June 26, 2026 4:16 PM
> >>>> To: Yang, Stanley <[email protected]>;
> >>>> [email protected]
> >>>> Subject: Re: [PATCH 1/1] drm/amdgpu/ras: Resum RAS IP hw init
> >>>> during nps dynamic switch
> >>>>
> >>>>
> >>>>
> >>>> On 26-Jun-26 12:47 PM, Stanley.Yang wrote:
> >>>>> On an XGMI reset-on-init (NPS memory patition mode swith), RAS IP
> >>>>> hw fini, sw fini is called but hw init is skipped due to RAS IP
> >>>>> block is not included in hwinit mask, so need call RAS IP hw init
> >>>>> during XGMI reset-on-init.
> >>>>>
> >>>>
> >>>> After reset, we set it to default level.
> >>>>
> >>>>
> >>
> https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/amd/amd
> >>>> g
> >>>> pu/amdgpu_device.c#L5211
> >>>>
> >>>> The default level includes all IP blocks, hence it's supposed to
> >>>> resume all blocks.
> >>>>
> >>>> With RAS as a separate ip block, ideally it should have resumed.
> >>>> Could you check why/how RAS IP block is missed?
> >>>
> >>> static const struct amd_ip_funcs __maybe_unused ras_v1_0_ip_funcs = {
> >>>       .name = "ras_v1_0",
> >>>       .sw_init = amdgpu_ras_mgr_sw_init,
> >>>       .sw_fini = amdgpu_ras_mgr_sw_fini,
> >>>       .hw_init = amdgpu_ras_mgr_hw_init,
> >>>       .hw_fini = amdgpu_ras_mgr_hw_fini, };
> >>>
> >>> The RAS IP block does not register suspend and resume callback
> >>> function, so
> >> RAS IP block hw init function missed under this case.
> >>>
> >>
> >> How does it work for regular reset? For regular reset also, driver
> >> calls the resume sequence for the IP block.
> >>
> >> I think the proper fix is to add a resume sequence which calls
> >> hw_init (if those paths are identical).
> >
> > [Stanley]: Normal cold start is at the DEFAULT init level, and RAS hw_init 
> > is
> executing normally, so uniras is enabled; Normal GPU reset, because there is
> no. suspend, ras_is_read remains true and the state is preserved - so only NPS
> switching to this XGMI reset on int path will trigger this bug.
> >
> > Not suggest add .resume sequence because during RAS IP block hw_init
> process need hold reset domain semaphore but the semaphore has already
> hold before, the other reason is adding .resume will break regular reset, it
> doesn't need to be reinitialized due to all RAS error info is cached.
> >
>
> Then a dedicated resume sequence needs to be added which checks if device is
> in reset (being resumed from a reset) before taking hold of the semaphore.

Yes, controlling the semaphore by checking if it is in the reset state can 
indeed solve the semaphore problem, but as I said there is no need to suspend 
and then resume the RAS IP block in regular reset.

Regards,
Stanley
>
> As an IP block, it will need suspend/resume for other scenarios like device
> runtime pm or system suspend/resume. This can be used only as a temporary
> workaround till that point.
>
> Thanks,
> Lijo
>
> > Regards,
> > Stanley
> >>
> >> Thanks,
> >> Lijo
> >>
> >>> Regards,
> >>> Stanley
> >>>>
> >>>> Thanks,
> >>>> Lijo
> >>>>> Signed-off-by: Stanley.Yang <[email protected]>
> >>>>> ---
> >>>>>     drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c       | 14
> +++++++++++-
> >>>>>     drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h       |  1 +
> >>>>>     drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c      | 10 +++++++++
> >>>>>     .../gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c  | 22
> >>>> +++++++++++++++++++
> >>>>>     .../gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.h  |  1 +
> >>>>>     5 files changed, 47 insertions(+), 1 deletion(-)
> >>>>>
> >>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
> >>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
> >>>>> index 7ef7c54ab982..e11c542a01b6 100644
> >>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
> >>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
> >>>>> @@ -3857,7 +3857,14 @@ int amdgpu_ras_init_badpage_info(struct
> >>>> amdgpu_device *adev)
> >>>>>       if (!con || amdgpu_sriov_vf(adev))
> >>>>>               return 0;
> >>>>>
> >>>>> -   if (amdgpu_uniras_enabled(adev))
> >>>>> +   /*
> >>>>> +    * For the reset-on-init path (e.g. an NPS memory partition,
> >>>>> +    * switch) the RAS IP block hw_init has not been enabled and
> >>>>> +    * the amdgpu_uniras_enabled return false, check amdgpu ras
> >>>>> +    * context uniras_enabled flag, eepron init will be called
> >>>>> +    * during RAS IP block hw_init.
> >>>>> +    */
> >>>>> +   if (amdgpu_uniras_enabled(adev) || con->uniras_enabled)
> >>>>>               return 0;
> >>>>>
> >>>>>       control = &con->eeprom_control; @@ -5859,3 +5866,8 @@ void
> >>>>> amdgpu_ras_post_reset(struct
> >>>> amdgpu_device *adev,
> >>>>>                       amdgpu_ras_mgr_post_reset(tmp_adev);
> >>>>>       }
> >>>>>     }
> >>>>> +
> >>>>> +void amdgpu_ras_resume_after_reset(struct amdgpu_device *adev) {
> >>>>> +   amdgpu_ras_mgr_resume_after_reset(adev);
> >>>>> +}
> >>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
> >>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
> >>>>> index a86ab65aa2f0..ad24c7cf8936 100644
> >>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
> >>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
> >>>>> @@ -1045,4 +1045,5 @@ void amdgpu_ras_pre_reset(struct
> >>>> amdgpu_device *adev,
> >>>>>                                         struct list_head *device_list);
> >>>>>     void amdgpu_ras_post_reset(struct amdgpu_device *adev,
> >>>>>                                         struct list_head
> >>>>> *device_list);
> >>>>> +void amdgpu_ras_resume_after_reset(struct amdgpu_device *adev);
> >>>>>     #endif
> >>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
> >>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
> >>>>> index 9a4e8715742a..f175c8987aeb 100644
> >>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
> >>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
> >>>>> @@ -1669,6 +1669,16 @@ static void
> >>>> amdgpu_xgmi_reset_on_init_work(struct work_struct *work)
> >>>>>               if (r && r != -EHWPOISON)
> >>>>>                       dev_err(tmp_adev->dev,
> >>>>>                               "error during bad page data
> >>>>> initialization");
> >>>>> +
> >>>>> +           /*
> >>>>> +            * For the reset-on-init path (e.g. an NPS memory partition
> >>>>> +            * switch) the RAS IP block hw_init was skipped under the
> >>>>> +            * minimal init level, so uniras was never enabled. Bring it
> >>>>> +            * up now that the reset domain has been unlocked. This is a
> >>>>> +            * no-op for any other reset path where RAS is already
> >>>>> +            * initialized, and for non-uniras devices.
> >>>>> +            */
> >>>>> +           amdgpu_ras_resume_after_reset(tmp_adev);
> >>>>>       }
> >>>>>     }
> >>>>>
> >>>>> diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c
> >>>>> b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c
> >>>>> index f627a97797ed..a70e532b3d00 100644
> >>>>> --- a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c
> >>>>> +++ b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c
> >>>>> @@ -465,6 +465,28 @@ static int amdgpu_ras_mgr_hw_fini(struct
> >>>> amdgpu_ip_block *ip_block)
> >>>>>       return 0;
> >>>>>     }
> >>>>>
> >>>>> +int amdgpu_ras_mgr_resume_after_reset(struct amdgpu_device
> *adev) {
> >>>>> +   struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
> >>>>> +   struct amdgpu_ras_mgr *ras_mgr =
> >>>> amdgpu_ras_mgr_get_context(adev);
> >>>>> +   struct amdgpu_ip_block *ip_block;
> >>>>> +
> >>>>> +   if (!con || !con->uniras_enabled)
> >>>>> +           return 0;
> >>>>> +
> >>>>> +   if (!ras_mgr || !ras_mgr->ras_core)
> >>>>> +           return -EINVAL;
> >>>>> +
> >>>>> +   if (ras_mgr->ras_is_ready)
> >>>>> +           return 0;
> >>>>> +
> >>>>> +   ip_block = amdgpu_device_ip_get_ip_block(adev,
> >>>> AMD_IP_BLOCK_TYPE_RAS);
> >>>>> +   if (!ip_block)
> >>>>> +           return -EINVAL;
> >>>>> +
> >>>>> +   return amdgpu_ras_mgr_hw_init(ip_block); }
> >>>>> +
> >>>>>     struct amdgpu_ras_mgr *amdgpu_ras_mgr_get_context(struct
> >>>> amdgpu_device *adev)
> >>>>>     {
> >>>>>       if (!adev || !adev->psp.ras_context.ras) diff --git
> >>>>> a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.h
> >>>>> b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.h
> >>>>> index 4f44a917d48b..3f80b9f1f0ac 100644
> >>>>> --- a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.h
> >>>>> +++ b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.h
> >>>>> @@ -82,6 +82,7 @@ int amdgpu_ras_mgr_handle_ras_cmd(struct
> >>>> amdgpu_device *adev,
> >>>>>               void *output, uint32_t out_size);
> >>>>>     int amdgpu_ras_mgr_pre_reset(struct amdgpu_device *adev);
> >>>>>     int amdgpu_ras_mgr_post_reset(struct amdgpu_device *adev);
> >>>>> +int amdgpu_ras_mgr_resume_after_reset(struct amdgpu_device
> >>>>> +*adev);
> >>>>>     int amdgpu_ras_mgr_lookup_bad_pages_in_a_row(struct
> >> amdgpu_device
> >>>> *adev,
> >>>>>               uint64_t addr, uint64_t *nps_page_addr, uint32_t
> >>>> max_page_count);
> >>>>>     #endif
> >>>
> >

Reply via email to