Use a bitmap to track PTL disable requests from sysfs and profiler.
PTL is only re-enabled once all sources have released their disable
requests, avoiding premature enablement.

Signed-off-by: Perry Yuan <[email protected]>
Reviewed-by: Yifan Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c  | 32 +++++++++++++++++++-----
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h  |  8 ++++++
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c |  4 +++
 3 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index 95af5f1d8f5b..3d7c1a788cf6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -1314,6 +1314,21 @@ int amdgpu_ptl_perf_monitor_ctrl(struct amdgpu_device 
*adev, u32 req_code,
                        ptl->fmt2 == ptl_fmt2)
                return 0;
 
+       /* If enabling PTL, check disable bitmap */
+       if (req_code == PSP_PTL_PERF_MON_SET && *ptl_state == 1) {
+               if (!bitmap_empty(ptl->disable_bitmap,
+                                       AMDGPU_PTL_DISABLE_MAX)) {
+                       dev_dbg(adev->dev,
+                                       "PTL enable blocked: SYSFS=%d, 
PROFILER=%d (ref=%d)\n",
+                                       test_bit(AMDGPU_PTL_DISABLE_SYSFS,
+                                               ptl->disable_bitmap),
+                                       test_bit(AMDGPU_PTL_DISABLE_PROFILER,
+                                               ptl->disable_bitmap),
+                                       atomic_read(&ptl->disable_ref));
+                       return 0;
+               }
+       }
+
        return psp_ptl_invoke(psp, req_code, ptl_state, &ptl_fmt1, &ptl_fmt2);
 }
 
@@ -1351,9 +1366,10 @@ static ssize_t ptl_enable_store(struct device *dev,
        struct amdgpu_device *adev = drm_to_adev(ddev);
        struct psp_context *psp = &adev->psp;
        struct amdgpu_ptl *ptl = &adev->psp.ptl;
-       bool enable, cur_enabled;
        uint32_t ptl_state, fmt1, fmt2;
        int ret;
+       bool enable;
+       bool bit_changed = false;
 
        mutex_lock(&ptl->mutex);
        if (sysfs_streq(buf, "enabled") || sysfs_streq(buf, "1")) {
@@ -1369,18 +1385,22 @@ static ssize_t ptl_enable_store(struct device *dev,
        fmt2 = ptl->fmt2;
        ptl_state = enable ? 1 : 0;
 
-       cur_enabled = READ_ONCE(psp->enabled);
-       if (cur_enabled == enable) {
-               mutex_unlock(&psp->mutex);
-               return count;
-       }
+       if (enable)
+               bit_changed = test_and_clear_bit(AMDGPU_PTL_DISABLE_SYSFS,
+                               ptl->disable_bitmap);
 
        ret = amdgpu_ptl_perf_monitor_ctrl(adev, PSP_PTL_PERF_MON_SET, 
&ptl_state, &fmt1, &fmt2);
        if (ret) {
                dev_err(adev->dev, "Failed to set PTL err = %d\n", ret);
+               if (enable && bit_changed)
+                       set_bit(AMDGPU_PTL_DISABLE_SYSFS, ptl->disable_bitmap);
                mutex_unlock(&ptl->mutex);
                return ret;
        }
+
+       if (!enable)
+               set_bit(AMDGPU_PTL_DISABLE_SYSFS, ptl->disable_bitmap);
+
        mutex_unlock(&ptl->mutex);
 
        return count;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
index 0997b13a5f41..2de7815c7516 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
@@ -31,6 +31,7 @@
 #include "ta_ras_if.h"
 #include "ta_rap_if.h"
 #include "ta_secureDisplay_if.h"
+#include <linux/bitops.h>
 
 #define PSP_FENCE_BUFFER_SIZE  0x1000
 #define PSP_CMD_BUFFER_SIZE    0x1000
@@ -382,6 +383,12 @@ struct psp_ptl_perf_req {
        uint32_t pref_format2;
 };
 
+enum amdgpu_ptl_disable_source {
+       AMDGPU_PTL_DISABLE_SYSFS = 0,
+       AMDGPU_PTL_DISABLE_PROFILER,
+       AMDGPU_PTL_DISABLE_MAX,
+};
+
 struct amdgpu_ptl {
        enum amdgpu_ptl_fmt             fmt1;
        enum amdgpu_ptl_fmt             fmt2;
@@ -390,6 +397,7 @@ struct amdgpu_ptl {
        /* PTL disable reference counting */
        atomic_t                        disable_ref;
        struct mutex                    mutex;
+       DECLARE_BITMAP(disable_bitmap, AMDGPU_PTL_DISABLE_MAX);
 };
 
 struct psp_context {
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index c276ef6801d0..f375dffcbdf6 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -1814,6 +1814,8 @@ int kfd_ptl_disable_request(struct kfd_process_device 
*pdd,
                        goto out;
                }
        }
+
+       set_bit(AMDGPU_PTL_DISABLE_PROFILER, ptl->disable_bitmap);
        pdd->ptl_disable_req = true;
 
 out:
@@ -1834,9 +1836,11 @@ int kfd_ptl_disable_release(struct kfd_process_device 
*pdd,
                goto out;
 
        if (atomic_dec_return(&ptl->disable_ref) == 0) {
+               clear_bit(AMDGPU_PTL_DISABLE_PROFILER, ptl->disable_bitmap);
                ret = kfd_ptl_control(pdd, true);
                if (ret) {
                        atomic_inc(&ptl->disable_ref);
+                       set_bit(AMDGPU_PTL_DISABLE_PROFILER, 
ptl->disable_bitmap);
                        dev_warn(adev->dev, "Failed to enable PTL on release: 
%d\n", ret);
                        goto out;
                }
-- 
2.34.1

Reply via email to