[PATCH <i-g-t> v5 1/4] lib/igt_device_scan: Enable finding all IGT devices for a specific driver
Soham Purkait
soham.purkait at intel.com
Tue Mar 25 19:12:27 UTC 2025
Add filter functions to find all the
available GPUs or few among them
by driver name and card type or card number.
Add driver field to igt_device_card structure
for storing driver names.
v2 : fix for refactoring GPUTOP into a
vendor-agnostic tool (Lucas)
v3 : Separate commit for lib (Kamil)
v4 : Refactor to use composition strategy
for driver and device type filtering
Refactor code to improve memory
allocation and error handling (Lucas)
v5 : Rename function name as per convention.
Use "dev_type" enum for card_type. (Krzysztof)
Add new filter to return collection
of matching devices. (Zbigniew)
Signed-off-by: Soham Purkait <soham.purkait at intel.com>
---
lib/igt_device_scan.c | 177 ++++++++++++++++++++++++++++++++++++++++--
lib/igt_device_scan.h | 12 +++
2 files changed, 183 insertions(+), 6 deletions(-)
diff --git a/lib/igt_device_scan.c b/lib/igt_device_scan.c
index 711bedc5c..452da2ee4 100644
--- a/lib/igt_device_scan.c
+++ b/lib/igt_device_scan.c
@@ -198,12 +198,6 @@
#define DBG(...) {}
#endif
-enum dev_type {
- DEVTYPE_ALL,
- DEVTYPE_INTEGRATED,
- DEVTYPE_DISCRETE,
-};
-
#define STR_INTEGRATED "integrated"
#define STR_DISCRETE "discrete"
@@ -774,6 +768,10 @@ __copy_dev_to_card(struct igt_device *dev, struct igt_device_card *card)
safe_strncpy(card->render, dev->drm_render,
sizeof(card->render));
+ if (dev->driver != NULL)
+ safe_strncpy(card->driver, dev->driver,
+ sizeof(card->driver));
+
if (dev->pci_slot_name != NULL)
safe_strncpy(card->pci_slot_name, dev->pci_slot_name,
sizeof(card->pci_slot_name));
@@ -820,6 +818,58 @@ static bool __find_first_intel_card_by_driver_name(struct igt_device_card *card,
return false;
}
+/**
+ * Iterate over all igt_devices array and find all discrete/integrated cards.
+ * @card: double pointer to igt_device_card structure, containing
+ * an array of igt_device_card structures upon successful return.
+ * @card_type: flag of type "enum igt_devices_card_type" to indicate
+ * whether to find discrete, integrated, or both types of cards.
+ * @drv_name: name of the driver to match.
+ *
+ * Returns the number of cards found, or -1 on error.
+ */
+int igt_device_find_all_intel_card_by_driver_name(struct igt_device_card **card,
+ enum dev_type card_type,
+ const char *drv_name)
+{
+ int count = 0;
+ struct igt_device *dev;
+ int is_integrated;
+ struct igt_device_card *tmp;
+ struct igt_device_card *crd = NULL;
+
+ igt_assert(drv_name);
+ *card = NULL;
+
+ igt_list_for_each_entry(dev, &igt_devs.all, link) {
+ if (!is_pci_subsystem(dev) || strcmp(dev->driver, drv_name))
+ continue;
+
+ is_integrated = !strncmp(dev->pci_slot_name, INTEGRATED_I915_GPU_PCI_ID,
+ PCI_SLOT_NAME_SIZE);
+
+ if ((card_type == DEVTYPE_INTEGRATED && !is_integrated) ||
+ (card_type == DEVTYPE_DISCRETE && is_integrated) ||
+ card_type == DEVTYPE_ALL) {
+ tmp = realloc(crd, sizeof(struct igt_device_card) * (count + 1));
+ if (!tmp && crd) {
+ free(crd);
+ return -1;
+ }
+
+ crd = tmp;
+ __copy_dev_to_card(dev, &crd[count]);
+ count++;
+ }
+ }
+
+ if (!count)
+ return 0;
+
+ *card = crd;
+ return count;
+}
+
bool igt_device_find_first_i915_discrete_card(struct igt_device_card *card)
{
igt_assert(card);
@@ -1705,6 +1755,55 @@ static struct igt_list_head *filter_sriov(const struct filter_class *fcls,
return &igt_devs.filtered;
}
+/*
+ * Find appropriate gpu device matching driver/card filter arguments.
+ */
+static struct igt_list_head *filter_device(const struct filter_class *fcls,
+ const struct filter *filter)
+{
+ struct igt_device *dev;
+ int card = -1;
+ (void)fcls;
+
+ DBG("filter device\n");
+
+ if (filter->data.card) {
+ sscanf(filter->data.card, "%d", &card);
+ if (card < 0)
+ return &igt_devs.filtered;
+ } else {
+ card = -1;
+ }
+
+ igt_list_for_each_entry(dev, &igt_devs.all, link) {
+ if (!is_pci_subsystem(dev))
+ continue;
+
+ /* Skip if 'driver' doesn't match */
+ if (filter->data.driver && !strequal(filter->data.driver, dev->driver))
+ continue;
+
+ /* We get n-th card */
+ if (!card) {
+ struct igt_device *dup = duplicate_device(dev);
+
+ igt_list_add_tail(&dup->link, &igt_devs.filtered);
+ break;
+ }
+ /* Include all the card */
+ else if (card == -1) {
+ struct igt_device *dup = duplicate_device(dev);
+
+ igt_list_add_tail(&dup->link, &igt_devs.filtered);
+ } else
+ card--;
+ }
+
+ DBG("Filter device filtered size: %d\n", igt_list_length(&igt_devs.filtered));
+
+ return &igt_devs.filtered;
+}
+
static bool sys_path_valid(const struct filter_class *fcls,
const struct filter *filter)
{
@@ -1746,6 +1845,12 @@ static struct filter_class filter_definition_list[] = {
.help = "sriov:[vendor=%04x/name][,device=%04x][,card=%d][,pf=%d][,vf=%d]",
.detail = "find pf or vf\n",
},
+ {
+ .name = "device",
+ .filter_function = filter_device,
+ .help = "device:[driver=name][,card=%d]",
+ .detail = "find device by driver name and card number\n",
+ },
{
.name = NULL,
},
@@ -2059,6 +2164,66 @@ bool igt_device_card_match_pci(const char *filter,
return __igt_device_card_match(filter, card, true);
}
+/**
+ * igt_device_card_match_all
+ * @filter: filter string
+ * @card: double pointer to igt_device_card structure, containing
+ * an array of igt_device_card structures upon successful return.
+ * @request_pci_ss: a boolean parameter determines whether to
+ * consider PCI subsystem information during this process.
+ * Function applies filter to match device from device array.
+ *
+ * Returns: the number of cards found.
+ */
+int igt_device_card_match_all(const char *filter, struct igt_device_card **card,
+ bool request_pci_ss, const char * const drivers[])
+{
+ struct igt_device *dev = NULL;
+ struct igt_device_card *crd = NULL;
+ struct igt_device_card *tmp;
+ int count = 0;
+
+ /*
+ * Scan devices in case the user hasn't yet,
+ * but leave a decision on forced rescan on the user side.
+ */
+ igt_devices_scan();
+
+ if (igt_device_filter_apply(filter) == false)
+ return 0;
+
+ if (igt_list_empty(&igt_devs.filtered))
+ return 0;
+
+ igt_list_for_each_entry(dev, &igt_devs.filtered, link) {
+ for (int i = 0;
+ drivers && drivers[i] && !strcmp(drivers[i],
+ dev->driver); i++) {
+ tmp = realloc(crd, sizeof(struct igt_device_card) * (count + 1));
+ if (!tmp && crd) {
+ free(crd);
+ return 0;
+ }
+
+ crd = tmp;
+
+ if (request_pci_ss && !is_pci_subsystem(dev) &&
+ dev->parent && is_pci_subsystem(dev->parent))
+ __copy_dev_to_card(dev->parent, crd);
+ else
+ __copy_dev_to_card(dev, crd);
+ count++;
+ break;
+ }
+ }
+
+ if (!count)
+ return 0;
+
+ *card = crd;
+ return count;
+}
+
/**
* igt_device_get_pretty_name
* @card: pointer to igt_device_card struct
diff --git a/lib/igt_device_scan.h b/lib/igt_device_scan.h
index 92741fe3c..62e7a1737 100644
--- a/lib/igt_device_scan.h
+++ b/lib/igt_device_scan.h
@@ -59,10 +59,17 @@ struct igt_device_card {
char subsystem[NAME_MAX];
char card[NAME_MAX];
char render[NAME_MAX];
+ char driver[NAME_MAX];
char pci_slot_name[PCI_SLOT_NAME_SIZE+1];
uint16_t pci_vendor, pci_device;
};
+enum dev_type {
+ DEVTYPE_ALL,
+ DEVTYPE_INTEGRATED,
+ DEVTYPE_DISCRETE,
+};
+
void igt_devices_scan(void);
void igt_devices_scan_all_attrs(void);
@@ -88,10 +95,15 @@ int igt_device_filter_pci(void);
bool igt_device_card_match(const char *filter, struct igt_device_card *card);
bool igt_device_card_match_pci(const char *filter,
struct igt_device_card *card);
+int igt_device_card_match_all(const char *filter, struct igt_device_card **card,
+ bool request_pci_ss, const char * const drivers[]);
bool igt_device_find_first_i915_discrete_card(struct igt_device_card *card);
bool igt_device_find_integrated_card(struct igt_device_card *card);
bool igt_device_find_first_xe_discrete_card(struct igt_device_card *card);
bool igt_device_find_xe_integrated_card(struct igt_device_card *card);
+int igt_device_find_all_intel_card_by_driver_name(struct igt_device_card **card,
+ enum dev_type card_type,
+ const char *drv_name);
char *igt_device_get_pretty_name(struct igt_device_card *card, bool numeric);
int igt_open_card(struct igt_device_card *card);
int igt_open_render(struct igt_device_card *card);
--
2.34.1
More information about the igt-dev
mailing list