[PATCH i-g-t 2/2] tools/xe-perf: Change xe_perf_recorder command line to use OA unit id

Umesh Nerlige Ramappa umesh.nerlige.ramappa at intel.com
Mon Jun 16 17:47:06 UTC 2025


On Fri, Jun 13, 2025 at 06:08:27PM -0700, Ashutosh Dixit wrote:
>Xe OA uapi identifies an OA unit by means of its OA unit id.
>xe_perf_recorder was instead using engine class/instance to identify the OA
>unit, in order to have a common command line with i915_perf_recorder.
>
>However, Xe KMD now supports new OA units, which don't have any associated
>engines. This means that it is not possible to use engine class/instance to
>identify these OA units and these OA units must instead be identified by
>means of the OA unit id, as originally intended in Xe OA uapi.
>
>Therefore, change xe_perf_recorder command line to use OA unit id instead
>of engine class/instance to identify the OA unit.
>
>Signed-off-by: Ashutosh Dixit <ashutosh.dixit at intel.com>

LGTM,

Reviewed-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa at intel.com>

Thanks,
Umesh
>---
> tools/xe-perf/xe_perf_recorder.c | 66 ++++++++++++++++++++++----------
> 1 file changed, 45 insertions(+), 21 deletions(-)
>
>diff --git a/tools/xe-perf/xe_perf_recorder.c b/tools/xe-perf/xe_perf_recorder.c
>index 5bd91aeb19..f200fe9c9b 100644
>--- a/tools/xe-perf/xe_perf_recorder.c
>+++ b/tools/xe-perf/xe_perf_recorder.c
>@@ -351,10 +351,9 @@ struct recording_context {
> 	const char *command_fifo;
> 	int command_fifo_fd;
>
>-	int gt;
>-	struct drm_xe_engine_class_instance eci;
>-	struct drm_xe_engine_class_instance *hwe;
>+	int oa_unit_id;
> 	struct drm_xe_oa_unit *oa_unit;
>+	struct drm_xe_engine_class_instance *hwe;
> };
>
> static void set_fd_flags(int fd, int flags)
>@@ -829,8 +828,7 @@ usage(const char *name)
> 		"     --output,             -o <path>   Output file (default = xe_perf.record)\n"
> 		"     --cpu-clock,          -k <path>   Cpu clock to use for correlations\n"
> 		"                                       Values: boot, mono, mono_raw (default = mono)\n"
>-		"     --engine-class        -e <value>  Engine class used for the OA capture.\n"
>-		"     --engine-instance     -i <value>  Engine instance used for the OA capture.\n",
>+		"     --oa-unit-id          -u <value>  OA unit id for 
>the capture.\n",
> 		name);
> }
>
>@@ -859,6 +857,40 @@ teardown_recording_context(struct recording_context *ctx)
> 		close(ctx->drm_fd);
> }
>
>+static int assign_hwe(int fd, struct recording_context *ctx)
>+{
>+	struct drm_xe_query_oa_units *qoa = xe_oa_units(fd);
>+	struct drm_xe_oa_unit *oau;
>+	int oam_sag_gt_id = 1;
>+	uint8_t *poau;
>+
>+	if (ctx->oa_unit->num_engines) {
>+		/* Just use the first hwe attached to the oa_unit */
>+		ctx->hwe = &ctx->oa_unit->eci[0];
>+		return 0;
>+	}
>+
>+	assert(ctx->oa_unit->oa_unit_type == DRM_XE_OA_UNIT_TYPE_OAM_SAG);
>+
>+	/* Use first hwe attached to a different oa_unit on the same gt */
>+	poau = (uint8_t *)&qoa->oa_units[0];
>+	for (int i = 0; i < qoa->num_oa_units; i++) {
>+		oau = (struct drm_xe_oa_unit *)poau;
>+
>+		if (!oau->num_engines)
>+			goto next;
>+
>+		if (oau->eci[0].gt_id == oam_sag_gt_id) {
>+			ctx->hwe = &oau->eci[0];
>+			return 0;
>+		}
>+next:
>+		poau += sizeof(*oau) + oau->num_engines * sizeof(oau->eci[0]);
>+	}
>+
>+	return -1;
>+}
>+
> static int assign_oa_unit(int fd, struct recording_context *ctx)
> {
> 	struct drm_xe_query_oa_units *qoa = xe_oa_units(fd);
>@@ -869,13 +901,9 @@ static int assign_oa_unit(int fd, struct recording_context *ctx)
> 	for (int i = 0; i < qoa->num_oa_units; i++) {
> 		oau = (struct drm_xe_oa_unit *)poau;
>
>-		for (int j = 0; j < oau->num_engines; j++) {
>-			if (oau->eci[j].engine_class == ctx->eci.engine_class &&
>-			    oau->eci[j].engine_instance == ctx->eci.engine_instance) {
>-				ctx->hwe = &oau->eci[j];
>-				ctx->oa_unit = oau;
>-				return 0;
>-			}
>+		if (oau->oa_unit_id == ctx->oa_unit_id) {
>+			ctx->oa_unit = oau;
>+			return assign_hwe(fd, ctx);
> 		}
>
> 		poau += sizeof(*oau) + oau->num_engines * sizeof(oau->eci[0]);
>@@ -898,8 +926,7 @@ main(int argc, char *argv[])
> 		{"size",		required_argument, 0, 's'},
> 		{"command-fifo",	required_argument, 0, 'f'},
> 		{"cpu-clock",		required_argument, 0, 'k'},
>-		{"engine-class",	required_argument, 0, 'e'},
>-		{"engine-instance",	required_argument, 0, 'i'},
>+		{"oa-unit-id",		required_argument, 0, 'u'},
> 		{0, 0, 0, 0}
> 	};
> 	const struct {
>@@ -927,10 +954,10 @@ main(int argc, char *argv[])
> 		.command_fifo = XE_PERF_RECORD_FIFO_PATH,
> 		.command_fifo_fd = -1,
>
>-		.eci = { DRM_XE_ENGINE_CLASS_RENDER, 0 },
>+		.oa_unit_id = 0,
> 	};
>
>-	while ((opt = getopt_long(argc, argv, "hc:d:p:m:Co:s:f:k:P:e:i:", long_options, NULL)) != -1) {
>+	while ((opt = getopt_long(argc, argv, "hc:d:p:m:Co:s:f:k:P:u:", long_options, NULL)) != -1) {
> 		switch (opt) {
> 		case 'h':
> 			usage(argv[0]);
>@@ -978,11 +1005,8 @@ main(int argc, char *argv[])
> 			}
> 			break;
> 		}
>-		case 'e':
>-			ctx.eci.engine_class = atoi(optarg);
>-			break;
>-		case 'i':
>-			ctx.eci.engine_instance = atoi(optarg);
>+		case 'u':
>+			ctx.oa_unit_id = atoi(optarg);
> 			break;
> 		default:
> 			fprintf(stderr, "Internal error: "
>-- 
>2.48.1
>


More information about the igt-dev mailing list