All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH i-g-t] lib/igt_amd: improve link_settings parser for old kernel compatibility
@ 2026-09-09 20:44 Roman.Li
  2026-09-10  0:33 ` ✓ Xe.CI.BAT: success for " Patchwork
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Roman.Li @ 2026-09-09 20:44 UTC (permalink / raw)
  To: igt-dev; +Cc: alex.hung, Roman Li, Harry Wentland

From: Roman Li <Roman.Li@amd.com>

The previous fix uses strstr() to locate each record label. However,
strstr() stops at the first NUL byte (C string semantics), which breaks
backward compatibility with old kernels that embed NUL bytes between
records. Only the Current record would parse, leaving Verified, Reported,
and Preferred unset (0), causing the same failure as the original bug.

Use memmem() instead to search the raw buffer across NUL boundaries,
combined with sscanf() for parsing. This works with both:
  - Old kernels: with embedded NUL separators
  - New kernels: with contiguous single string

Also replace hardcoded loop bound '4' with ARRAY_SIZE(labels) for
better maintainability.

Tested on eDP with both kernel variants: amd_ilr passes in both cases.

Fixes: f234bbd294f5 ("lib/igt_amd: don't rely on NUL separators parsing link_settings")
Cc: Harry Wentland <harry.wentland@amd.com>
Assisted-by: Claude Haiku 4.5
Signed-off-by: Roman Li <Roman.Li@amd.com>
---
 lib/igt_amd.c | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/lib/igt_amd.c b/lib/igt_amd.c
index 7d33ab658..ba1cfabcf 100644
--- a/lib/igt_amd.c
+++ b/lib/igt_amd.c
@@ -836,10 +836,8 @@ void igt_amd_read_link_settings(
 	static const char * const labels[] = {
 		"Current:", "Verified:", "Reported:", "Preferred:"
 	};
-	int fd, ret;
+	int fd, ret, i;
 	char buf[101];
-	char *ptr;
-	int i;
 
 	fd = igt_debugfs_connector_dir(drm_fd, connector_name, O_RDONLY);
 	if (fd < 0) {
@@ -853,22 +851,29 @@ void igt_amd_read_link_settings(
 
 	close(fd);
 
-	/* The debugfs node returns a single NUL-terminated string of the form:
+	/* The debugfs node returns a string of the form:
 	 *   "Current:  %d  0x%x  %d  Verified:  %d  0x%x  %d  "
 	 *   "Reported:  %d  0x%x  %d  Preferred:  %d  0x%x  %d\n"
-	 * Locate each label and parse the three values that follow it. Do not
-	 * rely on embedded NUL bytes (or any other delimiter) between records,
-	 * as the kernel emits a single contiguous string. */
-	ptr = buf;
-	for (i = 0; i < 4; i++) {
-		ptr = strstr(ptr, labels[i]);
-		if (ptr == NULL)
+	 * Old kernels embed NUL bytes between records; new kernels emit a
+	 * contiguous string. Use memmem() to locate each label across NUL
+	 * boundaries and sscanf() to parse values, so both layouts work.
+	 */
+	for (i = 0; i < ARRAY_SIZE(labels); i++) {
+		const char *label = labels[i];
+		char *rec = memmem(buf, ret, label, strlen(label));
+		unsigned int rate;
+		int lanes, spread;
+
+		if (!rec)
+			break;
+
+		if (sscanf(rec + strlen(label), "%d %x %d",
+			   &lanes, &rate, &spread) != 3)
 			break;
 
-		ptr += strlen(labels[i]);
-		lane_count[i] = strtol(ptr, &ptr, 10);
-		link_rate[i] = strtol(ptr, &ptr, 16);
-		link_spread[i] = strtol(ptr, &ptr, 10);
+		lane_count[i] = lanes;
+		link_rate[i] = rate;
+		link_spread[i] = spread;
 	}
 }
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-09-10 18:08 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-09 20:44 [PATCH i-g-t] lib/igt_amd: improve link_settings parser for old kernel compatibility Roman.Li
2026-09-10  0:33 ` ✓ Xe.CI.BAT: success for " Patchwork
2026-09-10  0:40 ` ✗ i915.CI.BAT: failure " Patchwork
2026-09-10 12:09 ` ✗ Xe.CI.FULL: " Patchwork
2026-09-10 18:07 ` [PATCH i-g-t] " Harry Wentland

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.