loader: Avoid enumerating drm devices just to get an fd's PCI ID.

Cuts 1/3 of the runtime of the VA-API unit tests (which do a separate
pipe-loader init per test) on radeonsi on my system by not faffing around
in sysfs so much.

Reviewed-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13324>
This commit is contained in:
Emma Anholt 2021-10-12 14:31:31 -07:00 committed by Marge Bot
parent b79e978ae4
commit f839b9599f
1 changed files with 43 additions and 0 deletions

View File

@ -47,6 +47,7 @@
#include <GL/gl.h>
#include <GL/internal/dri_interface.h>
#include "loader.h"
#include "util/os_file.h"
#ifdef HAVE_LIBDRM
#include <xf86drm.h>
@ -407,10 +408,52 @@ drm_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
}
#endif
#ifdef __linux__
static int loader_get_linux_pci_field(int maj, int min, const char *field)
{
char path[PATH_MAX + 1];
snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device/%s", maj, min, field);
char *field_str = os_read_file(path, NULL);
if (!field_str) {
/* Probably non-PCI device. */
return 0;
}
int value = (int)strtoll(field_str, NULL, 16);
free(field_str);
return value;
}
static bool
loader_get_linux_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
{
struct stat sbuf;
if (fstat(fd, &sbuf) != 0) {
log_(_LOADER_DEBUG, "MESA-LOADER: failed to fstat fd\n");
return false;
}
int maj = major(sbuf.st_rdev);
int min = minor(sbuf.st_rdev);
*vendor_id = loader_get_linux_pci_field(maj, min, "vendor");
*chip_id = loader_get_linux_pci_field(maj, min, "device");
return *vendor_id && *chip_id;
}
#endif /* __linux__ */
bool
loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id)
{
#ifdef __linux__
/* Implementation without causing full enumeration of DRM devices. */
if (loader_get_linux_pci_id_for_fd(fd, vendor_id, chip_id))
return true;
#endif
#if HAVE_LIBDRM
return drm_get_pci_id_for_fd(fd, vendor_id, chip_id);
#endif