On 22-Sep-26 1:33 AM, James Zhu wrote:
Add amdgpu_xcp_get_xcc_mask() to return the XCC instance mask for a given
XCP partition. This is needed by upcoming SPM (Stream Performance Monitor)
support, which programs hardware per partition and must operate only on
the XCCs that belong to a given XCP.

For partitioned systems the helper returns only the XCCs belonging to the
specified XCP. When @xcp_id is AMDGPU_XCP_NO_PARTITION (or the device is
not partitioned) it returns the device's full XCC mask (e.g. 0xFF for an
8-XCC device). Note that the full device mask is returned even on a
partitioned device; callers that require partition isolation (e.g. SPM)
must reject AMDGPU_XCP_NO_PARTITION on a partitioned device themselves.


Could you clarifiy on this part - xcp_id = AMDGPU_XCP_NO_PARTITION usage on 8-XCC device?

The default state on a multi-XCC device after driver load is all XCCs in a single partition called SPX. It should have at least one partition valid.

Thanks,
Lioj

amdgpu_xcp_get_num_xcc() is reworked to take (adev, xcp_id) and derive the
count from this helper via hweight32(). The helper is defined out of line
in amdgpu_xcp.c so that the static inline in amdgpu_xcp.h never has to
dereference the (incomplete) struct amdgpu_device; it only passes the
pointer through.

This is a user-visible change: amdgpu_xcp_get_num_xcc() previously
returned 1 for non-partitioned systems (and for AMDGPU_XCP_NO_PARTITION),
and now returns the actual XCC count (e.g. 8 for an 8-XCC device). CWSR
callers (amdgpu_kms.c, amdgpu_userq.c, mes_userqueue.c) scale the per-XCC
control-stack and debug-memory sizes by num_xcc, so the uAPI-visible
ctl_stack_size and dbg_mem_size values grow accordingly to match the
actual hardware resource requirements, which were previously undersized.

Fixes: 4cd417bfec49 ("drm/amdgpu: Add helper function to get xcc count")
Signed-off-by: James Zhu <[email protected]>
Reviewed-by: Bing Ma <[email protected]>
---
  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  2 +-
  drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c  |  2 +-
  drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c    | 48 ++++++++++++++++++++++
  drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.h    | 32 +++++++--------
  drivers/gpu/drm/amd/amdgpu/mes_userqueue.c |  3 +-
  5 files changed, 66 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 57fa69c0382d..7782ccd4d28f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -1501,7 +1501,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
                fpriv = (struct amdgpu_fpriv *)filp->driver_priv;
                if (!amdgpu_trap_is_enabled(adev) || !fpriv->trap_obj)
                        return -EOPNOTSUPP;
