intel/dev: Support INTEL_FORCE_PROBE env-var

This environment variable allows some Intel devices that are
unsupported to be forced to run. These devices have incomplete
support, and therefore might not work at all.

Reworks:
 * José: Simplify scan_for_force_probe() with strtok()

Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: José Roberto de Souza <jose.souza@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29273>
This commit is contained in:
Jordan Justen
2023-09-29 02:38:16 -07:00
committed by Marge Bot
parent c967b38c7c
commit 237d9e7c45
2 changed files with 85 additions and 1 deletions
+79 -1
View File
@@ -1333,6 +1333,69 @@ intel_device_info_update_cs_workgroup_threads(struct intel_device_info *devinfo)
MIN2(devinfo->max_cs_threads, 64);
}
static bool
parse_force_probe_entry(int pci_id, const char *entry, bool *force_on,
bool *force_off)
{
const char *cp = entry;
bool negated = *cp == '!';
if (negated)
cp++;
if (*cp == '\0')
return false;
bool wildcard = *cp == '*';
long val = 0;
if (wildcard) {
cp++;
} else {
char *end;
val = strtol(cp, &end, 16);
if (end == cp)
return false;
cp = end;
}
if (*cp != '\0')
return false;
bool matched = wildcard || (long)pci_id == val;
if (matched) {
*force_on = !negated;
*force_off = negated;
}
return matched;
}
static void
scan_for_force_probe(int pci_id, bool *force_on, bool *force_off)
{
*force_on = false;
*force_off = false;
const char *env = getenv("INTEL_FORCE_PROBE");
if (env == NULL)
return;
size_t len = strlen(env);
if (len == 0)
return;
char *dup = strndup(env, len);
if (dup == NULL)
return;
for (char *entry = strtok(dup, ","); entry; entry = strtok(NULL, ","))
parse_force_probe_entry(pci_id, entry, force_on, force_off);
free(dup);
assert(!*force_on || !*force_off);
}
struct device_init_config {
bool require_force_probe;
};
@@ -1383,8 +1446,23 @@ intel_device_info_init_common(int pci_id,
strncpy(devinfo->name, "Intel Unknown", sizeof(devinfo->name));
}
if (device_config.require_force_probe)
bool force_on = false;
bool force_off = false;
scan_for_force_probe(pci_id, &force_on, &force_off);
if (force_off) {
mesa_logw("%s (0x%x) disabled with INTEL_FORCE_PROBE", devinfo->name,
pci_id);
return false;
} else if (device_config.require_force_probe) {
if (force_on) {
mesa_logw("Forcing probe of unsupported: %s (0x%x)", devinfo->name,
pci_id);
} else {
mesa_loge("%s (0x%x) requires INTEL_FORCE_PROBE", devinfo->name,
pci_id);
return false;
}
}
devinfo->pci_device_id = pci_id;
+6
View File
@@ -1,6 +1,7 @@
#undef NDEBUG
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#include "intel_device_info.h"
@@ -21,7 +22,12 @@ main(int argc, char *argv[])
for (uint32_t i = 0; i < ARRAY_SIZE(chipsets); i++) {
struct intel_device_info devinfo = { 0, };
char force_probe[10];
int len = snprintf(force_probe, sizeof force_probe, "%x",
chipsets[i].pci_id);
assert(len < sizeof force_probe);
setenv("INTEL_FORCE_PROBE", force_probe, 1);
assert(intel_get_device_info_from_pci_id(chipsets[i].pci_id, &devinfo));
verify_device_info(&devinfo);