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); > } >
