From: Xin Wang <x.wang@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: Xin Wang <x.wang@intel.com>,
matthew.d.roper@intel.com, zbigniew.kempczynski@intel.com,
kamil.konieczny@linux.intel.com, stuart.summers@intel.com
Subject: [PATCH i-g-t v14 2/4] lib/intel_device_info: make device info cache process-wide
Date: Mon, 28 Sep 2026 10:27:05 -0700 [thread overview]
Message-ID: <20260928172713.1341060-3-x.wang@intel.com> (raw)
In-Reply-To: <20260928172713.1341060-1-x.wang@intel.com>
intel_get_device_info() caches the last looked-up entry in per-thread
variables that point into the static, read-only PCI-ID table. Such a
cache cannot carry data that is updated at runtime, e.g. the graphics
IP version reported by GMD_ID on Xe platforms.
Replace it with a process-wide cache keyed by devid which holds a
mutable copy of the matching static table entry. The cache is protected
by a statically initialized mutex, the map is created lazily on the
first lookup so it does not depend on constructor ordering, and it is
torn down via igt_destructor. Report allocation or map insertion failure
and exit instead of silently returning a static entry that cannot be
updated with the runtime IP version.
Also link igt_map.c into libigt_chipset to provide the map implementation.
V2:
- Report malloc, map creation and insertion failures with fprintf and
exit(EXIT_FAILURE) instead of falling back to a static entry.
- Release the cache mutex before reporting map insertion failures.
Signed-off-by: Xin Wang <x.wang@intel.com>
---
lib/intel_device_info.c | 114 +++++++++++++++++++++++++++++++++++-----
lib/meson.build | 1 +
2 files changed, 101 insertions(+), 14 deletions(-)
diff --git a/lib/intel_device_info.c b/lib/intel_device_info.c
index ae316bfcab..3f9dd42db1 100644
--- a/lib/intel_device_info.c
+++ b/lib/intel_device_info.c
@@ -1,8 +1,13 @@
#include "intel_chipset.h"
#include "pciids.h"
#include "i915_pciids_local.h"
+#include "igt_core.h"
+#include "igt_map.h"
#include <ctype.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <strings.h> /* ffs() */
static const struct intel_device_info intel_generic_info = {
@@ -716,6 +721,59 @@ static const struct pci_id_match intel_device_match[] = {
#undef INTEL_PCI_ID_INIT
+/*
+ * Process-wide cache of per-devid copies of the static PCI-ID table entries.
+ * Entries can be updated at runtime, e.g. by xe_device_get() with the graphics
+ * IP version reported by GMD_ID. The cache is keyed by PCI device ID, so all
+ * devices sharing a device ID share one entry.
+ *
+ * The map is created lazily on first lookup, so lookups do not depend on
+ * constructor ordering.
+ */
+static struct {
+ pthread_mutex_t mutex;
+ struct igt_map *map;
+} devinfo_cache = {
+ .mutex = PTHREAD_MUTEX_INITIALIZER,
+};
+
+static void free_device_info(struct igt_map_entry *entry)
+{
+ free(entry->data);
+ free((void *)entry->key);
+}
+
+igt_destructor
+{
+ pthread_mutex_lock(&devinfo_cache.mutex);
+ igt_map_destroy(devinfo_cache.map, free_device_info);
+ devinfo_cache.map = NULL;
+ pthread_mutex_unlock(&devinfo_cache.mutex);
+}
+
+/* Caller must hold devinfo_cache.mutex. */
+static struct intel_device_info *devinfo_cache_search(uint16_t devid)
+{
+ uint32_t key = devid;
+
+ if (!devinfo_cache.map)
+ return NULL;
+
+ return igt_map_search(devinfo_cache.map, &key);
+}
+
+static const struct intel_device_info *devinfo_table_lookup(uint16_t devid)
+{
+ int i;
+
+ for (i = 0; intel_device_match[i].device_id != PCI_MATCH_ANY; i++) {
+ if (devid == intel_device_match[i].device_id)
+ break;
+ }
+
+ return (const struct intel_device_info *)intel_device_match[i].match_data;
+}
+
/**
* intel_get_device_info:
* @devid: pci device id
@@ -727,24 +785,52 @@ static const struct pci_id_match intel_device_match[] = {
*/
const struct intel_device_info *intel_get_device_info(uint16_t devid)
{
- static __thread const struct intel_device_info *cache = &intel_generic_info;
- static __thread uint16_t cached_devid;
- int i;
-
- if (cached_devid == devid)
- goto out;
+ const struct intel_device_info *table_info;
+ struct intel_device_info *info, *new_info;
+ uint32_t *new_key;
+
+ pthread_mutex_lock(&devinfo_cache.mutex);
+ info = devinfo_cache_search(devid);
+ pthread_mutex_unlock(&devinfo_cache.mutex);
+ if (info)
+ return info;
+
+ table_info = devinfo_table_lookup(devid);
+
+ new_key = malloc(sizeof(*new_key));
+ new_info = malloc(sizeof(*new_info));
+ if (!new_key || !new_info) {
+ free(new_key);
+ free(new_info);
+ fprintf(stderr, "Failed to allocate device info for devid 0x%04x\n", devid);
+ exit(EXIT_FAILURE);
+ }
- /* XXX Presort table and bsearch! */
- for (i = 0; intel_device_match[i].device_id != PCI_MATCH_ANY; i++) {
- if (devid == intel_device_match[i].device_id)
- break;
+ *new_key = devid;
+ *new_info = *table_info;
+
+ pthread_mutex_lock(&devinfo_cache.mutex);
+ if (!devinfo_cache.map)
+ devinfo_cache.map = igt_map_create(igt_map_hash_32,
+ igt_map_equal_32);
+ /* Another thread may have inserted while we were allocating. */
+ info = devinfo_cache_search(devid);
+ if (!info && devinfo_cache.map &&
+ igt_map_insert(devinfo_cache.map, new_key, new_info)) {
+ info = new_info;
+ new_key = NULL;
+ new_info = NULL;
}
+ pthread_mutex_unlock(&devinfo_cache.mutex);
- cached_devid = devid;
- cache = (void *)intel_device_match[i].match_data;
+ free(new_info);
+ free(new_key);
+ if (!info) {
+ fprintf(stderr, "Failed to cache device info for devid 0x%04x\n", devid);
+ exit(EXIT_FAILURE);
+ }
-out:
- return cache;
+ return info;
}
static bool char_eq(char c1, char c2)
diff --git a/lib/meson.build b/lib/meson.build
index f3e6d96693..d15d25f150 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -398,6 +398,7 @@ igt_deps = [ lib_igt ] + lib_deps
lin_igt_chipset_build = static_library('igt_chipset',
['intel_chipset.c',
'intel_device_info.c',
+ 'igt_map.c',
'intel_cmds_info.c'],
include_directories : inc)
--
2.43.0
next prev parent reply other threads:[~2026-09-28 17:30 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-28 17:27 [PATCH i-g-t v14 0/4] lib/intel_device_info: get the xe .graphics_rel from GMD_ID Xin Wang
2026-09-28 17:27 ` [PATCH i-g-t v14 1/4] lib/igt_core: add igt_destructor helper macro Xin Wang
2026-10-02 4:55 ` Zbigniew Kempczyński
2026-09-28 17:27 ` Xin Wang [this message]
2026-10-02 4:56 ` [PATCH i-g-t v14 2/4] lib/intel_device_info: make device info cache process-wide Zbigniew Kempczyński
2026-09-28 17:27 ` [PATCH i-g-t v14 3/4] lib/intel_device_info: allow xe_query to override graphics version Xin Wang
2026-10-02 5:03 ` Zbigniew Kempczyński
2026-09-28 17:27 ` [PATCH i-g-t v14 4/4] lib/intel_device_info: remove the graphics_rel from xe2+ devices Xin Wang
2026-10-02 5:05 ` Zbigniew Kempczyński
2026-10-02 7:50 ` Wang, X
2026-10-05 8:23 ` Zbigniew Kempczyński
2026-09-28 21:39 ` ✓ Xe.CI.BAT: success for lib/intel_device_info: get the xe .graphics_rel from GMD_ID Patchwork
2026-09-28 22:22 ` ✓ i915.CI.BAT: " Patchwork
2026-09-29 3:39 ` ✗ Xe.CI.FULL: failure " Patchwork
2026-10-07 17:13 ` Wang, X
2026-09-29 6:08 ` ✓ i915.CI.Full: success " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260928172713.1341060-3-x.wang@intel.com \
--to=x.wang@intel.com \
--cc=igt-dev@lists.freedesktop.org \
--cc=kamil.konieczny@linux.intel.com \
--cc=matthew.d.roper@intel.com \
--cc=stuart.summers@intel.com \
--cc=zbigniew.kempczynski@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.