[RFC patch 5/9] selftests/resctrl: Refactor CPU vendor detection to use lookup table

Yifan Wu wuyifan50 at huawei.com
Tue Mar 3 20:03:30 PST 2026


Currently, the vendor detection is implemented using a series of
hard-coded "if/else if" string comparisons, which does not support ARM,
as the ARM implementer is indicated by other sequences in /proc/cpuinfo.

This commit refactors the vendor detection to be data-driven and
extensible.  It introduces a lookup table to define all vendor-specific
detection rules.  This separates the detection algorithm from the data.

The new lookup table is implemented as a variable-length array of nested
anonymous structs to to map a file to a sequence of string and vendor.

This makes the code cleaner, maintainable, and simplifies the addition
of support for new vendors (e.g., ARM) in the future.

Signed-off-by: Yifan Wu <wuyifan50 at huawei.com>
---
 .../testing/selftests/resctrl/resctrl_tests.c | 82 ++++++++++++++-----
 1 file changed, 60 insertions(+), 22 deletions(-)

diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c
index dbcd5eea9fbc..419d876a97c2 100644
--- a/tools/testing/selftests/resctrl/resctrl_tests.c
+++ b/tools/testing/selftests/resctrl/resctrl_tests.c
@@ -23,39 +23,77 @@ static struct resctrl_test *resctrl_tests[] = {
 	&l2_noncont_cat_test,
 };
 
+#define VENDOR_ENTRY struct {\
+	unsigned int vendor_id; \
+	void *arg; \
+	}
+
+#define SEQ_ENTRY struct {\
+	char *format; \
+	VENDOR_ENTRY *vendor; \
+	}
+
+#define DETECTION_ENTRY struct {\
+	char *pathname; \
+	SEQ_ENTRY *seq; \
+	}
+
+static DETECTION_ENTRY vendor_detection[] = {
+	{
+		.pathname = "/proc/cpuinfo",
+		.seq = (SEQ_ENTRY[]) {
+			{
+				.format = "vendor_id\t: %s\n",
+				.vendor = (VENDOR_ENTRY[]) {
+					{ .vendor_id = ARCH_INTEL,	.arg = "GenuineIntel" },
+					{ .vendor_id = ARCH_AMD,	.arg = "AuthenticAMD" },
+					{ .vendor_id = ARCH_HYGON,	.arg = "HygonGenuine" },
+					{ .vendor_id = 0,	.arg = NULL }
+				}
+			}
+		}
+	},
+	{ .pathname = NULL, .seq = NULL}
+};
+
 static unsigned int detect_vendor(void)
 {
 	static unsigned int vendor_id;
 	static bool initialized;
-	char *s = NULL;
+	char s[64];
 	FILE *inf;
 	char *res;
 
 	if (initialized)
 		return vendor_id;
 
-	inf = fopen("/proc/cpuinfo", "r");
-	if (!inf) {
-		vendor_id = 0;
-		initialized = true;
-		return vendor_id;
+	for (DETECTION_ENTRY *dentry = &vendor_detection[0];
+		 dentry && dentry->pathname;
+		 dentry++) {
+		inf = fopen(dentry->pathname, "r");
+		if (!inf)
+			continue;
+		for (SEQ_ENTRY *sentry = &dentry->seq[0];
+			 sentry && sentry->format;
+			 sentry++) {
+			for (VENDOR_ENTRY *ventry = &sentry->vendor[0];
+				 ventry && ventry->vendor_id;
+				 ventry++) {
+				snprintf(s, sizeof(s), sentry->format, ventry->arg);
+				char *res = fgrep(inf, s);
+
+				if (res) {
+					free(res);
+					fclose(inf);
+					vendor_id = ventry->vendor_id;
+					goto out;
+				}
+				rewind(inf);
+			}
+		}
+		fclose(inf);
 	}
-
-	res = fgrep(inf, "vendor_id");
-
-	if (res)
-		s = strchr(res, ':');
-
-	if (s && !strcmp(s, ": GenuineIntel\n"))
-		vendor_id = ARCH_INTEL;
-	else if (s && !strcmp(s, ": AuthenticAMD\n"))
-		vendor_id = ARCH_AMD;
-	else if (s && !strcmp(s, ": HygonGenuine\n"))
-		vendor_id = ARCH_HYGON;
-
-	fclose(inf);
-	free(res);
-
+out:
 	initialized = true;
 	return vendor_id;
 }
-- 
2.33.0




More information about the linux-arm-kernel mailing list