freedreno/fdperf: better compatible string matching
authorRob Clark <robdclark@chromium.org>
Sun, 5 Jul 2020 18:35:01 +0000 (11:35 -0700)
committerMarge Bot <eric+marge@anholt.net>
Mon, 6 Jul 2020 15:08:15 +0000 (15:08 +0000)
Previously we would match the start of the compatible string, in
a couple of cases, in order to match compatible strings like
"qcom,adreno-630.2".  But these cases would always list a more
generic compatible (ie. "qcom,adreno") as a later choice.  So if
we parse all the compatible strings, we can do a more precise
exact match.

This avoids us accidentially matching on "qcom,adreno-smmu" and
the hilarity that ensues.

Fixes: 5a13507164a ("freedreno/perfcntrs: add fdperf")
Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5762>

src/freedreno/perfcntrs/fdperf.c

index b16865fe66a3ed0b4a1c9f0fbebe38eb84c10900..83efe2d2b5356f5a2bd3e756803321d6d56b32cb 100644 (file)
@@ -212,6 +212,37 @@ find_freqs(void)
        free(path);
 }
 
+static const char * compatibles[] = {
+               "qcom,adreno-3xx",
+               "qcom,kgsl-3d0",
+               "amd,imageon",
+               "qcom,adreno",
+};
+
+/**
+ * compatstrs is a list of compatible strings separated by null, ie.
+ *
+ *       compatible = "qcom,adreno-630.2", "qcom,adreno";
+ *
+ * would result in "qcom,adreno-630.2\0qcom,adreno\0"
+ */
+static bool match_compatible(char *compatstrs, int sz)
+{
+       while (sz > 0) {
+               char *compatible = compatstrs;
+
+               for (unsigned i = 0; i < ARRAY_SIZE(compatibles); i++) {
+                       if (strcmp(compatible, compatibles[i]) == 0) {
+                               return true;
+                       }
+               }
+
+               compatstrs += strlen(compatible) + 1;
+               sz -= strlen(compatible) + 1;
+       }
+       return false;
+}
+
 static int
 find_device_fn(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
 {
@@ -220,10 +251,7 @@ find_device_fn(const char *fpath, const struct stat *sb, int typeflag, struct FT
 
        if (strcmp(fname, "compatible") == 0) {
                char *str = readfile(fpath, &sz);
-               if ((strcmp(str, "qcom,adreno-3xx") == 0) ||
-                               (strcmp(str, "qcom,kgsl-3d0") == 0) ||
-                               (strstr(str, "amd,imageon") == str) ||
-                               (strstr(str, "qcom,adreno") == str)) {
+               if (match_compatible(str, sz)) {
                        int dlen = strlen(fpath) - strlen("/compatible");
                        dev.dtnode = malloc(dlen + 1);
                        memcpy(dev.dtnode, fpath, dlen);