AMD General

-----Original Message-----
From: Lazar, Lijo <[email protected]>
Sent: Thursday, October 8, 2026 2:07 PM
To: [email protected]
Cc: Zhang, Hawking <[email protected]>; Deucher, Alexander 
<[email protected]>; Kamal, Asad <[email protected]>
Subject: Re: [PATCH] drm/amdgpu: Allow cancelling a requested NPS mode

<ping>

On 07-Oct-26 5:33 PM, Lijo Lazar wrote:
> NPS mode change request doesn't allow to request the current mode.
> This causes an issue where a user stores a request and later wants to
> cancel the request by writing the current mode back. Th pending


Minor nit:
Th->The

Reviewed-by: Asad Kamal <[email protected]>

Thanks & Regards
Asad
> request stays the same as before.
>
> Allow user to change the mode by comparing against the cached request.
> Writing the current mode back clears the pending request without
> asking for a reload.
>
> Fixes: 012be6f22c01 ("drm/amdgpu: Add sysfs interfaces for NPS mode")
> Signed-off-by: Lijo Lazar <[email protected]>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 52 ++++++++++++++++++-------
>   drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h |  4 ++
>   drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 13 +++++++
>   3 files changed, 56 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> index d25ca903e21b..87d78fd34e23 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
> @@ -1398,6 +1398,40 @@ static ssize_t available_memory_partition_show(struct 
> device *dev,
>       return size;
>   }
>
> +void amdgpu_gmc_set_requested_nps_mode(struct amdgpu_device *adev,
> +                                    enum amdgpu_memory_partition mode) {
> +     struct amdgpu_hive_info *hive;
> +
> +     /* If device is part of hive, all devices in the hive should request the
> +      * same mode. Hence store the requested mode in hive.
> +      */
> +     hive = amdgpu_get_xgmi_hive(adev);
> +     if (hive) {
> +             atomic_set(&hive->requested_nps_mode, mode);
> +             amdgpu_put_xgmi_hive(hive);
> +     } else {
> +             adev->gmc.requested_nps_mode = mode;
> +     }
> +}
> +
> +enum amdgpu_memory_partition
> +amdgpu_gmc_get_requested_nps_mode(struct amdgpu_device *adev) {
> +     struct amdgpu_hive_info *hive;
> +     enum amdgpu_memory_partition mode;
> +
> +     hive = amdgpu_get_xgmi_hive(adev);
> +     if (hive) {
> +             mode = atomic_read(&hive->requested_nps_mode);
> +             amdgpu_put_xgmi_hive(hive);
> +     } else {
> +             mode = adev->gmc.requested_nps_mode;
> +     }
> +
> +     return mode;
> +}
> +
>   static ssize_t current_memory_partition_store(struct device *dev,
>                                             struct device_attribute *attr,
>                                             const char *buf, size_t count) @@ 
> -1405,7 +1439,6 @@
> static ssize_t current_memory_partition_store(struct device *dev,
>       struct drm_device *ddev = dev_get_drvdata(dev);
>       struct amdgpu_device *adev = drm_to_adev(ddev);
>       enum amdgpu_memory_partition mode;
> -     struct amdgpu_hive_info *hive;
>       int i;
>
>       mode = UNKNOWN_MEMORY_PARTITION_MODE; @@ -1419,23 +1452,16 @@
> static ssize_t current_memory_partition_store(struct device *dev,
>       if (mode == UNKNOWN_MEMORY_PARTITION_MODE)
>               return -EINVAL;
>
> -     if (mode == adev->gmc.gmc_funcs->query_mem_partition_mode(adev)) {
> +     if (mode == amdgpu_gmc_get_requested_nps_mode(adev)) {
>               dev_info(
>                       adev->dev,
> -                     "requested NPS mode is same as current NPS mode, 
> skipping\n");
> +                     "requested NPS mode is same as current/already 
> requested NPS mode,
> +skipping\n");
>               return count;
>       }
>
> -     /* If device is part of hive, all devices in the hive should request the
> -      * same mode. Hence store the requested mode in hive.
> -      */
> -     hive = amdgpu_get_xgmi_hive(adev);
> -     if (hive) {
> -             atomic_set(&hive->requested_nps_mode, mode);
> -             amdgpu_put_xgmi_hive(hive);
> -     } else {
> -             adev->gmc.requested_nps_mode = mode;
> -     }
> +     amdgpu_gmc_set_requested_nps_mode(adev, mode);
> +     if (mode == amdgpu_gmc_query_memory_partition(adev))
> +             return count;
>
>       dev_info(
>               adev->dev,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
> index 76e6f1f96913..89f1ee829eea 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
> @@ -484,6 +484,10 @@ enum amdgpu_memory_partition
>   amdgpu_gmc_get_memory_partition(struct amdgpu_device *adev, u32 
> *supp_modes);
>   enum amdgpu_memory_partition
>   amdgpu_gmc_query_memory_partition(struct amdgpu_device *adev);
> +void amdgpu_gmc_set_requested_nps_mode(struct amdgpu_device *adev,
> +                                    enum amdgpu_memory_partition mode); enum
> +amdgpu_memory_partition amdgpu_gmc_get_requested_nps_mode(struct
> +amdgpu_device *adev);
>   int amdgpu_gmc_init_mem_ranges(struct amdgpu_device *adev);
>   void amdgpu_gmc_init_sw_mem_ranges(struct amdgpu_device *adev,
>                                  struct amdgpu_mem_partition_info 
> *mem_ranges); diff --git
> a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> index 85ba228f002d..5c233acba084 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> @@ -1617,6 +1617,7 @@ static int gmc_v9_0_early_init(struct amdgpu_ip_block 
> *ip_block)
>   static int gmc_v9_0_late_init(struct amdgpu_ip_block *ip_block)
>   {
>       struct amdgpu_device *adev = ip_block->adev;
> +     bool nps_switch_support;
>       int r;
>
>       r = amdgpu_gmc_allocate_vm_inv_eng(adev);
> @@ -1641,6 +1642,18 @@ static int gmc_v9_0_late_init(struct amdgpu_ip_block 
> *ip_block)
>               amdgpu_ras_reset_error_count(adev, AMDGPU_RAS_BLOCK__HDP);
>       }
>
> +     nps_switch_support = !adev->gmc.xgmi.connected_to_cpu &&
> +                          (hweight32(adev->gmc.supported_nps_modes &
> +                                     AMDGPU_ALL_NPS_MASK) > 1);
> +     /* Initialize requested NPS mode to be the same as current mode */
> +     if (nps_switch_support) {
> +             enum amdgpu_memory_partition mode =
> +                     amdgpu_gmc_get_requested_nps_mode(adev);
> +             if (mode == UNKNOWN_MEMORY_PARTITION_MODE)
> +                     amdgpu_gmc_set_requested_nps_mode(
> +                             adev, amdgpu_gmc_query_memory_partition(adev));
> +     }
> +
>       return amdgpu_irq_get(adev, &adev->gmc.vm_fault, 0);
>   }
>

Reply via email to