On 22-Sep-26 8:40 PM, James Zhu wrote:

On 2026-09-22 10:26, Lazar, Lijo wrote:


On 22-Sep-26 7:41 PM, James Zhu wrote:

On 2026-09-22 09:45, Lazar, Lijo wrote:


On 22-Sep-26 7:05 PM, James Zhu wrote:

On 2026-09-22 01:22, Lazar, Lijo wrote:


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.

[JZ] Yes, 8-XCC device should not reach AMDGPU_XCP_NO_PARTITION case.

the if(!xcp_mgr ||xcp_id ==AMDGPU_XCP_NO_PARTITION) mainly covers non partition device, I can remove the above comments which don't reflect the source accurately.

Then I'm not sure what issue this is fixing.

Multi-xcc devices will be in SPX mode and will return a mask with all the XCCs. Non-multi xcc devices are expected to have this set to 1 anyway to reflect that a single GC is present always.
[JZ] Just realized a Fixes tag is added. I think somehow AI review added it, and I did not check properly, is should be removed also. Sorry for this confusing!

I see that it also added an external function like this -

amdgpu_xcp_get_xcc_mask

The expectation is any IP instance mask within a partition needs to obtained through - amdgpu_xcp_get_inst_details

Also, amdgpu_xcp_get_xcc_mask provides this which is not correct -

*xcc_mask = adev->gfx.xcc_mask

xcp instance mask operates only return logical mask of instances present (xcc_mask could include disabled ones also).
[JZ] Here is only for non-partition device. I think adev->gfx.xcc_mask=0x1.
I can change it to below code to clear the confusing

*xcc_mask = BIT(0);

How Do you think?
Thanks!


Once that is done, it's the same as what exists now (without the extra function).

Also, why do you need get_xcc_mask function? If the difficulty is in getting amdgpu_xcp* pointer from xcp_id, then a wrapper could be added and used like

xcp = amdgpu_xcp_get_obj(adev, xcp_id);
amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_GFX, &xcc_mask);

Thanks,
Lijo

James


Thanks,
Lijo


Thanks,
Lijo

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