-               num_xcc = amdgpu_xcp_get_num_xcc(adev->xcp_mgr, fpriv->xcp_id);
+               num_xcc = amdgpu_xcp_get_num_xcc(adev, fpriv->xcp_id);
                cwsr_info.ctl_stack_size =
                        adev->trap_info->cwsr.xcc_ctl_stack_sz * num_xcc;
                cwsr_info.dbg_mem_size =
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
index db09e879b85e..d19af9cb6ee1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
@@ -258,7 +258,7 @@ int amdgpu_userq_input_trap_params_validate(struct 
amdgpu_usermode_queue *queue,
        int num_xcc;
        int r;
- num_xcc = amdgpu_xcp_get_num_xcc(adev->xcp_mgr, fpriv->xcp_id);
+       num_xcc = amdgpu_xcp_get_num_xcc(adev, fpriv->xcp_id);
        r = amdgpu_trap_validate_params(queue->userq_mgr->adev, trap_params,
                                        num_xcc);
        if (r)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c
index 2a56f5ec9c76..90846d55292b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c
@@ -390,6 +390,54 @@ int amdgpu_xcp_get_inst_details(struct amdgpu_xcp *xcp,
        return 0;
  }
+/**
+ * amdgpu_xcp_get_xcc_mask - Get XCC instance mask for a partition
+ * @adev: amdgpu device pointer
+ * @xcp_id: XCP partition ID
+ * @xcc_mask: output parameter for XCC instance mask
+ *
+ * Returns the XCC instance mask for the specified XCP partition.
+ * For partitioned systems, returns only the XCCs belonging to this XCP.
+ *
+ * When @xcp_id is AMDGPU_XCP_NO_PARTITION (or the device is not
+ * partitioned), the device's full XCC mask is returned (e.g. 0xFF for an
+ * 8-XCC device). Note that the full device mask is returned even on a
+ * partitioned device: callers that require partition isolation (e.g. SPM)
+ * must reject AMDGPU_XCP_NO_PARTITION on a partitioned device themselves.
+ *
+ * Note: On error, xcc_mask is undefined. Callers must check return code
+ * and only read xcc_mask when return == 0.
+ *
+ * Return: 0 on success (non-partitioned systems or valid XCP found),
+ *         -EINVAL if xcc_mask is NULL, no matching XCP id is found, or the
+ *         partition's GFX IP details are unavailable
+ */
+int amdgpu_xcp_get_xcc_mask(struct amdgpu_device *adev, int xcp_id,
+                           uint32_t *xcc_mask)
+{
+       struct amdgpu_xcp_mgr *xcp_mgr = adev->xcp_mgr;
+       struct amdgpu_xcp *xcp;
+       int i;
+
+       if (!xcc_mask)
+               return -EINVAL;
+
+       if (!xcp_mgr || xcp_id == AMDGPU_XCP_NO_PARTITION) {
+               /* Non-partitioned: return the device's full XCC mask. */
+               *xcc_mask = adev->gfx.xcc_mask;
+               return 0;
+       }
+
+       /* Partitioned system: get this XCP's XCCs */
+       for_each_xcp(xcp_mgr, xcp, i) {
+               if (xcp->id == xcp_id)
+                       return amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_GFX,
+                                                          xcc_mask);
+       }
+
+       return -EINVAL;
+}
+
  int amdgpu_xcp_dev_register(struct amdgpu_device *adev,
                        const struct pci_device_id *ent)
  {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.h
index 692508be23fb..6eed82ad49b1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.h
@@ -44,6 +44,7 @@
  #define XCP_INST_MASK(num_inst, xcp_id)               \
        (num_inst ? GENMASK(num_inst - 1, 0) << (xcp_id * num_inst) : 0)
+struct amdgpu_device;
  struct amdgpu_fpriv;
enum AMDGPU_XCP_IP_BLOCK {
@@ -219,26 +220,23 @@ amdgpu_get_next_xcp(struct amdgpu_xcp_mgr *xcp_mgr, int 
*from)
        for (i = 0, xcp = amdgpu_get_next_xcp(xcp_mgr, &i); xcp; \
             ++i, xcp = amdgpu_get_next_xcp(xcp_mgr, &i))
-static inline int amdgpu_xcp_get_num_xcc(struct amdgpu_xcp_mgr *xcp_mgr,
-                                        int xcp_id)
+int amdgpu_xcp_get_xcc_mask(struct amdgpu_device *adev, int xcp_id,
+                           uint32_t *xcc_mask);
+
+static inline int amdgpu_xcp_get_num_xcc(struct amdgpu_device *adev, int 
xcp_id)
  {
-       struct amdgpu_xcp *xcp;
        uint32_t xcc_mask;
-       int i, r;
-
-       if (!xcp_mgr || xcp_id == AMDGPU_XCP_NO_PARTITION)
+       int r, count;
+
+       /* Derive the XCC count from the partition's XCC mask (or the full
+        * device mask when not partitioned). amdgpu_xcp_get_xcc_mask()
+        * handles both partitioned and non-partitioned cases.
+        */
+       r = amdgpu_xcp_get_xcc_mask(adev, xcp_id, &xcc_mask);
+       if (unlikely(r))
                return 1;
-       for_each_xcp(xcp_mgr, xcp, i) {
-               if (xcp->id == xcp_id) {
-                       r = amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_GFX,
-                                                       &xcc_mask);
-                       if (unlikely(r))
-                               return 1;
-                       else
-                               return hweight32(xcc_mask);
-               }
-       }
- return 1;
+       count = hweight32(xcc_mask);
+       return count ? count : 1;
  }
  #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c 
b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
index 16aa22b25098..1c7b2f3227e5 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
@@ -503,8 +503,7 @@ static int mes_userq_mqd_create(struct 
amdgpu_usermode_queue *queue,
                                uq_mgr_to_fpriv(queue->userq_mgr);
                        int num_xcc;
- num_xcc = amdgpu_xcp_get_num_xcc(adev->xcp_mgr,
-                                                        fpriv->xcp_id);
+                       num_xcc = amdgpu_xcp_get_num_xcc(adev, fpriv->xcp_id);
                        trap_params.ctx_save_area_address =
                                compute_mqd->ctx_save_area_va;
                        trap_params.cwsr_sz = compute_mqd->ctx_save_area_size;

Reply via email to