public inbox for igt-dev@lists.freedesktop.org
 help / color / mirror / Atom feed
From: Sowmiya S <sowmiya.s@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: swati2.sharma@intel.com, karthik.b.s@intel.com,
	Sowmiya S <sowmiya.s@intel.com>
Subject: [PATCH i-g-t v2 1/2] tests/kms_pipe_stress: make pipe assignment joiner-aware
Date: Mon, 23 Feb 2026 14:02:58 +0530	[thread overview]
Message-ID: <20260223083259.187783-2-sowmiya.s@intel.com> (raw)
In-Reply-To: <20260223083259.187783-1-sowmiya.s@intel.com>

Use joiner-aware pipe allocation in kms_pipe_stress
by replacing linear output-to-pipe mapping with
igt_assign_pipes_for_outputs(). Assign outputs
incrementally, skip outputs that cannot get valid
pipe blocks, and proceed when at least one output
is assignable. Track outputs by driving CRTC pipe
(output_by_pipe) and iterate setup/stress using
assigned pipes.
Copy selected connector modes into owned storage
to avoid stale mode pointers after output refresh.
Clear temporary CRTC mappings after assignment to
preserve the test’s progressive modeset flow.

v2: Add close tag for the gitlab issue

Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/6928
Signed-off-by: Sowmiya S <sowmiya.s@intel.com>
---
 tests/intel/kms_pipe_stress.c | 198 +++++++++++++++++-----------------
 tests/meson.build             |   1 +
 2 files changed, 103 insertions(+), 96 deletions(-)

diff --git a/tests/intel/kms_pipe_stress.c b/tests/intel/kms_pipe_stress.c
index 47e7524c6..3caef8e18 100644
--- a/tests/intel/kms_pipe_stress.c
+++ b/tests/intel/kms_pipe_stress.c
@@ -19,6 +19,8 @@
 #include <semaphore.h>
 #include "i915/gem.h"
 #include "xe/xe_query.h"
