[PATCH] drm/xe: Add L3 bank and node masks to topology query

Lucas De Marchi lucas.demarchi at intel.com
Fri Jan 26 15:53:47 UTC 2024


On Fri, Jan 26, 2024 at 03:38:40PM +0000, Francois Dugast wrote:
>Expose the masks of L3 banks and of L3 nodes to user space. L3 count is not
>sufficient because in some configuration not all banks are enabled, so user
>space needs to know which ones.
>
>Bspec: 52545, 52546, 62482
>Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")

these are reserved for fixes, not feature additions. Particularly ones
adding UAPI, we don't want to rush it in the current kernel.

+Matt Roper

>Signed-off-by: Francois Dugast <francois.dugast at intel.com>
>Cc: Jonathan Cavitt <jonathan.cavitt at intel.com>
>Cc: Robert Krzemien <robert.krzemien at intel.com>
>---
> drivers/gpu/drm/xe/regs/xe_gt_regs.h |  1 +
> drivers/gpu/drm/xe/xe_gt_topology.c  | 38 ++++++++++++++++++++++++++++
> drivers/gpu/drm/xe/xe_gt_types.h     | 14 ++++++++--
> drivers/gpu/drm/xe/xe_query.c        | 20 +++++++++++++--
> include/uapi/drm/xe_drm.h            |  2 ++
> 5 files changed, 71 insertions(+), 4 deletions(-)
>
>diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
>index cd27480f6486..f8606649d1e2 100644
>--- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
>+++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
>@@ -156,6 +156,7 @@
> #define	MIRROR_FUSE3				XE_REG(0x9118)
> #define   XE2_NODE_ENABLE_MASK			REG_GENMASK(31, 16)
> #define   L3BANK_PAIR_COUNT			4
>+#define   L3MODE_MASK				REG_GENMASK(7, 4)

is this supposed to be L3*N*ODE_MASK?


Lucas De Marchi

> #define   L3BANK_MASK				REG_GENMASK(3, 0)
> /* on Xe_HP the same fuses indicates mslices instead of L3 banks */
> #define   MAX_MSLICES				4
>diff --git a/drivers/gpu/drm/xe/xe_gt_topology.c b/drivers/gpu/drm/xe/xe_gt_topology.c
>index a8d7f272c30a..6f4cf147a7aa 100644
>--- a/drivers/gpu/drm/xe/xe_gt_topology.c
>+++ b/drivers/gpu/drm/xe/xe_gt_topology.c
>@@ -13,6 +13,8 @@
>
> #define XE_MAX_DSS_FUSE_BITS (32 * XE_MAX_DSS_FUSE_REGS)
> #define XE_MAX_EU_FUSE_BITS (32 * XE_MAX_EU_FUSE_REGS)
>+#define XE_MAX_L3_BANK_FUSE_BITS (32 * XE_MAX_L3_BANK_FUSE_REGS)
>+#define XE_MAX_L3_NODE_FUSE_BITS (32 * XE_MAX_L3_NODE_FUSE_REGS)
>
> static void
> load_dss_mask(struct xe_gt *gt, xe_dss_mask_t mask, int numregs, ...)
>@@ -62,6 +64,36 @@ load_eu_mask(struct xe_gt *gt, xe_eu_mask_t mask)
> 	bitmap_from_arr32(mask, &val, XE_MAX_EU_FUSE_BITS);
> }
>
>+static void
>+load_l3_masks(struct xe_gt *gt, xe_l3_bank_mask_t l3_bank_mask,
>+	      xe_l3_node_mask_t l3_node_mask)
>+{
>+	u32 bank, node;
>+
>+	if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270) {
>+		node = REG_FIELD_GET(MEML3_EN_MASK,
>+				     xe_mmio_read32(gt, MIRROR_FUSE3));
>+		bank = REG_FIELD_GET(GT_L3_EXC_MASK,
>+				     xe_mmio_read32(gt, XEHP_FUSE4));
>+	} else if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1250) {
>+		node = REG_FIELD_GET(MEML3_EN_MASK,
>+				     xe_mmio_read32(gt, MIRROR_FUSE3));
>+		bank = REG_FIELD_GET(L3MODE_MASK,
>+				     xe_mmio_read32(gt, MIRROR_FUSE3));
>+	} else {
>+		/*
>+		 * Here the mask logic is reversed: a bit is set if the bank is
>+		 * disabled.
>+		 */
>+		bank = REG_FIELD_GET(L3BANK_MASK,
>+				     ~xe_mmio_read32(gt, MIRROR_FUSE3));
>+		node = 0; /* Unused */
>+	}
>+
>+	bitmap_from_arr32(l3_bank_mask, &bank, XE_MAX_L3_BANK_FUSE_BITS);
>+	bitmap_from_arr32(l3_node_mask, &node, XE_MAX_L3_NODE_FUSE_BITS);
>+}
>+
> static void
> get_num_dss_regs(struct xe_device *xe, int *geometry_regs, int *compute_regs)
> {
>@@ -106,6 +138,8 @@ xe_gt_topology_init(struct xe_gt *gt)
> 		      XEHPC_GT_COMPUTE_DSS_ENABLE_EXT,
> 		      XE2_GT_COMPUTE_DSS_2);
> 	load_eu_mask(gt, gt->fuse_topo.eu_mask_per_dss);
>+	load_l3_masks(gt, gt->fuse_topo.l3_bank_mask,
>+		      gt->fuse_topo.l3_node_mask);
>
> 	xe_gt_topology_dump(gt, &p);
> }
>@@ -121,6 +155,10 @@ xe_gt_topology_dump(struct xe_gt *gt, struct drm_printer *p)
> 	drm_printf(p, "EU mask per DSS:     %*pb\n", XE_MAX_EU_FUSE_BITS,
> 		   gt->fuse_topo.eu_mask_per_dss);
>
>+	drm_printf(p, "L3 bank mask:        %*pb\n", XE_MAX_L3_BANK_FUSE_BITS,
>+		   gt->fuse_topo.l3_bank_mask);
>+	drm_printf(p, "L3 node mask:        %*pb\n", XE_MAX_L3_NODE_FUSE_BITS,
>+		   gt->fuse_topo.l3_node_mask);
> }
>
> /*
>diff --git a/drivers/gpu/drm/xe/xe_gt_types.h b/drivers/gpu/drm/xe/xe_gt_types.h
>index 70c615dd1498..adb1de613e77 100644
>--- a/drivers/gpu/drm/xe/xe_gt_types.h
>+++ b/drivers/gpu/drm/xe/xe_gt_types.h
>@@ -24,11 +24,15 @@ enum xe_gt_type {
> 	XE_GT_TYPE_MEDIA,
> };
>
>-#define XE_MAX_DSS_FUSE_REGS	3
>-#define XE_MAX_EU_FUSE_REGS	1
>+#define XE_MAX_DSS_FUSE_REGS		3
>+#define XE_MAX_EU_FUSE_REGS		1
>+#define XE_MAX_L3_BANK_FUSE_REGS	1
>+#define XE_MAX_L3_NODE_FUSE_REGS	1
>
> typedef unsigned long xe_dss_mask_t[BITS_TO_LONGS(32 * XE_MAX_DSS_FUSE_REGS)];
> typedef unsigned long xe_eu_mask_t[BITS_TO_LONGS(32 * XE_MAX_EU_FUSE_REGS)];
>+typedef unsigned long xe_l3_bank_mask_t[BITS_TO_LONGS(32 * XE_MAX_L3_BANK_FUSE_REGS)];
>+typedef unsigned long xe_l3_node_mask_t[BITS_TO_LONGS(32 * XE_MAX_L3_NODE_FUSE_REGS)];
>
> struct xe_mmio_range {
> 	u32 start;
>@@ -332,6 +336,12 @@ struct xe_gt {
>
> 		/** @fuse_topo.eu_mask_per_dss: EU mask per DSS*/
> 		xe_eu_mask_t eu_mask_per_dss;
>+
>+		/** @l3_bank_mask: L3 bank mask */
>+		xe_l3_bank_mask_t l3_bank_mask;
>+
>+		/** @l3_node_mask: L3 node mask */
>+		xe_l3_node_mask_t l3_node_mask;
> 	} fuse_topo;
>
> 	/** @steering: register steering for individual HW units */
>diff --git a/drivers/gpu/drm/xe/xe_query.c b/drivers/gpu/drm/xe/xe_query.c
>index 9b35673b286c..fe3906e8f721 100644
>--- a/drivers/gpu/drm/xe/xe_query.c
>+++ b/drivers/gpu/drm/xe/xe_query.c
>@@ -453,10 +453,12 @@ static int query_hwconfig(struct xe_device *xe,
> static size_t calc_topo_query_size(struct xe_device *xe)
> {
> 	return xe->info.gt_count *
>-		(3 * sizeof(struct drm_xe_query_topology_mask) +
>+		(5 * sizeof(struct drm_xe_query_topology_mask) +
> 		 sizeof_field(struct xe_gt, fuse_topo.g_dss_mask) +
> 		 sizeof_field(struct xe_gt, fuse_topo.c_dss_mask) +
>-		 sizeof_field(struct xe_gt, fuse_topo.eu_mask_per_dss));
>+		 sizeof_field(struct xe_gt, fuse_topo.eu_mask_per_dss) +
>+		 sizeof_field(struct xe_gt, fuse_topo.l3_bank_mask) +
>+		 sizeof_field(struct xe_gt, fuse_topo.l3_node_mask));
> }
>
> static void __user *copy_mask(void __user *ptr,
>@@ -515,6 +517,20 @@ static int query_gt_topology(struct xe_device *xe,
> 				      sizeof(gt->fuse_topo.eu_mask_per_dss));
> 		if (IS_ERR(query_ptr))
> 			return PTR_ERR(query_ptr);
>+
>+		topo.type = DRM_XE_TOPO_L3_BANK;
>+		query_ptr = copy_mask(query_ptr, &topo,
>+				      gt->fuse_topo.l3_bank_mask,
>+				      sizeof(gt->fuse_topo.l3_bank_mask));
>+		if (IS_ERR(query_ptr))
>+			return PTR_ERR(query_ptr);
>+
>+		topo.type = DRM_XE_TOPO_L3_NODE;
>+		query_ptr = copy_mask(query_ptr, &topo,
>+				      gt->fuse_topo.l3_node_mask,
>+				      sizeof(gt->fuse_topo.l3_node_mask));
>+		if (IS_ERR(query_ptr))
>+			return PTR_ERR(query_ptr);
> 	}
>
> 	return 0;
>diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
>index 50bbea0992d9..eca8f5f502c3 100644
>--- a/include/uapi/drm/xe_drm.h
>+++ b/include/uapi/drm/xe_drm.h
>@@ -513,6 +513,8 @@ struct drm_xe_query_topology_mask {
> #define DRM_XE_TOPO_DSS_GEOMETRY	(1 << 0)
> #define DRM_XE_TOPO_DSS_COMPUTE		(1 << 1)
> #define DRM_XE_TOPO_EU_PER_DSS		(1 << 2)
>+#define DRM_XE_TOPO_L3_BANK		(1 << 3)
>+#define DRM_XE_TOPO_L3_NODE		(1 << 4)
> 	/** @type: type of mask */
> 	__u16 type;
>
>-- 
>2.34.1
>


More information about the Intel-xe mailing list