+#include "intel/kms_joiner_helper.h"
+
 /**
  * TEST: kms pipe stress
  * Category: Display
@@ -161,8 +163,7 @@ struct data {
 	struct gpu_context gpu_context[IGT_MAX_PIPES];
 	pthread_mutex_t gpu_fill_lock;
 	drmModeModeInfo *highest_mode[IGT_MAX_PIPES];
-	drmModeConnectorPtr *connectors;
-	drmModeRes *mode_resources;
+	igt_output_t *output_by_pipe[IGT_MAX_PIPES];
 	int number_of_cores;
 	igt_pipe_crc_t *pipe_crc[IGT_MAX_PIPES];
 };
@@ -505,7 +506,6 @@ static __u64 get_mode_data_rate(drmModeModeInfo *mode)
 	return data_rate;
 }
 
-
 static drmModeModeInfo *find_highest_mode(drmModeConnector *connector)
 {
 	drmModeModeInfo *highest_mode = NULL;
@@ -526,72 +526,26 @@ static drmModeModeInfo *find_highest_mode(drmModeConnector *connector)
 	return highest_mode;
 }
 
-typedef drmModeConnector *drmModeConnectorPtr;
-
-static void fill_connector_to_pipe_array(struct data *data,
-					 drmModeRes *mode_resources,
-					 drmModeConnectorPtr *connectors)
-{
-	int pipe = 0;
-	int i;
-
-	memset(connectors, 0, sizeof(drmModeConnectorPtr) *
-	       mode_resources->count_connectors);
-
-	igt_info("Got %d connectors\n", mode_resources->count_connectors);
-
-	for (i = 0; i < mode_resources->count_connectors; i++) {
-		drmModeConnector *connector;
-
-		connector = drmModeGetConnector(data->drm_fd,
-						mode_resources->connectors[i]);
-
-		if (!connector) {
-			igt_warn("could not get connector %i: %s\n",
-				 mode_resources->connectors[i], strerror(errno));
-			continue;
-		}
-
-		if (connector->connection == DRM_MODE_CONNECTED) {
-			igt_info("Connector %d connected to pipe %d\n", i, pipe);
-			connectors[pipe] = (drmModeConnectorPtr)connector;
-			++pipe;
-			if (pipe == IGT_MAX_PIPES)
-				break;
-		} else {
-			igt_info("Connector %d connection status %d\n",
-				 i, connector->connection);
-			drmModeFreeConnector(connector);
-		}
-	}
-}
-
-static void release_connectors(drmModeConnectorPtr *connectors)
-{
-	int i;
-
-	for (i = 0; i < IGT_MAX_PIPES; i++) {
-		if (connectors[i])
-			drmModeFreeConnector(connectors[i]);
-	}
-	free(connectors);
-}
 
 static void stress_pipes(struct data *data, struct timespec *start,
 			 struct timespec *end)
 {
 	igt_display_t *display = &data->display;
-	int pipe = 0;
 	int ret = 0;
 	igt_output_t *output;
 	igt_crc_t crc, crc2;
+	igt_crtc_t *crtc;
 
-	for_each_connected_output(&data->display, output) {
+	for_each_crtc(display, crtc) {
+		enum pipe pipe = crtc->pipe;
 
+		output = data->output_by_pipe[pipe];
+		if (!output)
+			continue;
 		if (!data->highest_mode[pipe])
 			continue;
 
-		igt_assert_f(igt_crtc_for_pipe(display, pipe)->n_planes < MAX_PLANES,
+		igt_assert_f(crtc->n_planes < MAX_PLANES,
 			     "Currently we don't support more than %d planes!",
 			     MAX_PLANES);
 
@@ -607,8 +561,6 @@ static void stress_pipes(struct data *data, struct timespec *start,
 		igt_pipe_crc_get_current(data->display.drm_fd, data->pipe_crc[pipe], &crc2);
 		igt_pipe_crc_stop(data->pipe_crc[pipe]);
 		igt_assert_crc_equal(&crc, &crc2);
-
-		++pipe;
 	}
 }
 
@@ -740,6 +692,79 @@ static void create_framebuffers(struct data *data)
 	}
 }
 
+static void assign_outputs_to_pipes(struct data *data)
+{
+	igt_display_t *display = &data->display;
+	igt_output_t *output;
+	igt_output_t *connected_outputs[IGT_MAX_PIPES];
+	igt_output_t *single_output[1];
+	uint32_t valid_pipes_mask = 0, used_pipes_mask = 0, master_pipes_mask = 0;
+	int connected_output_count = 0, assigned_output_count = 0;
+	int n_pipes = igt_display_n_crtcs(display);
+	enum pipe pipe;
+	int i;
+
+	for (i = 0; i < n_pipes; i++) {
+		if (igt_crtc_for_pipe(display, i)->valid)
+			valid_pipes_mask |= BIT(i);
+	}
+	igt_set_all_master_pipes_for_platform(display, &master_pipes_mask);
+
+	memset(data->highest_mode, 0, sizeof(drmModeModeInfo *) * IGT_MAX_PIPES);
+	for_each_connected_output(display, output) {
+		if (connected_output_count >= n_pipes)
+			break;
+		connected_outputs[connected_output_count++] = output;
+	}
+	igt_require_f(connected_output_count > 0, "No connected output found\n");
+
+	for (i = 0; i < connected_output_count; i++) {
+		igt_crtc_t *crtc;
+		uint32_t next_used_pipes_mask = used_pipes_mask;
+
+		output = connected_outputs[i];
+		single_output[0] = output;
+		if (!igt_assign_pipes_for_outputs(data->drm_fd,
+						  single_output,
+						  1,
+						  n_pipes,
+						  &next_used_pipes_mask,
+						  master_pipes_mask,
+						  valid_pipes_mask)) {
+			igt_info("Skipping output %s: no available pipes for joiner requirements\n",
+				 output->name);
+			continue;
+		}
+
+		used_pipes_mask = next_used_pipes_mask;
+		crtc = igt_output_get_driving_crtc(output);
+		igt_assert(crtc);
+		pipe = crtc->pipe;
+
+		if (output->config.connector && output->config.connector->count_modes) {
+			drmModeModeInfo *mode = find_highest_mode(output->config.connector);
+
+			if (mode) {
+				data->highest_mode[pipe] = malloc(sizeof(*mode));
+				igt_assert(data->highest_mode[pipe]);
+				*data->highest_mode[pipe] = *mode;
+			}
+		}
+		igt_assert(data->highest_mode[pipe]);
+		data->output_by_pipe[pipe] = output;
+		assigned_output_count++;
+	}
+	igt_require_f(assigned_output_count > 0,
+		      "No output could be assigned to available pipes with joiner constraints\n");
+
+	/*
+	 * Clear pending CRTC mappings from the pipe assignment stage so the test
+	 * keeps its original progressive modeset flow.
+	 */
+	for (i = 0; i < connected_output_count; i++)
+		igt_output_set_crtc(connected_outputs[i], NULL);
+}
+
 static void destroy_framebuffers(struct data *data)
 {
 	igt_display_t *display = &data->display;
@@ -768,11 +793,13 @@ static void destroy_framebuffers(struct data *data)
 static void prepare_test(struct data *data)
 {
 	igt_display_t *display = &data->display;
+	enum pipe pipe;
 	int i, j;
-	int num_connectors;
 	int num_cpus = (int) sysconf(_SC_NPROCESSORS_ONLN);
+	igt_crtc_t *crtc;
 
 	data->number_of_cores = min(num_cpus, MAX_CORES);
+	igt_display_reset(display);
 
 	for (i = 0; i < IGT_MAX_PIPES; i++) {
 		for (j = 0; j < MAX_PLANES; j++)
@@ -780,49 +807,26 @@ static void prepare_test(struct data *data)
 		data->cursor_fb[i].fb_id = 0;
 		data->num_planes[i] = -1;
 		data->last_mode[i] = NULL;
+		data->highest_mode[i] = NULL;
+		data->output_by_pipe[i] = NULL;
 		sem_init(&data->gpu_thread_pause_ack[i], 0, 0);
 	}
 
 	start_cpu_threads(data);
-	data->mode_resources = drmModeGetResources(data->drm_fd);
-	if (!data->mode_resources) {
-		igt_warn("drmModeGetResources failed: %s\n", strerror(errno));
-		return;
-	}
-
-	num_connectors = data->mode_resources->count_connectors;
-	num_connectors = max(num_connectors, IGT_MAX_PIPES);
-	memset(data->highest_mode, 0, sizeof(drmModeModeInfo *) * IGT_MAX_PIPES);
-	data->connectors =
-		(drmModeConnectorPtr *)calloc(sizeof(drmModeConnectorPtr) * num_connectors, 1);
-	fill_connector_to_pipe_array(data, data->mode_resources, data->connectors);
-
-	for (i = 0; i < IGT_MAX_PIPES; i++) {
-		drmModeConnector *connector = (drmModeConnector *)data->connectors[i];
+	assign_outputs_to_pipes(data);
 
-		if (!connector)
+	for_each_crtc(display, crtc) {
+		pipe = crtc->pipe;
+		if (!data->output_by_pipe[pipe])
 			continue;
+		igt_info("Using mode:\n");
+		kmstest_dump_mode(data->highest_mode[pipe]);
+		data->pipe_crc[pipe] = igt_crtc_crc_new(crtc, IGT_PIPE_CRC_SOURCE_AUTO);
 
-		if (!data->highest_mode[i]) {
-			if (connector->count_modes)
-				data->highest_mode[i] = find_highest_mode(connector);
-		}
-		igt_assert(data->highest_mode[i]);
-
-		if (data->highest_mode[i]) {
-			igt_info("Using mode: \n");
-			kmstest_dump_mode(data->highest_mode[i]);
-			data->pipe_crc[i] = igt_crtc_crc_new(igt_crtc_for_pipe(display, i),
-							     IGT_PIPE_CRC_SOURCE_AUTO);
-		} else
-			data->pipe_crc[i] = NULL;
-
-		if (data->num_planes[i] == -1)
-			data->num_planes[i] = igt_crtc_for_pipe(display,
-								i)->n_planes;
-
+		if (data->num_planes[pipe] == -1)
+			data->num_planes[pipe] = crtc->n_planes;
 		igt_info("Max number of planes is %d for pipe %d\n",
-			 data->num_planes[i], i);
+			 data->num_planes[pipe], pipe);
 	}
 
 	create_framebuffers(data);
@@ -848,11 +852,13 @@ static void finish_test(struct data *data)
 		data->last_mode[i] = NULL;
 		if (data->pipe_crc[i])
 			igt_pipe_crc_free(data->pipe_crc[i]);
+		if (data->highest_mode[i]) {
+			free(data->highest_mode[i]);
+			data->highest_mode[i] = NULL;
+		}
 	}
 
 	stop_cpu_threads(data);
-	release_connectors(data->connectors);
-	drmModeFreeResources(data->mode_resources);
 }
 
 struct data data = {
diff --git a/tests/meson.build b/tests/meson.build
index 7f356de9b..b8b287f50 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -399,6 +399,7 @@ extra_sources = {
            join_paths ('intel', 'kms_joiner_helper.c') ],
 	'kms_dsc': [ join_paths ('intel', 'kms_dsc_helper.c') ],
 	'kms_joiner': [ join_paths ('intel', 'kms_joiner_helper.c') ],
+	'kms_pipe_stress': [ join_paths ('intel', 'kms_joiner_helper.c') ],
 	'kms_psr2_sf':  [ join_paths ('intel', 'kms_dsc_helper.c') ],
 }
 
-- 
2.43.0


  reply	other threads:[~2026-02-23  8:12 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-23  8:32 [PATCH i-g-t v2 0/2] Make pipe assignment joiner-aware Sowmiya S
2026-02-23  8:32 ` Sowmiya S [this message]
2026-02-23  8:32 ` [PATCH i-g-t v2 2/2] tests/intel/kms_pipe_stress: Clamp the source size to the FB bounds Sowmiya S
2026-02-23  8:42 ` ✓ Xe.CI.BAT: success for Make pipe assignment joiner-aware (rev2) Patchwork
2026-02-23  9:01 ` ✓ i915.CI.BAT: " Patchwork
2026-02-23 16:39 ` ✗ i915.CI.Full: failure " Patchwork
2026-02-23 22:29 ` ✗ Xe.CI.FULL: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260223083259.187783-2-sowmiya.s@intel.com \
    --to=sowmiya.s@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=karthik.b.s@intel.com \
    --cc=swati2.sharma@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox