* [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support
@ 2023-10-05 18:57 Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 01/17] lib/igt_device_scan: added functions to get first Xe card Marcin Bernatowicz
` (19 more replies)
0 siblings, 20 replies; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
Added basic xe support. Single binary handles both i915 and Xe devices.
Some functionality is still missing: working sets, bonding.
The tool is handy for scheduling tests, we find it useful to verify vGPU
profiles defining different execution quantum/preemption timeout
settings.
There is also some rationale for the tool in following thread:
https://lore.kernel.org/dri-devel/a443495f-5d1b-52e1-9b2f-80167deb6d57@linux.intel.com/
With this patch it should be possible to run following on xe device:
gem_wsim -w benchmarks/wsim/media_load_balance_fhd26u7.wsim -c 36 -r 600
Best with drm debug logs disabled:
echo 0 > /sys/module/drm/parameters/debug
v2:
- split patches to easy review (Kamil),
all benchmarks/gem_wsim patches before [RFC] one
contain fixes (for scale duration option), cleanups (checkpatch.pl),
refactors (some code moved to functions),
not related to xe and ready to be applied
- lib/xe_spin is under review in other thread https://patchwork.freedesktop.org/series/122624/
v3:
- minimizing divergence - same workload syntax for both drivers,
so most existing examples should run on xe unmodified (Tvrtko)
This version creates one common VM per workload.
Explicit VM management, compute mode, improved engine handling
to come in next patchset.
- split patches to easy review (Tvrtko)
- dropped already merged patches, added documentation to public
lib functions, some code cleanups (Kamil)
v4:
- addressed review comments in previous patches
- added patch with for_each_dep macro (Tvrtko)
- added patch with bb_size field in w_step
- grouped xe specific fields (Tvrtko)
- moved is_xe boolean next to fd (Tvrtko)
- use xe_ prefix for Xe specific things (Tvrtko)
- left throttling untouched (Tvrtko)
- parse errors vs silent skips on not implemented steps (Tvrtko)
- add 'Xe and i915 differences' section to README (Tvrtko)
for now no data dependency implemented, left -1 <=> f-1
to not modify examples (maybe too optimistic assumption?)
- need to think on better engine handling in next version
v5:
- correct out of bound access if file ends with hash (Tvrtko)
- new patches intruducing for_each_ctx, for_each_w_step macros
- corrected engines mappings for xe
ex. "M.1.VCS,B.1,1.DEFAULT.1000.0.1" should use VCS
- verified engines selection works on MTL (Tvrtko)
- prevent misuse combinations of fence and implicit data deps (Tvrtko)
ex. "f,1.DEFAULT.1000.-1.0" should fail,
"f,1.DEFAULT.1000.f-1.0" is valid
- corrected error messages (Tvrtko)
- missing xe_device_put (Tvrtko)
- moved wsim_err up to be accessible from parse_dependencies
- left fini_workload cleanup for separate patch
- README updates
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
Marcin Bernatowicz (17):
lib/igt_device_scan: added functions to get first Xe card
benchmarks/gem_wsim: reposition the unbound duration boolean
benchmarks/gem_wsim: fix duration range check
benchmarks/gem_wsim: extract duration parsing code to new function
benchmarks/gem_wsim: fix conflicting SSEU #define and enum
benchmarks/gem_wsim: cleanups
benchmarks/gem_wsim: reposition repeat_start variable
benchmarks/gem_wsim: use lib code to query engines
benchmarks/gem_wsim: allow comments in workload description files
benchmarks/gem_wsim: introduce w_step_sync function
benchmarks/gem_wsim: extract allocate and prepare contexts code to new
functions
benchmarks/gem_wsim: extract prepare working sets code to new function
benchmarks/gem_wsim: group i915 fields
benchmarks/gem_wsim: for_each_dep macro
benchmarks/gem_wsim: for_each_ctx macro
benchmarks/gem_wsim: for_each_w_step macro
benchmarks/gem_wsim: added basic xe support
benchmarks/gem_wsim.c | 1177 +++++++++++++++++++++++++++-------------
benchmarks/wsim/README | 25 +-
lib/igt_device_scan.c | 52 +-
lib/igt_device_scan.h | 2 +
4 files changed, 860 insertions(+), 396 deletions(-)
--
2.42.0
^ permalink raw reply [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 01/17] lib/igt_device_scan: added functions to get first Xe card
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
@ 2023-10-05 18:57 ` Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 02/17] benchmarks/gem_wsim: reposition the unbound duration boolean Marcin Bernatowicz
` (18 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
Added functions to get integrated or first discrete Xe card.
v2:
- renamed __find_first_i915_card to
__find_first_intel_card_by_driver_name (Zbyszek)
v3:
- added documentation to public functions (Kamil)
v4:
- updated commit description (Kamil)
Reviewed-by: Kamil Konieczny <kamil.konieczny@linux.intel.com>
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
lib/igt_device_scan.c | 52 +++++++++++++++++++++++++++++++++++--------
lib/igt_device_scan.h | 2 ++
2 files changed, 45 insertions(+), 9 deletions(-)
diff --git a/lib/igt_device_scan.c b/lib/igt_device_scan.c
index ae69ed09f..f4f95fef3 100644
--- a/lib/igt_device_scan.c
+++ b/lib/igt_device_scan.c
@@ -769,25 +769,27 @@ __copy_dev_to_card(struct igt_device *dev, struct igt_device_card *card)
* Iterate over all igt_devices array and find first discrete/integrated card.
* card->pci_slot_name will be updated only if a card is found.
*/
-static bool __find_first_i915_card(struct igt_device_card *card, bool discrete)
+static bool __find_first_intel_card_by_driver_name(struct igt_device_card *card,
+ bool want_discrete, const char *drv_name)
{
struct igt_device *dev;
- int cmp;
+ int is_integrated;
+ igt_assert(drv_name);
memset(card, 0, sizeof(*card));
igt_list_for_each_entry(dev, &igt_devs.all, link) {
- if (!is_pci_subsystem(dev) || strcmp(dev->driver, "i915"))
+ if (!is_pci_subsystem(dev) || strcmp(dev->driver, drv_name))
continue;
- cmp = strncmp(dev->pci_slot_name, INTEGRATED_I915_GPU_PCI_ID,
- PCI_SLOT_NAME_SIZE);
+ is_integrated = !strncmp(dev->pci_slot_name, INTEGRATED_I915_GPU_PCI_ID,
+ PCI_SLOT_NAME_SIZE);
- if (discrete && cmp) {
+ if (want_discrete && !is_integrated) {
__copy_dev_to_card(dev, card);
return true;
- } else if (!discrete && !cmp) {
+ } else if (!want_discrete && is_integrated) {
__copy_dev_to_card(dev, card);
return true;
}
@@ -800,14 +802,46 @@ bool igt_device_find_first_i915_discrete_card(struct igt_device_card *card)
{
igt_assert(card);
- return __find_first_i915_card(card, true);
+ return __find_first_intel_card_by_driver_name(card, true, "i915");
+}
+
+/**
+ * igt_device_find_first_xe_discrete_card
+ * @card: pointer to igt_device_card structure
+ *
+ * Iterate over all igt_devices array and find first xe discrete card.
+ * card will be updated only if a device is found.
+ *
+ * Returns: true if device is found, false otherwise.
+ */
+bool igt_device_find_first_xe_discrete_card(struct igt_device_card *card)
+{
+ igt_assert(card);
+
+ return __find_first_intel_card_by_driver_name(card, true, "xe");
}
bool igt_device_find_integrated_card(struct igt_device_card *card)
{
igt_assert(card);
- return __find_first_i915_card(card, false);
+ return __find_first_intel_card_by_driver_name(card, false, "i915");
+}
+
+/**
+ * igt_device_find_xe_integrated_card
+ * @card: pointer to igt_device_card structure
+ *
+ * Iterate over all igt_devices array and find first xe integrated card.
+ * card will be updated only if a device is found.
+ *
+ * Returns: true if device is found, false otherwise.
+ */
+bool igt_device_find_xe_integrated_card(struct igt_device_card *card)
+{
+ igt_assert(card);
+
+ return __find_first_intel_card_by_driver_name(card, false, "xe");
}
static struct igt_device *igt_device_from_syspath(const char *syspath)
diff --git a/lib/igt_device_scan.h b/lib/igt_device_scan.h
index e6b0f1b90..b8f6a843d 100644
--- a/lib/igt_device_scan.h
+++ b/lib/igt_device_scan.h
@@ -87,6 +87,8 @@ bool igt_device_card_match_pci(const char *filter,
struct igt_device_card *card);
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);
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.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 02/17] benchmarks/gem_wsim: reposition the unbound duration boolean
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 01/17] lib/igt_device_scan: added functions to get first Xe card Marcin Bernatowicz
@ 2023-10-05 18:57 ` Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 03/17] benchmarks/gem_wsim: fix duration range check Marcin Bernatowicz
` (17 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
All duration info is now in struct duration of w_step.
v2:
- rename unbound_duration to unbound (Tvrtko)
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
benchmarks/gem_wsim.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index 7b5e62a3b..42690d3d0 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -73,6 +73,7 @@ enum intel_engine_id {
struct duration {
unsigned int min, max;
+ bool unbound;
};
enum w_type
@@ -145,7 +146,6 @@ struct w_step
unsigned int context;
unsigned int engine;
struct duration duration;
- bool unbound_duration;
struct deps data_deps;
struct deps fence_deps;
int emit_fence;
@@ -1130,7 +1130,7 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
check_arg(intel_gen(intel_get_drm_devid(fd)) < 8,
"Infinite batch at step %u needs Gen8+!\n",
nr_steps);
- step.unbound_duration = true;
+ step.duration.unbound = true;
} else {
tmpl = strtol(field, &sep, 10);
check_arg(tmpl <= 0 || tmpl == LONG_MIN ||
@@ -2172,8 +2172,8 @@ update_bb_start(struct workload *wrk, struct w_step *w)
/* ticks is inverted for MI_DO_COMPARE (less-than comparison) */
ticks = 0;
- if (!w->unbound_duration)
- ticks = ~ns_to_ctx_ticks(1000 * get_duration(wrk, w));
+ if (!w->duration.unbound)
+ ticks = ~ns_to_ctx_ticks(1000LL * get_duration(wrk, w));
*w->bb_duration = ticks;
}
@@ -2349,7 +2349,7 @@ static void *run_workload(void *data)
igt_assert(t_idx >= 0 && t_idx < i);
igt_assert(wrk->steps[t_idx].type == BATCH);
- igt_assert(wrk->steps[t_idx].unbound_duration);
+ igt_assert(wrk->steps[t_idx].duration.unbound);
*wrk->steps[t_idx].bb_duration = 0xffffffff;
__sync_synchronize();
--
2.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 03/17] benchmarks/gem_wsim: fix duration range check
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 01/17] lib/igt_device_scan: added functions to get first Xe card Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 02/17] benchmarks/gem_wsim: reposition the unbound duration boolean Marcin Bernatowicz
@ 2023-10-05 18:57 ` Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 04/17] benchmarks/gem_wsim: extract duration parsing code to new function Marcin Bernatowicz
` (16 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
When scale duration (-f) command line option is provided,
the max duration check does not take it into account, fix it.
v2:
- improve error message (Tvrtko)
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
benchmarks/gem_wsim.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index 42690d3d0..9d9cbd9c2 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -1142,10 +1142,10 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
if (sep && *sep == '-') {
tmpl = strtol(sep + 1, NULL, 10);
check_arg(tmpl <= 0 ||
- tmpl <= step.duration.min ||
+ __duration(tmpl, scale_dur) <= step.duration.min ||
tmpl == LONG_MIN ||
tmpl == LONG_MAX,
- "Invalid duration range at step %u!\n",
+ "Invalid maximum duration at step %u!\n",
nr_steps);
step.duration.max = __duration(tmpl,
scale_dur);
--
2.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 04/17] benchmarks/gem_wsim: extract duration parsing code to new function
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (2 preceding siblings ...)
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 03/17] benchmarks/gem_wsim: fix duration range check Marcin Bernatowicz
@ 2023-10-05 18:57 ` Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 05/17] benchmarks/gem_wsim: fix conflicting SSEU #define and enum Marcin Bernatowicz
` (15 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
Moved code from parse_workload to separate function.
v2:
- keep "field" parameter name (instead of "_desc") (Tvrtko)
- emit error messages from parse_duration, caller returns NULL
on parse_duration failure (Tvrtko)
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
benchmarks/gem_wsim.c | 70 ++++++++++++++++++++++++-------------------
1 file changed, 40 insertions(+), 30 deletions(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index 9d9cbd9c2..91410d42d 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -860,6 +860,44 @@ static long __duration(long dur, double scale)
return round(scale * dur);
}
+static int
+parse_duration(unsigned int nr_steps, struct duration *dur, double scale_dur, char *field)
+{
+ char *sep = NULL;
+ long tmpl;
+
+ if (field[0] == '*') {
+ if (intel_gen(intel_get_drm_devid(fd)) < 8) {
+ wsim_err("Infinite batch at step %u needs Gen8+!\n", nr_steps);
+ return -1;
+ }
+ dur->unbound = true;
+ } else {
+ tmpl = strtol(field, &sep, 10);
+ if (tmpl <= 0 || tmpl == LONG_MIN || tmpl == LONG_MAX) {
+ wsim_err("Invalid duration at step %u!\n", nr_steps);
+ return -1;
+ }
+
+ dur->min = __duration(tmpl, scale_dur);
+
+ if (sep && *sep == '-') {
+ tmpl = strtol(sep + 1, NULL, 10);
+ if (tmpl <= 0 || __duration(tmpl, scale_dur) <= dur->min ||
+ tmpl == LONG_MIN || tmpl == LONG_MAX) {
+ wsim_err("Invalid maximum duration at step %u!\n", nr_steps);
+ return -1;
+ }
+
+ dur->max = __duration(tmpl, scale_dur);
+ } else {
+ dur->max = dur->min;
+ }
+ }
+
+ return 0;
+}
+
#define int_field(_STEP_, _FIELD_, _COND_, _ERR_) \
if ((field = strtok_r(fstart, ".", &fctx))) { \
tmp = atoi(field); \
@@ -1121,38 +1159,10 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
}
if ((field = strtok_r(fstart, ".", &fctx))) {
- char *sep = NULL;
- long int tmpl;
-
fstart = NULL;
- if (field[0] == '*') {
- check_arg(intel_gen(intel_get_drm_devid(fd)) < 8,
- "Infinite batch at step %u needs Gen8+!\n",
- nr_steps);
- step.duration.unbound = true;
- } else {
- tmpl = strtol(field, &sep, 10);
- check_arg(tmpl <= 0 || tmpl == LONG_MIN ||
- tmpl == LONG_MAX,
- "Invalid duration at step %u!\n",
- nr_steps);
- step.duration.min = __duration(tmpl, scale_dur);
-
- if (sep && *sep == '-') {
- tmpl = strtol(sep + 1, NULL, 10);
- check_arg(tmpl <= 0 ||
- __duration(tmpl, scale_dur) <= step.duration.min ||
- tmpl == LONG_MIN ||
- tmpl == LONG_MAX,
- "Invalid maximum duration at step %u!\n",
- nr_steps);
- step.duration.max = __duration(tmpl,
- scale_dur);
- } else {
- step.duration.max = step.duration.min;
- }
- }
+ if (parse_duration(nr_steps, &step.duration, scale_dur, field))
+ return NULL;
valid++;
}
--
2.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 05/17] benchmarks/gem_wsim: fix conflicting SSEU #define and enum
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (3 preceding siblings ...)
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 04/17] benchmarks/gem_wsim: extract duration parsing code to new function Marcin Bernatowicz
@ 2023-10-05 18:57 ` Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 06/17] benchmarks/gem_wsim: cleanups Marcin Bernatowicz
` (14 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
One SSEU is in enum w_step and then as #define SSEU (1 << 3).
Fix this.
v2:
- add FLAG_ prefix to all flags (Tvrtko)
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
benchmarks/gem_wsim.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index 91410d42d..67d2bce18 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -236,9 +236,9 @@ static struct drm_i915_gem_context_param_sseu device_sseu = {
.slice_mask = -1 /* Force read on first use. */
};
-#define SYNCEDCLIENTS (1<<1)
-#define DEPSYNC (1<<2)
-#define SSEU (1<<3)
+#define FLAG_SYNCEDCLIENTS (1<<1)
+#define FLAG_DEPSYNC (1<<2)
+#define FLAG_SSEU (1<<3)
static const char *ring_str_map[NUM_ENGINES] = {
[DEFAULT] = "DEFAULT",
@@ -1230,7 +1230,7 @@ add_step:
wrk->sseu = arg->sseu;
wrk->max_working_set_id = -1;
wrk->working_sets = NULL;
- wrk->bo_prng = (flags & SYNCEDCLIENTS) ? master_prng : rand();
+ wrk->bo_prng = (flags & FLAG_SYNCEDCLIENTS) ? master_prng : rand();
free(desc);
@@ -1868,8 +1868,8 @@ static int prepare_workload(unsigned int id, struct workload *wrk)
int i, j;
wrk->id = id;
- wrk->bb_prng = (wrk->flags & SYNCEDCLIENTS) ? master_prng : rand();
- wrk->bo_prng = (wrk->flags & SYNCEDCLIENTS) ? master_prng : rand();
+ wrk->bb_prng = (wrk->flags & FLAG_SYNCEDCLIENTS) ? master_prng : rand();
+ wrk->bo_prng = (wrk->flags & FLAG_SYNCEDCLIENTS) ? master_prng : rand();
wrk->run = true;
/*
@@ -2387,7 +2387,7 @@ static void *run_workload(void *data)
igt_assert(w->type == BATCH);
- if (wrk->flags & DEPSYNC)
+ if (wrk->flags & FLAG_DEPSYNC)
sync_deps(wrk, w);
if (throttle > 0)
@@ -2594,7 +2594,7 @@ int main(int argc, char **argv)
/* Fall through */
case 'w':
w_args = add_workload_arg(w_args, ++nr_w_args, optarg,
- prio, flags & SSEU);
+ prio, flags & FLAG_SSEU);
break;
case 'p':
prio = atoi(optarg);
@@ -2620,13 +2620,13 @@ int main(int argc, char **argv)
verbose++;
break;
case 'S':
- flags |= SYNCEDCLIENTS;
+ flags |= FLAG_SYNCEDCLIENTS;
break;
case 's':
- flags ^= SSEU;
+ flags ^= FLAG_SSEU;
break;
case 'd':
- flags |= DEPSYNC;
+ flags |= FLAG_DEPSYNC;
break;
case 'I':
master_prng = strtol(optarg, NULL, 0);
--
2.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 06/17] benchmarks/gem_wsim: cleanups
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (4 preceding siblings ...)
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 05/17] benchmarks/gem_wsim: fix conflicting SSEU #define and enum Marcin Bernatowicz
@ 2023-10-05 18:57 ` Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 07/17] benchmarks/gem_wsim: reposition repeat_start variable Marcin Bernatowicz
` (13 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 5915 bytes --]
Cleaning checkpatch.pl reported warnings/errors.
Removed unused fence_signal field from struct w_step.
v2:
- restored unnecessarily changed malloc (Tvrtko)
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
benchmarks/gem_wsim.c | 54 ++++++++++++++++++++++++++-----------------
1 file changed, 33 insertions(+), 21 deletions(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index 67d2bce18..c64397eae 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
/*
* Copyright © 2017 Intel Corporation
*
@@ -76,8 +77,7 @@ struct duration {
bool unbound;
};
-enum w_type
-{
+enum w_type {
BATCH,
SYNC,
DELAY,
@@ -102,8 +102,7 @@ struct dep_entry {
int working_set; /* -1 = step dependecy, >= 0 working set id */
};
-struct deps
-{
+struct deps {
int nr;
bool submit_fence;
struct dep_entry *list;
@@ -137,8 +136,7 @@ struct working_set {
struct workload;
-struct w_step
-{
+struct w_step {
struct workload *wrk;
/* Workload step metadata */
@@ -155,7 +153,6 @@ struct w_step
int period;
int target;
int throttle;
- int fence_signal;
int priority;
struct {
unsigned int engine_map_count;
@@ -194,8 +191,7 @@ struct ctx {
uint64_t sseu;
};
-struct workload
-{
+struct workload {
unsigned int id;
unsigned int nr_steps;
@@ -807,6 +803,7 @@ static int add_buffers(struct working_set *set, char *str)
for (i = 0; i < add; i++) {
struct work_buffer_size *sz = &sizes[set->nr + i];
+
sz->min = min_sz;
sz->max = max_sz;
sz->size = 0;
@@ -899,13 +896,16 @@ parse_duration(unsigned int nr_steps, struct duration *dur, double scale_dur, ch
}
#define int_field(_STEP_, _FIELD_, _COND_, _ERR_) \
- if ((field = strtok_r(fstart, ".", &fctx))) { \
- tmp = atoi(field); \
- check_arg(_COND_, _ERR_, nr_steps); \
- step.type = _STEP_; \
- step._FIELD_ = tmp; \
- goto add_step; \
- } \
+ do { \
+ field = strtok_r(fstart, ".", &fctx); \
+ if (field) { \
+ tmp = atoi(field); \
+ check_arg(_COND_, _ERR_, nr_steps); \
+ step.type = _STEP_; \
+ step._FIELD_ = tmp; \
+ goto add_step; \
+ } \
+ } while (0)
static struct workload *
parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
@@ -930,7 +930,8 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
valid = 0;
memset(&step, 0, sizeof(step));
- if ((field = strtok_r(fstart, ".", &fctx))) {
+ field = strtok_r(fstart, ".", &fctx);
+ if (field) {
fstart = NULL;
if (!strcmp(field, "d")) {
@@ -941,6 +942,7 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
"Invalid period at step %u!\n");
} else if (!strcmp(field, "P")) {
unsigned int nr = 0;
+
while ((field = strtok_r(fstart, ".", &fctx))) {
tmp = atoi(field);
check_arg(nr == 0 && tmp <= 0,
@@ -966,6 +968,7 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
"Invalid sync target at step %u!\n");
} else if (!strcmp(field, "S")) {
unsigned int nr = 0;
+
while ((field = strtok_r(fstart, ".", &fctx))) {
tmp = atoi(field);
check_arg(tmp <= 0 && nr == 0,
@@ -1002,6 +1005,7 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
goto add_step;
} else if (!strcmp(field, "M")) {
unsigned int nr = 0;
+
while ((field = strtok_r(fstart, ".", &fctx))) {
tmp = atoi(field);
check_arg(nr == 0 && tmp <= 0,
@@ -1032,6 +1036,7 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
"Invalid terminate target at step %u!\n");
} else if (!strcmp(field, "X")) {
unsigned int nr = 0;
+
while ((field = strtok_r(fstart, ".", &fctx))) {
tmp = atoi(field);
check_arg(nr == 0 && tmp <= 0,
@@ -1056,6 +1061,7 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
goto add_step;
} else if (!strcmp(field, "B")) {
unsigned int nr = 0;
+
while ((field = strtok_r(fstart, ".", &fctx))) {
tmp = atoi(field);
check_arg(nr == 0 && tmp <= 0,
@@ -1075,6 +1081,7 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
goto add_step;
} else if (!strcmp(field, "b")) {
unsigned int nr = 0;
+
while ((field = strtok_r(fstart, ".", &fctx))) {
check_arg(nr > 2,
"Invalid bond format at step %u!\n",
@@ -1146,7 +1153,8 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
valid++;
}
- if ((field = strtok_r(fstart, ".", &fctx))) {
+ field = strtok_r(fstart, ".", &fctx);
+ if (field) {
fstart = NULL;
i = str_to_engine(field);
@@ -1158,7 +1166,8 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
step.engine = i;
}
- if ((field = strtok_r(fstart, ".", &fctx))) {
+ field = strtok_r(fstart, ".", &fctx);
+ if (field) {
fstart = NULL;
if (parse_duration(nr_steps, &step.duration, scale_dur, field))
@@ -1167,7 +1176,8 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
valid++;
}
- if ((field = strtok_r(fstart, ".", &fctx))) {
+ field = strtok_r(fstart, ".", &fctx);
+ if (field) {
fstart = NULL;
tmp = parse_dependencies(nr_steps, &step, field);
@@ -1177,7 +1187,8 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
valid++;
}
- if ((field = strtok_r(fstart, ".", &fctx))) {
+ field = strtok_r(fstart, ".", &fctx);
+ if (field) {
fstart = NULL;
check_arg(strlen(field) != 1 ||
@@ -2714,6 +2725,7 @@ int main(int argc, char **argv)
if (append_workload_arg) {
struct w_arg arg = { NULL, append_workload_arg, 0 };
+
app_w = parse_workload(&arg, flags, scale_dur, scale_time,
NULL);
if (!app_w) {
--
2.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 07/17] benchmarks/gem_wsim: reposition repeat_start variable
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (5 preceding siblings ...)
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 06/17] benchmarks/gem_wsim: cleanups Marcin Bernatowicz
@ 2023-10-05 18:57 ` Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 08/17] benchmarks/gem_wsim: use lib code to query engines Marcin Bernatowicz
` (12 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
No need for repeat_start in struct workload.
It's now a variable in run_workload function scope.
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
benchmarks/gem_wsim.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index c64397eae..24b51ec8a 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -209,8 +209,6 @@ struct workload {
uint32_t bb_prng;
uint32_t bo_prng;
- struct timespec repeat_start;
-
unsigned int nr_ctxs;
struct ctx *ctx_list;
@@ -2280,7 +2278,7 @@ static void sync_deps(struct workload *wrk, struct w_step *w)
static void *run_workload(void *data)
{
struct workload *wrk = (struct workload *)data;
- struct timespec t_start, t_end;
+ struct timespec t_start, t_end, repeat_start;
struct w_step *w;
int throttle = -1;
int qd_throttle = -1;
@@ -2294,7 +2292,7 @@ static void *run_workload(void *data)
count++) {
unsigned int cur_seqno = wrk->sync_seqno;
- clock_gettime(CLOCK_MONOTONIC, &wrk->repeat_start);
+ clock_gettime(CLOCK_MONOTONIC, &repeat_start);
for (i = 0, w = wrk->steps; wrk->run && (i < wrk->nr_steps);
i++, w++) {
@@ -2308,7 +2306,7 @@ static void *run_workload(void *data)
int elapsed;
clock_gettime(CLOCK_MONOTONIC, &now);
- elapsed = elapsed_us(&wrk->repeat_start, &now);
+ elapsed = elapsed_us(&repeat_start, &now);
do_sleep = w->period - elapsed;
time_tot += elapsed;
if (elapsed < time_min)
--
2.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 08/17] benchmarks/gem_wsim: use lib code to query engines
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (6 preceding siblings ...)
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 07/17] benchmarks/gem_wsim: reposition repeat_start variable Marcin Bernatowicz
@ 2023-10-05 18:57 ` Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 09/17] benchmarks/gem_wsim: allow comments in workload description files Marcin Bernatowicz
` (11 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
Use code in lib/i915/gem_engine_topology to query engines.
v2:
- keep i unsigned, restore igt_assert(count)
in num_engines_in_class (Tvrtko)
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
benchmarks/gem_wsim.c | 153 +++++-------------------------------------
1 file changed, 17 insertions(+), 136 deletions(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index 24b51ec8a..2a1991ca6 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -456,146 +456,27 @@ static int str_to_engine(const char *str)
return -1;
}
-static bool __engines_queried;
-static unsigned int __num_engines;
-static struct i915_engine_class_instance *__engines;
-
-static int
-__i915_query(int i915, struct drm_i915_query *q)
-{
- if (igt_ioctl(i915, DRM_IOCTL_I915_QUERY, q))
- return -errno;
- return 0;
-}
-
-static int
-__i915_query_items(int i915, struct drm_i915_query_item *items, uint32_t n_items)
-{
- struct drm_i915_query q = {
- .num_items = n_items,
- .items_ptr = to_user_pointer(items),
- };
- return __i915_query(i915, &q);
-}
-
-static void
-i915_query_items(int i915, struct drm_i915_query_item *items, uint32_t n_items)
-{
- igt_assert_eq(__i915_query_items(i915, items, n_items), 0);
-}
-
-static bool has_engine_query(int i915)
-{
- struct drm_i915_query_item item = {
- .query_id = DRM_I915_QUERY_ENGINE_INFO,
- };
-
- return __i915_query_items(i915, &item, 1) == 0 && item.length > 0;
-}
-
-static void query_engines(void)
+static struct intel_engine_data *query_engines(void)
{
- struct i915_engine_class_instance *engines;
- unsigned int num;
-
- if (__engines_queried)
- return;
-
- __engines_queried = true;
-
- if (!has_engine_query(fd)) {
- unsigned int num_bsd = gem_has_bsd(fd) + gem_has_bsd2(fd);
- unsigned int i = 0;
-
- igt_assert(num_bsd);
-
- num = 1 + num_bsd;
+ static struct intel_engine_data engines = {};
- if (gem_has_blt(fd))
- num++;
+ if (engines.nengines)
+ return &engines;
- if (gem_has_vebox(fd))
- num++;
-
- engines = calloc(num,
- sizeof(struct i915_engine_class_instance));
- igt_assert(engines);
-
- engines[i].engine_class = I915_ENGINE_CLASS_RENDER;
- engines[i].engine_instance = 0;
- i++;
-
- if (gem_has_blt(fd)) {
- engines[i].engine_class = I915_ENGINE_CLASS_COPY;
- engines[i].engine_instance = 0;
- i++;
- }
-
- if (gem_has_bsd(fd)) {
- engines[i].engine_class = I915_ENGINE_CLASS_VIDEO;
- engines[i].engine_instance = 0;
- i++;
- }
-
- if (gem_has_bsd2(fd)) {
- engines[i].engine_class = I915_ENGINE_CLASS_VIDEO;
- engines[i].engine_instance = 1;
- i++;
- }
-
- if (gem_has_vebox(fd)) {
- engines[i].engine_class =
- I915_ENGINE_CLASS_VIDEO_ENHANCE;
- engines[i].engine_instance = 0;
- i++;
- }
- } else {
- struct drm_i915_query_engine_info *engine_info;
- struct drm_i915_query_item item = {
- .query_id = DRM_I915_QUERY_ENGINE_INFO,
- };
- const unsigned int sz = 4096;
- unsigned int i;
-
- engine_info = malloc(sz);
- igt_assert(engine_info);
- memset(engine_info, 0, sz);
-
- item.data_ptr = to_user_pointer(engine_info);
- item.length = sz;
-
- i915_query_items(fd, &item, 1);
- igt_assert(item.length > 0);
- igt_assert(item.length <= sz);
-
- num = engine_info->num_engines;
-
- engines = calloc(num,
- sizeof(struct i915_engine_class_instance));
- igt_assert(engines);
-
- for (i = 0; i < num; i++) {
- struct drm_i915_engine_info *engine =
- (struct drm_i915_engine_info *)&engine_info->engines[i];
-
- engines[i] = engine->engine;
- }
- }
-
- __engines = engines;
- __num_engines = num;
+ engines = intel_engine_list_of_physical(fd);
+ igt_assert(engines.nengines);
+ return &engines;
}
static unsigned int num_engines_in_class(enum intel_engine_id class)
{
+ const struct intel_engine_data *engines = query_engines();
unsigned int i, count = 0;
igt_assert(class == VCS);
- query_engines();
-
- for (i = 0; i < __num_engines; i++) {
- if (__engines[i].engine_class == I915_ENGINE_CLASS_VIDEO)
+ for (i = 0; i < engines->nengines; i++) {
+ if (engines->engines[i].class == I915_ENGINE_CLASS_VIDEO)
count++;
}
@@ -607,16 +488,15 @@ static void
fill_engines_id_class(enum intel_engine_id *list,
enum intel_engine_id class)
{
+ const struct intel_engine_data *engines = query_engines();
enum intel_engine_id engine = VCS1;
unsigned int i, j = 0;
igt_assert(class == VCS);
igt_assert(num_engines_in_class(VCS) <= 2);
- query_engines();
-
- for (i = 0; i < __num_engines; i++) {
- if (__engines[i].engine_class != I915_ENGINE_CLASS_VIDEO)
+ for (i = 0; i < engines->nengines; i++) {
+ if (engines->engines[i].class != I915_ENGINE_CLASS_VIDEO)
continue;
list[j++] = engine++;
@@ -626,17 +506,18 @@ fill_engines_id_class(enum intel_engine_id *list,
static unsigned int
find_physical_instance(enum intel_engine_id class, unsigned int logical)
{
+ const struct intel_engine_data *engines = query_engines();
unsigned int i, j = 0;
igt_assert(class == VCS);
- for (i = 0; i < __num_engines; i++) {
- if (__engines[i].engine_class != I915_ENGINE_CLASS_VIDEO)
+ for (i = 0; i < engines->nengines; i++) {
+ if (engines->engines[i].class != I915_ENGINE_CLASS_VIDEO)
continue;
/* Map logical to physical instances. */
if (logical == j++)
- return __engines[i].engine_instance;
+ return engines->engines[i].instance;
}
igt_assert(0);
--
2.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 09/17] benchmarks/gem_wsim: allow comments in workload description files
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (7 preceding siblings ...)
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 08/17] benchmarks/gem_wsim: use lib code to query engines Marcin Bernatowicz
@ 2023-10-05 18:57 ` Marcin Bernatowicz
2023-10-06 8:37 ` Tvrtko Ursulin
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 10/17] benchmarks/gem_wsim: introduce w_step_sync function Marcin Bernatowicz
` (10 subsequent siblings)
19 siblings, 1 reply; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
Lines starting with '#' are skipped.
If command line step separator (',') is encountered after '#'
it is replaced with ';' to not break parsing.
v2:
- SKIP step type is not needed (Tvrtko)
v3:
- correct README comment (Tvrtko)
- removed hunk for trailing comments after BATCH step,
as some other steps do not support it either (Tvrtko)
v4:
- correct out of bound access if file ends with hash (Tvrtko)
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
benchmarks/gem_wsim.c | 18 +++++++++++++++++-
benchmarks/wsim/README | 2 ++
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index 2a1991ca6..43779c70e 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -43,6 +43,7 @@
#include <limits.h>
#include <pthread.h>
#include <math.h>
+#include <ctype.h>
#include "drm.h"
#include "drmtest.h"
@@ -813,6 +814,14 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
if (field) {
fstart = NULL;
+ /* line starting with # is a comment */
+ if (field[0] == '#') {
+ if (verbose > 3)
+ printf("skipped line: %s\n", _token);
+ free(token);
+ continue;
+ }
+
if (!strcmp(field, "d")) {
int_field(DELAY, delay, tmp <= 0,
"Invalid delay at step %u!\n");
@@ -2403,6 +2412,7 @@ static char *load_workload_descriptor(char *filename)
char *buf;
int infd, ret, i;
ssize_t len;
+ bool in_comment = false;
ret = stat(filename, &sbuf);
if (ret || !S_ISREG(sbuf.st_mode))
@@ -2419,8 +2429,14 @@ static char *load_workload_descriptor(char *filename)
close(infd);
for (i = 0; i < len; i++) {
- if (buf[i] == '\n')
+ /* '#' starts comment till end of line */
+ if (buf[i] == '#')
+ in_comment = true;
+ else if (buf[i] == '\n') {
buf[i] = ',';
+ in_comment = false;
+ } else if (in_comment && buf[i] == ',')
+ buf[i] = ';';
}
len--;
diff --git a/benchmarks/wsim/README b/benchmarks/wsim/README
index 8c71f2fe6..d4f3dd8ae 100644
--- a/benchmarks/wsim/README
+++ b/benchmarks/wsim/README
@@ -1,6 +1,8 @@
Workload descriptor format
==========================
+Lines starting with '#' are treated as comments and will not create a work step.
+
ctx.engine.duration_us.dependency.wait,...
<uint>.<str>.<uint>[-<uint>]|*.<int <= 0>[/<int <= 0>][...].<0|1>,...
B.<uint>
--
2.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 10/17] benchmarks/gem_wsim: introduce w_step_sync function
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (8 preceding siblings ...)
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 09/17] benchmarks/gem_wsim: allow comments in workload description files Marcin Bernatowicz
@ 2023-10-05 18:57 ` Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 11/17] benchmarks/gem_wsim: extract allocate and prepare contexts code to new functions Marcin Bernatowicz
` (9 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
Added w_step_sync function for workload step synchronization.
Change will allow cleaner xe integration.
v2:
- correct indentation (Tvrtko)
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
benchmarks/gem_wsim.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index 43779c70e..1914b81b7 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -245,6 +245,11 @@ static const char *ring_str_map[NUM_ENGINES] = {
[VECS] = "VECS",
};
+static void w_step_sync(struct w_step *w)
+{
+ gem_sync(fd, w->obj[0].handle);
+}
+
static int read_timestamp_frequency(int i915)
{
int value = 0;
@@ -2102,7 +2107,7 @@ static void w_sync_to(struct workload *wrk, struct w_step *w, int target)
igt_assert(target < wrk->nr_steps);
igt_assert(wrk->steps[target].type == BATCH);
- gem_sync(fd, wrk->steps[target].obj[0].handle);
+ w_step_sync(&wrk->steps[target]);
}
static void
@@ -2161,7 +2166,7 @@ static void sync_deps(struct workload *wrk, struct w_step *w)
igt_assert(dep_idx >= 0 && dep_idx < w->idx);
igt_assert(wrk->steps[dep_idx].type == BATCH);
- gem_sync(fd, wrk->steps[dep_idx].obj[0].handle);
+ w_step_sync(&wrk->steps[dep_idx]);
}
}
@@ -2215,7 +2220,7 @@ static void *run_workload(void *data)
igt_assert(s_idx >= 0 && s_idx < i);
igt_assert(wrk->steps[s_idx].type == BATCH);
- gem_sync(fd, wrk->steps[s_idx].obj[0].handle);
+ w_step_sync(&wrk->steps[s_idx]);
continue;
} else if (w->type == THROTTLE) {
throttle = w->throttle;
@@ -2306,7 +2311,7 @@ static void *run_workload(void *data)
break;
if (w->sync)
- gem_sync(fd, w->obj[0].handle);
+ w_step_sync(w);
if (qd_throttle > 0) {
while (wrk->nrequest[engine] > qd_throttle) {
@@ -2315,7 +2320,7 @@ static void *run_workload(void *data)
s = igt_list_first_entry(&wrk->requests[engine],
s, rq_link);
- gem_sync(fd, s->obj[0].handle);
+ w_step_sync(s);
s->request = -1;
igt_list_del(&s->rq_link);
@@ -2347,7 +2352,7 @@ static void *run_workload(void *data)
continue;
w = igt_list_last_entry(&wrk->requests[i], w, rq_link);
- gem_sync(fd, w->obj[0].handle);
+ w_step_sync(w);
}
clock_gettime(CLOCK_MONOTONIC, &t_end);
--
2.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 11/17] benchmarks/gem_wsim: extract allocate and prepare contexts code to new functions
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (9 preceding siblings ...)
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 10/17] benchmarks/gem_wsim: introduce w_step_sync function Marcin Bernatowicz
@ 2023-10-05 18:57 ` Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 12/17] benchmarks/gem_wsim: extract prepare working sets code to new function Marcin Bernatowicz
` (8 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
No functional changes.
Extracted allocate_contexts and prepare_contexts functions
from prepare_workload.
v2:
- propagate error code from prepare_contexts (Tvrtko)
- don't mix unrelated changes (Tvrtko)
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
benchmarks/gem_wsim.c | 43 ++++++++++++++++++++++++++++++++-----------
1 file changed, 32 insertions(+), 11 deletions(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index 1914b81b7..8d853a909 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -1762,19 +1762,11 @@ static void measure_active_set(struct workload *wrk)
#define alloca0(sz) ({ size_t sz__ = (sz); memset(alloca(sz__), 0, sz__); })
-static int prepare_workload(unsigned int id, struct workload *wrk)
+static void allocate_contexts(unsigned int id, struct workload *wrk)
{
- struct working_set **sets;
- unsigned long total = 0;
- uint32_t share_vm = 0;
int max_ctx = -1;
struct w_step *w;
- int i, j;
-
- wrk->id = id;
- wrk->bb_prng = (wrk->flags & FLAG_SYNCEDCLIENTS) ? master_prng : rand();
- wrk->bo_prng = (wrk->flags & FLAG_SYNCEDCLIENTS) ? master_prng : rand();
- wrk->run = true;
+ int i;
/*
* Pre-scan workload steps to allocate context list storage.
@@ -1798,6 +1790,13 @@ static int prepare_workload(unsigned int id, struct workload *wrk)
max_ctx = ctx;
}
+}
+
+static int prepare_contexts(unsigned int id, struct workload *wrk)
+{
+ uint32_t share_vm = 0;
+ struct w_step *w;
+ int i, j;
/*
* Transfer over engine map configuration from the workload step.
@@ -1964,6 +1963,28 @@ static int prepare_workload(unsigned int id, struct workload *wrk)
if (share_vm)
vm_destroy(fd, share_vm);
+ return 0;
+}
+
+static int prepare_workload(unsigned int id, struct workload *wrk)
+{
+ struct working_set **sets;
+ unsigned long total = 0;
+ struct w_step *w;
+ int i, j;
+ int ret = 0;
+
+ wrk->id = id;
+ wrk->bb_prng = (wrk->flags & FLAG_SYNCEDCLIENTS) ? master_prng : rand();
+ wrk->bo_prng = (wrk->flags & FLAG_SYNCEDCLIENTS) ? master_prng : rand();
+ wrk->run = true;
+
+ allocate_contexts(id, wrk);
+
+ ret = prepare_contexts(id, wrk);
+ if (ret)
+ return ret;
+
/* Record default preemption. */
for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
if (w->type == BATCH)
@@ -2065,7 +2086,7 @@ static int prepare_workload(unsigned int id, struct workload *wrk)
measure_active_set(wrk);
- return 0;
+ return ret;
}
static double elapsed(const struct timespec *start, const struct timespec *end)
--
2.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 12/17] benchmarks/gem_wsim: extract prepare working sets code to new function
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (10 preceding siblings ...)
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 11/17] benchmarks/gem_wsim: extract allocate and prepare contexts code to new functions Marcin Bernatowicz
@ 2023-10-05 18:57 ` Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 13/17] benchmarks/gem_wsim: group i915 fields Marcin Bernatowicz
` (7 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
No functional changes.
Extracted prepare_working_sets function from prepare_workload.
v2:
- return void (Tvrtko)
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
benchmarks/gem_wsim.c | 104 +++++++++++++++++++++++-------------------
1 file changed, 56 insertions(+), 48 deletions(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index 8d853a909..5fdd28494 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -1966,10 +1966,64 @@ static int prepare_contexts(unsigned int id, struct workload *wrk)
return 0;
}
-static int prepare_workload(unsigned int id, struct workload *wrk)
+static void prepare_working_sets(unsigned int id, struct workload *wrk)
{
struct working_set **sets;
unsigned long total = 0;
+ struct w_step *w;
+ int i;
+
+ /*
+ * Allocate working sets.
+ */
+ for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
+ if (w->type == WORKINGSET && !w->working_set.shared)
+ total += allocate_working_set(wrk, &w->working_set);
+ }
+
+ if (verbose > 2)
+ printf("%u: %lu bytes in working sets.\n", wrk->id, total);
+
+ /*
+ * Map of working set ids.
+ */
+ wrk->max_working_set_id = -1;
+ for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
+ if (w->type == WORKINGSET &&
+ w->working_set.id > wrk->max_working_set_id)
+ wrk->max_working_set_id = w->working_set.id;
+ }
+
+ sets = wrk->working_sets;
+ wrk->working_sets = calloc(wrk->max_working_set_id + 1,
+ sizeof(*wrk->working_sets));
+ igt_assert(wrk->working_sets);
+
+ for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
+ struct working_set *set;
+
+ if (w->type != WORKINGSET)
+ continue;
+
+ if (!w->working_set.shared) {
+ set = &w->working_set;
+ } else {
+ igt_assert(sets);
+
+ set = sets[w->working_set.id];
+ igt_assert(set->shared);
+ igt_assert(set->sizes);
+ }
+
+ wrk->working_sets[w->working_set.id] = set;
+ }
+
+ if (sets)
+ free(sets);
+}
+
+static int prepare_workload(unsigned int id, struct workload *wrk)
+{
struct w_step *w;
int i, j;
int ret = 0;
@@ -2026,53 +2080,7 @@ static int prepare_workload(unsigned int id, struct workload *wrk)
}
}
- /*
- * Allocate working sets.
- */
- for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
- if (w->type == WORKINGSET && !w->working_set.shared)
- total += allocate_working_set(wrk, &w->working_set);
- }
-
- if (verbose > 2)
- printf("%u: %lu bytes in working sets.\n", wrk->id, total);
-
- /*
- * Map of working set ids.
- */
- wrk->max_working_set_id = -1;
- for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
- if (w->type == WORKINGSET &&
- w->working_set.id > wrk->max_working_set_id)
- wrk->max_working_set_id = w->working_set.id;
- }
-
- sets = wrk->working_sets;
- wrk->working_sets = calloc(wrk->max_working_set_id + 1,
- sizeof(*wrk->working_sets));
- igt_assert(wrk->working_sets);
-
- for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
- struct working_set *set;
-
- if (w->type != WORKINGSET)
- continue;
-
- if (!w->working_set.shared) {
- set = &w->working_set;
- } else {
- igt_assert(sets);
-
- set = sets[w->working_set.id];
- igt_assert(set->shared);
- igt_assert(set->sizes);
- }
-
- wrk->working_sets[w->working_set.id] = set;
- }
-
- if (sets)
- free(sets);
+ prepare_working_sets(id, wrk);
/*
* Allocate batch buffers.
--
2.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 13/17] benchmarks/gem_wsim: group i915 fields
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (11 preceding siblings ...)
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 12/17] benchmarks/gem_wsim: extract prepare working sets code to new function Marcin Bernatowicz
@ 2023-10-05 18:57 ` Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 14/17] benchmarks/gem_wsim: for_each_dep macro Marcin Bernatowicz
` (6 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
Group i915 specific fields.
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
benchmarks/gem_wsim.c | 100 ++++++++++++++++++++++--------------------
1 file changed, 52 insertions(+), 48 deletions(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index 5fdd28494..306125f27 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -174,11 +174,15 @@ struct w_step {
unsigned int request;
unsigned int preempt_us;
- struct drm_i915_gem_execbuffer2 eb;
- struct drm_i915_gem_exec_object2 *obj;
- struct drm_i915_gem_relocation_entry reloc[3];
+ union {
+ struct {
+ struct drm_i915_gem_execbuffer2 eb;
+ struct drm_i915_gem_exec_object2 *obj;
+ struct drm_i915_gem_relocation_entry reloc[3];
+ uint32_t *bb_duration;
+ } i915;
+ };
uint32_t bb_handle;
- uint32_t *bb_duration;
};
struct ctx {
@@ -247,7 +251,7 @@ static const char *ring_str_map[NUM_ENGINES] = {
static void w_step_sync(struct w_step *w)
{
- gem_sync(fd, w->obj[0].handle);
+ gem_sync(fd, w->i915.obj[0].handle);
}
static int read_timestamp_frequency(int i915)
@@ -1372,9 +1376,9 @@ static unsigned int create_bb(struct w_step *w, int self)
/* Save delta for indirect read by COND_BBE */
*cs++ = MI_STORE_REGISTER_MEM_CMD | (1 + use_64b) | MI_CS_MMIO_DST;
*cs++ = CS_GPR(NOW_TS);
- w->reloc[r].target_handle = self;
- w->reloc[r].offset = offset_in_page(cs);
- *cs++ = w->reloc[r].delta = 4000;
+ w->i915.reloc[r].target_handle = self;
+ w->i915.reloc[r].offset = offset_in_page(cs);
+ *cs++ = w->i915.reloc[r].delta = 4000;
*cs++ = 0;
r++;
@@ -1387,19 +1391,19 @@ static unsigned int create_bb(struct w_step *w, int self)
/* Break if delta [time elapsed] > target ns (target filled in later) */
*cs++ = MI_COND_BATCH_BUFFER_END | MI_DO_COMPARE | (1 + use_64b);
- w->bb_duration = cs;
+ w->i915.bb_duration = cs;
*cs++ = 0;
- w->reloc[r].target_handle = self;
- w->reloc[r].offset = offset_in_page(cs);
- *cs++ = w->reloc[r].delta = 4000;
+ w->i915.reloc[r].target_handle = self;
+ w->i915.reloc[r].offset = offset_in_page(cs);
+ *cs++ = w->i915.reloc[r].delta = 4000;
*cs++ = 0;
r++;
/* Otherwise back to recalculating delta */
*cs++ = MI_BATCH_BUFFER_START | 1 << 8 | use_64b;
- w->reloc[r].target_handle = self;
- w->reloc[r].offset = offset_in_page(cs);
- *cs++ = w->reloc[r].delta = offset_in_page(jmp);
+ w->i915.reloc[r].target_handle = self;
+ w->i915.reloc[r].offset = offset_in_page(cs);
+ *cs++ = w->i915.reloc[r].delta = offset_in_page(jmp);
*cs++ = 0;
r++;
@@ -1444,16 +1448,16 @@ eb_update_flags(struct workload *wrk, struct w_step *w,
struct ctx *ctx = __get_ctx(wrk, w);
if (ctx->engine_map)
- w->eb.flags = find_engine_in_map(ctx, engine);
+ w->i915.eb.flags = find_engine_in_map(ctx, engine);
else
- eb_set_engine(&w->eb, engine);
+ eb_set_engine(&w->i915.eb, engine);
- w->eb.flags |= I915_EXEC_HANDLE_LUT;
- w->eb.flags |= I915_EXEC_NO_RELOC;
+ w->i915.eb.flags |= I915_EXEC_HANDLE_LUT;
+ w->i915.eb.flags |= I915_EXEC_NO_RELOC;
igt_assert(w->emit_fence <= 0);
if (w->emit_fence)
- w->eb.flags |= I915_EXEC_FENCE_OUT;
+ w->i915.eb.flags |= I915_EXEC_FENCE_OUT;
}
static uint32_t
@@ -1475,11 +1479,11 @@ alloc_step_batch(struct workload *wrk, struct w_step *w)
unsigned int nr_obj = 2 + w->data_deps.nr;
unsigned int i;
- w->obj = calloc(nr_obj, sizeof(*w->obj));
- igt_assert(w->obj);
+ w->i915.obj = calloc(nr_obj, sizeof(*w->i915.obj));
+ igt_assert(w->i915.obj);
- w->obj[j].handle = alloc_bo(fd, 4096);
- w->obj[j].flags = EXEC_OBJECT_WRITE;
+ w->i915.obj[j].handle = alloc_bo(fd, 4096);
+ w->i915.obj[j].flags = EXEC_OBJECT_WRITE;
j++;
igt_assert(j < nr_obj);
@@ -1494,7 +1498,7 @@ alloc_step_batch(struct workload *wrk, struct w_step *w)
igt_assert(dep_idx >= 0 && dep_idx < w->idx);
igt_assert(wrk->steps[dep_idx].type == BATCH);
- dep_handle = wrk->steps[dep_idx].obj[0].handle;
+ dep_handle = wrk->steps[dep_idx].i915.obj[0].handle;
} else {
struct working_set *set;
@@ -1510,28 +1514,28 @@ alloc_step_batch(struct workload *wrk, struct w_step *w)
dep_handle = set->handles[entry->target];
}
- w->obj[j].flags = entry->write ? EXEC_OBJECT_WRITE : 0;
- w->obj[j].handle = dep_handle;
+ w->i915.obj[j].flags = entry->write ? EXEC_OBJECT_WRITE : 0;
+ w->i915.obj[j].handle = dep_handle;
j++;
igt_assert(j < nr_obj);
}
- w->bb_handle = w->obj[j].handle = gem_create(fd, 4096);
- w->obj[j].relocation_count = create_bb(w, j);
- igt_assert(w->obj[j].relocation_count <= ARRAY_SIZE(w->reloc));
- w->obj[j].relocs_ptr = to_user_pointer(&w->reloc);
+ w->bb_handle = w->i915.obj[j].handle = gem_create(fd, 4096);
+ w->i915.obj[j].relocation_count = create_bb(w, j);
+ igt_assert(w->i915.obj[j].relocation_count <= ARRAY_SIZE(w->i915.reloc));
+ w->i915.obj[j].relocs_ptr = to_user_pointer(&w->i915.reloc);
- w->eb.buffers_ptr = to_user_pointer(w->obj);
- w->eb.buffer_count = j + 1;
- w->eb.rsvd1 = get_ctxid(wrk, w);
+ w->i915.eb.buffers_ptr = to_user_pointer(w->i915.obj);
+ w->i915.eb.buffer_count = j + 1;
+ w->i915.eb.rsvd1 = get_ctxid(wrk, w);
eb_update_flags(wrk, w, engine);
#ifdef DEBUG
- printf("%u: %u:|", w->idx, w->eb.buffer_count);
+ printf("%u: %u:|", w->idx, w->i915.eb.buffer_count);
for (i = 0; i <= j; i++)
- printf("%x|", w->obj[i].handle);
+ printf("%x|", w->i915.obj[i].handle);
printf(" flags=%llx bb=%x[%u] ctx[%u]=%u\n",
- w->eb.flags, w->bb_handle, j, w->context,
+ w->i915.eb.flags, w->bb_handle, j, w->context,
get_ctxid(wrk, w));
#endif
}
@@ -1728,7 +1732,7 @@ static void measure_active_set(struct workload *wrk)
igt_assert(idx >= 0 && idx < w->idx);
igt_assert(wrk->steps[idx].type == BATCH);
- _dep.target = wrk->steps[idx].obj[0].handle;
+ _dep.target = wrk->steps[idx].i915.obj[0].handle;
}
if (!find_dep(deps, nr, _dep)) {
@@ -2118,7 +2122,7 @@ update_bb_start(struct workload *wrk, struct w_step *w)
if (!w->duration.unbound)
ticks = ~ns_to_ctx_ticks(1000LL * get_duration(wrk, w));
- *w->bb_duration = ticks;
+ *w->i915.bb_duration = ticks;
}
static void w_sync_to(struct workload *wrk, struct w_step *w, int target)
@@ -2156,20 +2160,20 @@ do_eb(struct workload *wrk, struct w_step *w, enum intel_engine_id engine)
igt_assert(wrk->steps[tgt].emit_fence > 0);
if (w->fence_deps.submit_fence)
- w->eb.flags |= I915_EXEC_FENCE_SUBMIT;
+ w->i915.eb.flags |= I915_EXEC_FENCE_SUBMIT;
else
- w->eb.flags |= I915_EXEC_FENCE_IN;
+ w->i915.eb.flags |= I915_EXEC_FENCE_IN;
- w->eb.rsvd2 = wrk->steps[tgt].emit_fence;
+ w->i915.eb.rsvd2 = wrk->steps[tgt].emit_fence;
}
- if (w->eb.flags & I915_EXEC_FENCE_OUT)
- gem_execbuf_wr(fd, &w->eb);
+ if (w->i915.eb.flags & I915_EXEC_FENCE_OUT)
+ gem_execbuf_wr(fd, &w->i915.eb);
else
- gem_execbuf(fd, &w->eb);
+ gem_execbuf(fd, &w->i915.eb);
- if (w->eb.flags & I915_EXEC_FENCE_OUT) {
- w->emit_fence = w->eb.rsvd2 >> 32;
+ if (w->i915.eb.flags & I915_EXEC_FENCE_OUT) {
+ w->emit_fence = w->i915.eb.rsvd2 >> 32;
igt_assert(w->emit_fence > 0);
}
}
@@ -2294,7 +2298,7 @@ static void *run_workload(void *data)
igt_assert(wrk->steps[t_idx].type == BATCH);
igt_assert(wrk->steps[t_idx].duration.unbound);
- *wrk->steps[t_idx].bb_duration = 0xffffffff;
+ *wrk->steps[t_idx].i915.bb_duration = 0xffffffff;
__sync_synchronize();
continue;
} else if (w->type == SSEU) {
--
2.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 14/17] benchmarks/gem_wsim: for_each_dep macro
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (12 preceding siblings ...)
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 13/17] benchmarks/gem_wsim: group i915 fields Marcin Bernatowicz
@ 2023-10-05 18:57 ` Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 15/17] benchmarks/gem_wsim: for_each_ctx macro Marcin Bernatowicz
` (5 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
Utility macro to easy traverse dependencies.
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
benchmarks/gem_wsim.c | 45 ++++++++++++++++++++++++-------------------
1 file changed, 25 insertions(+), 20 deletions(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index 306125f27..0c360d891 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -109,6 +109,10 @@ struct deps {
struct dep_entry *list;
};
+#define for_each_dep(__dep, __deps) \
+ for (int __i = 0; __i < __deps.nr && \
+ (__dep = &__deps.list[__i]); ++__i)
+
struct w_arg {
char *filename;
char *desc;
@@ -1147,8 +1151,10 @@ add_step:
* referencing them as a sync fence dependency.
*/
for (i = 0; i < nr_steps; i++) {
- for (j = 0; j < steps[i].fence_deps.nr; j++) {
- tmp = steps[i].idx + steps[i].fence_deps.list[j].target;
+ struct dep_entry *dep;
+
+ for_each_dep(dep, steps[i].fence_deps) {
+ tmp = steps[i].idx + dep->target;
check_arg(tmp < 0 || tmp >= i ||
(steps[tmp].type != BATCH &&
steps[tmp].type != SW_FENCE),
@@ -1475,9 +1481,9 @@ static void
alloc_step_batch(struct workload *wrk, struct w_step *w)
{
enum intel_engine_id engine = w->engine;
+ struct dep_entry *dep;
unsigned int j = 0;
unsigned int nr_obj = 2 + w->data_deps.nr;
- unsigned int i;
w->i915.obj = calloc(nr_obj, sizeof(*w->i915.obj));
igt_assert(w->i915.obj);
@@ -1487,14 +1493,13 @@ alloc_step_batch(struct workload *wrk, struct w_step *w)
j++;
igt_assert(j < nr_obj);
- for (i = 0; i < w->data_deps.nr; i++) {
- struct dep_entry *entry = &w->data_deps.list[i];
+ for_each_dep(dep, w->data_deps) {
uint32_t dep_handle;
- if (entry->working_set == -1) {
- int dep_idx = w->idx + entry->target;
+ if (dep->working_set == -1) {
+ int dep_idx = w->idx + dep->target;
- igt_assert(entry->target <= 0);
+ igt_assert(dep->target <= 0);
igt_assert(dep_idx >= 0 && dep_idx < w->idx);
igt_assert(wrk->steps[dep_idx].type == BATCH);
@@ -1502,19 +1507,19 @@ alloc_step_batch(struct workload *wrk, struct w_step *w)
} else {
struct working_set *set;
- igt_assert(entry->working_set <=
+ igt_assert(dep->working_set <=
wrk->max_working_set_id);
- set = wrk->working_sets[entry->working_set];
+ set = wrk->working_sets[dep->working_set];
igt_assert(set->nr);
- igt_assert(entry->target < set->nr);
- igt_assert(set->sizes[entry->target].size);
+ igt_assert(dep->target < set->nr);
+ igt_assert(set->sizes[dep->target].size);
- dep_handle = set->handles[entry->target];
+ dep_handle = set->handles[dep->target];
}
- w->i915.obj[j].flags = entry->write ? EXEC_OBJECT_WRITE : 0;
+ w->i915.obj[j].flags = dep->write ? EXEC_OBJECT_WRITE : 0;
w->i915.obj[j].handle = dep_handle;
j++;
igt_assert(j < nr_obj);
@@ -1709,8 +1714,8 @@ find_dep(struct dep_entry *deps, unsigned int nr, struct dep_entry dep)
static void measure_active_set(struct workload *wrk)
{
unsigned long total = 0, batch_sizes = 0;
- struct dep_entry *deps = NULL;
- unsigned int nr = 0, i, j;
+ struct dep_entry *dep, *deps = NULL;
+ unsigned int nr = 0, i;
struct w_step *w;
if (verbose < 3)
@@ -1722,8 +1727,7 @@ static void measure_active_set(struct workload *wrk)
batch_sizes += 4096;
- for (j = 0; j < w->data_deps.nr; j++) {
- struct dep_entry *dep = &w->data_deps.list[j];
+ for_each_dep(dep, w->data_deps) {
struct dep_entry _dep = *dep;
if (dep->working_set == -1 && dep->target < 0) {
@@ -2146,13 +2150,14 @@ static void w_sync_to(struct workload *wrk, struct w_step *w, int target)
static void
do_eb(struct workload *wrk, struct w_step *w, enum intel_engine_id engine)
{
+ struct dep_entry *dep;
unsigned int i;
eb_update_flags(wrk, w, engine);
update_bb_start(wrk, w);
- for (i = 0; i < w->fence_deps.nr; i++) {
- int tgt = w->idx + w->fence_deps.list[i].target;
+ for_each_dep(dep, w->fence_deps) {
+ int tgt = w->idx + dep->target;
/* TODO: fence merging needed to support multiple inputs */
igt_assert(i == 0);
--
2.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 15/17] benchmarks/gem_wsim: for_each_ctx macro
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (13 preceding siblings ...)
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 14/17] benchmarks/gem_wsim: for_each_dep macro Marcin Bernatowicz
@ 2023-10-05 18:57 ` Marcin Bernatowicz
2023-10-06 8:49 ` Tvrtko Ursulin
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 16/17] benchmarks/gem_wsim: for_each_w_step macro Marcin Bernatowicz
` (4 subsequent siblings)
19 siblings, 1 reply; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
for_each_ctx_ctx_idx, for_each_ctx macros to easy traverse contexts.
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
benchmarks/gem_wsim.c | 46 ++++++++++++++++++++++++-------------------
1 file changed, 26 insertions(+), 20 deletions(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index 0c360d891..03a86b39c 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -231,6 +231,13 @@ struct workload {
unsigned int nrequest[NUM_ENGINES];
};
+#define for_each_ctx_ctx_idx(__ctx, __wrk, __ctx_idx) \
+ for (typeof((__wrk)->nr_ctxs) __ctx_idx = 0; __ctx_idx < (__wrk)->nr_ctxs && \
+ (__ctx = &(__wrk)->ctx_list[__ctx_idx]); ++__ctx_idx)
+
+#define for_each_ctx(__ctx, __wrk) \
+ for_each_ctx_ctx_idx(__ctx, __wrk, igt_unique(__ctx_idx))
+
static unsigned int master_prng;
static int verbose = 1;
@@ -1804,16 +1811,15 @@ static int prepare_contexts(unsigned int id, struct workload *wrk)
{
uint32_t share_vm = 0;
struct w_step *w;
- int i, j;
+ struct ctx *ctx, *ctx2;
+ unsigned int i, j;
/*
* Transfer over engine map configuration from the workload step.
*/
- for (j = 0; j < wrk->nr_ctxs; j++) {
- struct ctx *ctx = &wrk->ctx_list[j];
-
+ for_each_ctx_ctx_idx(ctx, wrk, ctx_idx) {
for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
- if (w->context != j)
+ if (w->context != ctx_idx)
continue;
if (w->type == ENGINE_MAP) {
@@ -1850,32 +1856,32 @@ static int prepare_contexts(unsigned int id, struct workload *wrk)
/*
* Create and configure contexts.
*/
- for (i = 0; i < wrk->nr_ctxs; i++) {
+ for_each_ctx(ctx, wrk) {
struct drm_i915_gem_context_create_ext_setparam ext = {
.base.name = I915_CONTEXT_CREATE_EXT_SETPARAM,
.param.param = I915_CONTEXT_PARAM_VM,
};
struct drm_i915_gem_context_create_ext args = { };
- struct ctx *ctx = &wrk->ctx_list[i];
uint32_t ctx_id;
igt_assert(!ctx->id);
/* Find existing context to share ppgtt with. */
- for (j = 0; !share_vm && j < wrk->nr_ctxs; j++) {
- struct drm_i915_gem_context_param param = {
- .param = I915_CONTEXT_PARAM_VM,
- .ctx_id = wrk->ctx_list[j].id,
- };
-
- if (!param.ctx_id)
- continue;
+ if (!share_vm)
+ for_each_ctx(ctx2, wrk) {
+ struct drm_i915_gem_context_param param = {
+ .param = I915_CONTEXT_PARAM_VM,
+ .ctx_id = ctx2->id,
+ };
+
+ if (!param.ctx_id)
+ continue;
- gem_context_get_param(fd, ¶m);
- igt_assert(param.value);
- share_vm = param.value;
- break;
- }
+ gem_context_get_param(fd, ¶m);
+ igt_assert(param.value);
+ share_vm = param.value;
+ break;
+ }
if (share_vm) {
ext.param.value = share_vm;
--
2.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 16/17] benchmarks/gem_wsim: for_each_w_step macro
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (14 preceding siblings ...)
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 15/17] benchmarks/gem_wsim: for_each_ctx macro Marcin Bernatowicz
@ 2023-10-05 18:57 ` Marcin Bernatowicz
2023-10-06 11:19 ` Tvrtko Ursulin
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 17/17] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (3 subsequent siblings)
19 siblings, 1 reply; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
for_each_w_step macro to easy traverse workload steps.
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
benchmarks/gem_wsim.c | 80 +++++++++++++++++++++++--------------------
1 file changed, 42 insertions(+), 38 deletions(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index 03a86b39c..e86519614 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -238,6 +238,10 @@ struct workload {
#define for_each_ctx(__ctx, __wrk) \
for_each_ctx_ctx_idx(__ctx, __wrk, igt_unique(__ctx_idx))
+#define for_each_w_step(__w_step, __wrk) \
+ for (typeof(__wrk->nr_steps) igt_unique(idx) = ({__w_step = __wrk->steps; 0; }); \
+ igt_unique(idx) < __wrk->nr_steps; igt_unique(idx)++, __w_step++)
+
static unsigned int master_prng;
static int verbose = 1;
@@ -1183,14 +1187,14 @@ add_step:
/*
* Check no duplicate working set ids.
*/
- for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
+ for_each_w_step(w, wrk) {
struct w_step *w2;
if (w->type != WORKINGSET)
continue;
- for (j = 0, w2 = wrk->steps; j < wrk->nr_steps; w2++, j++) {
- if (j == i)
+ for_each_w_step(w2, wrk) {
+ if (w->idx == w2->idx)
continue;
if (w2->type != WORKINGSET)
continue;
@@ -1203,7 +1207,7 @@ add_step:
/*
* Allocate shared working sets.
*/
- for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
+ for_each_w_step(w, wrk) {
if (w->type == WORKINGSET && w->working_set.shared) {
unsigned long total =
allocate_working_set(wrk, &w->working_set);
@@ -1215,7 +1219,7 @@ add_step:
}
wrk->max_working_set_id = -1;
- for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
+ for_each_w_step(w, wrk) {
if (w->type == WORKINGSET &&
w->working_set.shared &&
w->working_set.id > wrk->max_working_set_id)
@@ -1226,7 +1230,7 @@ add_step:
sizeof(*wrk->working_sets));
igt_assert(wrk->working_sets);
- for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
+ for_each_w_step(w, wrk) {
if (w->type == WORKINGSET && w->working_set.shared)
wrk->working_sets[w->working_set.id] = &w->working_set;
}
@@ -1238,6 +1242,7 @@ static struct workload *
clone_workload(struct workload *_wrk)
{
struct workload *wrk;
+ struct w_step *w;
int i;
wrk = malloc(sizeof(*wrk));
@@ -1265,8 +1270,8 @@ clone_workload(struct workload *_wrk)
}
/* Check if we need a sw sync timeline. */
- for (i = 0; i < wrk->nr_steps; i++) {
- if (wrk->steps[i].type == SW_FENCE) {
+ for_each_w_step(w, wrk) {
+ if (w->type == SW_FENCE) {
wrk->sync_timeline = sw_sync_timeline_create();
igt_assert(wrk->sync_timeline >= 0);
break;
@@ -1722,13 +1727,13 @@ static void measure_active_set(struct workload *wrk)
{
unsigned long total = 0, batch_sizes = 0;
struct dep_entry *dep, *deps = NULL;
- unsigned int nr = 0, i;
+ unsigned int nr = 0;
struct w_step *w;
if (verbose < 3)
return;
- for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
+ for_each_w_step(w, wrk) {
if (w->type != BATCH)
continue;
@@ -1781,12 +1786,11 @@ static void allocate_contexts(unsigned int id, struct workload *wrk)
{
int max_ctx = -1;
struct w_step *w;
- int i;
/*
* Pre-scan workload steps to allocate context list storage.
*/
- for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
+ for_each_w_step(w, wrk) {
int ctx = w->context + 1;
int delta;
@@ -1812,13 +1816,13 @@ static int prepare_contexts(unsigned int id, struct workload *wrk)
uint32_t share_vm = 0;
struct w_step *w;
struct ctx *ctx, *ctx2;
- unsigned int i, j;
+ unsigned int j;
/*
* Transfer over engine map configuration from the workload step.
*/
for_each_ctx_ctx_idx(ctx, wrk, ctx_idx) {
- for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
+ for_each_w_step(w, wrk) {
if (w->context != ctx_idx)
continue;
@@ -1985,12 +1989,11 @@ static void prepare_working_sets(unsigned int id, struct workload *wrk)
struct working_set **sets;
unsigned long total = 0;
struct w_step *w;
- int i;
/*
* Allocate working sets.
*/
- for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
+ for_each_w_step(w, wrk) {
if (w->type == WORKINGSET && !w->working_set.shared)
total += allocate_working_set(wrk, &w->working_set);
}
@@ -2002,7 +2005,7 @@ static void prepare_working_sets(unsigned int id, struct workload *wrk)
* Map of working set ids.
*/
wrk->max_working_set_id = -1;
- for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
+ for_each_w_step(w, wrk) {
if (w->type == WORKINGSET &&
w->working_set.id > wrk->max_working_set_id)
wrk->max_working_set_id = w->working_set.id;
@@ -2013,7 +2016,7 @@ static void prepare_working_sets(unsigned int id, struct workload *wrk)
sizeof(*wrk->working_sets));
igt_assert(wrk->working_sets);
- for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
+ for_each_w_step(w, wrk) {
struct working_set *set;
if (w->type != WORKINGSET)
@@ -2039,7 +2042,6 @@ static void prepare_working_sets(unsigned int id, struct workload *wrk)
static int prepare_workload(unsigned int id, struct workload *wrk)
{
struct w_step *w;
- int i, j;
int ret = 0;
wrk->id = id;
@@ -2054,23 +2056,22 @@ static int prepare_workload(unsigned int id, struct workload *wrk)
return ret;
/* Record default preemption. */
- for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
+ for_each_w_step(w, wrk)
if (w->type == BATCH)
w->preempt_us = 100;
- }
/*
* Scan for contexts with modified preemption config and record their
* preemption period for the following steps belonging to the same
* context.
*/
- for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
+ for_each_w_step(w, wrk) {
struct w_step *w2;
if (w->type != PREEMPTION)
continue;
- for (j = i + 1; j < wrk->nr_steps; j++) {
+ for (int j = w->idx + 1; j < wrk->nr_steps; j++) {
w2 = &wrk->steps[j];
if (w2->context != w->context)
@@ -2087,7 +2088,7 @@ static int prepare_workload(unsigned int id, struct workload *wrk)
/*
* Scan for SSEU control steps.
*/
- for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
+ for_each_w_step(w, wrk) {
if (w->type == SSEU) {
get_device_sseu();
break;
@@ -2099,7 +2100,7 @@ static int prepare_workload(unsigned int id, struct workload *wrk)
/*
* Allocate batch buffers.
*/
- for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
+ for_each_w_step(w, wrk) {
if (w->type != BATCH)
continue;
@@ -2223,7 +2224,6 @@ static void *run_workload(void *data)
int qd_throttle = -1;
int count, missed = 0;
unsigned long time_tot = 0, time_min = ULONG_MAX, time_max = 0;
- int i;
clock_gettime(CLOCK_MONOTONIC, &t_start);
@@ -2233,11 +2233,13 @@ static void *run_workload(void *data)
clock_gettime(CLOCK_MONOTONIC, &repeat_start);
- for (i = 0, w = wrk->steps; wrk->run && (i < wrk->nr_steps);
- i++, w++) {
+ for_each_w_step(w, wrk) {
enum intel_engine_id engine = w->engine;
int do_sleep = 0;
+ if (!wrk->run)
+ break;
+
if (w->type == DELAY) {
do_sleep = w->delay;
} else if (w->type == PERIOD) {
@@ -2256,13 +2258,13 @@ static void *run_workload(void *data)
missed++;
if (verbose > 2)
printf("%u: Dropped period @ %u/%u (%dus late)!\n",
- wrk->id, count, i, do_sleep);
+ wrk->id, count, w->idx, do_sleep);
continue;
}
} else if (w->type == SYNC) {
- unsigned int s_idx = i + w->target;
+ unsigned int s_idx = w->idx + w->target;
- igt_assert(s_idx >= 0 && s_idx < i);
+ igt_assert(s_idx >= 0 && s_idx < w->idx);
igt_assert(wrk->steps[s_idx].type == BATCH);
w_step_sync(&wrk->steps[s_idx]);
continue;
@@ -2283,7 +2285,7 @@ static void *run_workload(void *data)
int tgt = w->idx + w->target;
int inc;
- igt_assert(tgt >= 0 && tgt < i);
+ igt_assert(tgt >= 0 && tgt < w->idx);
igt_assert(wrk->steps[tgt].type == SW_FENCE);
cur_seqno += wrk->steps[tgt].idx;
inc = cur_seqno - wrk->sync_seqno;
@@ -2303,9 +2305,9 @@ static void *run_workload(void *data)
}
continue;
} else if (w->type == TERMINATE) {
- unsigned int t_idx = i + w->target;
+ unsigned int t_idx = w->idx + w->target;
- igt_assert(t_idx >= 0 && t_idx < i);
+ igt_assert(t_idx >= 0 && t_idx < w->idx);
igt_assert(wrk->steps[t_idx].type == BATCH);
igt_assert(wrk->steps[t_idx].duration.unbound);
@@ -2339,7 +2341,7 @@ static void *run_workload(void *data)
sync_deps(wrk, w);
if (throttle > 0)
- w_sync_to(wrk, w, i - throttle);
+ w_sync_to(wrk, w, w->idx - throttle);
do_eb(wrk, w, engine);
@@ -2382,8 +2384,10 @@ static void *run_workload(void *data)
}
/* Cleanup all fences instantiated in this iteration. */
- for (i = 0, w = wrk->steps; wrk->run && (i < wrk->nr_steps);
- i++, w++) {
+ for_each_w_step(w, wrk) {
+ if (!wrk->run)
+ break;
+
if (w->emit_fence > 0) {
close(w->emit_fence);
w->emit_fence = -1;
@@ -2391,7 +2395,7 @@ static void *run_workload(void *data)
}
}
- for (i = 0; i < NUM_ENGINES; i++) {
+ for (int i = 0; i < NUM_ENGINES; i++) {
if (!wrk->nrequest[i])
continue;
--
2.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 17/17] benchmarks/gem_wsim: added basic xe support
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (15 preceding siblings ...)
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 16/17] benchmarks/gem_wsim: for_each_w_step macro Marcin Bernatowicz
@ 2023-10-05 18:57 ` Marcin Bernatowicz
2023-10-06 14:12 ` Tvrtko Ursulin
2023-10-05 22:03 ` [igt-dev] ✓ Fi.CI.BAT: success for benchmarks/gem_wsim: added basic xe support (rev6) Patchwork
` (2 subsequent siblings)
19 siblings, 1 reply; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-05 18:57 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
Added basic xe support. Single binary handles both i915 and Xe devices.
Some functionality is still missing: working sets, bonding.
The tool is handy for scheduling tests, we find it useful to verify vGPU
profiles defining different execution quantum/preemption timeout
settings.
There is also some rationale for the tool in following thread:
https://lore.kernel.org/dri-devel/a443495f-5d1b-52e1-9b2f-80167deb6d57@linux.intel.com/
With this patch it should be possible to run following on xe device:
gem_wsim -w benchmarks/wsim/media_load_balance_fhd26u7.wsim -c 36 -r 600
Best with drm debug logs disabled:
echo 0 > /sys/module/drm/parameters/debug
v2: minimizing divergence - same workload syntax for both drivers,
so most existing examples should run on xe unmodified (Tvrtko)
This version creates one common VM per workload.
Explicit VM management, compute mode will come in next patchset.
v3:
- use calloc in parse_workload for struct workload,
to allow cleanups in fini_workload
- grouped xe specific fields (Tvrtko)
- moved is_xe boolean next to fd (Tvrtko)
- use xe_ prefix for Xe specific things (Tvrtko)
- left throttling untouched (Tvrtko)
- parse errors vs silent skips on not implemented steps (Tvrtko)
- need to think on better engine handling in next version
- add 'Xe and i915 differences' section to README (Tvrtko)
for now no data dependency implemented, left -1 <=> f-1
to not modify examples (maybe too optimistic assumption?)
v4:
- corrected engines mappings for xe (Tvrtko)
"M.1.VCS,B.1,1.DEFAULT.1000.0.1" should use VCS
- verified engines selection works on MTL (Tvrtko)
- prevent misuse combinations of fence and implicit data deps (Tvrtko)
ex. "f,1.DEFAULT.1000.-1.0" should fail
"f,1.DEFAULT.1000.f-1.0" is valid
- corrected error messages (Tvrtko)
- moved wsim_err up to be accessible from parse_dependencies
- missing xe_device_put (Tvrtko)
- left fini_workload cleanup for separate patch
- README updates
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
benchmarks/gem_wsim.c | 487 +++++++++++++++++++++++++++++++++++++++--
benchmarks/wsim/README | 23 +-
2 files changed, 483 insertions(+), 27 deletions(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index e86519614..ecbeb9175 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -62,6 +62,12 @@
#include "i915/gem_engine_topology.h"
#include "i915/gem_mman.h"
+#include "igt_syncobj.h"
+#include "intel_allocator.h"
+#include "xe_drm.h"
+#include "xe/xe_ioctl.h"
+#include "xe/xe_spin.h"
+
enum intel_engine_id {
DEFAULT,
RCS,
@@ -185,10 +191,31 @@ struct w_step {
struct drm_i915_gem_relocation_entry reloc[3];
uint32_t *bb_duration;
} i915;
+ struct {
+ struct drm_xe_exec exec;
+ struct {
+ struct xe_spin spin;
+ uint64_t vm_sync;
+ uint64_t exec_sync;
+ } *data;
+ struct drm_xe_sync *syncs;
+ } xe;
};
uint32_t bb_handle;
};
+struct xe_vm {
+ uint32_t id;
+ bool compute_mode;
+ uint64_t ahnd;
+};
+
+struct xe_exec_queue {
+ uint32_t id;
+ unsigned int nr_hwes;
+ struct drm_xe_engine_class_instance *hwe_list;
+};
+
struct ctx {
uint32_t id;
int priority;
@@ -198,6 +225,13 @@ struct ctx {
struct bond *bonds;
bool load_balance;
uint64_t sseu;
+ struct {
+ /* reference to vm */
+ struct xe_vm *vm;
+ /* exec queues */
+ unsigned int nr_queues;
+ struct xe_exec_queue *queue_list;
+ } xe;
};
struct workload {
@@ -221,6 +255,11 @@ struct workload {
unsigned int nr_ctxs;
struct ctx *ctx_list;
+ struct {
+ unsigned int nr_vms;
+ struct xe_vm *vm_list;
+ } xe;
+
struct working_set **working_sets; /* array indexed by set id */
int max_working_set_id;
@@ -246,6 +285,7 @@ static unsigned int master_prng;
static int verbose = 1;
static int fd;
+static bool is_xe;
static struct drm_i915_gem_context_param_sseu device_sseu = {
.slice_mask = -1 /* Force read on first use. */
};
@@ -266,7 +306,10 @@ static const char *ring_str_map[NUM_ENGINES] = {
static void w_step_sync(struct w_step *w)
{
- gem_sync(fd, w->i915.obj[0].handle);
+ if (is_xe)
+ igt_assert(syncobj_wait(fd, &w->xe.syncs[0].handle, 1, INT64_MAX, 0, NULL));
+ else
+ gem_sync(fd, w->i915.obj[0].handle);
}
static int read_timestamp_frequency(int i915)
@@ -354,6 +397,19 @@ parse_working_set_deps(struct workload *wrk,
return 0;
}
+static void __attribute__((format(printf, 1, 2)))
+wsim_err(const char *fmt, ...)
+{
+ va_list ap;
+
+ if (!verbose)
+ return;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+
static int
parse_dependency(unsigned int nr_steps, struct w_step *w, char *str)
{
@@ -374,11 +430,18 @@ parse_dependency(unsigned int nr_steps, struct w_step *w, char *str)
break;
case 's':
+ /* no submit fence in xe */
+ if (is_xe) {
+ wsim_err("Submit fences are not supported with xe\n");
+ return -1;
+ }
submit_fence = true;
/* Fall-through. */
case 'f':
- /* Multiple fences not yet supported. */
- igt_assert_eq(w->fence_deps.nr, 0);
+ /* xe supports multiple fences */
+ if (!is_xe)
+ /* Multiple fences not yet supported. */
+ igt_assert_eq(w->fence_deps.nr, 0);
entry.target = atoi(++str);
if (entry.target > 0 || ((int)nr_steps + entry.target) < 0)
@@ -448,19 +511,6 @@ out:
return ret;
}
-static void __attribute__((format(printf, 1, 2)))
-wsim_err(const char *fmt, ...)
-{
- va_list ap;
-
- if (!verbose)
- return;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-}
-
#define check_arg(cond, fmt, ...) \
{ \
if (cond) { \
@@ -488,7 +538,17 @@ static struct intel_engine_data *query_engines(void)
if (engines.nengines)
return &engines;
- engines = intel_engine_list_of_physical(fd);
+ if (is_xe) {
+ struct drm_xe_engine_class_instance *hwe;
+
+ xe_for_each_hw_engine(fd, hwe) {
+ engines.engines[engines.nengines].class = hwe->engine_class;
+ engines.engines[engines.nengines].instance = hwe->engine_instance;
+ engines.nengines++;
+ }
+ } else
+ engines = intel_engine_list_of_physical(fd);
+
igt_assert(engines.nengines);
return &engines;
}
@@ -581,6 +641,46 @@ get_engine(enum intel_engine_id engine)
return ci;
}
+static struct drm_xe_engine_class_instance
+xe_get_engine(enum intel_engine_id engine)
+{
+ struct drm_xe_engine_class_instance hwe = {}, *hwe1;
+ bool found_physical = false;
+
+ switch (engine) {
+ case RCS:
+ hwe.engine_class = DRM_XE_ENGINE_CLASS_RENDER;
+ break;
+ case BCS:
+ hwe.engine_class = DRM_XE_ENGINE_CLASS_COPY;
+ break;
+ case VCS1:
+ hwe.engine_class = DRM_XE_ENGINE_CLASS_VIDEO_DECODE;
+ break;
+ case VCS2:
+ hwe.engine_class = DRM_XE_ENGINE_CLASS_VIDEO_DECODE;
+ hwe.engine_instance = 1;
+ break;
+ case VECS:
+ hwe.engine_class = DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE;
+ break;
+ default:
+ igt_assert(0);
+ };
+
+ xe_for_each_hw_engine(fd, hwe1) {
+ if (hwe.engine_class == hwe1->engine_class &&
+ hwe.engine_instance == hwe1->engine_instance) {
+ hwe = *hwe1;
+ found_physical = true;
+ break;
+ }
+ }
+
+ igt_assert(found_physical);
+ return hwe;
+}
+
static int parse_engine_map(struct w_step *step, const char *_str)
{
char *token, *tctx = NULL, *tstart = (char *)_str;
@@ -855,6 +955,12 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
} else if (!strcmp(field, "P")) {
unsigned int nr = 0;
+ if (is_xe) {
+ wsim_err("Priority step is not implemented with xe yet.\n");
+ free(token);
+ return NULL;
+ }
+
while ((field = strtok_r(fstart, ".", &fctx))) {
tmp = atoi(field);
check_arg(nr == 0 && tmp <= 0,
@@ -881,6 +987,12 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
} else if (!strcmp(field, "S")) {
unsigned int nr = 0;
+ if (is_xe) {
+ wsim_err("SSEU step is not implemented with xe yet.\n");
+ free(token);
+ return NULL;
+ }
+
while ((field = strtok_r(fstart, ".", &fctx))) {
tmp = atoi(field);
check_arg(tmp <= 0 && nr == 0,
@@ -994,6 +1106,12 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
} else if (!strcmp(field, "b")) {
unsigned int nr = 0;
+ if (is_xe) {
+ wsim_err("Bonding is not implemented with xe yet.\n");
+ free(token);
+ return NULL;
+ }
+
while ((field = strtok_r(fstart, ".", &fctx))) {
check_arg(nr > 2,
"Invalid bond format at step %u!\n",
@@ -1028,6 +1146,12 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
} else if (!strcmp(field, "w") || !strcmp(field, "W")) {
unsigned int nr = 0;
+ if (is_xe) {
+ wsim_err("Working sets are not implemented with xe yet.\n");
+ free(token);
+ return NULL;
+ }
+
step.working_set.shared = field[0] == 'W';
while ((field = strtok_r(fstart, ".", &fctx))) {
@@ -1484,6 +1608,31 @@ get_ctxid(struct workload *wrk, struct w_step *w)
return wrk->ctx_list[w->context].id;
}
+static struct xe_exec_queue *
+xe_get_eq(struct workload *wrk, const struct w_step *w)
+{
+ struct ctx *ctx = __get_ctx(wrk, w);
+ struct xe_exec_queue *eq;
+
+ if (ctx->engine_map) {
+ igt_assert_eq(ctx->xe.nr_queues, 1);
+ igt_assert(ctx->xe.queue_list[0].id);
+ eq = &ctx->xe.queue_list[0];
+ } else {
+ igt_assert(w->engine >= 0 && w->engine < ctx->xe.nr_queues);
+ igt_assert(ctx->xe.queue_list[w->engine].id);
+ eq = &ctx->xe.queue_list[w->engine];
+ }
+
+ return eq;
+}
+
+static struct xe_vm *
+xe_get_vm(struct workload *wrk, const struct w_step *w)
+{
+ return wrk->xe.vm_list;
+}
+
static uint32_t alloc_bo(int i915, unsigned long size)
{
return gem_create(i915, size);
@@ -1557,6 +1706,71 @@ alloc_step_batch(struct workload *wrk, struct w_step *w)
#endif
}
+static void
+xe_alloc_step_batch(struct workload *wrk, struct w_step *w)
+{
+ struct xe_vm *vm = xe_get_vm(wrk, w);
+ struct xe_exec_queue *eq = xe_get_eq(wrk, w);
+ struct dep_entry *dep;
+ int i;
+
+ w->bb_handle = xe_bo_create_flags(fd, vm->id, PAGE_SIZE,
+ visible_vram_if_possible(fd, eq->hwe_list[0].gt_id));
+ w->xe.data = xe_bo_map(fd, w->bb_handle, PAGE_SIZE);
+ w->xe.exec.address =
+ intel_allocator_alloc_with_strategy(vm->ahnd, w->bb_handle, PAGE_SIZE,
+ 0, ALLOC_STRATEGY_LOW_TO_HIGH);
+ xe_vm_bind_sync(fd, vm->id, w->bb_handle, 0, w->xe.exec.address, PAGE_SIZE);
+ xe_spin_init_opts(&w->xe.data->spin, .addr = w->xe.exec.address,
+ .preempt = (w->preempt_us > 0),
+ .ctx_ticks = duration_to_ctx_ticks(fd, eq->hwe_list[0].gt_id,
+ 1000LL * get_duration(wrk, w)));
+ w->xe.exec.exec_queue_id = eq->id;
+ w->xe.exec.num_batch_buffer = 1;
+ /* always at least one out fence */
+ w->xe.exec.num_syncs = 1;
+ /* count syncs */
+ for_each_dep(dep, w->data_deps) {
+ int dep_idx = w->idx + dep->target;
+
+ igt_assert(dep_idx >= 0 && dep_idx < w->idx);
+ igt_assert(wrk->steps[dep_idx].type == BATCH);
+
+ w->xe.exec.num_syncs++;
+ }
+ for_each_dep(dep, w->fence_deps) {
+ int dep_idx = w->idx + dep->target;
+
+ igt_assert(dep_idx >= 0 && dep_idx < w->idx);
+ igt_assert(wrk->steps[dep_idx].type == SW_FENCE ||
+ wrk->steps[dep_idx].type == BATCH);
+
+ w->xe.exec.num_syncs++;
+ }
+ w->xe.syncs = calloc(w->xe.exec.num_syncs, sizeof(*w->xe.syncs));
+ /* fill syncs */
+ i = 0;
+ /* out fence */
+ w->xe.syncs[i].handle = syncobj_create(fd, 0);
+ w->xe.syncs[i++].flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL;
+ /* in fence(s) */
+ for_each_dep(dep, w->data_deps) {
+ int dep_idx = w->idx + dep->target;
+
+ igt_assert(wrk->steps[dep_idx].xe.syncs && wrk->steps[dep_idx].xe.syncs[0].handle);
+ w->xe.syncs[i].handle = wrk->steps[dep_idx].xe.syncs[0].handle;
+ w->xe.syncs[i++].flags = DRM_XE_SYNC_SYNCOBJ;
+ }
+ for_each_dep(dep, w->fence_deps) {
+ int dep_idx = w->idx + dep->target;
+
+ igt_assert(wrk->steps[dep_idx].xe.syncs && wrk->steps[dep_idx].xe.syncs[0].handle);
+ w->xe.syncs[i].handle = wrk->steps[dep_idx].xe.syncs[0].handle;
+ w->xe.syncs[i++].flags = DRM_XE_SYNC_SYNCOBJ;
+ }
+ w->xe.exec.syncs = to_user_pointer(w->xe.syncs);
+}
+
static bool set_priority(uint32_t ctx_id, int prio)
{
struct drm_i915_gem_context_param param = {
@@ -1739,6 +1953,9 @@ static void measure_active_set(struct workload *wrk)
batch_sizes += 4096;
+ if (is_xe)
+ continue;
+
for_each_dep(dep, w->data_deps) {
struct dep_entry _dep = *dep;
@@ -1782,6 +1999,31 @@ static void measure_active_set(struct workload *wrk)
#define alloca0(sz) ({ size_t sz__ = (sz); memset(alloca(sz__), 0, sz__); })
+static void xe_vm_create_(struct xe_vm *vm)
+{
+ uint32_t flags = 0;
+
+ if (vm->compute_mode)
+ flags |= DRM_XE_VM_CREATE_ASYNC_BIND_OPS |
+ DRM_XE_VM_CREATE_COMPUTE_MODE;
+
+ vm->id = xe_vm_create(fd, flags, 0);
+}
+
+static void xe_exec_queue_create_(struct ctx *ctx, struct xe_exec_queue *eq)
+{
+ struct drm_xe_exec_queue_create create = {
+ .vm_id = ctx->xe.vm->id,
+ .width = 1,
+ .num_placements = eq->nr_hwes,
+ .instances = to_user_pointer(eq->hwe_list),
+ };
+
+ igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC_QUEUE_CREATE, &create), 0);
+
+ eq->id = create.exec_queue_id;
+}
+
static void allocate_contexts(unsigned int id, struct workload *wrk)
{
int max_ctx = -1;
@@ -1984,6 +2226,140 @@ static int prepare_contexts(unsigned int id, struct workload *wrk)
return 0;
}
+static int xe_prepare_contexts(unsigned int id, struct workload *wrk)
+{
+ struct xe_exec_queue *eq;
+ struct w_step *w;
+ struct ctx *ctx;
+ unsigned int i;
+
+ /* shortcut, create one vm */
+ wrk->xe.nr_vms = 1;
+ wrk->xe.vm_list = calloc(wrk->xe.nr_vms, sizeof(struct xe_vm));
+ wrk->xe.vm_list->compute_mode = false;
+ xe_vm_create_(wrk->xe.vm_list);
+ wrk->xe.vm_list->ahnd = intel_allocator_open(fd, wrk->xe.vm_list->id,
+ INTEL_ALLOCATOR_RELOC);
+
+ for_each_ctx_ctx_idx(ctx, wrk, ctx_idx) {
+ /* link with vm */
+ ctx->xe.vm = wrk->xe.vm_list;
+ for_each_w_step(w, wrk) {
+ if (w->context != ctx_idx)
+ continue;
+ if (w->type == ENGINE_MAP) {
+ ctx->engine_map = w->engine_map;
+ ctx->engine_map_count = w->engine_map_count;
+ } else if (w->type == LOAD_BALANCE) {
+ if (!ctx->engine_map) {
+ wsim_err("Load balancing needs an engine map!\n");
+ return 1;
+ }
+ if (intel_gen(intel_get_drm_devid(fd)) < 11) {
+ wsim_err("Load balancing needs relative mmio support, gen11+!\n");
+ return 1;
+ }
+ ctx->load_balance = w->load_balance;
+ }
+ }
+
+ /* create exec queue for each referenced engine */
+ if (ctx->engine_map) {
+ ctx->xe.nr_queues = 1;
+ ctx->xe.queue_list = calloc(ctx->xe.nr_queues, sizeof(*ctx->xe.queue_list));
+ igt_assert(ctx->xe.queue_list);
+ eq = &ctx->xe.queue_list[ctx->xe.nr_queues - 1];
+ eq->nr_hwes = ctx->engine_map_count;
+ eq->hwe_list = calloc(eq->nr_hwes, sizeof(*eq->hwe_list));
+ for (i = 0; i < eq->nr_hwes; ++i) {
+ eq->hwe_list[i] = xe_get_engine(ctx->engine_map[i]);
+
+ /* check no mixing classes and no duplicates */
+ for (int j = 0; j < i; ++j) {
+ if (eq->hwe_list[j].engine_class !=
+ eq->hwe_list[i].engine_class) {
+ free(eq->hwe_list);
+ eq->nr_hwes = 0;
+ wsim_err("Mixing of engine class not supported!\n");
+ return 1;
+ }
+
+ if (eq->hwe_list[j].engine_instance ==
+ eq->hwe_list[i].engine_instance) {
+ free(eq->hwe_list);
+ eq->nr_hwes = 0;
+ wsim_err("Duplicate engine entry!\n");
+ return 1;
+ }
+ }
+
+ if (verbose > 3)
+ printf("%u ctx[%d] %s [%u:%u:%u]\n",
+ id, ctx_idx, ring_str_map[ctx->engine_map[i]],
+ eq->hwe_list[i].engine_class,
+ eq->hwe_list[i].engine_instance,
+ eq->hwe_list[i].gt_id);
+ }
+
+ xe_exec_queue_create_(ctx, eq);
+ } else {
+ int engine_classes[NUM_ENGINES] = {};
+
+ ctx->xe.nr_queues = NUM_ENGINES;
+ ctx->xe.queue_list = calloc(ctx->xe.nr_queues, sizeof(*ctx->xe.queue_list));
+
+ for_each_w_step(w, wrk) {
+ if (w->context != ctx_idx)
+ continue;
+ if (w->type == BATCH)
+ engine_classes[w->engine]++;
+ }
+
+ for (i = 0; i < NUM_ENGINES; i++) {
+ if (engine_classes[i]) {
+ eq = &ctx->xe.queue_list[i];
+ eq->nr_hwes = 1;
+ eq->hwe_list = calloc(1, sizeof(*eq->hwe_list));
+
+ if (i == DEFAULT) {
+ struct drm_xe_engine_class_instance *hwe;
+
+ /* select first available engine */
+ xe_for_each_hw_engine(fd, hwe) {
+ eq->hwe_list[0] = *hwe;
+ break;
+ }
+ } else if (i == VCS) {
+ eq->hwe_list[0] = xe_get_engine(VCS1);
+ } else {
+ eq->hwe_list[0] = xe_get_engine(i);
+ }
+
+ if (verbose > 3)
+ printf("%u ctx[%d] %s [%u:%u:%u]\n",
+ id, ctx_idx, ring_str_map[i],
+ eq->hwe_list[0].engine_class,
+ eq->hwe_list[0].engine_instance,
+ eq->hwe_list[0].gt_id);
+
+ xe_exec_queue_create_(ctx, eq);
+ }
+ engine_classes[i] = 0;
+ }
+ }
+ }
+
+ /* create syncobjs for SW_FENCE */
+ for_each_w_step(w, wrk)
+ if (w->type == SW_FENCE) {
+ w->xe.syncs = calloc(1, sizeof(struct drm_xe_sync));
+ w->xe.syncs[0].handle = syncobj_create(fd, 0);
+ w->xe.syncs[0].flags = DRM_XE_SYNC_SYNCOBJ;
+ }
+
+ return 0;
+}
+
static void prepare_working_sets(unsigned int id, struct workload *wrk)
{
struct working_set **sets;
@@ -2051,7 +2427,11 @@ static int prepare_workload(unsigned int id, struct workload *wrk)
allocate_contexts(id, wrk);
- ret = prepare_contexts(id, wrk);
+ if (is_xe)
+ ret = xe_prepare_contexts(id, wrk);
+ else
+ ret = prepare_contexts(id, wrk);
+
if (ret)
return ret;
@@ -2104,7 +2484,10 @@ static int prepare_workload(unsigned int id, struct workload *wrk)
if (w->type != BATCH)
continue;
- alloc_step_batch(wrk, w);
+ if (is_xe)
+ xe_alloc_step_batch(wrk, w);
+ else
+ alloc_step_batch(wrk, w);
}
measure_active_set(wrk);
@@ -2154,6 +2537,24 @@ static void w_sync_to(struct workload *wrk, struct w_step *w, int target)
w_step_sync(&wrk->steps[target]);
}
+static void do_xe_exec(struct workload *wrk, struct w_step *w)
+{
+ struct xe_exec_queue *eq = xe_get_eq(wrk, w);
+
+ igt_assert(w->emit_fence <= 0);
+ if (w->emit_fence == -1)
+ syncobj_reset(fd, &w->xe.syncs[0].handle, 1);
+
+ /* update duration if random */
+ if (w->duration.max != w->duration.min)
+ xe_spin_init_opts(&w->xe.data->spin,
+ .addr = w->xe.exec.address,
+ .preempt = (w->preempt_us > 0),
+ .ctx_ticks = duration_to_ctx_ticks(fd, eq->hwe_list[0].gt_id,
+ 1000LL * get_duration(wrk, w)));
+ xe_exec(fd, &w->xe.exec);
+}
+
static void
do_eb(struct workload *wrk, struct w_step *w, enum intel_engine_id engine)
{
@@ -2280,6 +2681,10 @@ static void *run_workload(void *data)
sw_sync_timeline_create_fence(wrk->sync_timeline,
cur_seqno + w->idx);
igt_assert(w->emit_fence > 0);
+ if (is_xe)
+ /* Convert sync file to syncobj */
+ syncobj_import_sync_file(fd, w->xe.syncs[0].handle,
+ w->emit_fence);
continue;
} else if (w->type == SW_FENCE_SIGNAL) {
int tgt = w->idx + w->target;
@@ -2311,7 +2716,10 @@ static void *run_workload(void *data)
igt_assert(wrk->steps[t_idx].type == BATCH);
igt_assert(wrk->steps[t_idx].duration.unbound);
- *wrk->steps[t_idx].i915.bb_duration = 0xffffffff;
+ if (is_xe)
+ xe_spin_end(&wrk->steps[t_idx].xe.data->spin);
+ else
+ *wrk->steps[t_idx].i915.bb_duration = 0xffffffff;
__sync_synchronize();
continue;
} else if (w->type == SSEU) {
@@ -2343,7 +2751,10 @@ static void *run_workload(void *data)
if (throttle > 0)
w_sync_to(wrk, w, w->idx - throttle);
- do_eb(wrk, w, engine);
+ if (is_xe)
+ do_xe_exec(wrk, w);
+ else
+ do_eb(wrk, w, engine);
if (w->request != -1) {
igt_list_del(&w->rq_link);
@@ -2389,6 +2800,10 @@ static void *run_workload(void *data)
break;
if (w->emit_fence > 0) {
+ if (is_xe) {
+ igt_assert(w->type == SW_FENCE);
+ syncobj_reset(fd, &w->xe.syncs[0].handle, 1);
+ }
close(w->emit_fence);
w->emit_fence = -1;
}
@@ -2403,6 +2818,23 @@ static void *run_workload(void *data)
w_step_sync(w);
}
+ if (is_xe) {
+ for_each_w_step(w, wrk) {
+ if (w->type == BATCH) {
+ w_step_sync(w);
+ syncobj_destroy(fd, w->xe.syncs[0].handle);
+ free(w->xe.syncs);
+ xe_vm_unbind_sync(fd, xe_get_vm(wrk, w)->id, 0, w->xe.exec.address,
+ PAGE_SIZE);
+ gem_munmap(w->xe.data, PAGE_SIZE);
+ gem_close(fd, w->bb_handle);
+ } else if (w->type == SW_FENCE) {
+ syncobj_destroy(fd, w->xe.syncs[0].handle);
+ free(w->xe.syncs);
+ }
+ }
+ }
+
clock_gettime(CLOCK_MONOTONIC, &t_end);
if (wrk->print_stats) {
@@ -2629,8 +3061,12 @@ int main(int argc, char **argv)
ret = igt_device_find_first_i915_discrete_card(&card);
if (!ret)
ret = igt_device_find_integrated_card(&card);
+ if (!ret)
+ ret = igt_device_find_first_xe_discrete_card(&card);
+ if (!ret)
+ ret = igt_device_find_xe_integrated_card(&card);
if (!ret) {
- wsim_err("No device filter specified and no i915 devices found!\n");
+ wsim_err("No device filter specified and no intel devices found!\n");
return EXIT_FAILURE;
}
}
@@ -2653,6 +3089,10 @@ int main(int argc, char **argv)
if (verbose > 1)
printf("Using device %s\n", drm_dev);
+ is_xe = is_xe_device(fd);
+ if (is_xe)
+ xe_device_get(fd);
+
if (!nr_w_args) {
wsim_err("No workload descriptor(s)!\n");
goto err;
@@ -2772,5 +3212,8 @@ int main(int argc, char **argv)
out:
exitcode = EXIT_SUCCESS;
err:
+ if (is_xe)
+ xe_device_put(fd);
+
return exitcode;
}
diff --git a/benchmarks/wsim/README b/benchmarks/wsim/README
index d4f3dd8ae..e43813335 100644
--- a/benchmarks/wsim/README
+++ b/benchmarks/wsim/README
@@ -88,6 +88,19 @@ Batch durations can also be specified as infinite by using the '*' in the
duration field. Such batches must be ended by the terminate command ('T')
otherwise they will cause a GPU hang to be reported.
+Xe and i915 differences
+------------------------
+
+There are differences between Xe and i915, like not allowing a BO list to
+be passed to an exec (and create implicit syncs). For more details see:
+https://gitlab.freedesktop.org/drm/xe/kernel/-/blob/drm-xe-next/drivers/gpu/drm/xe/xe_exec.c
+
+Currently following batch steps are equal on Xe:
+1.1000.-2.0 <==> 1.1000.f-2.0
+and will create explicit sync fence dependency (via syncobjects).
+
+The data dependency need to wait for working sets implementation.
+
Sync (fd) fences
----------------
@@ -131,7 +144,7 @@ runnable. When the second RCS batch completes the standalone fence is signaled
which allows the two VCS batches to be executed. Finally we wait until the both
VCS batches have completed before starting the (optional) next iteration.
-Submit fences
+Submit fences (i915 only)
-------------
Submit fences are a type of input fence which are signalled when the originating
@@ -148,7 +161,7 @@ Submit fences have the identical syntax as the sync fences with the lower-case
Here VCS1 and VCS2 batches will only be submitted for executing once the RCS
batch enters the GPU.
-Context priority
+Context priority (i915 only)
----------------
P.1.-1
@@ -213,7 +226,7 @@ Example:
This enables load balancing for context number one.
-Engine bonds
+Engine bonds (i915 only)
------------
Engine bonds are extensions on load balanced contexts. They allow expressing
@@ -261,7 +274,7 @@ then look like:
2.DEFAULT.1000.s-1.0
a.-3
-Context SSEU configuration
+Context SSEU configuration (i915 only)
--------------------------
S.1.1
@@ -281,7 +294,7 @@ Slice mask of -1 has a special meaning of "all slices". Otherwise any integer
can be specifying as the slice mask, but beware any apart from 1 and -1 can make
the workload not portable between different GPUs.
-Working sets
+Working sets (i915 only)
------------
When used plainly workload steps can create implicit data dependencies by
--
2.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [igt-dev] ✓ Fi.CI.BAT: success for benchmarks/gem_wsim: added basic xe support (rev6)
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (16 preceding siblings ...)
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 17/17] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
@ 2023-10-05 22:03 ` Patchwork
2023-10-06 0:10 ` [igt-dev] ✓ CI.xeBAT: " Patchwork
2023-10-06 12:23 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
19 siblings, 0 replies; 31+ messages in thread
From: Patchwork @ 2023-10-05 22:03 UTC (permalink / raw)
To: Tvrtko Ursulin; +Cc: igt-dev
[-- Attachment #1: Type: text/plain, Size: 6501 bytes --]
== Series Details ==
Series: benchmarks/gem_wsim: added basic xe support (rev6)
URL : https://patchwork.freedesktop.org/series/122920/
State : success
== Summary ==
CI Bug Log - changes from CI_DRM_13719 -> IGTPW_9933
====================================================
Summary
-------
**SUCCESS**
No regressions found.
External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/index.html
Participating hosts (41 -> 38)
------------------------------
Missing (3): fi-kbl-soraka fi-hsw-4770 fi-snb-2520m
Known issues
------------
Here are the changes found in IGTPW_9933 that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@gem_exec_suspend@basic-s3@smem:
- bat-mtlp-8: NOTRUN -> [ABORT][1] ([i915#8213] / [i915#9262])
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/bat-mtlp-8/igt@gem_exec_suspend@basic-s3@smem.html
- fi-cfl-8700k: [PASS][2] -> [ABORT][3] ([i915#8213])
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/fi-cfl-8700k/igt@gem_exec_suspend@basic-s3@smem.html
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/fi-cfl-8700k/igt@gem_exec_suspend@basic-s3@smem.html
* igt@i915_module_load@reload:
- fi-skl-6600u: [PASS][4] -> [DMESG-WARN][5] ([i915#1982])
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/fi-skl-6600u/igt@i915_module_load@reload.html
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/fi-skl-6600u/igt@i915_module_load@reload.html
* igt@i915_selftest@live@mman:
- bat-rpls-1: [PASS][6] -> [TIMEOUT][7] ([i915#6794] / [i915#7392])
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/bat-rpls-1/igt@i915_selftest@live@mman.html
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/bat-rpls-1/igt@i915_selftest@live@mman.html
* igt@i915_suspend@basic-s2idle-without-i915:
- bat-rpls-1: [PASS][8] -> [WARN][9] ([i915#8747])
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/bat-rpls-1/igt@i915_suspend@basic-s2idle-without-i915.html
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/bat-rpls-1/igt@i915_suspend@basic-s2idle-without-i915.html
* igt@i915_suspend@basic-s3-without-i915:
- bat-mtlp-8: NOTRUN -> [SKIP][10] ([i915#6645])
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/bat-mtlp-8/igt@i915_suspend@basic-s3-without-i915.html
* igt@kms_pipe_crc_basic@read-crc-frame-sequence@pipe-d-edp-1:
- bat-rplp-1: [PASS][11] -> [ABORT][12] ([i915#8668])
[11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/bat-rplp-1/igt@kms_pipe_crc_basic@read-crc-frame-sequence@pipe-d-edp-1.html
[12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/bat-rplp-1/igt@kms_pipe_crc_basic@read-crc-frame-sequence@pipe-d-edp-1.html
#### Possible fixes ####
* igt@i915_selftest@live@gt_lrc:
- bat-adlp-9: [INCOMPLETE][13] -> [PASS][14]
[13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/bat-adlp-9/igt@i915_selftest@live@gt_lrc.html
[14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/bat-adlp-9/igt@i915_selftest@live@gt_lrc.html
* igt@i915_selftest@live@requests:
- bat-mtlp-8: [ABORT][15] ([i915#9414]) -> [PASS][16]
[15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/bat-mtlp-8/igt@i915_selftest@live@requests.html
[16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/bat-mtlp-8/igt@i915_selftest@live@requests.html
* igt@kms_chamelium_frames@dp-crc-fast:
- {bat-dg2-13}: [DMESG-WARN][17] ([Intel XE#485]) -> [PASS][18]
[17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/bat-dg2-13/igt@kms_chamelium_frames@dp-crc-fast.html
[18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/bat-dg2-13/igt@kms_chamelium_frames@dp-crc-fast.html
* igt@kms_cursor_legacy@basic-flip-before-cursor-atomic:
- bat-adlp-11: [DMESG-WARN][19] ([i915#6868]) -> [PASS][20]
[19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/bat-adlp-11/igt@kms_cursor_legacy@basic-flip-before-cursor-atomic.html
[20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/bat-adlp-11/igt@kms_cursor_legacy@basic-flip-before-cursor-atomic.html
* igt@kms_flip@basic-flip-vs-modeset@a-dp5:
- bat-adlp-11: [DMESG-FAIL][21] ([i915#6868]) -> [PASS][22]
[21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/bat-adlp-11/igt@kms_flip@basic-flip-vs-modeset@a-dp5.html
[22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/bat-adlp-11/igt@kms_flip@basic-flip-vs-modeset@a-dp5.html
* igt@kms_flip@basic-flip-vs-modeset@b-dp5:
- bat-adlp-11: [FAIL][23] ([i915#6121]) -> [PASS][24] +6 other tests pass
[23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/bat-adlp-11/igt@kms_flip@basic-flip-vs-modeset@b-dp5.html
[24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/bat-adlp-11/igt@kms_flip@basic-flip-vs-modeset@b-dp5.html
{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).
[Intel XE#485]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/485
[i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
[i915#6121]: https://gitlab.freedesktop.org/drm/intel/issues/6121
[i915#6645]: https://gitlab.freedesktop.org/drm/intel/issues/6645
[i915#6794]: https://gitlab.freedesktop.org/drm/intel/issues/6794
[i915#6868]: https://gitlab.freedesktop.org/drm/intel/issues/6868
[i915#7392]: https://gitlab.freedesktop.org/drm/intel/issues/7392
[i915#7952]: https://gitlab.freedesktop.org/drm/intel/issues/7952
[i915#8213]: https://gitlab.freedesktop.org/drm/intel/issues/8213
[i915#8668]: https://gitlab.freedesktop.org/drm/intel/issues/8668
[i915#8747]: https://gitlab.freedesktop.org/drm/intel/issues/8747
[i915#9262]: https://gitlab.freedesktop.org/drm/intel/issues/9262
[i915#9414]: https://gitlab.freedesktop.org/drm/intel/issues/9414
Build changes
-------------
* CI: CI-20190529 -> None
* IGT: IGT_7517 -> IGTPW_9933
CI-20190529: 20190529
CI_DRM_13719: 68e5c10def179bde3bf44bd95d19eea796cbf7a3 @ git://anongit.freedesktop.org/gfx-ci/linux
IGTPW_9933: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/index.html
IGT_7517: 8368e3ad3f9459a8f5cdd24f813ae802c1211029 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/index.html
[-- Attachment #2: Type: text/html, Size: 7484 bytes --]
^ permalink raw reply [flat|nested] 31+ messages in thread
* [igt-dev] ✓ CI.xeBAT: success for benchmarks/gem_wsim: added basic xe support (rev6)
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (17 preceding siblings ...)
2023-10-05 22:03 ` [igt-dev] ✓ Fi.CI.BAT: success for benchmarks/gem_wsim: added basic xe support (rev6) Patchwork
@ 2023-10-06 0:10 ` Patchwork
2023-10-06 12:23 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
19 siblings, 0 replies; 31+ messages in thread
From: Patchwork @ 2023-10-06 0:10 UTC (permalink / raw)
To: Tvrtko Ursulin; +Cc: igt-dev
[-- Attachment #1: Type: text/plain, Size: 3093 bytes --]
== Series Details ==
Series: benchmarks/gem_wsim: added basic xe support (rev6)
URL : https://patchwork.freedesktop.org/series/122920/
State : success
== Summary ==
CI Bug Log - changes from XEIGT_7517_BAT -> XEIGTPW_9933_BAT
====================================================
Summary
-------
**SUCCESS**
No regressions found.
Participating hosts (4 -> 4)
------------------------------
No changes in participating hosts
Known issues
------------
Here are the changes found in XEIGTPW_9933_BAT that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@kms_flip@basic-flip-vs-wf_vblank:
- bat-dg2-oem2: [PASS][1] -> [FAIL][2] ([Intel XE#480]) +1 other test fail
[1]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_7517/bat-dg2-oem2/igt@kms_flip@basic-flip-vs-wf_vblank.html
[2]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_9933/bat-dg2-oem2/igt@kms_flip@basic-flip-vs-wf_vblank.html
* igt@kms_flip@basic-flip-vs-wf_vblank@d-edp1:
- bat-adlp-7: [PASS][3] -> [FAIL][4] ([Intel XE#480]) +1 other test fail
[3]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_7517/bat-adlp-7/igt@kms_flip@basic-flip-vs-wf_vblank@d-edp1.html
[4]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_9933/bat-adlp-7/igt@kms_flip@basic-flip-vs-wf_vblank@d-edp1.html
#### Possible fixes ####
* igt@core_hotunplug@unbind-rebind:
- bat-dg2-oem2: [INCOMPLETE][5] ([Intel XE#764]) -> [PASS][6]
[5]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_7517/bat-dg2-oem2/igt@core_hotunplug@unbind-rebind.html
[6]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_9933/bat-dg2-oem2/igt@core_hotunplug@unbind-rebind.html
* igt@xe_exec_store@basic-store:
- bat-adlp-7: [FAIL][7] ([Intel XE#761]) -> [PASS][8]
[7]: https://intel-gfx-ci.01.org/tree/intel-xe/IGT_7517/bat-adlp-7/igt@xe_exec_store@basic-store.html
[8]: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_9933/bat-adlp-7/igt@xe_exec_store@basic-store.html
{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).
[Intel XE#480]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/480
[Intel XE#524]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/524
[Intel XE#761]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/761
[Intel XE#764]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/764
Build changes
-------------
* IGT: IGT_7517 -> IGTPW_9933
* Linux: xe-415-3d2b298aaf52e74d4e90470cd65de047362e4875 -> xe-417-b3daf7f07d6accbe43feafcadeb0b0498063761e
IGTPW_9933: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/index.html
IGT_7517: 8368e3ad3f9459a8f5cdd24f813ae802c1211029 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
xe-415-3d2b298aaf52e74d4e90470cd65de047362e4875: 3d2b298aaf52e74d4e90470cd65de047362e4875
xe-417-b3daf7f07d6accbe43feafcadeb0b0498063761e: b3daf7f07d6accbe43feafcadeb0b0498063761e
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/intel-xe/IGTPW_9933/index.html
[-- Attachment #2: Type: text/html, Size: 3772 bytes --]
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 09/17] benchmarks/gem_wsim: allow comments in workload description files
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 09/17] benchmarks/gem_wsim: allow comments in workload description files Marcin Bernatowicz
@ 2023-10-06 8:37 ` Tvrtko Ursulin
0 siblings, 0 replies; 31+ messages in thread
From: Tvrtko Ursulin @ 2023-10-06 8:37 UTC (permalink / raw)
To: Marcin Bernatowicz, igt-dev; +Cc: chris.p.wilson
On 05/10/2023 19:57, Marcin Bernatowicz wrote:
> Lines starting with '#' are skipped.
> If command line step separator (',') is encountered after '#'
> it is replaced with ';' to not break parsing.
>
> v2:
> - SKIP step type is not needed (Tvrtko)
> v3:
> - correct README comment (Tvrtko)
> - removed hunk for trailing comments after BATCH step,
> as some other steps do not support it either (Tvrtko)
> v4:
> - correct out of bound access if file ends with hash (Tvrtko)
>
> Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
> ---
> benchmarks/gem_wsim.c | 18 +++++++++++++++++-
> benchmarks/wsim/README | 2 ++
> 2 files changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
> index 2a1991ca6..43779c70e 100644
> --- a/benchmarks/gem_wsim.c
> +++ b/benchmarks/gem_wsim.c
> @@ -43,6 +43,7 @@
> #include <limits.h>
> #include <pthread.h>
> #include <math.h>
> +#include <ctype.h>
>
> #include "drm.h"
> #include "drmtest.h"
> @@ -813,6 +814,14 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
> if (field) {
> fstart = NULL;
>
> + /* line starting with # is a comment */
> + if (field[0] == '#') {
> + if (verbose > 3)
> + printf("skipped line: %s\n", _token);
> + free(token);
> + continue;
> + }
> +
> if (!strcmp(field, "d")) {
> int_field(DELAY, delay, tmp <= 0,
> "Invalid delay at step %u!\n");
> @@ -2403,6 +2412,7 @@ static char *load_workload_descriptor(char *filename)
> char *buf;
> int infd, ret, i;
> ssize_t len;
> + bool in_comment = false;
>
> ret = stat(filename, &sbuf);
> if (ret || !S_ISREG(sbuf.st_mode))
> @@ -2419,8 +2429,14 @@ static char *load_workload_descriptor(char *filename)
> close(infd);
>
> for (i = 0; i < len; i++) {
> - if (buf[i] == '\n')
> + /* '#' starts comment till end of line */
> + if (buf[i] == '#')
> + in_comment = true;
> + else if (buf[i] == '\n') {
> buf[i] = ',';
> + in_comment = false;
> + } else if (in_comment && buf[i] == ',')
> + buf[i] = ';';
If you checked this works it looks good to me.
Perhaps just add the full text from the commit message as a comment?
/*
* Lines starting with '#' are skipped.
* If command line step separator (',') is encountered after '#'
* it is replaced with ';' to not break parsing.
*/
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Regards,
Tvrtko
> }
>
> len--;
> diff --git a/benchmarks/wsim/README b/benchmarks/wsim/README
> index 8c71f2fe6..d4f3dd8ae 100644
> --- a/benchmarks/wsim/README
> +++ b/benchmarks/wsim/README
> @@ -1,6 +1,8 @@
> Workload descriptor format
> ==========================
>
> +Lines starting with '#' are treated as comments and will not create a work step.
> +
> ctx.engine.duration_us.dependency.wait,...
> <uint>.<str>.<uint>[-<uint>]|*.<int <= 0>[/<int <= 0>][...].<0|1>,...
> B.<uint>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 15/17] benchmarks/gem_wsim: for_each_ctx macro
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 15/17] benchmarks/gem_wsim: for_each_ctx macro Marcin Bernatowicz
@ 2023-10-06 8:49 ` Tvrtko Ursulin
2023-10-06 10:49 ` Bernatowicz, Marcin
0 siblings, 1 reply; 31+ messages in thread
From: Tvrtko Ursulin @ 2023-10-06 8:49 UTC (permalink / raw)
To: Marcin Bernatowicz, igt-dev; +Cc: chris.p.wilson
On 05/10/2023 19:57, Marcin Bernatowicz wrote:
> for_each_ctx_ctx_idx, for_each_ctx macros to easy traverse contexts.
>
> Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
> ---
> benchmarks/gem_wsim.c | 46 ++++++++++++++++++++++++-------------------
> 1 file changed, 26 insertions(+), 20 deletions(-)
>
> diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
> index 0c360d891..03a86b39c 100644
> --- a/benchmarks/gem_wsim.c
> +++ b/benchmarks/gem_wsim.c
> @@ -231,6 +231,13 @@ struct workload {
> unsigned int nrequest[NUM_ENGINES];
> };
>
> +#define for_each_ctx_ctx_idx(__ctx, __wrk, __ctx_idx) \
> + for (typeof((__wrk)->nr_ctxs) __ctx_idx = 0; __ctx_idx < (__wrk)->nr_ctxs && \
> + (__ctx = &(__wrk)->ctx_list[__ctx_idx]); ++__ctx_idx)
> +
Is the macro name a typical naming convention for IGT stuff using
igt_unique? IMO it reads a bit odd and personally I think __for_each_ctx
+ for_each_ctx would read better, but perhaps it is a personal preference.
> +#define for_each_ctx(__ctx, __wrk) \
> + for_each_ctx_ctx_idx(__ctx, __wrk, igt_unique(__ctx_idx))
> +
> static unsigned int master_prng;
>
> static int verbose = 1;
> @@ -1804,16 +1811,15 @@ static int prepare_contexts(unsigned int id, struct workload *wrk)
> {
> uint32_t share_vm = 0;
> struct w_step *w;
> - int i, j;
> + struct ctx *ctx, *ctx2;
> + unsigned int i, j;
>
> /*
> * Transfer over engine map configuration from the workload step.
> */
> - for (j = 0; j < wrk->nr_ctxs; j++) {
> - struct ctx *ctx = &wrk->ctx_list[j];
> -
> + for_each_ctx_ctx_idx(ctx, wrk, ctx_idx) {
ctx ctx ctx ctx.. yeah it just reads wrong IMO. One ctx less would be
better. Maybe even as far as s/ctx_idx/idx/ for readability.
__for_each_ctx(ctx, wrk, ctx_idx)
I guess it is passable.
> for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
> - if (w->context != j)
> + if (w->context != ctx_idx)
> continue;
>
> if (w->type == ENGINE_MAP) {
> @@ -1850,32 +1856,32 @@ static int prepare_contexts(unsigned int id, struct workload *wrk)
> /*
> * Create and configure contexts.
> */
> - for (i = 0; i < wrk->nr_ctxs; i++) {
> + for_each_ctx(ctx, wrk) {
> struct drm_i915_gem_context_create_ext_setparam ext = {
> .base.name = I915_CONTEXT_CREATE_EXT_SETPARAM,
> .param.param = I915_CONTEXT_PARAM_VM,
> };
> struct drm_i915_gem_context_create_ext args = { };
> - struct ctx *ctx = &wrk->ctx_list[i];
> uint32_t ctx_id;
>
> igt_assert(!ctx->id);
>
> /* Find existing context to share ppgtt with. */
> - for (j = 0; !share_vm && j < wrk->nr_ctxs; j++) {
> - struct drm_i915_gem_context_param param = {
> - .param = I915_CONTEXT_PARAM_VM,
> - .ctx_id = wrk->ctx_list[j].id,
> - };
> -
> - if (!param.ctx_id)
> - continue;
> + if (!share_vm)
> + for_each_ctx(ctx2, wrk) {
> + struct drm_i915_gem_context_param param = {
> + .param = I915_CONTEXT_PARAM_VM,
> + .ctx_id = ctx2->id,
> + };
> +
> + if (!param.ctx_id)
> + continue;
>
> - gem_context_get_param(fd, ¶m);
> - igt_assert(param.value);
> - share_vm = param.value;
> - break;
> - }
> + gem_context_get_param(fd, ¶m);
> + igt_assert(param.value);
> + share_vm = param.value;
> + break;
> + }
>
> if (share_vm) {
> ext.param.value = share_vm;
Conversion looks correct.
Hopefully you agree __for_each_ctx + for_each_ctx is more readable, in
which case:
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Regards,
Tvrtko
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 15/17] benchmarks/gem_wsim: for_each_ctx macro
2023-10-06 8:49 ` Tvrtko Ursulin
@ 2023-10-06 10:49 ` Bernatowicz, Marcin
0 siblings, 0 replies; 31+ messages in thread
From: Bernatowicz, Marcin @ 2023-10-06 10:49 UTC (permalink / raw)
To: Tvrtko Ursulin, igt-dev; +Cc: chris.p.wilson
Hi,
On 10/6/2023 10:49 AM, Tvrtko Ursulin wrote:
>
> On 05/10/2023 19:57, Marcin Bernatowicz wrote:
>> for_each_ctx_ctx_idx, for_each_ctx macros to easy traverse contexts.
>>
>> Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
>> ---
>> benchmarks/gem_wsim.c | 46 ++++++++++++++++++++++++-------------------
>> 1 file changed, 26 insertions(+), 20 deletions(-)
>>
>> diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
>> index 0c360d891..03a86b39c 100644
>> --- a/benchmarks/gem_wsim.c
>> +++ b/benchmarks/gem_wsim.c
>> @@ -231,6 +231,13 @@ struct workload {
>> unsigned int nrequest[NUM_ENGINES];
>> };
>> +#define for_each_ctx_ctx_idx(__ctx, __wrk, __ctx_idx) \
>> + for (typeof((__wrk)->nr_ctxs) __ctx_idx = 0; __ctx_idx <
>> (__wrk)->nr_ctxs && \
>> + (__ctx = &(__wrk)->ctx_list[__ctx_idx]); ++__ctx_idx)
>> +
>
> Is the macro name a typical naming convention for IGT stuff using
> igt_unique? IMO it reads a bit odd and personally I think __for_each_ctx
> + for_each_ctx would read better, but perhaps it is a personal preference.
igt_unique allows to nest the for_each_ctx loops without a warning on
shadowed variable, I see it in macros like igt_subtest_group,
igt_subtest_with_dynamic_f to name variables igt_unique(__tmpint),
igt_unique(__tmpchar) .
I agree __for_each_ctx reads better.
>
>> +#define for_each_ctx(__ctx, __wrk) \
>> + for_each_ctx_ctx_idx(__ctx, __wrk, igt_unique(__ctx_idx))
>> +
>> static unsigned int master_prng;
>> static int verbose = 1;
>> @@ -1804,16 +1811,15 @@ static int prepare_contexts(unsigned int id,
>> struct workload *wrk)
>> {
>> uint32_t share_vm = 0;
>> struct w_step *w;
>> - int i, j;
>> + struct ctx *ctx, *ctx2;
>> + unsigned int i, j;
>> /*
>> * Transfer over engine map configuration from the workload step.
>> */
>> - for (j = 0; j < wrk->nr_ctxs; j++) {
>> - struct ctx *ctx = &wrk->ctx_list[j];
>> -
>> + for_each_ctx_ctx_idx(ctx, wrk, ctx_idx) {
>
> ctx ctx ctx ctx.. yeah it just reads wrong IMO. One ctx less would be
> better. Maybe even as far as s/ctx_idx/idx/ for readability.
>
> __for_each_ctx(ctx, wrk, ctx_idx)
>
> I guess it is passable.
>
>> for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>> - if (w->context != j)
>> + if (w->context != ctx_idx)
>> continue;
>> if (w->type == ENGINE_MAP) {
>> @@ -1850,32 +1856,32 @@ static int prepare_contexts(unsigned int id,
>> struct workload *wrk)
>> /*
>> * Create and configure contexts.
>> */
>> - for (i = 0; i < wrk->nr_ctxs; i++) {
>> + for_each_ctx(ctx, wrk) {
>> struct drm_i915_gem_context_create_ext_setparam ext = {
>> .base.name = I915_CONTEXT_CREATE_EXT_SETPARAM,
>> .param.param = I915_CONTEXT_PARAM_VM,
>> };
>> struct drm_i915_gem_context_create_ext args = { };
>> - struct ctx *ctx = &wrk->ctx_list[i];
>> uint32_t ctx_id;
>> igt_assert(!ctx->id);
>> /* Find existing context to share ppgtt with. */
>> - for (j = 0; !share_vm && j < wrk->nr_ctxs; j++) {
>> - struct drm_i915_gem_context_param param = {
>> - .param = I915_CONTEXT_PARAM_VM,
>> - .ctx_id = wrk->ctx_list[j].id,
>> - };
>> -
>> - if (!param.ctx_id)
>> - continue;
>> + if (!share_vm)
>> + for_each_ctx(ctx2, wrk) {
>> + struct drm_i915_gem_context_param param = {
>> + .param = I915_CONTEXT_PARAM_VM,
>> + .ctx_id = ctx2->id,
>> + };
>> +
>> + if (!param.ctx_id)
>> + continue;
>> - gem_context_get_param(fd, ¶m);
>> - igt_assert(param.value);
>> - share_vm = param.value;
>> - break;
>> - }
>> + gem_context_get_param(fd, ¶m);
>> + igt_assert(param.value);
>> + share_vm = param.value;
>> + break;
>> + }
>> if (share_vm) {
>> ext.param.value = share_vm;
>
> Conversion looks correct.
>
> Hopefully you agree __for_each_ctx + for_each_ctx is more readable, in
> which case:
Yes, proposed names look much better.
Thank You for review,
marcin
>
> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>
> Regards,
>
> Tvrtko
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 16/17] benchmarks/gem_wsim: for_each_w_step macro
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 16/17] benchmarks/gem_wsim: for_each_w_step macro Marcin Bernatowicz
@ 2023-10-06 11:19 ` Tvrtko Ursulin
2023-10-06 12:15 ` Bernatowicz, Marcin
0 siblings, 1 reply; 31+ messages in thread
From: Tvrtko Ursulin @ 2023-10-06 11:19 UTC (permalink / raw)
To: Marcin Bernatowicz, igt-dev; +Cc: chris.p.wilson
On 05/10/2023 19:57, Marcin Bernatowicz wrote:
> for_each_w_step macro to easy traverse workload steps.
>
> Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
> ---
> benchmarks/gem_wsim.c | 80 +++++++++++++++++++++++--------------------
> 1 file changed, 42 insertions(+), 38 deletions(-)
>
> diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
> index 03a86b39c..e86519614 100644
> --- a/benchmarks/gem_wsim.c
> +++ b/benchmarks/gem_wsim.c
> @@ -238,6 +238,10 @@ struct workload {
> #define for_each_ctx(__ctx, __wrk) \
> for_each_ctx_ctx_idx(__ctx, __wrk, igt_unique(__ctx_idx))
>
> +#define for_each_w_step(__w_step, __wrk) \
> + for (typeof(__wrk->nr_steps) igt_unique(idx) = ({__w_step = __wrk->steps; 0; }); \
> + igt_unique(idx) < __wrk->nr_steps; igt_unique(idx)++, __w_step++)
Hm two igt_unique(idx) are on different lines - how does that work?
Macro ends up on single line after the C pre-processor?
The rest looks good, a nice improvement in readability!
Regards,
Tvrtko
> +
> static unsigned int master_prng;
>
> static int verbose = 1;
> @@ -1183,14 +1187,14 @@ add_step:
> /*
> * Check no duplicate working set ids.
> */
> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
> + for_each_w_step(w, wrk) {
> struct w_step *w2;
>
> if (w->type != WORKINGSET)
> continue;
>
> - for (j = 0, w2 = wrk->steps; j < wrk->nr_steps; w2++, j++) {
> - if (j == i)
> + for_each_w_step(w2, wrk) {
> + if (w->idx == w2->idx)
> continue;
> if (w2->type != WORKINGSET)
> continue;
> @@ -1203,7 +1207,7 @@ add_step:
> /*
> * Allocate shared working sets.
> */
> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
> + for_each_w_step(w, wrk) {
> if (w->type == WORKINGSET && w->working_set.shared) {
> unsigned long total =
> allocate_working_set(wrk, &w->working_set);
> @@ -1215,7 +1219,7 @@ add_step:
> }
>
> wrk->max_working_set_id = -1;
> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
> + for_each_w_step(w, wrk) {
> if (w->type == WORKINGSET &&
> w->working_set.shared &&
> w->working_set.id > wrk->max_working_set_id)
> @@ -1226,7 +1230,7 @@ add_step:
> sizeof(*wrk->working_sets));
> igt_assert(wrk->working_sets);
>
> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
> + for_each_w_step(w, wrk) {
> if (w->type == WORKINGSET && w->working_set.shared)
> wrk->working_sets[w->working_set.id] = &w->working_set;
> }
> @@ -1238,6 +1242,7 @@ static struct workload *
> clone_workload(struct workload *_wrk)
> {
> struct workload *wrk;
> + struct w_step *w;
> int i;
>
> wrk = malloc(sizeof(*wrk));
> @@ -1265,8 +1270,8 @@ clone_workload(struct workload *_wrk)
> }
>
> /* Check if we need a sw sync timeline. */
> - for (i = 0; i < wrk->nr_steps; i++) {
> - if (wrk->steps[i].type == SW_FENCE) {
> + for_each_w_step(w, wrk) {
> + if (w->type == SW_FENCE) {
> wrk->sync_timeline = sw_sync_timeline_create();
> igt_assert(wrk->sync_timeline >= 0);
> break;
> @@ -1722,13 +1727,13 @@ static void measure_active_set(struct workload *wrk)
> {
> unsigned long total = 0, batch_sizes = 0;
> struct dep_entry *dep, *deps = NULL;
> - unsigned int nr = 0, i;
> + unsigned int nr = 0;
> struct w_step *w;
>
> if (verbose < 3)
> return;
>
> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
> + for_each_w_step(w, wrk) {
> if (w->type != BATCH)
> continue;
>
> @@ -1781,12 +1786,11 @@ static void allocate_contexts(unsigned int id, struct workload *wrk)
> {
> int max_ctx = -1;
> struct w_step *w;
> - int i;
>
> /*
> * Pre-scan workload steps to allocate context list storage.
> */
> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
> + for_each_w_step(w, wrk) {
> int ctx = w->context + 1;
> int delta;
>
> @@ -1812,13 +1816,13 @@ static int prepare_contexts(unsigned int id, struct workload *wrk)
> uint32_t share_vm = 0;
> struct w_step *w;
> struct ctx *ctx, *ctx2;
> - unsigned int i, j;
> + unsigned int j;
>
> /*
> * Transfer over engine map configuration from the workload step.
> */
> for_each_ctx_ctx_idx(ctx, wrk, ctx_idx) {
> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
> + for_each_w_step(w, wrk) {
> if (w->context != ctx_idx)
> continue;
>
> @@ -1985,12 +1989,11 @@ static void prepare_working_sets(unsigned int id, struct workload *wrk)
> struct working_set **sets;
> unsigned long total = 0;
> struct w_step *w;
> - int i;
>
> /*
> * Allocate working sets.
> */
> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
> + for_each_w_step(w, wrk) {
> if (w->type == WORKINGSET && !w->working_set.shared)
> total += allocate_working_set(wrk, &w->working_set);
> }
> @@ -2002,7 +2005,7 @@ static void prepare_working_sets(unsigned int id, struct workload *wrk)
> * Map of working set ids.
> */
> wrk->max_working_set_id = -1;
> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
> + for_each_w_step(w, wrk) {
> if (w->type == WORKINGSET &&
> w->working_set.id > wrk->max_working_set_id)
> wrk->max_working_set_id = w->working_set.id;
> @@ -2013,7 +2016,7 @@ static void prepare_working_sets(unsigned int id, struct workload *wrk)
> sizeof(*wrk->working_sets));
> igt_assert(wrk->working_sets);
>
> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
> + for_each_w_step(w, wrk) {
> struct working_set *set;
>
> if (w->type != WORKINGSET)
> @@ -2039,7 +2042,6 @@ static void prepare_working_sets(unsigned int id, struct workload *wrk)
> static int prepare_workload(unsigned int id, struct workload *wrk)
> {
> struct w_step *w;
> - int i, j;
> int ret = 0;
>
> wrk->id = id;
> @@ -2054,23 +2056,22 @@ static int prepare_workload(unsigned int id, struct workload *wrk)
> return ret;
>
> /* Record default preemption. */
> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
> + for_each_w_step(w, wrk)
> if (w->type == BATCH)
> w->preempt_us = 100;
> - }
>
> /*
> * Scan for contexts with modified preemption config and record their
> * preemption period for the following steps belonging to the same
> * context.
> */
> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
> + for_each_w_step(w, wrk) {
> struct w_step *w2;
>
> if (w->type != PREEMPTION)
> continue;
>
> - for (j = i + 1; j < wrk->nr_steps; j++) {
> + for (int j = w->idx + 1; j < wrk->nr_steps; j++) {
> w2 = &wrk->steps[j];
>
> if (w2->context != w->context)
> @@ -2087,7 +2088,7 @@ static int prepare_workload(unsigned int id, struct workload *wrk)
> /*
> * Scan for SSEU control steps.
> */
> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
> + for_each_w_step(w, wrk) {
> if (w->type == SSEU) {
> get_device_sseu();
> break;
> @@ -2099,7 +2100,7 @@ static int prepare_workload(unsigned int id, struct workload *wrk)
> /*
> * Allocate batch buffers.
> */
> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
> + for_each_w_step(w, wrk) {
> if (w->type != BATCH)
> continue;
>
> @@ -2223,7 +2224,6 @@ static void *run_workload(void *data)
> int qd_throttle = -1;
> int count, missed = 0;
> unsigned long time_tot = 0, time_min = ULONG_MAX, time_max = 0;
> - int i;
>
> clock_gettime(CLOCK_MONOTONIC, &t_start);
>
> @@ -2233,11 +2233,13 @@ static void *run_workload(void *data)
>
> clock_gettime(CLOCK_MONOTONIC, &repeat_start);
>
> - for (i = 0, w = wrk->steps; wrk->run && (i < wrk->nr_steps);
> - i++, w++) {
> + for_each_w_step(w, wrk) {
> enum intel_engine_id engine = w->engine;
> int do_sleep = 0;
>
> + if (!wrk->run)
> + break;
> +
> if (w->type == DELAY) {
> do_sleep = w->delay;
> } else if (w->type == PERIOD) {
> @@ -2256,13 +2258,13 @@ static void *run_workload(void *data)
> missed++;
> if (verbose > 2)
> printf("%u: Dropped period @ %u/%u (%dus late)!\n",
> - wrk->id, count, i, do_sleep);
> + wrk->id, count, w->idx, do_sleep);
> continue;
> }
> } else if (w->type == SYNC) {
> - unsigned int s_idx = i + w->target;
> + unsigned int s_idx = w->idx + w->target;
>
> - igt_assert(s_idx >= 0 && s_idx < i);
> + igt_assert(s_idx >= 0 && s_idx < w->idx);
> igt_assert(wrk->steps[s_idx].type == BATCH);
> w_step_sync(&wrk->steps[s_idx]);
> continue;
> @@ -2283,7 +2285,7 @@ static void *run_workload(void *data)
> int tgt = w->idx + w->target;
> int inc;
>
> - igt_assert(tgt >= 0 && tgt < i);
> + igt_assert(tgt >= 0 && tgt < w->idx);
> igt_assert(wrk->steps[tgt].type == SW_FENCE);
> cur_seqno += wrk->steps[tgt].idx;
> inc = cur_seqno - wrk->sync_seqno;
> @@ -2303,9 +2305,9 @@ static void *run_workload(void *data)
> }
> continue;
> } else if (w->type == TERMINATE) {
> - unsigned int t_idx = i + w->target;
> + unsigned int t_idx = w->idx + w->target;
>
> - igt_assert(t_idx >= 0 && t_idx < i);
> + igt_assert(t_idx >= 0 && t_idx < w->idx);
> igt_assert(wrk->steps[t_idx].type == BATCH);
> igt_assert(wrk->steps[t_idx].duration.unbound);
>
> @@ -2339,7 +2341,7 @@ static void *run_workload(void *data)
> sync_deps(wrk, w);
>
> if (throttle > 0)
> - w_sync_to(wrk, w, i - throttle);
> + w_sync_to(wrk, w, w->idx - throttle);
>
> do_eb(wrk, w, engine);
>
> @@ -2382,8 +2384,10 @@ static void *run_workload(void *data)
> }
>
> /* Cleanup all fences instantiated in this iteration. */
> - for (i = 0, w = wrk->steps; wrk->run && (i < wrk->nr_steps);
> - i++, w++) {
> + for_each_w_step(w, wrk) {
> + if (!wrk->run)
> + break;
> +
> if (w->emit_fence > 0) {
> close(w->emit_fence);
> w->emit_fence = -1;
> @@ -2391,7 +2395,7 @@ static void *run_workload(void *data)
> }
> }
>
> - for (i = 0; i < NUM_ENGINES; i++) {
> + for (int i = 0; i < NUM_ENGINES; i++) {
> if (!wrk->nrequest[i])
> continue;
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 16/17] benchmarks/gem_wsim: for_each_w_step macro
2023-10-06 11:19 ` Tvrtko Ursulin
@ 2023-10-06 12:15 ` Bernatowicz, Marcin
2023-10-06 12:39 ` Tvrtko Ursulin
0 siblings, 1 reply; 31+ messages in thread
From: Bernatowicz, Marcin @ 2023-10-06 12:15 UTC (permalink / raw)
To: Tvrtko Ursulin, igt-dev; +Cc: chris.p.wilson
On 10/6/2023 1:19 PM, Tvrtko Ursulin wrote:
>
> On 05/10/2023 19:57, Marcin Bernatowicz wrote:
>> for_each_w_step macro to easy traverse workload steps.
>>
>> Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
>> ---
>> benchmarks/gem_wsim.c | 80 +++++++++++++++++++++++--------------------
>> 1 file changed, 42 insertions(+), 38 deletions(-)
>>
>> diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
>> index 03a86b39c..e86519614 100644
>> --- a/benchmarks/gem_wsim.c
>> +++ b/benchmarks/gem_wsim.c
>> @@ -238,6 +238,10 @@ struct workload {
>> #define for_each_ctx(__ctx, __wrk) \
>> for_each_ctx_ctx_idx(__ctx, __wrk, igt_unique(__ctx_idx))
>> +#define for_each_w_step(__w_step, __wrk) \
>> + for (typeof(__wrk->nr_steps) igt_unique(idx) = ({__w_step =
>> __wrk->steps; 0; }); \
>> + igt_unique(idx) < __wrk->nr_steps; igt_unique(idx)++,
>> __w_step++)
>
> Hm two igt_unique(idx) are on different lines - how does that work?
> Macro ends up on single line after the C pre-processor?
At beginning I thought I need a helper macro like __for_each_ctx and a
second with only one igt_unique,
but macro when expanded comes out on one line, so it works.
>
> The rest looks good, a nice improvement in readability!
>
> Regards,
>
> Tvrtko
>
>> +
>> static unsigned int master_prng;
>> static int verbose = 1;
>> @@ -1183,14 +1187,14 @@ add_step:
>> /*
>> * Check no duplicate working set ids.
>> */
>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>> + for_each_w_step(w, wrk) {
>> struct w_step *w2;
>> if (w->type != WORKINGSET)
>> continue;
>> - for (j = 0, w2 = wrk->steps; j < wrk->nr_steps; w2++, j++) {
>> - if (j == i)
>> + for_each_w_step(w2, wrk) {
>> + if (w->idx == w2->idx)
>> continue;
>> if (w2->type != WORKINGSET)
>> continue;
>> @@ -1203,7 +1207,7 @@ add_step:
>> /*
>> * Allocate shared working sets.
>> */
>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>> + for_each_w_step(w, wrk) {
>> if (w->type == WORKINGSET && w->working_set.shared) {
>> unsigned long total =
>> allocate_working_set(wrk, &w->working_set);
>> @@ -1215,7 +1219,7 @@ add_step:
>> }
>> wrk->max_working_set_id = -1;
>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>> + for_each_w_step(w, wrk) {
>> if (w->type == WORKINGSET &&
>> w->working_set.shared &&
>> w->working_set.id > wrk->max_working_set_id)
>> @@ -1226,7 +1230,7 @@ add_step:
>> sizeof(*wrk->working_sets));
>> igt_assert(wrk->working_sets);
>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>> + for_each_w_step(w, wrk) {
>> if (w->type == WORKINGSET && w->working_set.shared)
>> wrk->working_sets[w->working_set.id] = &w->working_set;
>> }
>> @@ -1238,6 +1242,7 @@ static struct workload *
>> clone_workload(struct workload *_wrk)
>> {
>> struct workload *wrk;
>> + struct w_step *w;
>> int i;
>> wrk = malloc(sizeof(*wrk));
>> @@ -1265,8 +1270,8 @@ clone_workload(struct workload *_wrk)
>> }
>> /* Check if we need a sw sync timeline. */
>> - for (i = 0; i < wrk->nr_steps; i++) {
>> - if (wrk->steps[i].type == SW_FENCE) {
>> + for_each_w_step(w, wrk) {
>> + if (w->type == SW_FENCE) {
>> wrk->sync_timeline = sw_sync_timeline_create();
>> igt_assert(wrk->sync_timeline >= 0);
>> break;
>> @@ -1722,13 +1727,13 @@ static void measure_active_set(struct workload
>> *wrk)
>> {
>> unsigned long total = 0, batch_sizes = 0;
>> struct dep_entry *dep, *deps = NULL;
>> - unsigned int nr = 0, i;
>> + unsigned int nr = 0;
>> struct w_step *w;
>> if (verbose < 3)
>> return;
>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>> + for_each_w_step(w, wrk) {
>> if (w->type != BATCH)
>> continue;
>> @@ -1781,12 +1786,11 @@ static void allocate_contexts(unsigned int id,
>> struct workload *wrk)
>> {
>> int max_ctx = -1;
>> struct w_step *w;
>> - int i;
>> /*
>> * Pre-scan workload steps to allocate context list storage.
>> */
>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>> + for_each_w_step(w, wrk) {
>> int ctx = w->context + 1;
>> int delta;
>> @@ -1812,13 +1816,13 @@ static int prepare_contexts(unsigned int id,
>> struct workload *wrk)
>> uint32_t share_vm = 0;
>> struct w_step *w;
>> struct ctx *ctx, *ctx2;
>> - unsigned int i, j;
>> + unsigned int j;
>> /*
>> * Transfer over engine map configuration from the workload step.
>> */
>> for_each_ctx_ctx_idx(ctx, wrk, ctx_idx) {
>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>> + for_each_w_step(w, wrk) {
>> if (w->context != ctx_idx)
>> continue;
>> @@ -1985,12 +1989,11 @@ static void prepare_working_sets(unsigned int
>> id, struct workload *wrk)
>> struct working_set **sets;
>> unsigned long total = 0;
>> struct w_step *w;
>> - int i;
>> /*
>> * Allocate working sets.
>> */
>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>> + for_each_w_step(w, wrk) {
>> if (w->type == WORKINGSET && !w->working_set.shared)
>> total += allocate_working_set(wrk, &w->working_set);
>> }
>> @@ -2002,7 +2005,7 @@ static void prepare_working_sets(unsigned int
>> id, struct workload *wrk)
>> * Map of working set ids.
>> */
>> wrk->max_working_set_id = -1;
>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>> + for_each_w_step(w, wrk) {
>> if (w->type == WORKINGSET &&
>> w->working_set.id > wrk->max_working_set_id)
>> wrk->max_working_set_id = w->working_set.id;
>> @@ -2013,7 +2016,7 @@ static void prepare_working_sets(unsigned int
>> id, struct workload *wrk)
>> sizeof(*wrk->working_sets));
>> igt_assert(wrk->working_sets);
>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>> + for_each_w_step(w, wrk) {
>> struct working_set *set;
>> if (w->type != WORKINGSET)
>> @@ -2039,7 +2042,6 @@ static void prepare_working_sets(unsigned int
>> id, struct workload *wrk)
>> static int prepare_workload(unsigned int id, struct workload *wrk)
>> {
>> struct w_step *w;
>> - int i, j;
>> int ret = 0;
>> wrk->id = id;
>> @@ -2054,23 +2056,22 @@ static int prepare_workload(unsigned int id,
>> struct workload *wrk)
>> return ret;
>> /* Record default preemption. */
>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>> + for_each_w_step(w, wrk)
>> if (w->type == BATCH)
>> w->preempt_us = 100;
>> - }
>> /*
>> * Scan for contexts with modified preemption config and record
>> their
>> * preemption period for the following steps belonging to the same
>> * context.
>> */
>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>> + for_each_w_step(w, wrk) {
>> struct w_step *w2;
>> if (w->type != PREEMPTION)
>> continue;
>> - for (j = i + 1; j < wrk->nr_steps; j++) {
>> + for (int j = w->idx + 1; j < wrk->nr_steps; j++) {
>> w2 = &wrk->steps[j];
>> if (w2->context != w->context)
>> @@ -2087,7 +2088,7 @@ static int prepare_workload(unsigned int id,
>> struct workload *wrk)
>> /*
>> * Scan for SSEU control steps.
>> */
>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>> + for_each_w_step(w, wrk) {
>> if (w->type == SSEU) {
>> get_device_sseu();
>> break;
>> @@ -2099,7 +2100,7 @@ static int prepare_workload(unsigned int id,
>> struct workload *wrk)
>> /*
>> * Allocate batch buffers.
>> */
>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>> + for_each_w_step(w, wrk) {
>> if (w->type != BATCH)
>> continue;
>> @@ -2223,7 +2224,6 @@ static void *run_workload(void *data)
>> int qd_throttle = -1;
>> int count, missed = 0;
>> unsigned long time_tot = 0, time_min = ULONG_MAX, time_max = 0;
>> - int i;
>> clock_gettime(CLOCK_MONOTONIC, &t_start);
>> @@ -2233,11 +2233,13 @@ static void *run_workload(void *data)
>> clock_gettime(CLOCK_MONOTONIC, &repeat_start);
>> - for (i = 0, w = wrk->steps; wrk->run && (i < wrk->nr_steps);
>> - i++, w++) {
>> + for_each_w_step(w, wrk) {
>> enum intel_engine_id engine = w->engine;
>> int do_sleep = 0;
>> + if (!wrk->run)
>> + break;
>> +
>> if (w->type == DELAY) {
>> do_sleep = w->delay;
>> } else if (w->type == PERIOD) {
>> @@ -2256,13 +2258,13 @@ static void *run_workload(void *data)
>> missed++;
>> if (verbose > 2)
>> printf("%u: Dropped period @ %u/%u (%dus
>> late)!\n",
>> - wrk->id, count, i, do_sleep);
>> + wrk->id, count, w->idx, do_sleep);
>> continue;
>> }
>> } else if (w->type == SYNC) {
>> - unsigned int s_idx = i + w->target;
>> + unsigned int s_idx = w->idx + w->target;
>> - igt_assert(s_idx >= 0 && s_idx < i);
>> + igt_assert(s_idx >= 0 && s_idx < w->idx);
>> igt_assert(wrk->steps[s_idx].type == BATCH);
>> w_step_sync(&wrk->steps[s_idx]);
>> continue;
>> @@ -2283,7 +2285,7 @@ static void *run_workload(void *data)
>> int tgt = w->idx + w->target;
>> int inc;
>> - igt_assert(tgt >= 0 && tgt < i);
>> + igt_assert(tgt >= 0 && tgt < w->idx);
>> igt_assert(wrk->steps[tgt].type == SW_FENCE);
>> cur_seqno += wrk->steps[tgt].idx;
>> inc = cur_seqno - wrk->sync_seqno;
>> @@ -2303,9 +2305,9 @@ static void *run_workload(void *data)
>> }
>> continue;
>> } else if (w->type == TERMINATE) {
>> - unsigned int t_idx = i + w->target;
>> + unsigned int t_idx = w->idx + w->target;
>> - igt_assert(t_idx >= 0 && t_idx < i);
>> + igt_assert(t_idx >= 0 && t_idx < w->idx);
>> igt_assert(wrk->steps[t_idx].type == BATCH);
>> igt_assert(wrk->steps[t_idx].duration.unbound);
>> @@ -2339,7 +2341,7 @@ static void *run_workload(void *data)
>> sync_deps(wrk, w);
>> if (throttle > 0)
>> - w_sync_to(wrk, w, i - throttle);
>> + w_sync_to(wrk, w, w->idx - throttle);
>> do_eb(wrk, w, engine);
>> @@ -2382,8 +2384,10 @@ static void *run_workload(void *data)
>> }
>> /* Cleanup all fences instantiated in this iteration. */
>> - for (i = 0, w = wrk->steps; wrk->run && (i < wrk->nr_steps);
>> - i++, w++) {
>> + for_each_w_step(w, wrk) {
>> + if (!wrk->run)
>> + break;
>> +
>> if (w->emit_fence > 0) {
>> close(w->emit_fence);
>> w->emit_fence = -1;
>> @@ -2391,7 +2395,7 @@ static void *run_workload(void *data)
>> }
>> }
>> - for (i = 0; i < NUM_ENGINES; i++) {
>> + for (int i = 0; i < NUM_ENGINES; i++) {
>> if (!wrk->nrequest[i])
>> continue;
^ permalink raw reply [flat|nested] 31+ messages in thread
* [igt-dev] ✓ Fi.CI.IGT: success for benchmarks/gem_wsim: added basic xe support (rev6)
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
` (18 preceding siblings ...)
2023-10-06 0:10 ` [igt-dev] ✓ CI.xeBAT: " Patchwork
@ 2023-10-06 12:23 ` Patchwork
19 siblings, 0 replies; 31+ messages in thread
From: Patchwork @ 2023-10-06 12:23 UTC (permalink / raw)
To: Tvrtko Ursulin; +Cc: igt-dev
[-- Attachment #1: Type: text/plain, Size: 75730 bytes --]
== Series Details ==
Series: benchmarks/gem_wsim: added basic xe support (rev6)
URL : https://patchwork.freedesktop.org/series/122920/
State : success
== Summary ==
CI Bug Log - changes from CI_DRM_13719_full -> IGTPW_9933_full
====================================================
Summary
-------
**SUCCESS**
No regressions found.
External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/index.html
Participating hosts (9 -> 9)
------------------------------
No changes in participating hosts
Possible new issues
-------------------
Here are the unknown changes that may have been introduced in IGTPW_9933_full:
### IGT changes ###
#### Suppressed ####
The following results come from untrusted machines, tests, or statuses.
They do not affect the overall result.
* {igt@kms_content_protection@mei-interface}:
- shard-rkl: [SKIP][1] ([i915#9424]) -> [SKIP][2]
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-rkl-6/igt@kms_content_protection@mei-interface.html
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-4/igt@kms_content_protection@mei-interface.html
- shard-tglu: [SKIP][3] ([i915#9424]) -> [SKIP][4]
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-tglu-6/igt@kms_content_protection@mei-interface.html
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-tglu-7/igt@kms_content_protection@mei-interface.html
New tests
---------
New tests have been introduced between CI_DRM_13719_full and IGTPW_9933_full:
### New IGT tests (8) ###
* igt@kms_flip@basic-flip-vs-dpms@a-dp4:
- Statuses : 1 pass(s)
- Exec time: [0.0] s
* igt@kms_flip@basic-flip-vs-dpms@b-dp4:
- Statuses : 1 pass(s)
- Exec time: [0.0] s
* igt@kms_flip@basic-flip-vs-dpms@c-dp4:
- Statuses : 1 pass(s)
- Exec time: [0.0] s
* igt@kms_flip@basic-flip-vs-dpms@d-dp4:
- Statuses : 1 pass(s)
- Exec time: [0.0] s
* igt@kms_flip@basic-plain-flip@a-dp4:
- Statuses : 1 pass(s)
- Exec time: [0.0] s
* igt@kms_flip@basic-plain-flip@b-dp4:
- Statuses : 1 pass(s)
- Exec time: [0.0] s
* igt@kms_flip@basic-plain-flip@c-dp4:
- Statuses : 1 pass(s)
- Exec time: [0.0] s
* igt@kms_flip@basic-plain-flip@d-dp4:
- Statuses : 1 pass(s)
- Exec time: [0.0] s
Known issues
------------
Here are the changes found in IGTPW_9933_full that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@api_intel_bb@blit-reloc-keep-cache:
- shard-rkl: NOTRUN -> [SKIP][5] ([i915#8411])
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@api_intel_bb@blit-reloc-keep-cache.html
* igt@api_intel_bb@blit-reloc-purge-cache:
- shard-dg2: NOTRUN -> [SKIP][6] ([i915#8411]) +1 other test skip
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-7/igt@api_intel_bb@blit-reloc-purge-cache.html
* igt@api_intel_bb@crc32:
- shard-dg1: NOTRUN -> [SKIP][7] ([i915#6230])
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-17/igt@api_intel_bb@crc32.html
* igt@drm_fdinfo@busy-idle-check-all@vcs1:
- shard-dg1: NOTRUN -> [SKIP][8] ([i915#8414]) +9 other tests skip
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-12/igt@drm_fdinfo@busy-idle-check-all@vcs1.html
* igt@drm_fdinfo@most-busy-check-all@bcs0:
- shard-dg2: NOTRUN -> [SKIP][9] ([i915#8414]) +11 other tests skip
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-11/igt@drm_fdinfo@most-busy-check-all@bcs0.html
* igt@drm_fdinfo@virtual-idle:
- shard-rkl: NOTRUN -> [FAIL][10] ([i915#7742])
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-4/igt@drm_fdinfo@virtual-idle.html
* igt@gem_basic@multigpu-create-close:
- shard-rkl: NOTRUN -> [SKIP][11] ([i915#7697])
[11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-2/igt@gem_basic@multigpu-create-close.html
- shard-dg2: NOTRUN -> [SKIP][12] ([i915#7697])
[12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-3/igt@gem_basic@multigpu-create-close.html
* igt@gem_ccs@ctrl-surf-copy:
- shard-mtlp: NOTRUN -> [SKIP][13] ([i915#3555])
[13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-6/igt@gem_ccs@ctrl-surf-copy.html
* igt@gem_ctx_exec@basic-nohangcheck:
- shard-rkl: [PASS][14] -> [FAIL][15] ([i915#6268])
[14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-rkl-2/igt@gem_ctx_exec@basic-nohangcheck.html
[15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-4/igt@gem_ctx_exec@basic-nohangcheck.html
* igt@gem_ctx_isolation@preservation@ccs0:
- shard-mtlp: [PASS][16] -> [ABORT][17] ([i915#9414])
[16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-mtlp-4/igt@gem_ctx_isolation@preservation@ccs0.html
[17]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-5/igt@gem_ctx_isolation@preservation@ccs0.html
* igt@gem_ctx_persistence@saturated-hostile-nopreempt@ccs0:
- shard-dg2: NOTRUN -> [SKIP][18] ([i915#5882]) +9 other tests skip
[18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-1/igt@gem_ctx_persistence@saturated-hostile-nopreempt@ccs0.html
* igt@gem_ctx_sseu@invalid-sseu:
- shard-dg2: NOTRUN -> [SKIP][19] ([i915#280])
[19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-7/igt@gem_ctx_sseu@invalid-sseu.html
* igt@gem_eio@hibernate:
- shard-dg2: NOTRUN -> [ABORT][20] ([i915#7975] / [i915#8213])
[20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-10/igt@gem_eio@hibernate.html
* igt@gem_exec_balancer@noheartbeat:
- shard-dg2: NOTRUN -> [SKIP][21] ([i915#8555]) +1 other test skip
[21]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-10/igt@gem_exec_balancer@noheartbeat.html
* igt@gem_exec_capture@pi@vcs0:
- shard-mtlp: [PASS][22] -> [FAIL][23] ([i915#4475])
[22]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-mtlp-2/igt@gem_exec_capture@pi@vcs0.html
[23]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-2/igt@gem_exec_capture@pi@vcs0.html
* igt@gem_exec_fair@basic-pace:
- shard-dg2: NOTRUN -> [SKIP][24] ([i915#3539]) +1 other test skip
[24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-1/igt@gem_exec_fair@basic-pace.html
* igt@gem_exec_fair@basic-pace-share:
- shard-dg1: NOTRUN -> [SKIP][25] ([i915#3539] / [i915#4852])
[25]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-14/igt@gem_exec_fair@basic-pace-share.html
* igt@gem_exec_fair@basic-pace-share@rcs0:
- shard-rkl: [PASS][26] -> [FAIL][27] ([i915#2842]) +1 other test fail
[26]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-rkl-6/igt@gem_exec_fair@basic-pace-share@rcs0.html
[27]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-6/igt@gem_exec_fair@basic-pace-share@rcs0.html
* igt@gem_exec_fence@parallel@rcs0:
- shard-mtlp: [PASS][28] -> [DMESG-FAIL][29] ([i915#8962])
[28]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-mtlp-1/igt@gem_exec_fence@parallel@rcs0.html
[29]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-4/igt@gem_exec_fence@parallel@rcs0.html
* igt@gem_exec_fence@parallel@vcs0:
- shard-mtlp: [PASS][30] -> [FAIL][31] ([i915#8758])
[30]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-mtlp-1/igt@gem_exec_fence@parallel@vcs0.html
[31]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-4/igt@gem_exec_fence@parallel@vcs0.html
* igt@gem_exec_fence@parallel@vcs1:
- shard-mtlp: [PASS][32] -> [DMESG-WARN][33] ([i915#8962]) +1 other test dmesg-warn
[32]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-mtlp-1/igt@gem_exec_fence@parallel@vcs1.html
[33]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-4/igt@gem_exec_fence@parallel@vcs1.html
* igt@gem_exec_fence@parallel@vecs0:
- shard-mtlp: [PASS][34] -> [FAIL][35] ([i915#8957]) +1 other test fail
[34]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-mtlp-1/igt@gem_exec_fence@parallel@vecs0.html
[35]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-4/igt@gem_exec_fence@parallel@vecs0.html
* igt@gem_exec_flush@basic-uc-pro-default:
- shard-dg2: NOTRUN -> [SKIP][36] ([i915#3539] / [i915#4852]) +5 other tests skip
[36]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-6/igt@gem_exec_flush@basic-uc-pro-default.html
* igt@gem_exec_params@secure-non-master:
- shard-dg2: NOTRUN -> [SKIP][37] ([fdo#112283])
[37]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-6/igt@gem_exec_params@secure-non-master.html
* igt@gem_exec_reloc@basic-gtt-cpu-active:
- shard-dg2: NOTRUN -> [SKIP][38] ([i915#3281]) +8 other tests skip
[38]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-6/igt@gem_exec_reloc@basic-gtt-cpu-active.html
* igt@gem_exec_reloc@basic-gtt-wc-noreloc:
- shard-dg1: NOTRUN -> [SKIP][39] ([i915#3281]) +2 other tests skip
[39]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-12/igt@gem_exec_reloc@basic-gtt-wc-noreloc.html
* igt@gem_exec_reloc@basic-write-read:
- shard-rkl: NOTRUN -> [SKIP][40] ([i915#3281]) +3 other tests skip
[40]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-1/igt@gem_exec_reloc@basic-write-read.html
* igt@gem_exec_schedule@preempt-queue:
- shard-dg2: NOTRUN -> [SKIP][41] ([i915#4537] / [i915#4812])
[41]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-6/igt@gem_exec_schedule@preempt-queue.html
* igt@gem_exec_schedule@preempt-queue-contexts:
- shard-dg1: NOTRUN -> [SKIP][42] ([i915#4812])
[42]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-19/igt@gem_exec_schedule@preempt-queue-contexts.html
* igt@gem_exec_schedule@preemptive-hang@vcs0:
- shard-mtlp: [PASS][43] -> [FAIL][44] ([i915#9051])
[43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-mtlp-1/igt@gem_exec_schedule@preemptive-hang@vcs0.html
[44]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-5/igt@gem_exec_schedule@preemptive-hang@vcs0.html
* igt@gem_exec_suspend@basic-s4-devices@smem:
- shard-tglu: [PASS][45] -> [ABORT][46] ([i915#7975] / [i915#8213])
[45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-tglu-6/igt@gem_exec_suspend@basic-s4-devices@smem.html
[46]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-tglu-10/igt@gem_exec_suspend@basic-s4-devices@smem.html
* igt@gem_fenced_exec_thrash@no-spare-fences-busy:
- shard-dg2: NOTRUN -> [SKIP][47] ([i915#4860]) +1 other test skip
[47]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-6/igt@gem_fenced_exec_thrash@no-spare-fences-busy.html
* igt@gem_lmem_swapping@heavy-random:
- shard-rkl: NOTRUN -> [SKIP][48] ([i915#4613])
[48]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-6/igt@gem_lmem_swapping@heavy-random.html
* igt@gem_mmap@big-bo:
- shard-mtlp: NOTRUN -> [SKIP][49] ([i915#4083]) +1 other test skip
[49]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-8/igt@gem_mmap@big-bo.html
* igt@gem_mmap@short-mmap:
- shard-dg2: NOTRUN -> [SKIP][50] ([i915#4083]) +2 other tests skip
[50]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-3/igt@gem_mmap@short-mmap.html
* igt@gem_mmap_gtt@cpuset-big-copy:
- shard-dg2: NOTRUN -> [SKIP][51] ([i915#4077]) +8 other tests skip
[51]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-6/igt@gem_mmap_gtt@cpuset-big-copy.html
* igt@gem_mmap_gtt@fault-concurrent-x:
- shard-dg1: NOTRUN -> [SKIP][52] ([i915#4077]) +1 other test skip
[52]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-18/igt@gem_mmap_gtt@fault-concurrent-x.html
- shard-mtlp: NOTRUN -> [SKIP][53] ([i915#4077])
[53]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-8/igt@gem_mmap_gtt@fault-concurrent-x.html
* igt@gem_mmap_wc@read:
- shard-dg1: NOTRUN -> [SKIP][54] ([i915#4083]) +5 other tests skip
[54]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-14/igt@gem_mmap_wc@read.html
* igt@gem_partial_pwrite_pread@write-display:
- shard-dg1: NOTRUN -> [SKIP][55] ([i915#3282]) +2 other tests skip
[55]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-18/igt@gem_partial_pwrite_pread@write-display.html
* igt@gem_pwrite@basic-random:
- shard-dg2: NOTRUN -> [SKIP][56] ([i915#3282]) +3 other tests skip
[56]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-5/igt@gem_pwrite@basic-random.html
- shard-rkl: NOTRUN -> [SKIP][57] ([i915#3282])
[57]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-4/igt@gem_pwrite@basic-random.html
* igt@gem_pxp@create-regular-context-2:
- shard-rkl: NOTRUN -> [SKIP][58] ([i915#4270])
[58]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-1/igt@gem_pxp@create-regular-context-2.html
* igt@gem_pxp@protected-raw-src-copy-not-readible:
- shard-dg1: NOTRUN -> [SKIP][59] ([i915#4270]) +1 other test skip
[59]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-17/igt@gem_pxp@protected-raw-src-copy-not-readible.html
- shard-tglu: NOTRUN -> [SKIP][60] ([i915#4270])
[60]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-tglu-8/igt@gem_pxp@protected-raw-src-copy-not-readible.html
* igt@gem_pxp@regular-baseline-src-copy-readible:
- shard-dg2: NOTRUN -> [SKIP][61] ([i915#4270]) +3 other tests skip
[61]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-7/igt@gem_pxp@regular-baseline-src-copy-readible.html
* igt@gem_render_copy@y-tiled-ccs-to-yf-tiled-mc-ccs:
- shard-mtlp: NOTRUN -> [SKIP][62] ([i915#8428])
[62]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-1/igt@gem_render_copy@y-tiled-ccs-to-yf-tiled-mc-ccs.html
* igt@gem_set_tiling_vs_blt@untiled-to-tiled:
- shard-dg1: NOTRUN -> [SKIP][63] ([i915#4079])
[63]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-12/igt@gem_set_tiling_vs_blt@untiled-to-tiled.html
* igt@gem_tiled_pread_basic:
- shard-dg2: NOTRUN -> [SKIP][64] ([i915#4079])
[64]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-3/igt@gem_tiled_pread_basic.html
* igt@gem_userptr_blits@create-destroy-unsync:
- shard-dg2: NOTRUN -> [SKIP][65] ([i915#3297]) +2 other tests skip
[65]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-6/igt@gem_userptr_blits@create-destroy-unsync.html
- shard-rkl: NOTRUN -> [SKIP][66] ([i915#3297])
[66]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@gem_userptr_blits@create-destroy-unsync.html
* igt@gem_userptr_blits@dmabuf-unsync:
- shard-dg1: NOTRUN -> [SKIP][67] ([i915#3297]) +1 other test skip
[67]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-19/igt@gem_userptr_blits@dmabuf-unsync.html
* igt@gem_userptr_blits@map-fixed-invalidate-overlap:
- shard-dg2: NOTRUN -> [SKIP][68] ([i915#3297] / [i915#4880])
[68]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-6/igt@gem_userptr_blits@map-fixed-invalidate-overlap.html
* igt@gem_userptr_blits@nohangcheck:
- shard-mtlp: [PASS][69] -> [FAIL][70] ([i915#9353])
[69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-mtlp-4/igt@gem_userptr_blits@nohangcheck.html
[70]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-3/igt@gem_userptr_blits@nohangcheck.html
* igt@gem_userptr_blits@vma-merge:
- shard-rkl: NOTRUN -> [FAIL][71] ([i915#3318])
[71]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@gem_userptr_blits@vma-merge.html
* igt@gen3_render_linear_blits:
- shard-dg2: NOTRUN -> [SKIP][72] ([fdo#109289]) +4 other tests skip
[72]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-6/igt@gen3_render_linear_blits.html
* igt@gen7_exec_parse@cmd-crossing-page:
- shard-rkl: NOTRUN -> [SKIP][73] ([fdo#109289])
[73]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@gen7_exec_parse@cmd-crossing-page.html
* igt@gen9_exec_parse@bb-start-cmd:
- shard-dg1: NOTRUN -> [SKIP][74] ([i915#2527]) +3 other tests skip
[74]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-18/igt@gen9_exec_parse@bb-start-cmd.html
* igt@gen9_exec_parse@secure-batches:
- shard-tglu: NOTRUN -> [SKIP][75] ([i915#2527] / [i915#2856])
[75]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-tglu-10/igt@gen9_exec_parse@secure-batches.html
* igt@gen9_exec_parse@unaligned-jump:
- shard-dg2: NOTRUN -> [SKIP][76] ([i915#2856]) +1 other test skip
[76]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-3/igt@gen9_exec_parse@unaligned-jump.html
* igt@i915_module_load@reload-with-fault-injection:
- shard-mtlp: [PASS][77] -> [ABORT][78] ([i915#8489] / [i915#8668])
[77]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-mtlp-4/igt@i915_module_load@reload-with-fault-injection.html
[78]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-1/igt@i915_module_load@reload-with-fault-injection.html
* igt@i915_pm_freq_api@freq-suspend@gt0:
- shard-dg2: [PASS][79] -> [INCOMPLETE][80] ([i915#9407])
[79]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-dg2-7/igt@i915_pm_freq_api@freq-suspend@gt0.html
[80]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-2/igt@i915_pm_freq_api@freq-suspend@gt0.html
* igt@i915_pm_rpm@dpms-lpsp:
- shard-dg1: [PASS][81] -> [SKIP][82] ([i915#1397]) +1 other test skip
[81]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-dg1-19/igt@i915_pm_rpm@dpms-lpsp.html
[82]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-12/igt@i915_pm_rpm@dpms-lpsp.html
- shard-dg2: NOTRUN -> [SKIP][83] ([i915#1397])
[83]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-6/igt@i915_pm_rpm@dpms-lpsp.html
* igt@i915_pm_rpm@dpms-mode-unset-lpsp:
- shard-dg2: [PASS][84] -> [SKIP][85] ([i915#1397])
[84]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-dg2-10/igt@i915_pm_rpm@dpms-mode-unset-lpsp.html
[85]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-6/igt@i915_pm_rpm@dpms-mode-unset-lpsp.html
* igt@i915_pm_rpm@dpms-mode-unset-non-lpsp:
- shard-rkl: [PASS][86] -> [SKIP][87] ([i915#1397])
[86]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-rkl-6/igt@i915_pm_rpm@dpms-mode-unset-non-lpsp.html
[87]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@i915_pm_rpm@dpms-mode-unset-non-lpsp.html
* igt@i915_pm_rpm@modeset-pc8-residency-stress:
- shard-dg1: NOTRUN -> [SKIP][88] ([fdo#109506])
[88]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-14/igt@i915_pm_rpm@modeset-pc8-residency-stress.html
* igt@i915_pm_rpm@pc8-residency:
- shard-dg2: NOTRUN -> [SKIP][89] ([fdo#109506])
[89]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-10/igt@i915_pm_rpm@pc8-residency.html
* igt@i915_pm_rps@min-max-config-loaded:
- shard-dg1: NOTRUN -> [SKIP][90] ([i915#6621])
[90]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-19/igt@i915_pm_rps@min-max-config-loaded.html
* igt@i915_pm_rps@thresholds-park@gt0:
- shard-dg2: NOTRUN -> [SKIP][91] ([i915#8925]) +1 other test skip
[91]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-6/igt@i915_pm_rps@thresholds-park@gt0.html
* igt@i915_query@query-topology-coherent-slice-mask:
- shard-dg2: NOTRUN -> [SKIP][92] ([i915#6188])
[92]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-11/igt@i915_query@query-topology-coherent-slice-mask.html
* igt@kms_addfb_basic@basic-x-tiled-legacy:
- shard-dg2: NOTRUN -> [SKIP][93] ([i915#4212]) +1 other test skip
[93]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-1/igt@kms_addfb_basic@basic-x-tiled-legacy.html
* igt@kms_async_flips@async-flip-with-page-flip-events@pipe-a-hdmi-a-3-4-mc_ccs:
- shard-dg2: NOTRUN -> [SKIP][94] ([i915#8502] / [i915#8709]) +11 other tests skip
[94]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-3/igt@kms_async_flips@async-flip-with-page-flip-events@pipe-a-hdmi-a-3-4-mc_ccs.html
* igt@kms_async_flips@async-flip-with-page-flip-events@pipe-b-hdmi-a-1-y-rc_ccs:
- shard-rkl: NOTRUN -> [SKIP][95] ([i915#8502]) +3 other tests skip
[95]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@kms_async_flips@async-flip-with-page-flip-events@pipe-b-hdmi-a-1-y-rc_ccs.html
* igt@kms_async_flips@async-flip-with-page-flip-events@pipe-c-hdmi-a-4-y-rc_ccs:
- shard-dg1: NOTRUN -> [SKIP][96] ([i915#8502]) +7 other tests skip
[96]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-17/igt@kms_async_flips@async-flip-with-page-flip-events@pipe-c-hdmi-a-4-y-rc_ccs.html
* igt@kms_big_fb@4-tiled-64bpp-rotate-180:
- shard-dg1: NOTRUN -> [SKIP][97] ([i915#4538] / [i915#5286]) +1 other test skip
[97]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-16/igt@kms_big_fb@4-tiled-64bpp-rotate-180.html
* igt@kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-180-hflip:
- shard-rkl: NOTRUN -> [SKIP][98] ([i915#5286]) +2 other tests skip
[98]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-1/igt@kms_big_fb@4-tiled-max-hw-stride-64bpp-rotate-180-hflip.html
* igt@kms_big_fb@linear-32bpp-rotate-180:
- shard-mtlp: [PASS][99] -> [FAIL][100] ([i915#5138])
[99]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-mtlp-8/igt@kms_big_fb@linear-32bpp-rotate-180.html
[100]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-6/igt@kms_big_fb@linear-32bpp-rotate-180.html
* igt@kms_big_fb@x-tiled-16bpp-rotate-90:
- shard-dg2: NOTRUN -> [SKIP][101] ([fdo#111614]) +5 other tests skip
[101]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-1/igt@kms_big_fb@x-tiled-16bpp-rotate-90.html
* igt@kms_big_fb@x-tiled-8bpp-rotate-270:
- shard-rkl: NOTRUN -> [SKIP][102] ([fdo#111614] / [i915#3638])
[102]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-4/igt@kms_big_fb@x-tiled-8bpp-rotate-270.html
* igt@kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip:
- shard-tglu: [PASS][103] -> [FAIL][104] ([i915#3743]) +1 other test fail
[103]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-tglu-3/igt@kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip.html
[104]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-tglu-6/igt@kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-0-hflip-async-flip.html
* igt@kms_big_fb@y-tiled-64bpp-rotate-90:
- shard-dg1: NOTRUN -> [SKIP][105] ([i915#3638]) +1 other test skip
[105]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-14/igt@kms_big_fb@y-tiled-64bpp-rotate-90.html
* igt@kms_big_fb@y-tiled-addfb-size-offset-overflow:
- shard-dg2: NOTRUN -> [SKIP][106] ([i915#5190]) +9 other tests skip
[106]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-1/igt@kms_big_fb@y-tiled-addfb-size-offset-overflow.html
* igt@kms_big_fb@yf-tiled-16bpp-rotate-270:
- shard-dg1: NOTRUN -> [SKIP][107] ([i915#4538]) +1 other test skip
[107]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-19/igt@kms_big_fb@yf-tiled-16bpp-rotate-270.html
- shard-tglu: NOTRUN -> [SKIP][108] ([fdo#111615])
[108]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-tglu-9/igt@kms_big_fb@yf-tiled-16bpp-rotate-270.html
* igt@kms_big_fb@yf-tiled-16bpp-rotate-90:
- shard-dg2: NOTRUN -> [SKIP][109] ([i915#4538] / [i915#5190]) +5 other tests skip
[109]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-6/igt@kms_big_fb@yf-tiled-16bpp-rotate-90.html
- shard-rkl: NOTRUN -> [SKIP][110] ([fdo#110723]) +1 other test skip
[110]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@kms_big_fb@yf-tiled-16bpp-rotate-90.html
* igt@kms_big_fb@yf-tiled-addfb:
- shard-dg1: NOTRUN -> [SKIP][111] ([fdo#111615])
[111]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-19/igt@kms_big_fb@yf-tiled-addfb.html
- shard-mtlp: NOTRUN -> [SKIP][112] ([i915#6187])
[112]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-5/igt@kms_big_fb@yf-tiled-addfb.html
* igt@kms_ccs@pipe-a-bad-aux-stride-y_tiled_gen12_rc_ccs_cc:
- shard-mtlp: NOTRUN -> [SKIP][113] ([i915#3886] / [i915#5354] / [i915#6095]) +2 other tests skip
[113]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-2/igt@kms_ccs@pipe-a-bad-aux-stride-y_tiled_gen12_rc_ccs_cc.html
* igt@kms_ccs@pipe-a-bad-pixel-format-y_tiled_gen12_mc_ccs:
- shard-rkl: NOTRUN -> [SKIP][114] ([i915#3886] / [i915#5354] / [i915#6095])
[114]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-6/igt@kms_ccs@pipe-a-bad-pixel-format-y_tiled_gen12_mc_ccs.html
* igt@kms_ccs@pipe-a-missing-ccs-buffer-yf_tiled_ccs:
- shard-dg1: NOTRUN -> [SKIP][115] ([i915#3689] / [i915#5354] / [i915#6095]) +7 other tests skip
[115]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-15/igt@kms_ccs@pipe-a-missing-ccs-buffer-yf_tiled_ccs.html
* igt@kms_ccs@pipe-a-random-ccs-data-y_tiled_ccs:
- shard-rkl: NOTRUN -> [SKIP][116] ([i915#3734] / [i915#5354] / [i915#6095]) +2 other tests skip
[116]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-6/igt@kms_ccs@pipe-a-random-ccs-data-y_tiled_ccs.html
* igt@kms_ccs@pipe-b-crc-primary-rotation-180-4_tiled_dg2_rc_ccs_cc:
- shard-rkl: NOTRUN -> [SKIP][117] ([i915#5354] / [i915#6095]) +3 other tests skip
[117]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@kms_ccs@pipe-b-crc-primary-rotation-180-4_tiled_dg2_rc_ccs_cc.html
* igt@kms_ccs@pipe-c-ccs-on-another-bo-y_tiled_gen12_mc_ccs:
- shard-dg1: NOTRUN -> [SKIP][118] ([i915#3689] / [i915#3886] / [i915#5354] / [i915#6095])
[118]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-18/igt@kms_ccs@pipe-c-ccs-on-another-bo-y_tiled_gen12_mc_ccs.html
* igt@kms_ccs@pipe-c-ccs-on-another-bo-y_tiled_gen12_rc_ccs_cc:
- shard-dg2: NOTRUN -> [SKIP][119] ([i915#3689] / [i915#3886] / [i915#5354]) +9 other tests skip
[119]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-1/igt@kms_ccs@pipe-c-ccs-on-another-bo-y_tiled_gen12_rc_ccs_cc.html
* igt@kms_ccs@pipe-d-crc-primary-basic-yf_tiled_ccs:
- shard-dg2: NOTRUN -> [SKIP][120] ([i915#3689] / [i915#5354]) +24 other tests skip
[120]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-7/igt@kms_ccs@pipe-d-crc-primary-basic-yf_tiled_ccs.html
* igt@kms_ccs@pipe-d-crc-primary-rotation-180-4_tiled_mtl_mc_ccs:
- shard-rkl: NOTRUN -> [SKIP][121] ([i915#5354]) +7 other tests skip
[121]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@kms_ccs@pipe-d-crc-primary-rotation-180-4_tiled_mtl_mc_ccs.html
* igt@kms_ccs@pipe-d-missing-ccs-buffer-4_tiled_mtl_rc_ccs_cc:
- shard-dg1: NOTRUN -> [SKIP][122] ([i915#5354] / [i915#6095]) +9 other tests skip
[122]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-19/igt@kms_ccs@pipe-d-missing-ccs-buffer-4_tiled_mtl_rc_ccs_cc.html
* igt@kms_cdclk@plane-scaling@pipe-a-hdmi-a-2:
- shard-dg2: NOTRUN -> [SKIP][123] ([i915#4087]) +3 other tests skip
[123]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-2/igt@kms_cdclk@plane-scaling@pipe-a-hdmi-a-2.html
* igt@kms_chamelium_color@ctm-negative:
- shard-dg1: NOTRUN -> [SKIP][124] ([fdo#111827]) +1 other test skip
[124]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-14/igt@kms_chamelium_color@ctm-negative.html
- shard-mtlp: NOTRUN -> [SKIP][125] ([fdo#111827])
[125]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-5/igt@kms_chamelium_color@ctm-negative.html
* igt@kms_chamelium_edid@dp-mode-timings:
- shard-dg1: NOTRUN -> [SKIP][126] ([i915#7828]) +3 other tests skip
[126]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-15/igt@kms_chamelium_edid@dp-mode-timings.html
- shard-mtlp: NOTRUN -> [SKIP][127] ([i915#7828])
[127]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-8/igt@kms_chamelium_edid@dp-mode-timings.html
* igt@kms_chamelium_edid@hdmi-edid-stress-resolution-non-4k:
- shard-dg2: NOTRUN -> [SKIP][128] ([i915#7828]) +8 other tests skip
[128]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-3/igt@kms_chamelium_edid@hdmi-edid-stress-resolution-non-4k.html
* igt@kms_chamelium_frames@hdmi-frame-dump:
- shard-rkl: NOTRUN -> [SKIP][129] ([i915#7828]) +2 other tests skip
[129]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-6/igt@kms_chamelium_frames@hdmi-frame-dump.html
* igt@kms_color@deep-color:
- shard-dg2: NOTRUN -> [SKIP][130] ([i915#3555]) +5 other tests skip
[130]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-1/igt@kms_color@deep-color.html
- shard-rkl: NOTRUN -> [SKIP][131] ([i915#3555]) +2 other tests skip
[131]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-6/igt@kms_color@deep-color.html
* igt@kms_content_protection@atomic-dpms:
- shard-dg2: NOTRUN -> [SKIP][132] ([i915#7118]) +1 other test skip
[132]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-6/igt@kms_content_protection@atomic-dpms.html
* igt@kms_content_protection@dp-mst-lic-type-1:
- shard-dg2: NOTRUN -> [SKIP][133] ([i915#3299])
[133]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-11/igt@kms_content_protection@dp-mst-lic-type-1.html
* igt@kms_cursor_crc@cursor-random-512x170:
- shard-dg2: NOTRUN -> [SKIP][134] ([i915#3359]) +1 other test skip
[134]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-11/igt@kms_cursor_crc@cursor-random-512x170.html
- shard-rkl: NOTRUN -> [SKIP][135] ([i915#3359]) +1 other test skip
[135]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-1/igt@kms_cursor_crc@cursor-random-512x170.html
* igt@kms_cursor_crc@cursor-sliding-512x512:
- shard-dg1: NOTRUN -> [SKIP][136] ([i915#3359])
[136]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-14/igt@kms_cursor_crc@cursor-sliding-512x512.html
* igt@kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic:
- shard-mtlp: NOTRUN -> [SKIP][137] ([i915#3546])
[137]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-2/igt@kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic.html
* igt@kms_cursor_legacy@cursorb-vs-flipb-varying-size:
- shard-dg2: NOTRUN -> [SKIP][138] ([fdo#109274] / [i915#5354]) +5 other tests skip
[138]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-5/igt@kms_cursor_legacy@cursorb-vs-flipb-varying-size.html
* igt@kms_cursor_legacy@short-busy-flip-before-cursor-atomic-transitions:
- shard-dg1: NOTRUN -> [SKIP][139] ([i915#4103] / [i915#4213])
[139]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-14/igt@kms_cursor_legacy@short-busy-flip-before-cursor-atomic-transitions.html
* igt@kms_dirtyfb@dirtyfb-ioctl@fbc-hdmi-a-1:
- shard-rkl: NOTRUN -> [SKIP][140] ([i915#9227])
[140]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@kms_dirtyfb@dirtyfb-ioctl@fbc-hdmi-a-1.html
* igt@kms_dirtyfb@dirtyfb-ioctl@psr-hdmi-a-1:
- shard-rkl: NOTRUN -> [SKIP][141] ([i915#9226] / [i915#9261]) +1 other test skip
[141]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@kms_dirtyfb@dirtyfb-ioctl@psr-hdmi-a-1.html
* igt@kms_dither@fb-8bpc-vs-panel-6bpc@pipe-a-hdmi-a-2:
- shard-rkl: NOTRUN -> [SKIP][142] ([i915#3804])
[142]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-6/igt@kms_dither@fb-8bpc-vs-panel-6bpc@pipe-a-hdmi-a-2.html
* igt@kms_draw_crc@draw-method-mmap-gtt:
- shard-dg2: NOTRUN -> [SKIP][143] ([i915#8812])
[143]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-3/igt@kms_draw_crc@draw-method-mmap-gtt.html
* igt@kms_dsc@dsc-basic:
- shard-dg2: NOTRUN -> [SKIP][144] ([i915#3555] / [i915#3840]) +1 other test skip
[144]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-1/igt@kms_dsc@dsc-basic.html
* igt@kms_dsc@dsc-with-output-formats:
- shard-rkl: NOTRUN -> [SKIP][145] ([i915#3555] / [i915#3840])
[145]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@kms_dsc@dsc-with-output-formats.html
* igt@kms_fbcon_fbt@psr:
- shard-dg2: NOTRUN -> [SKIP][146] ([i915#3469]) +1 other test skip
[146]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-10/igt@kms_fbcon_fbt@psr.html
- shard-rkl: NOTRUN -> [SKIP][147] ([fdo#110189] / [i915#3955])
[147]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-1/igt@kms_fbcon_fbt@psr.html
* igt@kms_flip@2x-blocking-absolute-wf_vblank-interruptible:
- shard-tglu: NOTRUN -> [SKIP][148] ([fdo#109274] / [i915#3637])
[148]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-tglu-8/igt@kms_flip@2x-blocking-absolute-wf_vblank-interruptible.html
* igt@kms_flip@2x-dpms-vs-vblank-race:
- shard-rkl: NOTRUN -> [SKIP][149] ([fdo#111825]) +3 other tests skip
[149]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-1/igt@kms_flip@2x-dpms-vs-vblank-race.html
* igt@kms_flip@2x-flip-vs-expired-vblank-interruptible:
- shard-snb: NOTRUN -> [SKIP][150] ([fdo#109271] / [fdo#111767])
[150]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-snb4/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible.html
* igt@kms_flip@2x-flip-vs-fences:
- shard-dg2: NOTRUN -> [SKIP][151] ([i915#8381]) +1 other test skip
[151]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-7/igt@kms_flip@2x-flip-vs-fences.html
* igt@kms_flip@2x-flip-vs-suspend@ab-vga1-hdmi-a1:
- shard-snb: NOTRUN -> [DMESG-WARN][152] ([i915#8841]) +2 other tests dmesg-warn
[152]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-snb1/igt@kms_flip@2x-flip-vs-suspend@ab-vga1-hdmi-a1.html
* igt@kms_flip@2x-modeset-vs-vblank-race:
- shard-dg2: NOTRUN -> [SKIP][153] ([fdo#109274]) +13 other tests skip
[153]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-3/igt@kms_flip@2x-modeset-vs-vblank-race.html
* igt@kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling@pipe-a-default-mode:
- shard-mtlp: NOTRUN -> [SKIP][154] ([i915#3555] / [i915#8810])
[154]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-3/igt@kms_flip_scaled_crc@flip-32bpp-linear-to-64bpp-linear-downscaling@pipe-a-default-mode.html
* igt@kms_flip_scaled_crc@flip-32bpp-yftile-to-64bpp-yftile-upscaling@pipe-a-valid-mode:
- shard-rkl: NOTRUN -> [SKIP][155] ([i915#2672]) +1 other test skip
[155]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@kms_flip_scaled_crc@flip-32bpp-yftile-to-64bpp-yftile-upscaling@pipe-a-valid-mode.html
* igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-downscaling@pipe-a-default-mode:
- shard-mtlp: NOTRUN -> [SKIP][156] ([i915#2672] / [i915#3555])
[156]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-7/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-downscaling@pipe-a-default-mode.html
* igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-upscaling@pipe-a-valid-mode:
- shard-dg2: NOTRUN -> [SKIP][157] ([i915#2672]) +4 other tests skip
[157]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-11/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs-upscaling@pipe-a-valid-mode.html
* igt@kms_flip_scaled_crc@flip-64bpp-4tile-to-32bpp-4tile-downscaling@pipe-a-valid-mode:
- shard-dg1: NOTRUN -> [SKIP][158] ([i915#2587] / [i915#2672]) +2 other tests skip
[158]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-17/igt@kms_flip_scaled_crc@flip-64bpp-4tile-to-32bpp-4tile-downscaling@pipe-a-valid-mode.html
* igt@kms_force_connector_basic@force-load-detect:
- shard-dg2: NOTRUN -> [SKIP][159] ([fdo#109285])
[159]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-7/igt@kms_force_connector_basic@force-load-detect.html
- shard-rkl: NOTRUN -> [SKIP][160] ([fdo#109285] / [i915#4098])
[160]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-2/igt@kms_force_connector_basic@force-load-detect.html
* igt@kms_frontbuffer_tracking@fbc-1p-offscren-pri-indfb-draw-mmap-cpu:
- shard-dg2: [PASS][161] -> [FAIL][162] ([i915#6880]) +1 other test fail
[161]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-dg2-7/igt@kms_frontbuffer_tracking@fbc-1p-offscren-pri-indfb-draw-mmap-cpu.html
[162]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-6/igt@kms_frontbuffer_tracking@fbc-1p-offscren-pri-indfb-draw-mmap-cpu.html
* igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-blt:
- shard-dg2: NOTRUN -> [SKIP][163] ([i915#5354]) +46 other tests skip
[163]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-2/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-blt.html
* igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-spr-indfb-draw-mmap-gtt:
- shard-mtlp: NOTRUN -> [SKIP][164] ([i915#8708])
[164]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-1/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-spr-indfb-draw-mmap-gtt.html
* igt@kms_frontbuffer_tracking@fbc-rgb565-draw-pwrite:
- shard-dg2: NOTRUN -> [FAIL][165] ([i915#6880])
[165]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-6/igt@kms_frontbuffer_tracking@fbc-rgb565-draw-pwrite.html
* igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-shrfb-draw-mmap-gtt:
- shard-dg1: NOTRUN -> [SKIP][166] ([i915#8708]) +4 other tests skip
[166]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-17/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-shrfb-draw-mmap-gtt.html
* igt@kms_frontbuffer_tracking@fbcpsr-2p-pri-indfb-multidraw:
- shard-dg1: NOTRUN -> [SKIP][167] ([fdo#111825]) +19 other tests skip
[167]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-18/igt@kms_frontbuffer_tracking@fbcpsr-2p-pri-indfb-multidraw.html
* igt@kms_frontbuffer_tracking@fbcpsr-rgb565-draw-mmap-gtt:
- shard-rkl: NOTRUN -> [SKIP][168] ([i915#3023]) +4 other tests skip
[168]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@kms_frontbuffer_tracking@fbcpsr-rgb565-draw-mmap-gtt.html
* igt@kms_frontbuffer_tracking@fbcpsr-tiling-4:
- shard-dg1: NOTRUN -> [SKIP][169] ([i915#5439])
[169]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-17/igt@kms_frontbuffer_tracking@fbcpsr-tiling-4.html
* igt@kms_frontbuffer_tracking@fbcpsr-tiling-y:
- shard-dg2: NOTRUN -> [SKIP][170] ([i915#5460])
[170]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-3/igt@kms_frontbuffer_tracking@fbcpsr-tiling-y.html
* igt@kms_frontbuffer_tracking@psr-2p-primscrn-pri-shrfb-draw-mmap-cpu:
- shard-snb: NOTRUN -> [SKIP][171] ([fdo#109271]) +177 other tests skip
[171]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-snb4/igt@kms_frontbuffer_tracking@psr-2p-primscrn-pri-shrfb-draw-mmap-cpu.html
* igt@kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-move:
- shard-mtlp: NOTRUN -> [SKIP][172] ([i915#1825])
[172]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-3/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-move.html
* igt@kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-onoff:
- shard-rkl: NOTRUN -> [SKIP][173] ([fdo#111825] / [i915#1825]) +6 other tests skip
[173]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-1/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-spr-indfb-onoff.html
* igt@kms_frontbuffer_tracking@psr-indfb-scaledprimary:
- shard-dg2: NOTRUN -> [SKIP][174] ([i915#3458]) +16 other tests skip
[174]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-5/igt@kms_frontbuffer_tracking@psr-indfb-scaledprimary.html
* igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-gtt:
- shard-dg2: NOTRUN -> [SKIP][175] ([i915#8708]) +16 other tests skip
[175]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-7/igt@kms_frontbuffer_tracking@psr-rgb101010-draw-mmap-gtt.html
* igt@kms_frontbuffer_tracking@psr-suspend:
- shard-dg1: NOTRUN -> [SKIP][176] ([i915#3458]) +7 other tests skip
[176]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-17/igt@kms_frontbuffer_tracking@psr-suspend.html
- shard-tglu: NOTRUN -> [SKIP][177] ([fdo#110189])
[177]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-tglu-8/igt@kms_frontbuffer_tracking@psr-suspend.html
* igt@kms_hdr@bpc-switch:
- shard-mtlp: NOTRUN -> [SKIP][178] ([i915#3555] / [i915#8228])
[178]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-2/igt@kms_hdr@bpc-switch.html
* igt@kms_hdr@bpc-switch-dpms:
- shard-rkl: NOTRUN -> [SKIP][179] ([i915#3555] / [i915#8228])
[179]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-2/igt@kms_hdr@bpc-switch-dpms.html
* igt@kms_hdr@bpc-switch-suspend:
- shard-dg1: NOTRUN -> [SKIP][180] ([i915#3555] / [i915#8228])
[180]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-16/igt@kms_hdr@bpc-switch-suspend.html
* igt@kms_hdr@static-toggle-suspend:
- shard-dg2: NOTRUN -> [SKIP][181] ([i915#3555] / [i915#8228]) +4 other tests skip
[181]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-7/igt@kms_hdr@static-toggle-suspend.html
* igt@kms_multipipe_modeset@basic-max-pipe-crc-check:
- shard-dg2: NOTRUN -> [SKIP][182] ([i915#4816])
[182]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-2/igt@kms_multipipe_modeset@basic-max-pipe-crc-check.html
* igt@kms_panel_fitting@atomic-fastset:
- shard-dg2: NOTRUN -> [SKIP][183] ([i915#6301])
[183]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-11/igt@kms_panel_fitting@atomic-fastset.html
* igt@kms_plane_scaling@intel-max-src-size@pipe-a-hdmi-a-4:
- shard-dg1: NOTRUN -> [FAIL][184] ([i915#8292])
[184]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-15/igt@kms_plane_scaling@intel-max-src-size@pipe-a-hdmi-a-4.html
* igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-a-hdmi-a-3:
- shard-dg1: NOTRUN -> [SKIP][185] ([i915#5176]) +3 other tests skip
[185]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-12/igt@kms_plane_scaling@plane-scaler-with-clipping-clamping-rotation@pipe-a-hdmi-a-3.html
* igt@kms_plane_scaling@planes-downscale-factor-0-25-upscale-factor-0-25@pipe-b-hdmi-a-2:
- shard-rkl: NOTRUN -> [SKIP][186] ([i915#5235]) +5 other tests skip
[186]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-4/igt@kms_plane_scaling@planes-downscale-factor-0-25-upscale-factor-0-25@pipe-b-hdmi-a-2.html
* igt@kms_plane_scaling@planes-upscale-factor-0-25-downscale-factor-0-25@pipe-a-hdmi-a-3:
- shard-dg2: NOTRUN -> [SKIP][187] ([i915#5235]) +19 other tests skip
[187]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-3/igt@kms_plane_scaling@planes-upscale-factor-0-25-downscale-factor-0-25@pipe-a-hdmi-a-3.html
* igt@kms_plane_scaling@planes-upscale-factor-0-25-downscale-factor-0-25@pipe-d-hdmi-a-4:
- shard-dg1: NOTRUN -> [SKIP][188] ([i915#5235]) +23 other tests skip
[188]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-18/igt@kms_plane_scaling@planes-upscale-factor-0-25-downscale-factor-0-25@pipe-d-hdmi-a-4.html
* igt@kms_prime@basic-crc-hybrid:
- shard-dg2: NOTRUN -> [SKIP][189] ([i915#6524] / [i915#6805])
[189]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-1/igt@kms_prime@basic-crc-hybrid.html
* igt@kms_prime@basic-crc-vgem:
- shard-dg1: NOTRUN -> [SKIP][190] ([i915#6524])
[190]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-16/igt@kms_prime@basic-crc-vgem.html
* igt@kms_psr2_sf@cursor-plane-move-continuous-exceed-fully-sf:
- shard-dg1: NOTRUN -> [SKIP][191] ([i915#658])
[191]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-12/igt@kms_psr2_sf@cursor-plane-move-continuous-exceed-fully-sf.html
* igt@kms_psr2_sf@overlay-plane-update-continuous-sf:
- shard-dg1: NOTRUN -> [SKIP][192] ([fdo#111068] / [i915#658])
[192]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-17/igt@kms_psr2_sf@overlay-plane-update-continuous-sf.html
* igt@kms_psr2_sf@plane-move-sf-dmg-area:
- shard-rkl: NOTRUN -> [SKIP][193] ([fdo#111068] / [i915#658])
[193]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-1/igt@kms_psr2_sf@plane-move-sf-dmg-area.html
* igt@kms_psr2_su@frontbuffer-xrgb8888:
- shard-dg2: NOTRUN -> [SKIP][194] ([i915#658]) +2 other tests skip
[194]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-11/igt@kms_psr2_su@frontbuffer-xrgb8888.html
* igt@kms_psr@cursor_mmap_cpu:
- shard-dg1: NOTRUN -> [SKIP][195] ([i915#1072] / [i915#4078]) +2 other tests skip
[195]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-16/igt@kms_psr@cursor_mmap_cpu.html
* igt@kms_psr@no_drrs:
- shard-rkl: NOTRUN -> [SKIP][196] ([i915#1072])
[196]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-1/igt@kms_psr@no_drrs.html
* igt@kms_psr@psr2_dpms:
- shard-dg2: NOTRUN -> [SKIP][197] ([i915#1072]) +6 other tests skip
[197]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-3/igt@kms_psr@psr2_dpms.html
* igt@kms_rotation_crc@primary-rotation-270:
- shard-dg2: NOTRUN -> [SKIP][198] ([i915#4235]) +1 other test skip
[198]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-3/igt@kms_rotation_crc@primary-rotation-270.html
* igt@kms_rotation_crc@primary-y-tiled-reflect-x-90:
- shard-mtlp: NOTRUN -> [SKIP][199] ([i915#4235])
[199]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-8/igt@kms_rotation_crc@primary-y-tiled-reflect-x-90.html
* igt@kms_rotation_crc@primary-yf-tiled-reflect-x-270:
- shard-rkl: NOTRUN -> [SKIP][200] ([fdo#111615] / [i915#5289]) +1 other test skip
[200]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@kms_rotation_crc@primary-yf-tiled-reflect-x-270.html
* igt@kms_rotation_crc@primary-yf-tiled-reflect-x-90:
- shard-dg2: NOTRUN -> [SKIP][201] ([i915#4235] / [i915#5190])
[201]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-1/igt@kms_rotation_crc@primary-yf-tiled-reflect-x-90.html
* igt@kms_scaling_modes@scaling-mode-none:
- shard-dg1: NOTRUN -> [SKIP][202] ([i915#3555]) +3 other tests skip
[202]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-15/igt@kms_scaling_modes@scaling-mode-none.html
* igt@kms_setmode@basic@pipe-a-vga-1:
- shard-snb: NOTRUN -> [FAIL][203] ([i915#5465]) +1 other test fail
[203]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-snb2/igt@kms_setmode@basic@pipe-a-vga-1.html
* igt@kms_setmode@clone-exclusive-crtc:
- shard-rkl: NOTRUN -> [SKIP][204] ([i915#3555] / [i915#4098])
[204]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-2/igt@kms_setmode@clone-exclusive-crtc.html
* igt@kms_universal_plane@cursor-fb-leak-pipe-d:
- shard-mtlp: [PASS][205] -> [FAIL][206] ([i915#9196])
[205]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-mtlp-6/igt@kms_universal_plane@cursor-fb-leak-pipe-d.html
[206]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-8/igt@kms_universal_plane@cursor-fb-leak-pipe-d.html
* igt@kms_vblank@pipe-c-ts-continuation-dpms-suspend:
- shard-rkl: NOTRUN -> [SKIP][207] ([i915#4070] / [i915#6768]) +2 other tests skip
[207]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-6/igt@kms_vblank@pipe-c-ts-continuation-dpms-suspend.html
* igt@kms_vblank@pipe-d-wait-forked-busy-hang:
- shard-mtlp: [PASS][208] -> [DMESG-WARN][209] ([i915#2017] / [i915#9157])
[208]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-mtlp-3/igt@kms_vblank@pipe-d-wait-forked-busy-hang.html
[209]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-5/igt@kms_vblank@pipe-d-wait-forked-busy-hang.html
* igt@kms_writeback@writeback-fb-id:
- shard-dg2: NOTRUN -> [SKIP][210] ([i915#2437])
[210]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-7/igt@kms_writeback@writeback-fb-id.html
* igt@perf@enable-disable@0-rcs0:
- shard-dg2: [PASS][211] -> [FAIL][212] ([i915#8724])
[211]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-dg2-6/igt@perf@enable-disable@0-rcs0.html
[212]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-11/igt@perf@enable-disable@0-rcs0.html
* igt@perf@global-sseu-config-invalid:
- shard-dg2: NOTRUN -> [SKIP][213] ([i915#7387])
[213]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-7/igt@perf@global-sseu-config-invalid.html
* igt@perf@mi-rpc:
- shard-dg2: NOTRUN -> [SKIP][214] ([i915#2434])
[214]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-10/igt@perf@mi-rpc.html
* igt@perf_pmu@busy-idle@vcs0:
- shard-dg2: [PASS][215] -> [FAIL][216] ([i915#4349]) +7 other tests fail
[215]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-dg2-7/igt@perf_pmu@busy-idle@vcs0.html
[216]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-11/igt@perf_pmu@busy-idle@vcs0.html
- shard-dg1: [PASS][217] -> [FAIL][218] ([i915#4349]) +2 other tests fail
[217]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-dg1-14/igt@perf_pmu@busy-idle@vcs0.html
[218]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-19/igt@perf_pmu@busy-idle@vcs0.html
- shard-mtlp: [PASS][219] -> [FAIL][220] ([i915#4349]) +3 other tests fail
[219]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-mtlp-6/igt@perf_pmu@busy-idle@vcs0.html
[220]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-4/igt@perf_pmu@busy-idle@vcs0.html
* igt@perf_pmu@module-unload:
- shard-dg2: NOTRUN -> [FAIL][221] ([i915#5793])
[221]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-1/igt@perf_pmu@module-unload.html
* igt@perf_pmu@rc6@other-idle-gt0:
- shard-dg1: NOTRUN -> [SKIP][222] ([i915#8516])
[222]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-19/igt@perf_pmu@rc6@other-idle-gt0.html
* igt@prime_vgem@basic-fence-mmap:
- shard-dg2: NOTRUN -> [SKIP][223] ([i915#3708] / [i915#4077])
[223]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-7/igt@prime_vgem@basic-fence-mmap.html
* igt@prime_vgem@basic-fence-read:
- shard-dg2: NOTRUN -> [SKIP][224] ([i915#3291] / [i915#3708])
[224]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-7/igt@prime_vgem@basic-fence-read.html
* igt@prime_vgem@fence-flip-hang:
- shard-dg2: NOTRUN -> [SKIP][225] ([i915#3708])
[225]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-1/igt@prime_vgem@fence-flip-hang.html
* igt@sysfs_preempt_timeout@timeout@vecs0:
- shard-mtlp: [PASS][226] -> [ABORT][227] ([i915#8521] / [i915#8865])
[226]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-mtlp-8/igt@sysfs_preempt_timeout@timeout@vecs0.html
[227]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-8/igt@sysfs_preempt_timeout@timeout@vecs0.html
* igt@tools_test@sysfs_l3_parity:
- shard-dg2: NOTRUN -> [SKIP][228] ([i915#4818])
[228]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-2/igt@tools_test@sysfs_l3_parity.html
- shard-rkl: NOTRUN -> [SKIP][229] ([fdo#109307])
[229]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-4/igt@tools_test@sysfs_l3_parity.html
* igt@v3d/v3d_perfmon@create-perfmon-invalid-counters:
- shard-dg2: NOTRUN -> [SKIP][230] ([i915#2575]) +13 other tests skip
[230]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-3/igt@v3d/v3d_perfmon@create-perfmon-invalid-counters.html
* igt@v3d/v3d_submit_cl@bad-multisync-in-sync:
- shard-rkl: NOTRUN -> [SKIP][231] ([fdo#109315]) +3 other tests skip
[231]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-4/igt@v3d/v3d_submit_cl@bad-multisync-in-sync.html
* igt@v3d/v3d_submit_cl@simple-flush-cache:
- shard-dg1: NOTRUN -> [SKIP][232] ([i915#2575]) +5 other tests skip
[232]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-12/igt@v3d/v3d_submit_cl@simple-flush-cache.html
* igt@vc4/vc4_label_bo@set-kernel-name:
- shard-dg1: NOTRUN -> [SKIP][233] ([i915#7711]) +3 other tests skip
[233]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-19/igt@vc4/vc4_label_bo@set-kernel-name.html
* igt@vc4/vc4_mmap@mmap-bad-handle:
- shard-mtlp: NOTRUN -> [SKIP][234] ([i915#7711])
[234]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-7/igt@vc4/vc4_mmap@mmap-bad-handle.html
* igt@vc4/vc4_tiling@get-bad-flags:
- shard-rkl: NOTRUN -> [SKIP][235] ([i915#7711]) +1 other test skip
[235]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@vc4/vc4_tiling@get-bad-flags.html
* igt@vc4/vc4_tiling@get-bad-handle:
- shard-dg2: NOTRUN -> [SKIP][236] ([i915#7711]) +9 other tests skip
[236]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-10/igt@vc4/vc4_tiling@get-bad-handle.html
#### Possible fixes ####
* igt@gem_ctx_persistence@legacy-engines-hostile@blt:
- shard-mtlp: [ABORT][237] ([i915#9414]) -> [PASS][238]
[237]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-mtlp-2/igt@gem_ctx_persistence@legacy-engines-hostile@blt.html
[238]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-2/igt@gem_ctx_persistence@legacy-engines-hostile@blt.html
* igt@gem_eio@unwedge-stress:
- shard-dg1: [FAIL][239] ([i915#5784]) -> [PASS][240]
[239]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-dg1-18/igt@gem_eio@unwedge-stress.html
[240]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-14/igt@gem_eio@unwedge-stress.html
* igt@gem_exec_fair@basic-deadline:
- shard-rkl: [FAIL][241] ([i915#2846]) -> [PASS][242]
[241]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-rkl-1/igt@gem_exec_fair@basic-deadline.html
[242]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@gem_exec_fair@basic-deadline.html
* igt@gem_exec_fair@basic-pace@rcs0:
- shard-rkl: [FAIL][243] ([i915#2842]) -> [PASS][244]
[243]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-rkl-6/igt@gem_exec_fair@basic-pace@rcs0.html
[244]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-4/igt@gem_exec_fair@basic-pace@rcs0.html
* igt@gem_exec_suspend@basic-s0@lmem0:
- shard-dg2: [INCOMPLETE][245] -> [PASS][246]
[245]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-dg2-5/igt@gem_exec_suspend@basic-s0@lmem0.html
[246]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-1/igt@gem_exec_suspend@basic-s0@lmem0.html
* igt@i915_hangman@gt-engine-hang@vcs0:
- shard-mtlp: [FAIL][247] ([i915#7069]) -> [PASS][248]
[247]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-mtlp-5/igt@i915_hangman@gt-engine-hang@vcs0.html
[248]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-2/igt@i915_hangman@gt-engine-hang@vcs0.html
* igt@i915_pm_rc6_residency@rc6-idle@bcs0:
- shard-dg1: [FAIL][249] ([i915#3591]) -> [PASS][250]
[249]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-dg1-19/igt@i915_pm_rc6_residency@rc6-idle@bcs0.html
[250]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-18/igt@i915_pm_rc6_residency@rc6-idle@bcs0.html
* igt@i915_pm_rpm@modeset-lpsp-stress-no-wait:
- shard-rkl: [SKIP][251] ([i915#1397]) -> [PASS][252]
[251]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-rkl-6/igt@i915_pm_rpm@modeset-lpsp-stress-no-wait.html
[252]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-7/igt@i915_pm_rpm@modeset-lpsp-stress-no-wait.html
* igt@i915_pm_rpm@modeset-non-lpsp:
- shard-dg1: [SKIP][253] ([i915#1397]) -> [PASS][254]
[253]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-dg1-19/igt@i915_pm_rpm@modeset-non-lpsp.html
[254]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-12/igt@i915_pm_rpm@modeset-non-lpsp.html
* igt@i915_suspend@basic-s3-without-i915:
- shard-rkl: [FAIL][255] ([fdo#103375]) -> [PASS][256]
[255]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-rkl-6/igt@i915_suspend@basic-s3-without-i915.html
[256]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-4/igt@i915_suspend@basic-s3-without-i915.html
* igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip:
- shard-tglu: [FAIL][257] ([i915#3743]) -> [PASS][258]
[257]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-tglu-8/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip.html
[258]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-tglu-4/igt@kms_big_fb@y-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip.html
* igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size:
- shard-apl: [FAIL][259] ([i915#2346]) -> [PASS][260] +1 other test pass
[259]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-apl6/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
[260]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-apl6/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
- shard-glk: [FAIL][261] ([i915#2346]) -> [PASS][262]
[261]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-glk2/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
[262]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-glk2/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
* igt@kms_cursor_legacy@forked-bo@all-pipes:
- shard-mtlp: [DMESG-WARN][263] ([i915#2017]) -> [PASS][264]
[263]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-mtlp-4/igt@kms_cursor_legacy@forked-bo@all-pipes.html
[264]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-mtlp-5/igt@kms_cursor_legacy@forked-bo@all-pipes.html
* igt@kms_flip@flip-vs-expired-vblank@a-hdmi-a2:
- shard-glk: [FAIL][265] ([i915#79]) -> [PASS][266]
[265]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-glk2/igt@kms_flip@flip-vs-expired-vblank@a-hdmi-a2.html
[266]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-glk7/igt@kms_flip@flip-vs-expired-vblank@a-hdmi-a2.html
* igt@kms_frontbuffer_tracking@fbc-indfb-scaledprimary:
- shard-dg2: [FAIL][267] ([i915#6880]) -> [PASS][268] +1 other test pass
[267]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-dg2-10/igt@kms_frontbuffer_tracking@fbc-indfb-scaledprimary.html
[268]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-1/igt@kms_frontbuffer_tracking@fbc-indfb-scaledprimary.html
* igt@kms_universal_plane@cursor-fb-leak-pipe-b:
- shard-snb: [FAIL][269] ([i915#9196]) -> [PASS][270]
[269]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-snb1/igt@kms_universal_plane@cursor-fb-leak-pipe-b.html
[270]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-snb7/igt@kms_universal_plane@cursor-fb-leak-pipe-b.html
* igt@perf@non-zero-reason@0-rcs0:
- shard-dg2: [FAIL][271] ([i915#7484]) -> [PASS][272]
[271]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-dg2-5/igt@perf@non-zero-reason@0-rcs0.html
[272]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-1/igt@perf@non-zero-reason@0-rcs0.html
* igt@syncobj_timeline@wait-all-for-submit-delayed-submit:
- shard-dg1: [DMESG-WARN][273] ([i915#1982]) -> [PASS][274]
[273]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-dg1-14/igt@syncobj_timeline@wait-all-for-submit-delayed-submit.html
[274]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg1-19/igt@syncobj_timeline@wait-all-for-submit-delayed-submit.html
#### Warnings ####
* igt@i915_module_load@reload-with-fault-injection:
- shard-dg2: [WARN][275] ([i915#7356]) -> [DMESG-WARN][276] ([i915#8617])
[275]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-dg2-2/igt@i915_module_load@reload-with-fault-injection.html
[276]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-dg2-1/igt@i915_module_load@reload-with-fault-injection.html
* igt@i915_pm_rc6_residency@rc6-idle@vcs0:
- shard-tglu: [FAIL][277] ([i915#2681] / [i915#3591]) -> [WARN][278] ([i915#2681])
[277]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-tglu-9/igt@i915_pm_rc6_residency@rc6-idle@vcs0.html
[278]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-tglu-7/igt@i915_pm_rc6_residency@rc6-idle@vcs0.html
* igt@kms_multipipe_modeset@basic-max-pipe-crc-check:
- shard-rkl: [SKIP][279] ([i915#4070] / [i915#4816]) -> [SKIP][280] ([i915#4816])
[279]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13719/shard-rkl-6/igt@kms_multipipe_modeset@basic-max-pipe-crc-check.html
[280]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/shard-rkl-4/igt@kms_multipipe_modeset@basic-max-pipe-crc-check.html
{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).
[fdo#103375]: https://bugs.freedesktop.org/show_bug.cgi?id=103375
[fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
[fdo#109274]: https://bugs.freedesktop.org/show_bug.cgi?id=109274
[fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
[fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
[fdo#109307]: https://bugs.freedesktop.org/show_bug.cgi?id=109307
[fdo#109315]: https://bugs.freedesktop.org/show_bug.cgi?id=109315
[fdo#109506]: https://bugs.freedesktop.org/show_bug.cgi?id=109506
[fdo#110189]: https://bugs.freedesktop.org/show_bug.cgi?id=110189
[fdo#110723]: https://bugs.freedesktop.org/show_bug.cgi?id=110723
[fdo#111068]: https://bugs.freedesktop.org/show_bug.cgi?id=111068
[fdo#111614]: https://bugs.freedesktop.org/show_bug.cgi?id=111614
[fdo#111615]: https://bugs.freedesktop.org/show_bug.cgi?id=111615
[fdo#111767]: https://bugs.freedesktop.org/show_bug.cgi?id=111767
[fdo#111825]: https://bugs.freedesktop.org/show_bug.cgi?id=111825
[fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
[fdo#112283]: https://bugs.freedesktop.org/show_bug.cgi?id=112283
[i915#1072]: https://gitlab.freedesktop.org/drm/intel/issues/1072
[i915#1397]: https://gitlab.freedesktop.org/drm/intel/issues/1397
[i915#1825]: https://gitlab.freedesktop.org/drm/intel/issues/1825
[i915#1839]: https://gitlab.freedesktop.org/drm/intel/issues/1839
[i915#1937]: https://gitlab.freedesktop.org/drm/intel/issues/1937
[i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
[i915#2017]: https://gitlab.freedesktop.org/drm/intel/issues/2017
[i915#2346]: https://gitlab.freedesktop.org/drm/intel/issues/2346
[i915#2434]: https://gitlab.freedesktop.org/drm/intel/issues/2434
[i915#2437]: https://gitlab.freedesktop.org/drm/intel/issues/2437
[i915#2527]: https://gitlab.freedesktop.org/drm/intel/issues/2527
[i915#2575]: https://gitlab.freedesktop.org/drm/intel/issues/2575
[i915#2587]: https://gitlab.freedesktop.org/drm/intel/issues/2587
[i915#2672]: https://gitlab.freedesktop.org/drm/intel/issues/2672
[i915#2681]: https://gitlab.freedesktop.org/drm/intel/issues/2681
[i915#280]: https://gitlab.freedesktop.org/drm/intel/issues/280
[i915#2842]: https://gitlab.freedesktop.org/drm/intel/issues/2842
[i915#2846]: https://gitlab.freedesktop.org/drm/intel/issues/2846
[i915#2856]: https://gitlab.freedesktop.org/drm/intel/issues/2856
[i915#3023]: https://gitlab.freedesktop.org/drm/intel/issues/3023
[i915#3281]: https://gitlab.freedesktop.org/drm/intel/issues/3281
[i915#3282]: https://gitlab.freedesktop.org/drm/intel/issues/3282
[i915#3291]: https://gitlab.freedesktop.org/drm/intel/issues/3291
[i915#3297]: https://gitlab.freedesktop.org/drm/intel/issues/3297
[i915#3299]: https://gitlab.freedesktop.org/drm/intel/issues/3299
[i915#3318]: https://gitlab.freedesktop.org/drm/intel/issues/3318
[i915#3359]: https://gitlab.freedesktop.org/drm/intel/issues/3359
[i915#3458]: https://gitlab.freedesktop.org/drm/intel/issues/3458
[i915#3469]: https://gitlab.freedesktop.org/drm/intel/issues/3469
[i915#3539]: https://gitlab.freedesktop.org/drm/intel/issues/3539
[i915#3546]: https://gitlab.freedesktop.org/drm/intel/issues/3546
[i915#3555]: https://gitlab.freedesktop.org/drm/intel/issues/3555
[i915#3591]: https://gitlab.freedesktop.org/drm/intel/issues/3591
[i915#3637]: https://gitlab.freedesktop.org/drm/intel/issues/3637
[i915#3638]: https://gitlab.freedesktop.org/drm/intel/issues/3638
[i915#3689]: https://gitlab.freedesktop.org/drm/intel/issues/3689
[i915#3708]: https://gitlab.freedesktop.org/drm/intel/issues/3708
[i915#3734]: https://gitlab.freedesktop.org/drm/intel/issues/3734
[i915#3743]: https://gitlab.freedesktop.org/drm/intel/issues/3743
[i915#3804]: https://gitlab.freedesktop.org/drm/intel/issues/3804
[i915#3840]: https://gitlab.freedesktop.org/drm/intel/issues/3840
[i915#3886]: https://gitlab.freedesktop.org/drm/intel/issues/3886
[i915#3955]: https://gitlab.freedesktop.org/drm/intel/issues/3955
[i915#4070]: https://gitlab.freedesktop.org/drm/intel/issues/4070
[i915#4077]: https://gitlab.freedesktop.org/drm/intel/issues/4077
[i915#4078]: https://gitlab.freedesktop.org/drm/intel/issues/4078
[i915#4079]: https://gitlab.freedesktop.org/drm/intel/issues/4079
[i915#4083]: https://gitlab.freedesktop.org/drm/intel/issues/4083
[i915#4087]: https://gitlab.freedesktop.org/drm/intel/issues/4087
[i915#4098]: https://gitlab.freedesktop.org/drm/intel/issues/4098
[i915#4103]: https://gitlab.freedesktop.org/drm/intel/issues/4103
[i915#4212]: https://gitlab.freedesktop.org/drm/intel/issues/4212
[i915#4213]: https://gitlab.freedesktop.org/drm/intel/issues/4213
[i915#4235]: https://gitlab.freedesktop.org/drm/intel/issues/4235
[i915#4270]: https://gitlab.freedesktop.org/drm/intel/issues/4270
[i915#4349]: https://gitlab.freedesktop.org/drm/intel/issues/4349
[i915#4475]: https://gitlab.freedesktop.org/drm/intel/issues/4475
[i915#4537]: https://gitlab.freedesktop.org/drm/intel/issues/4537
[i915#4538]: https://gitlab.freedesktop.org/drm/intel/issues/4538
[i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
[i915#4812]: https://gitlab.freedesktop.org/drm/intel/issues/4812
[i915#4816]: https://gitlab.freedesktop.org/drm/intel/issues/4816
[i915#4818]: https://gitlab.freedesktop.org/drm/intel/issues/4818
[i915#4852]: https://gitlab.freedesktop.org/drm/intel/issues/4852
[i915#4860]: https://gitlab.freedesktop.org/drm/intel/issues/4860
[i915#4880]: https://gitlab.freedesktop.org/drm/intel/issues/4880
[i915#5138]: https://gitlab.freedesktop.org/drm/intel/issues/5138
[i915#5176]: https://gitlab.freedesktop.org/drm/intel/issues/5176
[i915#5190]: https://gitlab.freedesktop.org/drm/intel/issues/5190
[i915#5235]: https://gitlab.freedesktop.org/drm/intel/issues/5235
[i915#5286]: https://gitlab.freedesktop.org/drm/intel/issues/5286
[i915#5289]: https://gitlab.freedesktop.org/drm/intel/issues/5289
[i915#5354]: https://gitlab.freedesktop.org/drm/intel/issues/5354
[i915#5439]: https://gitlab.freedesktop.org/drm/intel/issues/5439
[i915#5460]: https://gitlab.freedesktop.org/drm/intel/issues/5460
[i915#5465]: https://gitlab.freedesktop.org/drm/intel/issues/5465
[i915#5784]: https://gitlab.freedesktop.org/drm/intel/issues/5784
[i915#5793]: https://gitlab.freedesktop.org/drm/intel/issues/5793
[i915#5882]: https://gitlab.freedesktop.org/drm/intel/issues/5882
[i915#6095]: https://gitlab.freedesktop.org/drm/intel/issues/6095
[i915#6187]: https://gitlab.freedesktop.org/drm/intel/issues/6187
[i915#6188]: https://gitlab.freedesktop.org/drm/intel/issues/6188
[i915#6230]: https://gitlab.freedesktop.org/drm/intel/issues/6230
[i915#6268]: https://gitlab.freedesktop.org/drm/intel/issues/6268
[i915#6301]: https://gitlab.freedesktop.org/drm/intel/issues/6301
[i915#6524]: https://gitlab.freedesktop.org/drm/intel/issues/6524
[i915#658]: https://gitlab.freedesktop.org/drm/intel/issues/658
[i915#6621]: https://gitlab.freedesktop.org/drm/intel/issues/6621
[i915#6768]: https://gitlab.freedesktop.org/drm/intel/issues/6768
[i915#6805]: https://gitlab.freedesktop.org/drm/intel/issues/6805
[i915#6880]: https://gitlab.freedesktop.org/drm/intel/issues/6880
[i915#7069]: https://gitlab.freedesktop.org/drm/intel/issues/7069
[i915#7118]: https://gitlab.freedesktop.org/drm/intel/issues/7118
[i915#7356]: https://gitlab.freedesktop.org/drm/intel/issues/7356
[i915#7387]: https://gitlab.freedesktop.org/drm/intel/issues/7387
[i915#7484]: https://gitlab.freedesktop.org/drm/intel/issues/7484
[i915#7697]: https://gitlab.freedesktop.org/drm/intel/issues/7697
[i915#7711]: https://gitlab.freedesktop.org/drm/intel/issues/7711
[i915#7742]: https://gitlab.freedesktop.org/drm/intel/issues/7742
[i915#7828]: https://gitlab.freedesktop.org/drm/intel/issues/7828
[i915#79]: https://gitlab.freedesktop.org/drm/intel/issues/79
[i915#7975]: https://gitlab.freedesktop.org/drm/intel/issues/7975
[i915#8063]: https://gitlab.freedesktop.org/drm/intel/issues/8063
[i915#8213]: https://gitlab.freedesktop.org/drm/intel/issues/8213
[i915#8228]: https://gitlab.freedesktop.org/drm/intel/issues/8228
[i915#8292]: https://gitlab.freedesktop.org/drm/intel/issues/8292
[i915#8381]: https://gitlab.freedesktop.org/drm/intel/issues/8381
[i915#8411]: https://gitlab.freedesktop.org/drm/intel/issues/8411
[i915#8414]: https://gitlab.freedesktop.org/drm/intel/issues/8414
[i915#8428]: https://gitlab.freedesktop.org/drm/intel/issues/8428
[i915#8489]: https://gitlab.freedesktop.org/drm/intel/issues/8489
[i915#8502]: https://gitlab.freedesktop.org/drm/intel/issues/8502
[i915#8516]: https://gitlab.freedesktop.org/drm/intel/issues/8516
[i915#8521]: https://gitlab.freedesktop.org/drm/intel/issues/8521
[i915#8555]: https://gitlab.freedesktop.org/drm/intel/issues/8555
[i915#8617]: https://gitlab.freedesktop.org/drm/intel/issues/8617
[i915#8668]: https://gitlab.freedesktop.org/drm/intel/issues/8668
[i915#8708]: https://gitlab.freedesktop.org/drm/intel/issues/8708
[i915#8709]: https://gitlab.freedesktop.org/drm/intel/issues/8709
[i915#8724]: https://gitlab.freedesktop.org/drm/intel/issues/8724
[i915#8758]: https://gitlab.freedesktop.org/drm/intel/issues/8758
[i915#8810]: https://gitlab.freedesktop.org/drm/intel/issues/8810
[i915#8812]: https://gitlab.freedesktop.org/drm/intel/issues/8812
[i915#8841]: https://gitlab.freedesktop.org/drm/intel/issues/8841
[i915#8865]: https://gitlab.freedesktop.org/drm/intel/issues/8865
[i915#8925]: https://gitlab.freedesktop.org/drm/intel/issues/8925
[i915#8957]: https://gitlab.freedesktop.org/drm/intel/issues/8957
[i915#8962]: https://gitlab.freedesktop.org/drm/intel/issues/8962
[i915#9051]: https://gitlab.freedesktop.org/drm/intel/issues/9051
[i915#9067]: https://gitlab.freedesktop.org/drm/intel/issues/9067
[i915#9157]: https://gitlab.freedesktop.org/drm/intel/issues/9157
[i915#9196]: https://gitlab.freedesktop.org/drm/intel/issues/9196
[i915#9226]: https://gitlab.freedesktop.org/drm/intel/issues/9226
[i915#9227]: https://gitlab.freedesktop.org/drm/intel/issues/9227
[i915#9261]: https://gitlab.freedesktop.org/drm/intel/issues/9261
[i915#9353]: https://gitlab.freedesktop.org/drm/intel/issues/9353
[i915#9407]: https://gitlab.freedesktop.org/drm/intel/issues/9407
[i915#9412]: https://gitlab.freedesktop.org/drm/intel/issues/9412
[i915#9414]: https://gitlab.freedesktop.org/drm/intel/issues/9414
[i915#9423]: https://gitlab.freedesktop.org/drm/intel/issues/9423
[i915#9424]: https://gitlab.freedesktop.org/drm/intel/issues/9424
[i915#9433]: https://gitlab.freedesktop.org/drm/intel/issues/9433
Build changes
-------------
* CI: CI-20190529 -> None
* IGT: IGT_7517 -> IGTPW_9933
* Piglit: piglit_4509 -> None
CI-20190529: 20190529
CI_DRM_13719: 68e5c10def179bde3bf44bd95d19eea796cbf7a3 @ git://anongit.freedesktop.org/gfx-ci/linux
IGTPW_9933: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/index.html
IGT_7517: 8368e3ad3f9459a8f5cdd24f813ae802c1211029 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_9933/index.html
[-- Attachment #2: Type: text/html, Size: 90803 bytes --]
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 16/17] benchmarks/gem_wsim: for_each_w_step macro
2023-10-06 12:15 ` Bernatowicz, Marcin
@ 2023-10-06 12:39 ` Tvrtko Ursulin
0 siblings, 0 replies; 31+ messages in thread
From: Tvrtko Ursulin @ 2023-10-06 12:39 UTC (permalink / raw)
To: Bernatowicz, Marcin, igt-dev; +Cc: chris.p.wilson
On 06/10/2023 13:15, Bernatowicz, Marcin wrote:
>
>
> On 10/6/2023 1:19 PM, Tvrtko Ursulin wrote:
>>
>> On 05/10/2023 19:57, Marcin Bernatowicz wrote:
>>> for_each_w_step macro to easy traverse workload steps.
>>>
>>> Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
>>> ---
>>> benchmarks/gem_wsim.c | 80 +++++++++++++++++++++++--------------------
>>> 1 file changed, 42 insertions(+), 38 deletions(-)
>>>
>>> diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
>>> index 03a86b39c..e86519614 100644
>>> --- a/benchmarks/gem_wsim.c
>>> +++ b/benchmarks/gem_wsim.c
>>> @@ -238,6 +238,10 @@ struct workload {
>>> #define for_each_ctx(__ctx, __wrk) \
>>> for_each_ctx_ctx_idx(__ctx, __wrk, igt_unique(__ctx_idx))
>>> +#define for_each_w_step(__w_step, __wrk) \
>>> + for (typeof(__wrk->nr_steps) igt_unique(idx) = ({__w_step =
>>> __wrk->steps; 0; }); \
>>> + igt_unique(idx) < __wrk->nr_steps; igt_unique(idx)++,
>>> __w_step++)
>>
>> Hm two igt_unique(idx) are on different lines - how does that work?
>> Macro ends up on single line after the C pre-processor?
>
> At beginning I thought I need a helper macro like __for_each_ctx and a
> second with only one igt_unique,
> but macro when expanded comes out on one line, so it works.
Okay, makes sense that pre-processing works like that now that I think
about it, since line continuation is purely a pre-processor concept it
has to be removed.
It is a bit confusing to read a macro with multiple igt_unique depending
on them not to be unique but shrug. Put a comment if you think it is
warranted.
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Regards,
Tvrtko
>
>>
>> The rest looks good, a nice improvement in readability!
>>
>> Regards,
>>
>> Tvrtko
>>
>>> +
>>> static unsigned int master_prng;
>>> static int verbose = 1;
>>> @@ -1183,14 +1187,14 @@ add_step:
>>> /*
>>> * Check no duplicate working set ids.
>>> */
>>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>>> + for_each_w_step(w, wrk) {
>>> struct w_step *w2;
>>> if (w->type != WORKINGSET)
>>> continue;
>>> - for (j = 0, w2 = wrk->steps; j < wrk->nr_steps; w2++, j++) {
>>> - if (j == i)
>>> + for_each_w_step(w2, wrk) {
>>> + if (w->idx == w2->idx)
>>> continue;
>>> if (w2->type != WORKINGSET)
>>> continue;
>>> @@ -1203,7 +1207,7 @@ add_step:
>>> /*
>>> * Allocate shared working sets.
>>> */
>>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>>> + for_each_w_step(w, wrk) {
>>> if (w->type == WORKINGSET && w->working_set.shared) {
>>> unsigned long total =
>>> allocate_working_set(wrk, &w->working_set);
>>> @@ -1215,7 +1219,7 @@ add_step:
>>> }
>>> wrk->max_working_set_id = -1;
>>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>>> + for_each_w_step(w, wrk) {
>>> if (w->type == WORKINGSET &&
>>> w->working_set.shared &&
>>> w->working_set.id > wrk->max_working_set_id)
>>> @@ -1226,7 +1230,7 @@ add_step:
>>> sizeof(*wrk->working_sets));
>>> igt_assert(wrk->working_sets);
>>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>>> + for_each_w_step(w, wrk) {
>>> if (w->type == WORKINGSET && w->working_set.shared)
>>> wrk->working_sets[w->working_set.id] = &w->working_set;
>>> }
>>> @@ -1238,6 +1242,7 @@ static struct workload *
>>> clone_workload(struct workload *_wrk)
>>> {
>>> struct workload *wrk;
>>> + struct w_step *w;
>>> int i;
>>> wrk = malloc(sizeof(*wrk));
>>> @@ -1265,8 +1270,8 @@ clone_workload(struct workload *_wrk)
>>> }
>>> /* Check if we need a sw sync timeline. */
>>> - for (i = 0; i < wrk->nr_steps; i++) {
>>> - if (wrk->steps[i].type == SW_FENCE) {
>>> + for_each_w_step(w, wrk) {
>>> + if (w->type == SW_FENCE) {
>>> wrk->sync_timeline = sw_sync_timeline_create();
>>> igt_assert(wrk->sync_timeline >= 0);
>>> break;
>>> @@ -1722,13 +1727,13 @@ static void measure_active_set(struct
>>> workload *wrk)
>>> {
>>> unsigned long total = 0, batch_sizes = 0;
>>> struct dep_entry *dep, *deps = NULL;
>>> - unsigned int nr = 0, i;
>>> + unsigned int nr = 0;
>>> struct w_step *w;
>>> if (verbose < 3)
>>> return;
>>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>>> + for_each_w_step(w, wrk) {
>>> if (w->type != BATCH)
>>> continue;
>>> @@ -1781,12 +1786,11 @@ static void allocate_contexts(unsigned int
>>> id, struct workload *wrk)
>>> {
>>> int max_ctx = -1;
>>> struct w_step *w;
>>> - int i;
>>> /*
>>> * Pre-scan workload steps to allocate context list storage.
>>> */
>>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>>> + for_each_w_step(w, wrk) {
>>> int ctx = w->context + 1;
>>> int delta;
>>> @@ -1812,13 +1816,13 @@ static int prepare_contexts(unsigned int id,
>>> struct workload *wrk)
>>> uint32_t share_vm = 0;
>>> struct w_step *w;
>>> struct ctx *ctx, *ctx2;
>>> - unsigned int i, j;
>>> + unsigned int j;
>>> /*
>>> * Transfer over engine map configuration from the workload step.
>>> */
>>> for_each_ctx_ctx_idx(ctx, wrk, ctx_idx) {
>>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>>> + for_each_w_step(w, wrk) {
>>> if (w->context != ctx_idx)
>>> continue;
>>> @@ -1985,12 +1989,11 @@ static void prepare_working_sets(unsigned int
>>> id, struct workload *wrk)
>>> struct working_set **sets;
>>> unsigned long total = 0;
>>> struct w_step *w;
>>> - int i;
>>> /*
>>> * Allocate working sets.
>>> */
>>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>>> + for_each_w_step(w, wrk) {
>>> if (w->type == WORKINGSET && !w->working_set.shared)
>>> total += allocate_working_set(wrk, &w->working_set);
>>> }
>>> @@ -2002,7 +2005,7 @@ static void prepare_working_sets(unsigned int
>>> id, struct workload *wrk)
>>> * Map of working set ids.
>>> */
>>> wrk->max_working_set_id = -1;
>>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>>> + for_each_w_step(w, wrk) {
>>> if (w->type == WORKINGSET &&
>>> w->working_set.id > wrk->max_working_set_id)
>>> wrk->max_working_set_id = w->working_set.id;
>>> @@ -2013,7 +2016,7 @@ static void prepare_working_sets(unsigned int
>>> id, struct workload *wrk)
>>> sizeof(*wrk->working_sets));
>>> igt_assert(wrk->working_sets);
>>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>>> + for_each_w_step(w, wrk) {
>>> struct working_set *set;
>>> if (w->type != WORKINGSET)
>>> @@ -2039,7 +2042,6 @@ static void prepare_working_sets(unsigned int
>>> id, struct workload *wrk)
>>> static int prepare_workload(unsigned int id, struct workload *wrk)
>>> {
>>> struct w_step *w;
>>> - int i, j;
>>> int ret = 0;
>>> wrk->id = id;
>>> @@ -2054,23 +2056,22 @@ static int prepare_workload(unsigned int id,
>>> struct workload *wrk)
>>> return ret;
>>> /* Record default preemption. */
>>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>>> + for_each_w_step(w, wrk)
>>> if (w->type == BATCH)
>>> w->preempt_us = 100;
>>> - }
>>> /*
>>> * Scan for contexts with modified preemption config and record
>>> their
>>> * preemption period for the following steps belonging to the same
>>> * context.
>>> */
>>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>>> + for_each_w_step(w, wrk) {
>>> struct w_step *w2;
>>> if (w->type != PREEMPTION)
>>> continue;
>>> - for (j = i + 1; j < wrk->nr_steps; j++) {
>>> + for (int j = w->idx + 1; j < wrk->nr_steps; j++) {
>>> w2 = &wrk->steps[j];
>>> if (w2->context != w->context)
>>> @@ -2087,7 +2088,7 @@ static int prepare_workload(unsigned int id,
>>> struct workload *wrk)
>>> /*
>>> * Scan for SSEU control steps.
>>> */
>>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>>> + for_each_w_step(w, wrk) {
>>> if (w->type == SSEU) {
>>> get_device_sseu();
>>> break;
>>> @@ -2099,7 +2100,7 @@ static int prepare_workload(unsigned int id,
>>> struct workload *wrk)
>>> /*
>>> * Allocate batch buffers.
>>> */
>>> - for (i = 0, w = wrk->steps; i < wrk->nr_steps; i++, w++) {
>>> + for_each_w_step(w, wrk) {
>>> if (w->type != BATCH)
>>> continue;
>>> @@ -2223,7 +2224,6 @@ static void *run_workload(void *data)
>>> int qd_throttle = -1;
>>> int count, missed = 0;
>>> unsigned long time_tot = 0, time_min = ULONG_MAX, time_max = 0;
>>> - int i;
>>> clock_gettime(CLOCK_MONOTONIC, &t_start);
>>> @@ -2233,11 +2233,13 @@ static void *run_workload(void *data)
>>> clock_gettime(CLOCK_MONOTONIC, &repeat_start);
>>> - for (i = 0, w = wrk->steps; wrk->run && (i < wrk->nr_steps);
>>> - i++, w++) {
>>> + for_each_w_step(w, wrk) {
>>> enum intel_engine_id engine = w->engine;
>>> int do_sleep = 0;
>>> + if (!wrk->run)
>>> + break;
>>> +
>>> if (w->type == DELAY) {
>>> do_sleep = w->delay;
>>> } else if (w->type == PERIOD) {
>>> @@ -2256,13 +2258,13 @@ static void *run_workload(void *data)
>>> missed++;
>>> if (verbose > 2)
>>> printf("%u: Dropped period @ %u/%u (%dus
>>> late)!\n",
>>> - wrk->id, count, i, do_sleep);
>>> + wrk->id, count, w->idx, do_sleep);
>>> continue;
>>> }
>>> } else if (w->type == SYNC) {
>>> - unsigned int s_idx = i + w->target;
>>> + unsigned int s_idx = w->idx + w->target;
>>> - igt_assert(s_idx >= 0 && s_idx < i);
>>> + igt_assert(s_idx >= 0 && s_idx < w->idx);
>>> igt_assert(wrk->steps[s_idx].type == BATCH);
>>> w_step_sync(&wrk->steps[s_idx]);
>>> continue;
>>> @@ -2283,7 +2285,7 @@ static void *run_workload(void *data)
>>> int tgt = w->idx + w->target;
>>> int inc;
>>> - igt_assert(tgt >= 0 && tgt < i);
>>> + igt_assert(tgt >= 0 && tgt < w->idx);
>>> igt_assert(wrk->steps[tgt].type == SW_FENCE);
>>> cur_seqno += wrk->steps[tgt].idx;
>>> inc = cur_seqno - wrk->sync_seqno;
>>> @@ -2303,9 +2305,9 @@ static void *run_workload(void *data)
>>> }
>>> continue;
>>> } else if (w->type == TERMINATE) {
>>> - unsigned int t_idx = i + w->target;
>>> + unsigned int t_idx = w->idx + w->target;
>>> - igt_assert(t_idx >= 0 && t_idx < i);
>>> + igt_assert(t_idx >= 0 && t_idx < w->idx);
>>> igt_assert(wrk->steps[t_idx].type == BATCH);
>>> igt_assert(wrk->steps[t_idx].duration.unbound);
>>> @@ -2339,7 +2341,7 @@ static void *run_workload(void *data)
>>> sync_deps(wrk, w);
>>> if (throttle > 0)
>>> - w_sync_to(wrk, w, i - throttle);
>>> + w_sync_to(wrk, w, w->idx - throttle);
>>> do_eb(wrk, w, engine);
>>> @@ -2382,8 +2384,10 @@ static void *run_workload(void *data)
>>> }
>>> /* Cleanup all fences instantiated in this iteration. */
>>> - for (i = 0, w = wrk->steps; wrk->run && (i < wrk->nr_steps);
>>> - i++, w++) {
>>> + for_each_w_step(w, wrk) {
>>> + if (!wrk->run)
>>> + break;
>>> +
>>> if (w->emit_fence > 0) {
>>> close(w->emit_fence);
>>> w->emit_fence = -1;
>>> @@ -2391,7 +2395,7 @@ static void *run_workload(void *data)
>>> }
>>> }
>>> - for (i = 0; i < NUM_ENGINES; i++) {
>>> + for (int i = 0; i < NUM_ENGINES; i++) {
>>> if (!wrk->nrequest[i])
>>> continue;
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 17/17] benchmarks/gem_wsim: added basic xe support
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 17/17] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
@ 2023-10-06 14:12 ` Tvrtko Ursulin
2023-10-06 15:43 ` Bernatowicz, Marcin
0 siblings, 1 reply; 31+ messages in thread
From: Tvrtko Ursulin @ 2023-10-06 14:12 UTC (permalink / raw)
To: Marcin Bernatowicz, igt-dev; +Cc: chris.p.wilson
On 05/10/2023 19:57, Marcin Bernatowicz wrote:
> Added basic xe support. Single binary handles both i915 and Xe devices.
>
> Some functionality is still missing: working sets, bonding.
>
> The tool is handy for scheduling tests, we find it useful to verify vGPU
> profiles defining different execution quantum/preemption timeout
> settings.
>
> There is also some rationale for the tool in following thread:
> https://lore.kernel.org/dri-devel/a443495f-5d1b-52e1-9b2f-80167deb6d57@linux.intel.com/
>
> With this patch it should be possible to run following on xe device:
>
> gem_wsim -w benchmarks/wsim/media_load_balance_fhd26u7.wsim -c 36 -r 600
>
> Best with drm debug logs disabled:
>
> echo 0 > /sys/module/drm/parameters/debug
>
> v2: minimizing divergence - same workload syntax for both drivers,
> so most existing examples should run on xe unmodified (Tvrtko)
> This version creates one common VM per workload.
> Explicit VM management, compute mode will come in next patchset.
>
> v3:
> - use calloc in parse_workload for struct workload,
> to allow cleanups in fini_workload
> - grouped xe specific fields (Tvrtko)
> - moved is_xe boolean next to fd (Tvrtko)
> - use xe_ prefix for Xe specific things (Tvrtko)
> - left throttling untouched (Tvrtko)
> - parse errors vs silent skips on not implemented steps (Tvrtko)
> - need to think on better engine handling in next version
> - add 'Xe and i915 differences' section to README (Tvrtko)
> for now no data dependency implemented, left -1 <=> f-1
> to not modify examples (maybe too optimistic assumption?)
>
> v4:
> - corrected engines mappings for xe (Tvrtko)
> "M.1.VCS,B.1,1.DEFAULT.1000.0.1" should use VCS
> - verified engines selection works on MTL (Tvrtko)
> - prevent misuse combinations of fence and implicit data deps (Tvrtko)
> ex. "f,1.DEFAULT.1000.-1.0" should fail
> "f,1.DEFAULT.1000.f-1.0" is valid
> - corrected error messages (Tvrtko)
> - moved wsim_err up to be accessible from parse_dependencies
> - missing xe_device_put (Tvrtko)
> - left fini_workload cleanup for separate patch
> - README updates
>
> Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
> ---
> benchmarks/gem_wsim.c | 487 +++++++++++++++++++++++++++++++++++++++--
> benchmarks/wsim/README | 23 +-
> 2 files changed, 483 insertions(+), 27 deletions(-)
>
> diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
> index e86519614..ecbeb9175 100644
> --- a/benchmarks/gem_wsim.c
> +++ b/benchmarks/gem_wsim.c
> @@ -62,6 +62,12 @@
> #include "i915/gem_engine_topology.h"
> #include "i915/gem_mman.h"
>
> +#include "igt_syncobj.h"
> +#include "intel_allocator.h"
> +#include "xe_drm.h"
> +#include "xe/xe_ioctl.h"
> +#include "xe/xe_spin.h"
> +
> enum intel_engine_id {
> DEFAULT,
> RCS,
> @@ -185,10 +191,31 @@ struct w_step {
> struct drm_i915_gem_relocation_entry reloc[3];
> uint32_t *bb_duration;
> } i915;
> + struct {
> + struct drm_xe_exec exec;
> + struct {
> + struct xe_spin spin;
> + uint64_t vm_sync;
> + uint64_t exec_sync;
> + } *data;
> + struct drm_xe_sync *syncs;
> + } xe;
> };
> uint32_t bb_handle;
> };
>
> +struct xe_vm {
> + uint32_t id;
> + bool compute_mode;
> + uint64_t ahnd;
> +};
> +
> +struct xe_exec_queue {
> + uint32_t id;
> + unsigned int nr_hwes;
> + struct drm_xe_engine_class_instance *hwe_list;
> +};
> +
> struct ctx {
> uint32_t id;
> int priority;
> @@ -198,6 +225,13 @@ struct ctx {
> struct bond *bonds;
> bool load_balance;
> uint64_t sseu;
> + struct {
> + /* reference to vm */
> + struct xe_vm *vm;
> + /* exec queues */
> + unsigned int nr_queues;
> + struct xe_exec_queue *queue_list;
> + } xe;
> };
>
> struct workload {
> @@ -221,6 +255,11 @@ struct workload {
> unsigned int nr_ctxs;
> struct ctx *ctx_list;
>
> + struct {
> + unsigned int nr_vms;
> + struct xe_vm *vm_list;
> + } xe;
> +
> struct working_set **working_sets; /* array indexed by set id */
> int max_working_set_id;
>
> @@ -246,6 +285,7 @@ static unsigned int master_prng;
>
> static int verbose = 1;
> static int fd;
> +static bool is_xe;
> static struct drm_i915_gem_context_param_sseu device_sseu = {
> .slice_mask = -1 /* Force read on first use. */
> };
> @@ -266,7 +306,10 @@ static const char *ring_str_map[NUM_ENGINES] = {
>
> static void w_step_sync(struct w_step *w)
> {
> - gem_sync(fd, w->i915.obj[0].handle);
> + if (is_xe)
> + igt_assert(syncobj_wait(fd, &w->xe.syncs[0].handle, 1, INT64_MAX, 0, NULL));
> + else
> + gem_sync(fd, w->i915.obj[0].handle);
> }
>
> static int read_timestamp_frequency(int i915)
> @@ -354,6 +397,19 @@ parse_working_set_deps(struct workload *wrk,
> return 0;
> }
>
> +static void __attribute__((format(printf, 1, 2)))
> +wsim_err(const char *fmt, ...)
> +{
> + va_list ap;
> +
> + if (!verbose)
> + return;
> +
> + va_start(ap, fmt);
> + vfprintf(stderr, fmt, ap);
> + va_end(ap);
> +}
> +
> static int
> parse_dependency(unsigned int nr_steps, struct w_step *w, char *str)
> {
> @@ -374,11 +430,18 @@ parse_dependency(unsigned int nr_steps, struct w_step *w, char *str)
>
> break;
> case 's':
> + /* no submit fence in xe */
> + if (is_xe) {
> + wsim_err("Submit fences are not supported with xe\n");
> + return -1;
> + }
> submit_fence = true;
> /* Fall-through. */
> case 'f':
> - /* Multiple fences not yet supported. */
> - igt_assert_eq(w->fence_deps.nr, 0);
> + /* xe supports multiple fences */
> + if (!is_xe)
> + /* Multiple fences not yet supported. */
> + igt_assert_eq(w->fence_deps.nr, 0);
>
> entry.target = atoi(++str);
> if (entry.target > 0 || ((int)nr_steps + entry.target) < 0)
> @@ -448,19 +511,6 @@ out:
> return ret;
> }
>
> -static void __attribute__((format(printf, 1, 2)))
> -wsim_err(const char *fmt, ...)
> -{
> - va_list ap;
> -
> - if (!verbose)
> - return;
> -
> - va_start(ap, fmt);
> - vfprintf(stderr, fmt, ap);
> - va_end(ap);
> -}
> -
> #define check_arg(cond, fmt, ...) \
> { \
> if (cond) { \
> @@ -488,7 +538,17 @@ static struct intel_engine_data *query_engines(void)
> if (engines.nengines)
> return &engines;
>
> - engines = intel_engine_list_of_physical(fd);
> + if (is_xe) {
> + struct drm_xe_engine_class_instance *hwe;
> +
> + xe_for_each_hw_engine(fd, hwe) {
> + engines.engines[engines.nengines].class = hwe->engine_class;
> + engines.engines[engines.nengines].instance = hwe->engine_instance;
> + engines.nengines++;
> + }
> + } else
> + engines = intel_engine_list_of_physical(fd);
> +
> igt_assert(engines.nengines);
> return &engines;
> }
> @@ -581,6 +641,46 @@ get_engine(enum intel_engine_id engine)
> return ci;
> }
>
> +static struct drm_xe_engine_class_instance
> +xe_get_engine(enum intel_engine_id engine)
> +{
> + struct drm_xe_engine_class_instance hwe = {}, *hwe1;
> + bool found_physical = false;
> +
> + switch (engine) {
> + case RCS:
> + hwe.engine_class = DRM_XE_ENGINE_CLASS_RENDER;
> + break;
> + case BCS:
> + hwe.engine_class = DRM_XE_ENGINE_CLASS_COPY;
> + break;
> + case VCS1:
> + hwe.engine_class = DRM_XE_ENGINE_CLASS_VIDEO_DECODE;
> + break;
> + case VCS2:
> + hwe.engine_class = DRM_XE_ENGINE_CLASS_VIDEO_DECODE;
> + hwe.engine_instance = 1;
> + break;
> + case VECS:
> + hwe.engine_class = DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE;
> + break;
> + default:
> + igt_assert(0);
> + };
> +
> + xe_for_each_hw_engine(fd, hwe1) {
> + if (hwe.engine_class == hwe1->engine_class &&
> + hwe.engine_instance == hwe1->engine_instance) {
> + hwe = *hwe1;
> + found_physical = true;
> + break;
> + }
> + }
> +
> + igt_assert(found_physical);
> + return hwe;
> +}
> +
> static int parse_engine_map(struct w_step *step, const char *_str)
> {
> char *token, *tctx = NULL, *tstart = (char *)_str;
> @@ -855,6 +955,12 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
> } else if (!strcmp(field, "P")) {
> unsigned int nr = 0;
>
> + if (is_xe) {
> + wsim_err("Priority step is not implemented with xe yet.\n");
> + free(token);
> + return NULL;
> + }
> +
> while ((field = strtok_r(fstart, ".", &fctx))) {
> tmp = atoi(field);
> check_arg(nr == 0 && tmp <= 0,
> @@ -881,6 +987,12 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
> } else if (!strcmp(field, "S")) {
> unsigned int nr = 0;
>
> + if (is_xe) {
> + wsim_err("SSEU step is not implemented with xe yet.\n");
> + free(token);
> + return NULL;
> + }
> +
> while ((field = strtok_r(fstart, ".", &fctx))) {
> tmp = atoi(field);
> check_arg(tmp <= 0 && nr == 0,
> @@ -994,6 +1106,12 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
> } else if (!strcmp(field, "b")) {
> unsigned int nr = 0;
>
> + if (is_xe) {
> + wsim_err("Bonding is not implemented with xe yet.\n");
> + free(token);
> + return NULL;
> + }
> +
> while ((field = strtok_r(fstart, ".", &fctx))) {
> check_arg(nr > 2,
> "Invalid bond format at step %u!\n",
> @@ -1028,6 +1146,12 @@ parse_workload(struct w_arg *arg, unsigned int flags, double scale_dur,
> } else if (!strcmp(field, "w") || !strcmp(field, "W")) {
> unsigned int nr = 0;
>
> + if (is_xe) {
> + wsim_err("Working sets are not implemented with xe yet.\n");
> + free(token);
> + return NULL;
> + }
> +
> step.working_set.shared = field[0] == 'W';
>
> while ((field = strtok_r(fstart, ".", &fctx))) {
> @@ -1484,6 +1608,31 @@ get_ctxid(struct workload *wrk, struct w_step *w)
> return wrk->ctx_list[w->context].id;
> }
>
> +static struct xe_exec_queue *
> +xe_get_eq(struct workload *wrk, const struct w_step *w)
> +{
> + struct ctx *ctx = __get_ctx(wrk, w);
> + struct xe_exec_queue *eq;
> +
> + if (ctx->engine_map) {
> + igt_assert_eq(ctx->xe.nr_queues, 1);
> + igt_assert(ctx->xe.queue_list[0].id);
> + eq = &ctx->xe.queue_list[0];
> + } else {
> + igt_assert(w->engine >= 0 && w->engine < ctx->xe.nr_queues);
> + igt_assert(ctx->xe.queue_list[w->engine].id);
> + eq = &ctx->xe.queue_list[w->engine];
> + }
> +
> + return eq;
> +}
> +
> +static struct xe_vm *
> +xe_get_vm(struct workload *wrk, const struct w_step *w)
> +{
> + return wrk->xe.vm_list;
> +}
> +
> static uint32_t alloc_bo(int i915, unsigned long size)
> {
> return gem_create(i915, size);
> @@ -1557,6 +1706,71 @@ alloc_step_batch(struct workload *wrk, struct w_step *w)
> #endif
> }
>
> +static void
> +xe_alloc_step_batch(struct workload *wrk, struct w_step *w)
> +{
> + struct xe_vm *vm = xe_get_vm(wrk, w);
> + struct xe_exec_queue *eq = xe_get_eq(wrk, w);
> + struct dep_entry *dep;
> + int i;
> +
> + w->bb_handle = xe_bo_create_flags(fd, vm->id, PAGE_SIZE,
> + visible_vram_if_possible(fd, eq->hwe_list[0].gt_id));
> + w->xe.data = xe_bo_map(fd, w->bb_handle, PAGE_SIZE);
> + w->xe.exec.address =
> + intel_allocator_alloc_with_strategy(vm->ahnd, w->bb_handle, PAGE_SIZE,
> + 0, ALLOC_STRATEGY_LOW_TO_HIGH);
> + xe_vm_bind_sync(fd, vm->id, w->bb_handle, 0, w->xe.exec.address, PAGE_SIZE);
> + xe_spin_init_opts(&w->xe.data->spin, .addr = w->xe.exec.address,
> + .preempt = (w->preempt_us > 0),
> + .ctx_ticks = duration_to_ctx_ticks(fd, eq->hwe_list[0].gt_id,
> + 1000LL * get_duration(wrk, w)));
> + w->xe.exec.exec_queue_id = eq->id;
> + w->xe.exec.num_batch_buffer = 1;
> + /* always at least one out fence */
> + w->xe.exec.num_syncs = 1;
> + /* count syncs */
> + for_each_dep(dep, w->data_deps) {
> + int dep_idx = w->idx + dep->target;
> +
> + igt_assert(dep_idx >= 0 && dep_idx < w->idx);
> + igt_assert(wrk->steps[dep_idx].type == BATCH);
> +
> + w->xe.exec.num_syncs++;
> + }
> + for_each_dep(dep, w->fence_deps) {
> + int dep_idx = w->idx + dep->target;
> +
> + igt_assert(dep_idx >= 0 && dep_idx < w->idx);
> + igt_assert(wrk->steps[dep_idx].type == SW_FENCE ||
> + wrk->steps[dep_idx].type == BATCH);
> +
> + w->xe.exec.num_syncs++;
> + }
> + w->xe.syncs = calloc(w->xe.exec.num_syncs, sizeof(*w->xe.syncs));
> + /* fill syncs */
> + i = 0;
> + /* out fence */
> + w->xe.syncs[i].handle = syncobj_create(fd, 0);
> + w->xe.syncs[i++].flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL;
> + /* in fence(s) */
> + for_each_dep(dep, w->data_deps) {
> + int dep_idx = w->idx + dep->target;
> +
> + igt_assert(wrk->steps[dep_idx].xe.syncs && wrk->steps[dep_idx].xe.syncs[0].handle);
> + w->xe.syncs[i].handle = wrk->steps[dep_idx].xe.syncs[0].handle;
> + w->xe.syncs[i++].flags = DRM_XE_SYNC_SYNCOBJ;
> + }
> + for_each_dep(dep, w->fence_deps) {
> + int dep_idx = w->idx + dep->target;
> +
> + igt_assert(wrk->steps[dep_idx].xe.syncs && wrk->steps[dep_idx].xe.syncs[0].handle);
> + w->xe.syncs[i].handle = wrk->steps[dep_idx].xe.syncs[0].handle;
> + w->xe.syncs[i++].flags = DRM_XE_SYNC_SYNCOBJ;
> + }
> + w->xe.exec.syncs = to_user_pointer(w->xe.syncs);
> +}
> +
> static bool set_priority(uint32_t ctx_id, int prio)
> {
> struct drm_i915_gem_context_param param = {
> @@ -1739,6 +1953,9 @@ static void measure_active_set(struct workload *wrk)
>
> batch_sizes += 4096;
>
> + if (is_xe)
> + continue;
I guess you re-use data_deps for something with xe so you can't just let
it run the loop here and find no data deps, resulting in the same zero
result?
> +
> for_each_dep(dep, w->data_deps) {
> struct dep_entry _dep = *dep;
>
> @@ -1782,6 +1999,31 @@ static void measure_active_set(struct workload *wrk)
>
> #define alloca0(sz) ({ size_t sz__ = (sz); memset(alloca(sz__), 0, sz__); })
>
> +static void xe_vm_create_(struct xe_vm *vm)
> +{
> + uint32_t flags = 0;
> +
> + if (vm->compute_mode)
> + flags |= DRM_XE_VM_CREATE_ASYNC_BIND_OPS |
> + DRM_XE_VM_CREATE_COMPUTE_MODE;
> +
> + vm->id = xe_vm_create(fd, flags, 0);
> +}
> +
> +static void xe_exec_queue_create_(struct ctx *ctx, struct xe_exec_queue *eq)
> +{
> + struct drm_xe_exec_queue_create create = {
> + .vm_id = ctx->xe.vm->id,
> + .width = 1,
> + .num_placements = eq->nr_hwes,
> + .instances = to_user_pointer(eq->hwe_list),
> + };
> +
> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC_QUEUE_CREATE, &create), 0);
> +
> + eq->id = create.exec_queue_id;
> +}
> +
> static void allocate_contexts(unsigned int id, struct workload *wrk)
> {
> int max_ctx = -1;
> @@ -1984,6 +2226,140 @@ static int prepare_contexts(unsigned int id, struct workload *wrk)
> return 0;
> }
>
> +static int xe_prepare_contexts(unsigned int id, struct workload *wrk)
> +{
> + struct xe_exec_queue *eq;
> + struct w_step *w;
> + struct ctx *ctx;
> + unsigned int i;
> +
> + /* shortcut, create one vm */
> + wrk->xe.nr_vms = 1;
> + wrk->xe.vm_list = calloc(wrk->xe.nr_vms, sizeof(struct xe_vm));
> + wrk->xe.vm_list->compute_mode = false;
> + xe_vm_create_(wrk->xe.vm_list);
> + wrk->xe.vm_list->ahnd = intel_allocator_open(fd, wrk->xe.vm_list->id,
> + INTEL_ALLOCATOR_RELOC);
> +
> + for_each_ctx_ctx_idx(ctx, wrk, ctx_idx) {
> + /* link with vm */
> + ctx->xe.vm = wrk->xe.vm_list;
> + for_each_w_step(w, wrk) {
> + if (w->context != ctx_idx)
> + continue;
> + if (w->type == ENGINE_MAP) {
> + ctx->engine_map = w->engine_map;
> + ctx->engine_map_count = w->engine_map_count;
> + } else if (w->type == LOAD_BALANCE) {
> + if (!ctx->engine_map) {
> + wsim_err("Load balancing needs an engine map!\n");
> + return 1;
> + }
> + if (intel_gen(intel_get_drm_devid(fd)) < 11) {
> + wsim_err("Load balancing needs relative mmio support, gen11+!\n");
> + return 1;
> + }
If xe supports gen12+ then you can drop this?
> + ctx->load_balance = w->load_balance;
> + }
> + }
> +
> + /* create exec queue for each referenced engine */
> + if (ctx->engine_map) {
> + ctx->xe.nr_queues = 1;
> + ctx->xe.queue_list = calloc(ctx->xe.nr_queues, sizeof(*ctx->xe.queue_list));
> + igt_assert(ctx->xe.queue_list);
> + eq = &ctx->xe.queue_list[ctx->xe.nr_queues - 1];
> + eq->nr_hwes = ctx->engine_map_count;
> + eq->hwe_list = calloc(eq->nr_hwes, sizeof(*eq->hwe_list));
> + for (i = 0; i < eq->nr_hwes; ++i) {
> + eq->hwe_list[i] = xe_get_engine(ctx->engine_map[i]);
> +
> + /* check no mixing classes and no duplicates */
> + for (int j = 0; j < i; ++j) {
> + if (eq->hwe_list[j].engine_class !=
> + eq->hwe_list[i].engine_class) {
> + free(eq->hwe_list);
> + eq->nr_hwes = 0;
> + wsim_err("Mixing of engine class not supported!\n");
> + return 1;
> + }
> +
> + if (eq->hwe_list[j].engine_instance ==
> + eq->hwe_list[i].engine_instance) {
> + free(eq->hwe_list);
> + eq->nr_hwes = 0;
> + wsim_err("Duplicate engine entry!\n");
> + return 1;
> + }
> + }
> +
> + if (verbose > 3)
> + printf("%u ctx[%d] %s [%u:%u:%u]\n",
> + id, ctx_idx, ring_str_map[ctx->engine_map[i]],
> + eq->hwe_list[i].engine_class,
> + eq->hwe_list[i].engine_instance,
> + eq->hwe_list[i].gt_id);
> + }
> +
> + xe_exec_queue_create_(ctx, eq);
> + } else {
> + int engine_classes[NUM_ENGINES] = {};
> +
> + ctx->xe.nr_queues = NUM_ENGINES;
> + ctx->xe.queue_list = calloc(ctx->xe.nr_queues, sizeof(*ctx->xe.queue_list));
> +
> + for_each_w_step(w, wrk) {
> + if (w->context != ctx_idx)
> + continue;
> + if (w->type == BATCH)
> + engine_classes[w->engine]++;
> + }
> +
> + for (i = 0; i < NUM_ENGINES; i++) {
> + if (engine_classes[i]) {
> + eq = &ctx->xe.queue_list[i];
> + eq->nr_hwes = 1;
> + eq->hwe_list = calloc(1, sizeof(*eq->hwe_list));
> +
> + if (i == DEFAULT) {
> + struct drm_xe_engine_class_instance *hwe;
> +
> + /* select first available engine */
With no engine map you probably want to ensure this is rcs0 to ensure
cross driver workload compatibility. Maybe xe_for_each_hw_engine already
works like that, I don't know.
> + xe_for_each_hw_engine(fd, hwe) {
> + eq->hwe_list[0] = *hwe;
> + break;
> + }
> + } else if (i == VCS) {
> + eq->hwe_list[0] = xe_get_engine(VCS1);
> + } else {
> + eq->hwe_list[0] = xe_get_engine(i);
> + }
> +
> + if (verbose > 3)
> + printf("%u ctx[%d] %s [%u:%u:%u]\n",
> + id, ctx_idx, ring_str_map[i],
> + eq->hwe_list[0].engine_class,
> + eq->hwe_list[0].engine_instance,
> + eq->hwe_list[0].gt_id);
> +
> + xe_exec_queue_create_(ctx, eq);
> + }
> + engine_classes[i] = 0;
> + }
> + }
> + }
> +
> + /* create syncobjs for SW_FENCE */
> + for_each_w_step(w, wrk)
> + if (w->type == SW_FENCE) {
> + w->xe.syncs = calloc(1, sizeof(struct drm_xe_sync));
> + w->xe.syncs[0].handle = syncobj_create(fd, 0);
> + w->xe.syncs[0].flags = DRM_XE_SYNC_SYNCOBJ;
> + }
> +
> + return 0;
> +}
> +
> static void prepare_working_sets(unsigned int id, struct workload *wrk)
> {
> struct working_set **sets;
> @@ -2051,7 +2427,11 @@ static int prepare_workload(unsigned int id, struct workload *wrk)
>
> allocate_contexts(id, wrk);
>
> - ret = prepare_contexts(id, wrk);
> + if (is_xe)
> + ret = xe_prepare_contexts(id, wrk);
> + else
> + ret = prepare_contexts(id, wrk);
> +
> if (ret)
> return ret;
>
> @@ -2104,7 +2484,10 @@ static int prepare_workload(unsigned int id, struct workload *wrk)
> if (w->type != BATCH)
> continue;
>
> - alloc_step_batch(wrk, w);
> + if (is_xe)
> + xe_alloc_step_batch(wrk, w);
> + else
> + alloc_step_batch(wrk, w);
> }
>
> measure_active_set(wrk);
> @@ -2154,6 +2537,24 @@ static void w_sync_to(struct workload *wrk, struct w_step *w, int target)
> w_step_sync(&wrk->steps[target]);
> }
>
> +static void do_xe_exec(struct workload *wrk, struct w_step *w)
> +{
> + struct xe_exec_queue *eq = xe_get_eq(wrk, w);
> +
> + igt_assert(w->emit_fence <= 0);
> + if (w->emit_fence == -1)
> + syncobj_reset(fd, &w->xe.syncs[0].handle, 1);
> +
> + /* update duration if random */
> + if (w->duration.max != w->duration.min)
> + xe_spin_init_opts(&w->xe.data->spin,
> + .addr = w->xe.exec.address,
> + .preempt = (w->preempt_us > 0),
> + .ctx_ticks = duration_to_ctx_ticks(fd, eq->hwe_list[0].gt_id,
> + 1000LL * get_duration(wrk, w)));
> + xe_exec(fd, &w->xe.exec);
> +}
> +
> static void
> do_eb(struct workload *wrk, struct w_step *w, enum intel_engine_id engine)
> {
> @@ -2280,6 +2681,10 @@ static void *run_workload(void *data)
> sw_sync_timeline_create_fence(wrk->sync_timeline,
> cur_seqno + w->idx);
> igt_assert(w->emit_fence > 0);
> + if (is_xe)
> + /* Convert sync file to syncobj */
> + syncobj_import_sync_file(fd, w->xe.syncs[0].handle,
> + w->emit_fence);
> continue;
> } else if (w->type == SW_FENCE_SIGNAL) {
> int tgt = w->idx + w->target;
> @@ -2311,7 +2716,10 @@ static void *run_workload(void *data)
> igt_assert(wrk->steps[t_idx].type == BATCH);
> igt_assert(wrk->steps[t_idx].duration.unbound);
>
> - *wrk->steps[t_idx].i915.bb_duration = 0xffffffff;
> + if (is_xe)
> + xe_spin_end(&wrk->steps[t_idx].xe.data->spin);
> + else
> + *wrk->steps[t_idx].i915.bb_duration = 0xffffffff;
> __sync_synchronize();
> continue;
> } else if (w->type == SSEU) {
> @@ -2343,7 +2751,10 @@ static void *run_workload(void *data)
> if (throttle > 0)
> w_sync_to(wrk, w, w->idx - throttle);
>
> - do_eb(wrk, w, engine);
> + if (is_xe)
> + do_xe_exec(wrk, w);
> + else
> + do_eb(wrk, w, engine);
>
> if (w->request != -1) {
> igt_list_del(&w->rq_link);
> @@ -2389,6 +2800,10 @@ static void *run_workload(void *data)
> break;
>
> if (w->emit_fence > 0) {
> + if (is_xe) {
> + igt_assert(w->type == SW_FENCE);
> + syncobj_reset(fd, &w->xe.syncs[0].handle, 1);
> + }
> close(w->emit_fence);
> w->emit_fence = -1;
> }
> @@ -2403,6 +2818,23 @@ static void *run_workload(void *data)
> w_step_sync(w);
> }
>
> + if (is_xe) {
> + for_each_w_step(w, wrk) {
> + if (w->type == BATCH) {
> + w_step_sync(w);
> + syncobj_destroy(fd, w->xe.syncs[0].handle);
> + free(w->xe.syncs);
> + xe_vm_unbind_sync(fd, xe_get_vm(wrk, w)->id, 0, w->xe.exec.address,
> + PAGE_SIZE);
> + gem_munmap(w->xe.data, PAGE_SIZE);
> + gem_close(fd, w->bb_handle);
> + } else if (w->type == SW_FENCE) {
> + syncobj_destroy(fd, w->xe.syncs[0].handle);
> + free(w->xe.syncs);
> + }
> + }
> + }
> +
> clock_gettime(CLOCK_MONOTONIC, &t_end);
>
> if (wrk->print_stats) {
> @@ -2629,8 +3061,12 @@ int main(int argc, char **argv)
> ret = igt_device_find_first_i915_discrete_card(&card);
> if (!ret)
> ret = igt_device_find_integrated_card(&card);
> + if (!ret)
> + ret = igt_device_find_first_xe_discrete_card(&card);
> + if (!ret)
> + ret = igt_device_find_xe_integrated_card(&card);
> if (!ret) {
> - wsim_err("No device filter specified and no i915 devices found!\n");
> + wsim_err("No device filter specified and no intel devices found!\n");
> return EXIT_FAILURE;
> }
> }
> @@ -2653,6 +3089,10 @@ int main(int argc, char **argv)
> if (verbose > 1)
> printf("Using device %s\n", drm_dev);
>
> + is_xe = is_xe_device(fd);
> + if (is_xe)
> + xe_device_get(fd);
> +
> if (!nr_w_args) {
> wsim_err("No workload descriptor(s)!\n");
> goto err;
> @@ -2772,5 +3212,8 @@ int main(int argc, char **argv)
> out:
> exitcode = EXIT_SUCCESS;
> err:
> + if (is_xe)
> + xe_device_put(fd);
> +
> return exitcode;
> }
> diff --git a/benchmarks/wsim/README b/benchmarks/wsim/README
> index d4f3dd8ae..e43813335 100644
> --- a/benchmarks/wsim/README
> +++ b/benchmarks/wsim/README
> @@ -88,6 +88,19 @@ Batch durations can also be specified as infinite by using the '*' in the
> duration field. Such batches must be ended by the terminate command ('T')
> otherwise they will cause a GPU hang to be reported.
>
> +Xe and i915 differences
> +------------------------
> +
> +There are differences between Xe and i915, like not allowing a BO list to
> +be passed to an exec (and create implicit syncs). For more details see:
> +https://gitlab.freedesktop.org/drm/xe/kernel/-/blob/drm-xe-next/drivers/gpu/drm/xe/xe_exec.c
> +
> +Currently following batch steps are equal on Xe:
> +1.1000.-2.0 <==> 1.1000.f-2.0
> +and will create explicit sync fence dependency (via syncobjects).
> +
> +The data dependency need to wait for working sets implementation.
> +
> Sync (fd) fences
> ----------------
>
> @@ -131,7 +144,7 @@ runnable. When the second RCS batch completes the standalone fence is signaled
> which allows the two VCS batches to be executed. Finally we wait until the both
> VCS batches have completed before starting the (optional) next iteration.
>
> -Submit fences
> +Submit fences (i915 only)
> -------------
>
> Submit fences are a type of input fence which are signalled when the originating
> @@ -148,7 +161,7 @@ Submit fences have the identical syntax as the sync fences with the lower-case
> Here VCS1 and VCS2 batches will only be submitted for executing once the RCS
> batch enters the GPU.
>
> -Context priority
> +Context priority (i915 only)
> ----------------
>
> P.1.-1
> @@ -213,7 +226,7 @@ Example:
>
> This enables load balancing for context number one.
>
> -Engine bonds
> +Engine bonds (i915 only)
> ------------
>
> Engine bonds are extensions on load balanced contexts. They allow expressing
> @@ -261,7 +274,7 @@ then look like:
> 2.DEFAULT.1000.s-1.0
> a.-3
>
> -Context SSEU configuration
> +Context SSEU configuration (i915 only)
> --------------------------
>
> S.1.1
> @@ -281,7 +294,7 @@ Slice mask of -1 has a special meaning of "all slices". Otherwise any integer
> can be specifying as the slice mask, but beware any apart from 1 and -1 can make
> the workload not portable between different GPUs.
>
> -Working sets
> +Working sets (i915 only)
> ------------
>
> When used plainly workload steps can create implicit data dependencies by
Less than 500 lines, neat. Nothin offsensive jumps out, it all looks
cleanly organized. I did not do a detailed review of the new code so
from me just:
Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Regards,
Tvrtko
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 17/17] benchmarks/gem_wsim: added basic xe support
2023-10-06 14:12 ` Tvrtko Ursulin
@ 2023-10-06 15:43 ` Bernatowicz, Marcin
2023-10-09 8:38 ` Tvrtko Ursulin
0 siblings, 1 reply; 31+ messages in thread
From: Bernatowicz, Marcin @ 2023-10-06 15:43 UTC (permalink / raw)
To: Tvrtko Ursulin, igt-dev; +Cc: chris.p.wilson
Hi,
On 10/6/2023 4:12 PM, Tvrtko Ursulin wrote:
>
> On 05/10/2023 19:57, Marcin Bernatowicz wrote:
>> Added basic xe support. Single binary handles both i915 and Xe devices.
>>
>> Some functionality is still missing: working sets, bonding.
>>
>> The tool is handy for scheduling tests, we find it useful to verify vGPU
>> profiles defining different execution quantum/preemption timeout
>> settings.
>>
>> There is also some rationale for the tool in following thread:
>> https://lore.kernel.org/dri-devel/a443495f-5d1b-52e1-9b2f-80167deb6d57@linux.intel.com/
>>
>> With this patch it should be possible to run following on xe device:
>>
>> gem_wsim -w benchmarks/wsim/media_load_balance_fhd26u7.wsim -c 36 -r 600
>>
>> Best with drm debug logs disabled:
>>
>> echo 0 > /sys/module/drm/parameters/debug
>>
>> v2: minimizing divergence - same workload syntax for both drivers,
>> so most existing examples should run on xe unmodified (Tvrtko)
>> This version creates one common VM per workload.
>> Explicit VM management, compute mode will come in next patchset.
>>
>> v3:
>> - use calloc in parse_workload for struct workload,
>> to allow cleanups in fini_workload
>> - grouped xe specific fields (Tvrtko)
>> - moved is_xe boolean next to fd (Tvrtko)
>> - use xe_ prefix for Xe specific things (Tvrtko)
>> - left throttling untouched (Tvrtko)
>> - parse errors vs silent skips on not implemented steps (Tvrtko)
>> - need to think on better engine handling in next version
>> - add 'Xe and i915 differences' section to README (Tvrtko)
>> for now no data dependency implemented, left -1 <=> f-1
>> to not modify examples (maybe too optimistic assumption?)
>>
>> v4:
>> - corrected engines mappings for xe (Tvrtko)
>> "M.1.VCS,B.1,1.DEFAULT.1000.0.1" should use VCS
>> - verified engines selection works on MTL (Tvrtko)
>> - prevent misuse combinations of fence and implicit data deps (Tvrtko)
>> ex. "f,1.DEFAULT.1000.-1.0" should fail
>> "f,1.DEFAULT.1000.f-1.0" is valid
>> - corrected error messages (Tvrtko)
>> - moved wsim_err up to be accessible from parse_dependencies
>> - missing xe_device_put (Tvrtko)
>> - left fini_workload cleanup for separate patch
>> - README updates
>>
>> Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
>> ---
>> benchmarks/gem_wsim.c | 487 +++++++++++++++++++++++++++++++++++++++--
>> benchmarks/wsim/README | 23 +-
>> 2 files changed, 483 insertions(+), 27 deletions(-)
>>
>> diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
>> index e86519614..ecbeb9175 100644
>> --- a/benchmarks/gem_wsim.c
>> +++ b/benchmarks/gem_wsim.c
>> @@ -62,6 +62,12 @@
>> #include "i915/gem_engine_topology.h"
>> #include "i915/gem_mman.h"
>> +#include "igt_syncobj.h"
>> +#include "intel_allocator.h"
>> +#include "xe_drm.h"
>> +#include "xe/xe_ioctl.h"
>> +#include "xe/xe_spin.h"
>> +
>> enum intel_engine_id {
>> DEFAULT,
>> RCS,
>> @@ -185,10 +191,31 @@ struct w_step {
>> struct drm_i915_gem_relocation_entry reloc[3];
>> uint32_t *bb_duration;
>> } i915;
>> + struct {
>> + struct drm_xe_exec exec;
>> + struct {
>> + struct xe_spin spin;
>> + uint64_t vm_sync;
>> + uint64_t exec_sync;
>> + } *data;
>> + struct drm_xe_sync *syncs;
>> + } xe;
>> };
>> uint32_t bb_handle;
>> };
>> +struct xe_vm {
>> + uint32_t id;
>> + bool compute_mode;
>> + uint64_t ahnd;
>> +};
>> +
>> +struct xe_exec_queue {
>> + uint32_t id;
>> + unsigned int nr_hwes;
>> + struct drm_xe_engine_class_instance *hwe_list;
>> +};
>> +
>> struct ctx {
>> uint32_t id;
>> int priority;
>> @@ -198,6 +225,13 @@ struct ctx {
>> struct bond *bonds;
>> bool load_balance;
>> uint64_t sseu;
>> + struct {
>> + /* reference to vm */
>> + struct xe_vm *vm;
>> + /* exec queues */
>> + unsigned int nr_queues;
>> + struct xe_exec_queue *queue_list;
>> + } xe;
>> };
>> struct workload {
>> @@ -221,6 +255,11 @@ struct workload {
>> unsigned int nr_ctxs;
>> struct ctx *ctx_list;
>> + struct {
>> + unsigned int nr_vms;
>> + struct xe_vm *vm_list;
>> + } xe;
>> +
>> struct working_set **working_sets; /* array indexed by set id */
>> int max_working_set_id;
>> @@ -246,6 +285,7 @@ static unsigned int master_prng;
>> static int verbose = 1;
>> static int fd;
>> +static bool is_xe;
>> static struct drm_i915_gem_context_param_sseu device_sseu = {
>> .slice_mask = -1 /* Force read on first use. */
>> };
>> @@ -266,7 +306,10 @@ static const char *ring_str_map[NUM_ENGINES] = {
>> static void w_step_sync(struct w_step *w)
>> {
>> - gem_sync(fd, w->i915.obj[0].handle);
>> + if (is_xe)
>> + igt_assert(syncobj_wait(fd, &w->xe.syncs[0].handle, 1,
>> INT64_MAX, 0, NULL));
>> + else
>> + gem_sync(fd, w->i915.obj[0].handle);
>> }
>> static int read_timestamp_frequency(int i915)
>> @@ -354,6 +397,19 @@ parse_working_set_deps(struct workload *wrk,
>> return 0;
>> }
>> +static void __attribute__((format(printf, 1, 2)))
>> +wsim_err(const char *fmt, ...)
>> +{
>> + va_list ap;
>> +
>> + if (!verbose)
>> + return;
>> +
>> + va_start(ap, fmt);
>> + vfprintf(stderr, fmt, ap);
>> + va_end(ap);
>> +}
>> +
>> static int
>> parse_dependency(unsigned int nr_steps, struct w_step *w, char *str)
>> {
>> @@ -374,11 +430,18 @@ parse_dependency(unsigned int nr_steps, struct
>> w_step *w, char *str)
>> break;
>> case 's':
>> + /* no submit fence in xe */
>> + if (is_xe) {
>> + wsim_err("Submit fences are not supported with xe\n");
>> + return -1;
>> + }
>> submit_fence = true;
>> /* Fall-through. */
>> case 'f':
>> - /* Multiple fences not yet supported. */
>> - igt_assert_eq(w->fence_deps.nr, 0);
>> + /* xe supports multiple fences */
>> + if (!is_xe)
>> + /* Multiple fences not yet supported. */
>> + igt_assert_eq(w->fence_deps.nr, 0);
>> entry.target = atoi(++str);
>> if (entry.target > 0 || ((int)nr_steps + entry.target) < 0)
>> @@ -448,19 +511,6 @@ out:
>> return ret;
>> }
>> -static void __attribute__((format(printf, 1, 2)))
>> -wsim_err(const char *fmt, ...)
>> -{
>> - va_list ap;
>> -
>> - if (!verbose)
>> - return;
>> -
>> - va_start(ap, fmt);
>> - vfprintf(stderr, fmt, ap);
>> - va_end(ap);
>> -}
>> -
>> #define check_arg(cond, fmt, ...) \
>> { \
>> if (cond) { \
>> @@ -488,7 +538,17 @@ static struct intel_engine_data *query_engines(void)
>> if (engines.nengines)
>> return &engines;
>> - engines = intel_engine_list_of_physical(fd);
>> + if (is_xe) {
>> + struct drm_xe_engine_class_instance *hwe;
>> +
>> + xe_for_each_hw_engine(fd, hwe) {
>> + engines.engines[engines.nengines].class = hwe->engine_class;
>> + engines.engines[engines.nengines].instance =
>> hwe->engine_instance;
>> + engines.nengines++;
>> + }
>> + } else
>> + engines = intel_engine_list_of_physical(fd);
>> +
>> igt_assert(engines.nengines);
>> return &engines;
>> }
>> @@ -581,6 +641,46 @@ get_engine(enum intel_engine_id engine)
>> return ci;
>> }
>> +static struct drm_xe_engine_class_instance
>> +xe_get_engine(enum intel_engine_id engine)
>> +{
>> + struct drm_xe_engine_class_instance hwe = {}, *hwe1;
>> + bool found_physical = false;
>> +
>> + switch (engine) {
>> + case RCS:
>> + hwe.engine_class = DRM_XE_ENGINE_CLASS_RENDER;
>> + break;
>> + case BCS:
>> + hwe.engine_class = DRM_XE_ENGINE_CLASS_COPY;
>> + break;
>> + case VCS1:
>> + hwe.engine_class = DRM_XE_ENGINE_CLASS_VIDEO_DECODE;
>> + break;
>> + case VCS2:
>> + hwe.engine_class = DRM_XE_ENGINE_CLASS_VIDEO_DECODE;
>> + hwe.engine_instance = 1;
>> + break;
>> + case VECS:
>> + hwe.engine_class = DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE;
>> + break;
>> + default:
>> + igt_assert(0);
>> + };
>> +
>> + xe_for_each_hw_engine(fd, hwe1) {
>> + if (hwe.engine_class == hwe1->engine_class &&
>> + hwe.engine_instance == hwe1->engine_instance) {
>> + hwe = *hwe1;
>> + found_physical = true;
>> + break;
>> + }
>> + }
>> +
>> + igt_assert(found_physical);
>> + return hwe;
>> +}
>> +
>> static int parse_engine_map(struct w_step *step, const char *_str)
>> {
>> char *token, *tctx = NULL, *tstart = (char *)_str;
>> @@ -855,6 +955,12 @@ parse_workload(struct w_arg *arg, unsigned int
>> flags, double scale_dur,
>> } else if (!strcmp(field, "P")) {
>> unsigned int nr = 0;
>> + if (is_xe) {
>> + wsim_err("Priority step is not implemented with
>> xe yet.\n");
>> + free(token);
>> + return NULL;
>> + }
>> +
>> while ((field = strtok_r(fstart, ".", &fctx))) {
>> tmp = atoi(field);
>> check_arg(nr == 0 && tmp <= 0,
>> @@ -881,6 +987,12 @@ parse_workload(struct w_arg *arg, unsigned int
>> flags, double scale_dur,
>> } else if (!strcmp(field, "S")) {
>> unsigned int nr = 0;
>> + if (is_xe) {
>> + wsim_err("SSEU step is not implemented with xe
>> yet.\n");
>> + free(token);
>> + return NULL;
>> + }
>> +
>> while ((field = strtok_r(fstart, ".", &fctx))) {
>> tmp = atoi(field);
>> check_arg(tmp <= 0 && nr == 0,
>> @@ -994,6 +1106,12 @@ parse_workload(struct w_arg *arg, unsigned int
>> flags, double scale_dur,
>> } else if (!strcmp(field, "b")) {
>> unsigned int nr = 0;
>> + if (is_xe) {
>> + wsim_err("Bonding is not implemented with xe
>> yet.\n");
>> + free(token);
>> + return NULL;
>> + }
>> +
>> while ((field = strtok_r(fstart, ".", &fctx))) {
>> check_arg(nr > 2,
>> "Invalid bond format at step %u!\n",
>> @@ -1028,6 +1146,12 @@ parse_workload(struct w_arg *arg, unsigned int
>> flags, double scale_dur,
>> } else if (!strcmp(field, "w") || !strcmp(field, "W")) {
>> unsigned int nr = 0;
>> + if (is_xe) {
>> + wsim_err("Working sets are not implemented with
>> xe yet.\n");
>> + free(token);
>> + return NULL;
>> + }
>> +
>> step.working_set.shared = field[0] == 'W';
>> while ((field = strtok_r(fstart, ".", &fctx))) {
>> @@ -1484,6 +1608,31 @@ get_ctxid(struct workload *wrk, struct w_step *w)
>> return wrk->ctx_list[w->context].id;
>> }
>> +static struct xe_exec_queue *
>> +xe_get_eq(struct workload *wrk, const struct w_step *w)
>> +{
>> + struct ctx *ctx = __get_ctx(wrk, w);
>> + struct xe_exec_queue *eq;
>> +
>> + if (ctx->engine_map) {
>> + igt_assert_eq(ctx->xe.nr_queues, 1);
>> + igt_assert(ctx->xe.queue_list[0].id);
>> + eq = &ctx->xe.queue_list[0];
>> + } else {
>> + igt_assert(w->engine >= 0 && w->engine < ctx->xe.nr_queues);
>> + igt_assert(ctx->xe.queue_list[w->engine].id);
>> + eq = &ctx->xe.queue_list[w->engine];
>> + }
>> +
>> + return eq;
>> +}
>> +
>> +static struct xe_vm *
>> +xe_get_vm(struct workload *wrk, const struct w_step *w)
>> +{
>> + return wrk->xe.vm_list;
>> +}
>> +
>> static uint32_t alloc_bo(int i915, unsigned long size)
>> {
>> return gem_create(i915, size);
>> @@ -1557,6 +1706,71 @@ alloc_step_batch(struct workload *wrk, struct
>> w_step *w)
>> #endif
>> }
>> +static void
>> +xe_alloc_step_batch(struct workload *wrk, struct w_step *w)
>> +{
>> + struct xe_vm *vm = xe_get_vm(wrk, w);
>> + struct xe_exec_queue *eq = xe_get_eq(wrk, w);
>> + struct dep_entry *dep;
>> + int i;
>> +
>> + w->bb_handle = xe_bo_create_flags(fd, vm->id, PAGE_SIZE,
>> + visible_vram_if_possible(fd, eq->hwe_list[0].gt_id));
>> + w->xe.data = xe_bo_map(fd, w->bb_handle, PAGE_SIZE);
>> + w->xe.exec.address =
>> + intel_allocator_alloc_with_strategy(vm->ahnd, w->bb_handle,
>> PAGE_SIZE,
>> + 0, ALLOC_STRATEGY_LOW_TO_HIGH);
>> + xe_vm_bind_sync(fd, vm->id, w->bb_handle, 0, w->xe.exec.address,
>> PAGE_SIZE);
>> + xe_spin_init_opts(&w->xe.data->spin, .addr = w->xe.exec.address,
>> + .preempt = (w->preempt_us > 0),
>> + .ctx_ticks = duration_to_ctx_ticks(fd,
>> eq->hwe_list[0].gt_id,
>> + 1000LL * get_duration(wrk, w)));
>> + w->xe.exec.exec_queue_id = eq->id;
>> + w->xe.exec.num_batch_buffer = 1;
>> + /* always at least one out fence */
>> + w->xe.exec.num_syncs = 1;
>> + /* count syncs */
>> + for_each_dep(dep, w->data_deps) {
>> + int dep_idx = w->idx + dep->target;
>> +
>> + igt_assert(dep_idx >= 0 && dep_idx < w->idx);
>> + igt_assert(wrk->steps[dep_idx].type == BATCH);
>> +
>> + w->xe.exec.num_syncs++;
>> + }
>> + for_each_dep(dep, w->fence_deps) {
>> + int dep_idx = w->idx + dep->target;
>> +
>> + igt_assert(dep_idx >= 0 && dep_idx < w->idx);
>> + igt_assert(wrk->steps[dep_idx].type == SW_FENCE ||
>> + wrk->steps[dep_idx].type == BATCH);
>> +
>> + w->xe.exec.num_syncs++;
>> + }
>> + w->xe.syncs = calloc(w->xe.exec.num_syncs, sizeof(*w->xe.syncs));
>> + /* fill syncs */
>> + i = 0;
>> + /* out fence */
>> + w->xe.syncs[i].handle = syncobj_create(fd, 0);
>> + w->xe.syncs[i++].flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL;
>> + /* in fence(s) */
>> + for_each_dep(dep, w->data_deps) {
>> + int dep_idx = w->idx + dep->target;
>> +
>> + igt_assert(wrk->steps[dep_idx].xe.syncs &&
>> wrk->steps[dep_idx].xe.syncs[0].handle);
>> + w->xe.syncs[i].handle = wrk->steps[dep_idx].xe.syncs[0].handle;
>> + w->xe.syncs[i++].flags = DRM_XE_SYNC_SYNCOBJ;
>> + }
>> + for_each_dep(dep, w->fence_deps) {
>> + int dep_idx = w->idx + dep->target;
>> +
>> + igt_assert(wrk->steps[dep_idx].xe.syncs &&
>> wrk->steps[dep_idx].xe.syncs[0].handle);
>> + w->xe.syncs[i].handle = wrk->steps[dep_idx].xe.syncs[0].handle;
>> + w->xe.syncs[i++].flags = DRM_XE_SYNC_SYNCOBJ;
>> + }
>> + w->xe.exec.syncs = to_user_pointer(w->xe.syncs);
>> +}
>> +
>> static bool set_priority(uint32_t ctx_id, int prio)
>> {
>> struct drm_i915_gem_context_param param = {
>> @@ -1739,6 +1953,9 @@ static void measure_active_set(struct workload
>> *wrk)
>> batch_sizes += 4096;
>> + if (is_xe)
>> + continue;
>
> I guess you re-use data_deps for something with xe so you can't just let
> it run the loop here and find no data deps, resulting in the same zero
> result?
data_deps is allowed for BATCH type dependency only (WORKING_SET is not
implemented yet) and protects against "f,1.DEFAULT.1000.-1.0".
As we do not share any buffer yet, I skip the loop for now, otherwise I
would need other if for:
_dep.target = wrk->steps[idx].i915.obj[0].handle;
>
>> +
>> for_each_dep(dep, w->data_deps) {
>> struct dep_entry _dep = *dep;
>> @@ -1782,6 +1999,31 @@ static void measure_active_set(struct workload
>> *wrk)
>> #define alloca0(sz) ({ size_t sz__ = (sz); memset(alloca(sz__), 0,
>> sz__); })
>> +static void xe_vm_create_(struct xe_vm *vm)
>> +{
>> + uint32_t flags = 0;
>> +
>> + if (vm->compute_mode)
>> + flags |= DRM_XE_VM_CREATE_ASYNC_BIND_OPS |
>> + DRM_XE_VM_CREATE_COMPUTE_MODE;
>> +
>> + vm->id = xe_vm_create(fd, flags, 0);
>> +}
>> +
>> +static void xe_exec_queue_create_(struct ctx *ctx, struct
>> xe_exec_queue *eq)
>> +{
>> + struct drm_xe_exec_queue_create create = {
>> + .vm_id = ctx->xe.vm->id,
>> + .width = 1,
>> + .num_placements = eq->nr_hwes,
>> + .instances = to_user_pointer(eq->hwe_list),
>> + };
>> +
>> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC_QUEUE_CREATE,
>> &create), 0);
>> +
>> + eq->id = create.exec_queue_id;
>> +}
>> +
>> static void allocate_contexts(unsigned int id, struct workload *wrk)
>> {
>> int max_ctx = -1;
>> @@ -1984,6 +2226,140 @@ static int prepare_contexts(unsigned int id,
>> struct workload *wrk)
>> return 0;
>> }
>> +static int xe_prepare_contexts(unsigned int id, struct workload *wrk)
>> +{
>> + struct xe_exec_queue *eq;
>> + struct w_step *w;
>> + struct ctx *ctx;
>> + unsigned int i;
>> +
>> + /* shortcut, create one vm */
>> + wrk->xe.nr_vms = 1;
>> + wrk->xe.vm_list = calloc(wrk->xe.nr_vms, sizeof(struct xe_vm));
>> + wrk->xe.vm_list->compute_mode = false;
>> + xe_vm_create_(wrk->xe.vm_list);
>> + wrk->xe.vm_list->ahnd = intel_allocator_open(fd,
>> wrk->xe.vm_list->id,
>> + INTEL_ALLOCATOR_RELOC);
>> +
>> + for_each_ctx_ctx_idx(ctx, wrk, ctx_idx) {
>> + /* link with vm */
>> + ctx->xe.vm = wrk->xe.vm_list;
>> + for_each_w_step(w, wrk) {
>> + if (w->context != ctx_idx)
>> + continue;
>> + if (w->type == ENGINE_MAP) {
>> + ctx->engine_map = w->engine_map;
>> + ctx->engine_map_count = w->engine_map_count;
>> + } else if (w->type == LOAD_BALANCE) {
>> + if (!ctx->engine_map) {
>> + wsim_err("Load balancing needs an engine map!\n");
>> + return 1;
>> + }
>> + if (intel_gen(intel_get_drm_devid(fd)) < 11) {
>> + wsim_err("Load balancing needs relative mmio
>> support, gen11+!\n");
>> + return 1;
>> + }
>
> If xe supports gen12+ then you can drop this?
good point.
>
>> + ctx->load_balance = w->load_balance;
>> + }
>> + }
>> +
>> + /* create exec queue for each referenced engine */
>> + if (ctx->engine_map) {
>> + ctx->xe.nr_queues = 1;
>> + ctx->xe.queue_list = calloc(ctx->xe.nr_queues,
>> sizeof(*ctx->xe.queue_list));
>> + igt_assert(ctx->xe.queue_list);
>> + eq = &ctx->xe.queue_list[ctx->xe.nr_queues - 1];
>> + eq->nr_hwes = ctx->engine_map_count;
>> + eq->hwe_list = calloc(eq->nr_hwes, sizeof(*eq->hwe_list));
>> + for (i = 0; i < eq->nr_hwes; ++i) {
>> + eq->hwe_list[i] = xe_get_engine(ctx->engine_map[i]);
>> +
>> + /* check no mixing classes and no duplicates */
>> + for (int j = 0; j < i; ++j) {
>> + if (eq->hwe_list[j].engine_class !=
>> + eq->hwe_list[i].engine_class) {
>> + free(eq->hwe_list);
>> + eq->nr_hwes = 0;
>> + wsim_err("Mixing of engine class not
>> supported!\n");
>> + return 1;
>> + }
>> +
>> + if (eq->hwe_list[j].engine_instance ==
>> + eq->hwe_list[i].engine_instance) {
>> + free(eq->hwe_list);
>> + eq->nr_hwes = 0;
>> + wsim_err("Duplicate engine entry!\n");
>> + return 1;
>> + }
>> + }
>> +
>> + if (verbose > 3)
>> + printf("%u ctx[%d] %s [%u:%u:%u]\n",
>> + id, ctx_idx, ring_str_map[ctx->engine_map[i]],
>> + eq->hwe_list[i].engine_class,
>> + eq->hwe_list[i].engine_instance,
>> + eq->hwe_list[i].gt_id);
>> + }
>> +
>> + xe_exec_queue_create_(ctx, eq);
>> + } else {
>> + int engine_classes[NUM_ENGINES] = {};
>> +
>> + ctx->xe.nr_queues = NUM_ENGINES;
>> + ctx->xe.queue_list = calloc(ctx->xe.nr_queues,
>> sizeof(*ctx->xe.queue_list));
>> +
>> + for_each_w_step(w, wrk) {
>> + if (w->context != ctx_idx)
>> + continue;
>> + if (w->type == BATCH)
>> + engine_classes[w->engine]++;
>> + }
>> +
>> + for (i = 0; i < NUM_ENGINES; i++) {
>> + if (engine_classes[i]) {
>> + eq = &ctx->xe.queue_list[i];
>> + eq->nr_hwes = 1;
>> + eq->hwe_list = calloc(1, sizeof(*eq->hwe_list));
>> +
>> + if (i == DEFAULT) {
>> + struct drm_xe_engine_class_instance *hwe;
>> +
>> + /* select first available engine */
>
> With no engine map you probably want to ensure this is rcs0 to ensure
> cross driver workload compatibility. Maybe xe_for_each_hw_engine already
> works like that, I don't know.
DEFAULT works when no RCS is present (for i915). Maybe I should search
for RCS and return whatever is first when not found, something like:
/* select RCS0 or first available engine */
eq->hwe_list[0] = *xe_hw_engine(fd, 0);
xe_for_each_hw_engine(fd, hwe) {
if (hwe->engine_class == DRM_XE_ENGINE_CLASS_RENDER &&
hwe->engine_instance == 0) {
eq->hwe_list[0] = *hwe;
break;
}
}
>
>> + xe_for_each_hw_engine(fd, hwe) {
>> + eq->hwe_list[0] = *hwe;
>> + break;
>> + }
>> + } else if (i == VCS) {
>> + eq->hwe_list[0] = xe_get_engine(VCS1);
>> + } else {
>> + eq->hwe_list[0] = xe_get_engine(i);
>> + }
>> +
>> + if (verbose > 3)
>> + printf("%u ctx[%d] %s [%u:%u:%u]\n",
>> + id, ctx_idx, ring_str_map[i],
>> + eq->hwe_list[0].engine_class,
>> + eq->hwe_list[0].engine_instance,
>> + eq->hwe_list[0].gt_id);
>> +
>> + xe_exec_queue_create_(ctx, eq);
>> + }
>> + engine_classes[i] = 0;
>> + }
>> + }
>> + }
>> +
>> + /* create syncobjs for SW_FENCE */
>> + for_each_w_step(w, wrk)
>> + if (w->type == SW_FENCE) {
>> + w->xe.syncs = calloc(1, sizeof(struct drm_xe_sync));
>> + w->xe.syncs[0].handle = syncobj_create(fd, 0);
>> + w->xe.syncs[0].flags = DRM_XE_SYNC_SYNCOBJ;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> static void prepare_working_sets(unsigned int id, struct workload *wrk)
>> {
>> struct working_set **sets;
>> @@ -2051,7 +2427,11 @@ static int prepare_workload(unsigned int id,
>> struct workload *wrk)
>> allocate_contexts(id, wrk);
>> - ret = prepare_contexts(id, wrk);
>> + if (is_xe)
>> + ret = xe_prepare_contexts(id, wrk);
>> + else
>> + ret = prepare_contexts(id, wrk);
>> +
>> if (ret)
>> return ret;
>> @@ -2104,7 +2484,10 @@ static int prepare_workload(unsigned int id,
>> struct workload *wrk)
>> if (w->type != BATCH)
>> continue;
>> - alloc_step_batch(wrk, w);
>> + if (is_xe)
>> + xe_alloc_step_batch(wrk, w);
>> + else
>> + alloc_step_batch(wrk, w);
>> }
>> measure_active_set(wrk);
>> @@ -2154,6 +2537,24 @@ static void w_sync_to(struct workload *wrk,
>> struct w_step *w, int target)
>> w_step_sync(&wrk->steps[target]);
>> }
>> +static void do_xe_exec(struct workload *wrk, struct w_step *w)
>> +{
>> + struct xe_exec_queue *eq = xe_get_eq(wrk, w);
>> +
>> + igt_assert(w->emit_fence <= 0);
>> + if (w->emit_fence == -1)
>> + syncobj_reset(fd, &w->xe.syncs[0].handle, 1);
>> +
>> + /* update duration if random */
>> + if (w->duration.max != w->duration.min)
>> + xe_spin_init_opts(&w->xe.data->spin,
>> + .addr = w->xe.exec.address,
>> + .preempt = (w->preempt_us > 0),
>> + .ctx_ticks = duration_to_ctx_ticks(fd,
>> eq->hwe_list[0].gt_id,
>> + 1000LL * get_duration(wrk, w)));
>> + xe_exec(fd, &w->xe.exec);
>> +}
>> +
>> static void
>> do_eb(struct workload *wrk, struct w_step *w, enum intel_engine_id
>> engine)
>> {
>> @@ -2280,6 +2681,10 @@ static void *run_workload(void *data)
>> sw_sync_timeline_create_fence(wrk->sync_timeline,
>> cur_seqno + w->idx);
>> igt_assert(w->emit_fence > 0);
>> + if (is_xe)
>> + /* Convert sync file to syncobj */
>> + syncobj_import_sync_file(fd, w->xe.syncs[0].handle,
>> + w->emit_fence);
>> continue;
>> } else if (w->type == SW_FENCE_SIGNAL) {
>> int tgt = w->idx + w->target;
>> @@ -2311,7 +2716,10 @@ static void *run_workload(void *data)
>> igt_assert(wrk->steps[t_idx].type == BATCH);
>> igt_assert(wrk->steps[t_idx].duration.unbound);
>> - *wrk->steps[t_idx].i915.bb_duration = 0xffffffff;
>> + if (is_xe)
>> + xe_spin_end(&wrk->steps[t_idx].xe.data->spin);
>> + else
>> + *wrk->steps[t_idx].i915.bb_duration = 0xffffffff;
>> __sync_synchronize();
>> continue;
>> } else if (w->type == SSEU) {
>> @@ -2343,7 +2751,10 @@ static void *run_workload(void *data)
>> if (throttle > 0)
>> w_sync_to(wrk, w, w->idx - throttle);
>> - do_eb(wrk, w, engine);
>> + if (is_xe)
>> + do_xe_exec(wrk, w);
>> + else
>> + do_eb(wrk, w, engine);
>> if (w->request != -1) {
>> igt_list_del(&w->rq_link);
>> @@ -2389,6 +2800,10 @@ static void *run_workload(void *data)
>> break;
>> if (w->emit_fence > 0) {
>> + if (is_xe) {
>> + igt_assert(w->type == SW_FENCE);
>> + syncobj_reset(fd, &w->xe.syncs[0].handle, 1);
>> + }
>> close(w->emit_fence);
>> w->emit_fence = -1;
>> }
>> @@ -2403,6 +2818,23 @@ static void *run_workload(void *data)
>> w_step_sync(w);
>> }
>> + if (is_xe) {
>> + for_each_w_step(w, wrk) {
>> + if (w->type == BATCH) {
>> + w_step_sync(w);
>> + syncobj_destroy(fd, w->xe.syncs[0].handle);
>> + free(w->xe.syncs);
>> + xe_vm_unbind_sync(fd, xe_get_vm(wrk, w)->id, 0,
>> w->xe.exec.address,
>> + PAGE_SIZE);
>> + gem_munmap(w->xe.data, PAGE_SIZE);
>> + gem_close(fd, w->bb_handle);
>> + } else if (w->type == SW_FENCE) {
>> + syncobj_destroy(fd, w->xe.syncs[0].handle);
>> + free(w->xe.syncs);
>> + }
>> + }
>> + }
>> +
>> clock_gettime(CLOCK_MONOTONIC, &t_end);
>> if (wrk->print_stats) {
>> @@ -2629,8 +3061,12 @@ int main(int argc, char **argv)
>> ret = igt_device_find_first_i915_discrete_card(&card);
>> if (!ret)
>> ret = igt_device_find_integrated_card(&card);
>> + if (!ret)
>> + ret = igt_device_find_first_xe_discrete_card(&card);
>> + if (!ret)
>> + ret = igt_device_find_xe_integrated_card(&card);
>> if (!ret) {
>> - wsim_err("No device filter specified and no i915 devices
>> found!\n");
>> + wsim_err("No device filter specified and no intel devices
>> found!\n");
>> return EXIT_FAILURE;
>> }
>> }
>> @@ -2653,6 +3089,10 @@ int main(int argc, char **argv)
>> if (verbose > 1)
>> printf("Using device %s\n", drm_dev);
>> + is_xe = is_xe_device(fd);
>> + if (is_xe)
>> + xe_device_get(fd);
>> +
>> if (!nr_w_args) {
>> wsim_err("No workload descriptor(s)!\n");
>> goto err;
>> @@ -2772,5 +3212,8 @@ int main(int argc, char **argv)
>> out:
>> exitcode = EXIT_SUCCESS;
>> err:
>> + if (is_xe)
>> + xe_device_put(fd);
>> +
>> return exitcode;
>> }
>> diff --git a/benchmarks/wsim/README b/benchmarks/wsim/README
>> index d4f3dd8ae..e43813335 100644
>> --- a/benchmarks/wsim/README
>> +++ b/benchmarks/wsim/README
>> @@ -88,6 +88,19 @@ Batch durations can also be specified as infinite
>> by using the '*' in the
>> duration field. Such batches must be ended by the terminate command
>> ('T')
>> otherwise they will cause a GPU hang to be reported.
>> +Xe and i915 differences
>> +------------------------
>> +
>> +There are differences between Xe and i915, like not allowing a BO
>> list to
>> +be passed to an exec (and create implicit syncs). For more details see:
>> +https://gitlab.freedesktop.org/drm/xe/kernel/-/blob/drm-xe-next/drivers/gpu/drm/xe/xe_exec.c
>> +
>> +Currently following batch steps are equal on Xe:
>> +1.1000.-2.0 <==> 1.1000.f-2.0
>> +and will create explicit sync fence dependency (via syncobjects).
>> +
>> +The data dependency need to wait for working sets implementation.
>> +
>> Sync (fd) fences
>> ----------------
>> @@ -131,7 +144,7 @@ runnable. When the second RCS batch completes the
>> standalone fence is signaled
>> which allows the two VCS batches to be executed. Finally we wait
>> until the both
>> VCS batches have completed before starting the (optional) next
>> iteration.
>> -Submit fences
>> +Submit fences (i915 only)
>> -------------
>> Submit fences are a type of input fence which are signalled when the
>> originating
>> @@ -148,7 +161,7 @@ Submit fences have the identical syntax as the
>> sync fences with the lower-case
>> Here VCS1 and VCS2 batches will only be submitted for executing once
>> the RCS
>> batch enters the GPU.
>> -Context priority
>> +Context priority (i915 only)
>> ----------------
>> P.1.-1
>> @@ -213,7 +226,7 @@ Example:
>> This enables load balancing for context number one.
>> -Engine bonds
>> +Engine bonds (i915 only)
>> ------------
>> Engine bonds are extensions on load balanced contexts. They allow
>> expressing
>> @@ -261,7 +274,7 @@ then look like:
>> 2.DEFAULT.1000.s-1.0
>> a.-3
>> -Context SSEU configuration
>> +Context SSEU configuration (i915 only)
>> --------------------------
>> S.1.1
>> @@ -281,7 +294,7 @@ Slice mask of -1 has a special meaning of "all
>> slices". Otherwise any integer
>> can be specifying as the slice mask, but beware any apart from 1 and
>> -1 can make
>> the workload not portable between different GPUs.
>> -Working sets
>> +Working sets (i915 only)
>> ------------
>> When used plainly workload steps can create implicit data
>> dependencies by
>
> Less than 500 lines, neat. Nothin offsensive jumps out, it all looks
> cleanly organized. I did not do a detailed review of the new code so
> from me just:
>
> Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>
> Regards,
>
> Tvrtko
^ permalink raw reply [flat|nested] 31+ messages in thread
* [igt-dev] [PATCH i-g-t 05/17] benchmarks/gem_wsim: fix conflicting SSEU #define and enum
2023-10-06 16:06 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
@ 2023-10-06 16:06 ` Marcin Bernatowicz
0 siblings, 0 replies; 31+ messages in thread
From: Marcin Bernatowicz @ 2023-10-06 16:06 UTC (permalink / raw)
To: igt-dev; +Cc: chris.p.wilson
One SSEU is in enum w_step and then as #define SSEU (1 << 3).
Fix this.
v2:
- add FLAG_ prefix to all flags (Tvrtko)
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
---
benchmarks/gem_wsim.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index 91410d42d..67d2bce18 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -236,9 +236,9 @@ static struct drm_i915_gem_context_param_sseu device_sseu = {
.slice_mask = -1 /* Force read on first use. */
};
-#define SYNCEDCLIENTS (1<<1)
-#define DEPSYNC (1<<2)
-#define SSEU (1<<3)
+#define FLAG_SYNCEDCLIENTS (1<<1)
+#define FLAG_DEPSYNC (1<<2)
+#define FLAG_SSEU (1<<3)
static const char *ring_str_map[NUM_ENGINES] = {
[DEFAULT] = "DEFAULT",
@@ -1230,7 +1230,7 @@ add_step:
wrk->sseu = arg->sseu;
wrk->max_working_set_id = -1;
wrk->working_sets = NULL;
- wrk->bo_prng = (flags & SYNCEDCLIENTS) ? master_prng : rand();
+ wrk->bo_prng = (flags & FLAG_SYNCEDCLIENTS) ? master_prng : rand();
free(desc);
@@ -1868,8 +1868,8 @@ static int prepare_workload(unsigned int id, struct workload *wrk)
int i, j;
wrk->id = id;
- wrk->bb_prng = (wrk->flags & SYNCEDCLIENTS) ? master_prng : rand();
- wrk->bo_prng = (wrk->flags & SYNCEDCLIENTS) ? master_prng : rand();
+ wrk->bb_prng = (wrk->flags & FLAG_SYNCEDCLIENTS) ? master_prng : rand();
+ wrk->bo_prng = (wrk->flags & FLAG_SYNCEDCLIENTS) ? master_prng : rand();
wrk->run = true;
/*
@@ -2387,7 +2387,7 @@ static void *run_workload(void *data)
igt_assert(w->type == BATCH);
- if (wrk->flags & DEPSYNC)
+ if (wrk->flags & FLAG_DEPSYNC)
sync_deps(wrk, w);
if (throttle > 0)
@@ -2594,7 +2594,7 @@ int main(int argc, char **argv)
/* Fall through */
case 'w':
w_args = add_workload_arg(w_args, ++nr_w_args, optarg,
- prio, flags & SSEU);
+ prio, flags & FLAG_SSEU);
break;
case 'p':
prio = atoi(optarg);
@@ -2620,13 +2620,13 @@ int main(int argc, char **argv)
verbose++;
break;
case 'S':
- flags |= SYNCEDCLIENTS;
+ flags |= FLAG_SYNCEDCLIENTS;
break;
case 's':
- flags ^= SSEU;
+ flags ^= FLAG_SSEU;
break;
case 'd':
- flags |= DEPSYNC;
+ flags |= FLAG_DEPSYNC;
break;
case 'I':
master_prng = strtol(optarg, NULL, 0);
--
2.42.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 17/17] benchmarks/gem_wsim: added basic xe support
2023-10-06 15:43 ` Bernatowicz, Marcin
@ 2023-10-09 8:38 ` Tvrtko Ursulin
0 siblings, 0 replies; 31+ messages in thread
From: Tvrtko Ursulin @ 2023-10-09 8:38 UTC (permalink / raw)
To: Bernatowicz, Marcin, igt-dev; +Cc: chris.p.wilson
On 06/10/2023 16:43, Bernatowicz, Marcin wrote:
> Hi,
>
> On 10/6/2023 4:12 PM, Tvrtko Ursulin wrote:
>>
>> On 05/10/2023 19:57, Marcin Bernatowicz wrote:
>>> Added basic xe support. Single binary handles both i915 and Xe devices.
>>>
>>> Some functionality is still missing: working sets, bonding.
>>>
>>> The tool is handy for scheduling tests, we find it useful to verify vGPU
>>> profiles defining different execution quantum/preemption timeout
>>> settings.
>>>
>>> There is also some rationale for the tool in following thread:
>>> https://lore.kernel.org/dri-devel/a443495f-5d1b-52e1-9b2f-80167deb6d57@linux.intel.com/
>>>
>>> With this patch it should be possible to run following on xe device:
>>>
>>> gem_wsim -w benchmarks/wsim/media_load_balance_fhd26u7.wsim -c 36 -r 600
>>>
>>> Best with drm debug logs disabled:
>>>
>>> echo 0 > /sys/module/drm/parameters/debug
>>>
>>> v2: minimizing divergence - same workload syntax for both drivers,
>>> so most existing examples should run on xe unmodified (Tvrtko)
>>> This version creates one common VM per workload.
>>> Explicit VM management, compute mode will come in next patchset.
>>>
>>> v3:
>>> - use calloc in parse_workload for struct workload,
>>> to allow cleanups in fini_workload
>>> - grouped xe specific fields (Tvrtko)
>>> - moved is_xe boolean next to fd (Tvrtko)
>>> - use xe_ prefix for Xe specific things (Tvrtko)
>>> - left throttling untouched (Tvrtko)
>>> - parse errors vs silent skips on not implemented steps (Tvrtko)
>>> - need to think on better engine handling in next version
>>> - add 'Xe and i915 differences' section to README (Tvrtko)
>>> for now no data dependency implemented, left -1 <=> f-1
>>> to not modify examples (maybe too optimistic assumption?)
>>>
>>> v4:
>>> - corrected engines mappings for xe (Tvrtko)
>>> "M.1.VCS,B.1,1.DEFAULT.1000.0.1" should use VCS
>>> - verified engines selection works on MTL (Tvrtko)
>>> - prevent misuse combinations of fence and implicit data deps (Tvrtko)
>>> ex. "f,1.DEFAULT.1000.-1.0" should fail
>>> "f,1.DEFAULT.1000.f-1.0" is valid
>>> - corrected error messages (Tvrtko)
>>> - moved wsim_err up to be accessible from parse_dependencies
>>> - missing xe_device_put (Tvrtko)
>>> - left fini_workload cleanup for separate patch
>>> - README updates
>>>
>>> Signed-off-by: Marcin Bernatowicz <marcin.bernatowicz@linux.intel.com>
>>> ---
>>> benchmarks/gem_wsim.c | 487 +++++++++++++++++++++++++++++++++++++++--
>>> benchmarks/wsim/README | 23 +-
>>> 2 files changed, 483 insertions(+), 27 deletions(-)
>>>
>>> diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
>>> index e86519614..ecbeb9175 100644
>>> --- a/benchmarks/gem_wsim.c
>>> +++ b/benchmarks/gem_wsim.c
>>> @@ -62,6 +62,12 @@
>>> #include "i915/gem_engine_topology.h"
>>> #include "i915/gem_mman.h"
>>> +#include "igt_syncobj.h"
>>> +#include "intel_allocator.h"
>>> +#include "xe_drm.h"
>>> +#include "xe/xe_ioctl.h"
>>> +#include "xe/xe_spin.h"
>>> +
>>> enum intel_engine_id {
>>> DEFAULT,
>>> RCS,
>>> @@ -185,10 +191,31 @@ struct w_step {
>>> struct drm_i915_gem_relocation_entry reloc[3];
>>> uint32_t *bb_duration;
>>> } i915;
>>> + struct {
>>> + struct drm_xe_exec exec;
>>> + struct {
>>> + struct xe_spin spin;
>>> + uint64_t vm_sync;
>>> + uint64_t exec_sync;
>>> + } *data;
>>> + struct drm_xe_sync *syncs;
>>> + } xe;
>>> };
>>> uint32_t bb_handle;
>>> };
>>> +struct xe_vm {
>>> + uint32_t id;
>>> + bool compute_mode;
>>> + uint64_t ahnd;
>>> +};
>>> +
>>> +struct xe_exec_queue {
>>> + uint32_t id;
>>> + unsigned int nr_hwes;
>>> + struct drm_xe_engine_class_instance *hwe_list;
>>> +};
>>> +
>>> struct ctx {
>>> uint32_t id;
>>> int priority;
>>> @@ -198,6 +225,13 @@ struct ctx {
>>> struct bond *bonds;
>>> bool load_balance;
>>> uint64_t sseu;
>>> + struct {
>>> + /* reference to vm */
>>> + struct xe_vm *vm;
>>> + /* exec queues */
>>> + unsigned int nr_queues;
>>> + struct xe_exec_queue *queue_list;
>>> + } xe;
>>> };
>>> struct workload {
>>> @@ -221,6 +255,11 @@ struct workload {
>>> unsigned int nr_ctxs;
>>> struct ctx *ctx_list;
>>> + struct {
>>> + unsigned int nr_vms;
>>> + struct xe_vm *vm_list;
>>> + } xe;
>>> +
>>> struct working_set **working_sets; /* array indexed by set id */
>>> int max_working_set_id;
>>> @@ -246,6 +285,7 @@ static unsigned int master_prng;
>>> static int verbose = 1;
>>> static int fd;
>>> +static bool is_xe;
>>> static struct drm_i915_gem_context_param_sseu device_sseu = {
>>> .slice_mask = -1 /* Force read on first use. */
>>> };
>>> @@ -266,7 +306,10 @@ static const char *ring_str_map[NUM_ENGINES] = {
>>> static void w_step_sync(struct w_step *w)
>>> {
>>> - gem_sync(fd, w->i915.obj[0].handle);
>>> + if (is_xe)
>>> + igt_assert(syncobj_wait(fd, &w->xe.syncs[0].handle, 1,
>>> INT64_MAX, 0, NULL));
>>> + else
>>> + gem_sync(fd, w->i915.obj[0].handle);
>>> }
>>> static int read_timestamp_frequency(int i915)
>>> @@ -354,6 +397,19 @@ parse_working_set_deps(struct workload *wrk,
>>> return 0;
>>> }
>>> +static void __attribute__((format(printf, 1, 2)))
>>> +wsim_err(const char *fmt, ...)
>>> +{
>>> + va_list ap;
>>> +
>>> + if (!verbose)
>>> + return;
>>> +
>>> + va_start(ap, fmt);
>>> + vfprintf(stderr, fmt, ap);
>>> + va_end(ap);
>>> +}
>>> +
>>> static int
>>> parse_dependency(unsigned int nr_steps, struct w_step *w, char *str)
>>> {
>>> @@ -374,11 +430,18 @@ parse_dependency(unsigned int nr_steps, struct
>>> w_step *w, char *str)
>>> break;
>>> case 's':
>>> + /* no submit fence in xe */
>>> + if (is_xe) {
>>> + wsim_err("Submit fences are not supported with xe\n");
>>> + return -1;
>>> + }
>>> submit_fence = true;
>>> /* Fall-through. */
>>> case 'f':
>>> - /* Multiple fences not yet supported. */
>>> - igt_assert_eq(w->fence_deps.nr, 0);
>>> + /* xe supports multiple fences */
>>> + if (!is_xe)
>>> + /* Multiple fences not yet supported. */
>>> + igt_assert_eq(w->fence_deps.nr, 0);
>>> entry.target = atoi(++str);
>>> if (entry.target > 0 || ((int)nr_steps + entry.target) < 0)
>>> @@ -448,19 +511,6 @@ out:
>>> return ret;
>>> }
>>> -static void __attribute__((format(printf, 1, 2)))
>>> -wsim_err(const char *fmt, ...)
>>> -{
>>> - va_list ap;
>>> -
>>> - if (!verbose)
>>> - return;
>>> -
>>> - va_start(ap, fmt);
>>> - vfprintf(stderr, fmt, ap);
>>> - va_end(ap);
>>> -}
>>> -
>>> #define check_arg(cond, fmt, ...) \
>>> { \
>>> if (cond) { \
>>> @@ -488,7 +538,17 @@ static struct intel_engine_data
>>> *query_engines(void)
>>> if (engines.nengines)
>>> return &engines;
>>> - engines = intel_engine_list_of_physical(fd);
>>> + if (is_xe) {
>>> + struct drm_xe_engine_class_instance *hwe;
>>> +
>>> + xe_for_each_hw_engine(fd, hwe) {
>>> + engines.engines[engines.nengines].class =
>>> hwe->engine_class;
>>> + engines.engines[engines.nengines].instance =
>>> hwe->engine_instance;
>>> + engines.nengines++;
>>> + }
>>> + } else
>>> + engines = intel_engine_list_of_physical(fd);
>>> +
>>> igt_assert(engines.nengines);
>>> return &engines;
>>> }
>>> @@ -581,6 +641,46 @@ get_engine(enum intel_engine_id engine)
>>> return ci;
>>> }
>>> +static struct drm_xe_engine_class_instance
>>> +xe_get_engine(enum intel_engine_id engine)
>>> +{
>>> + struct drm_xe_engine_class_instance hwe = {}, *hwe1;
>>> + bool found_physical = false;
>>> +
>>> + switch (engine) {
>>> + case RCS:
>>> + hwe.engine_class = DRM_XE_ENGINE_CLASS_RENDER;
>>> + break;
>>> + case BCS:
>>> + hwe.engine_class = DRM_XE_ENGINE_CLASS_COPY;
>>> + break;
>>> + case VCS1:
>>> + hwe.engine_class = DRM_XE_ENGINE_CLASS_VIDEO_DECODE;
>>> + break;
>>> + case VCS2:
>>> + hwe.engine_class = DRM_XE_ENGINE_CLASS_VIDEO_DECODE;
>>> + hwe.engine_instance = 1;
>>> + break;
>>> + case VECS:
>>> + hwe.engine_class = DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE;
>>> + break;
>>> + default:
>>> + igt_assert(0);
>>> + };
>>> +
>>> + xe_for_each_hw_engine(fd, hwe1) {
>>> + if (hwe.engine_class == hwe1->engine_class &&
>>> + hwe.engine_instance == hwe1->engine_instance) {
>>> + hwe = *hwe1;
>>> + found_physical = true;
>>> + break;
>>> + }
>>> + }
>>> +
>>> + igt_assert(found_physical);
>>> + return hwe;
>>> +}
>>> +
>>> static int parse_engine_map(struct w_step *step, const char *_str)
>>> {
>>> char *token, *tctx = NULL, *tstart = (char *)_str;
>>> @@ -855,6 +955,12 @@ parse_workload(struct w_arg *arg, unsigned int
>>> flags, double scale_dur,
>>> } else if (!strcmp(field, "P")) {
>>> unsigned int nr = 0;
>>> + if (is_xe) {
>>> + wsim_err("Priority step is not implemented with
>>> xe yet.\n");
>>> + free(token);
>>> + return NULL;
>>> + }
>>> +
>>> while ((field = strtok_r(fstart, ".", &fctx))) {
>>> tmp = atoi(field);
>>> check_arg(nr == 0 && tmp <= 0,
>>> @@ -881,6 +987,12 @@ parse_workload(struct w_arg *arg, unsigned int
>>> flags, double scale_dur,
>>> } else if (!strcmp(field, "S")) {
>>> unsigned int nr = 0;
>>> + if (is_xe) {
>>> + wsim_err("SSEU step is not implemented with xe
>>> yet.\n");
>>> + free(token);
>>> + return NULL;
>>> + }
>>> +
>>> while ((field = strtok_r(fstart, ".", &fctx))) {
>>> tmp = atoi(field);
>>> check_arg(tmp <= 0 && nr == 0,
>>> @@ -994,6 +1106,12 @@ parse_workload(struct w_arg *arg, unsigned int
>>> flags, double scale_dur,
>>> } else if (!strcmp(field, "b")) {
>>> unsigned int nr = 0;
>>> + if (is_xe) {
>>> + wsim_err("Bonding is not implemented with xe
>>> yet.\n");
>>> + free(token);
>>> + return NULL;
>>> + }
>>> +
>>> while ((field = strtok_r(fstart, ".", &fctx))) {
>>> check_arg(nr > 2,
>>> "Invalid bond format at step %u!\n",
>>> @@ -1028,6 +1146,12 @@ parse_workload(struct w_arg *arg, unsigned int
>>> flags, double scale_dur,
>>> } else if (!strcmp(field, "w") || !strcmp(field, "W")) {
>>> unsigned int nr = 0;
>>> + if (is_xe) {
>>> + wsim_err("Working sets are not implemented with
>>> xe yet.\n");
>>> + free(token);
>>> + return NULL;
>>> + }
>>> +
>>> step.working_set.shared = field[0] == 'W';
>>> while ((field = strtok_r(fstart, ".", &fctx))) {
>>> @@ -1484,6 +1608,31 @@ get_ctxid(struct workload *wrk, struct w_step *w)
>>> return wrk->ctx_list[w->context].id;
>>> }
>>> +static struct xe_exec_queue *
>>> +xe_get_eq(struct workload *wrk, const struct w_step *w)
>>> +{
>>> + struct ctx *ctx = __get_ctx(wrk, w);
>>> + struct xe_exec_queue *eq;
>>> +
>>> + if (ctx->engine_map) {
>>> + igt_assert_eq(ctx->xe.nr_queues, 1);
>>> + igt_assert(ctx->xe.queue_list[0].id);
>>> + eq = &ctx->xe.queue_list[0];
>>> + } else {
>>> + igt_assert(w->engine >= 0 && w->engine < ctx->xe.nr_queues);
>>> + igt_assert(ctx->xe.queue_list[w->engine].id);
>>> + eq = &ctx->xe.queue_list[w->engine];
>>> + }
>>> +
>>> + return eq;
>>> +}
>>> +
>>> +static struct xe_vm *
>>> +xe_get_vm(struct workload *wrk, const struct w_step *w)
>>> +{
>>> + return wrk->xe.vm_list;
>>> +}
>>> +
>>> static uint32_t alloc_bo(int i915, unsigned long size)
>>> {
>>> return gem_create(i915, size);
>>> @@ -1557,6 +1706,71 @@ alloc_step_batch(struct workload *wrk, struct
>>> w_step *w)
>>> #endif
>>> }
>>> +static void
>>> +xe_alloc_step_batch(struct workload *wrk, struct w_step *w)
>>> +{
>>> + struct xe_vm *vm = xe_get_vm(wrk, w);
>>> + struct xe_exec_queue *eq = xe_get_eq(wrk, w);
>>> + struct dep_entry *dep;
>>> + int i;
>>> +
>>> + w->bb_handle = xe_bo_create_flags(fd, vm->id, PAGE_SIZE,
>>> + visible_vram_if_possible(fd, eq->hwe_list[0].gt_id));
>>> + w->xe.data = xe_bo_map(fd, w->bb_handle, PAGE_SIZE);
>>> + w->xe.exec.address =
>>> + intel_allocator_alloc_with_strategy(vm->ahnd, w->bb_handle,
>>> PAGE_SIZE,
>>> + 0, ALLOC_STRATEGY_LOW_TO_HIGH);
>>> + xe_vm_bind_sync(fd, vm->id, w->bb_handle, 0, w->xe.exec.address,
>>> PAGE_SIZE);
>>> + xe_spin_init_opts(&w->xe.data->spin, .addr = w->xe.exec.address,
>>> + .preempt = (w->preempt_us > 0),
>>> + .ctx_ticks = duration_to_ctx_ticks(fd,
>>> eq->hwe_list[0].gt_id,
>>> + 1000LL * get_duration(wrk, w)));
>>> + w->xe.exec.exec_queue_id = eq->id;
>>> + w->xe.exec.num_batch_buffer = 1;
>>> + /* always at least one out fence */
>>> + w->xe.exec.num_syncs = 1;
>>> + /* count syncs */
>>> + for_each_dep(dep, w->data_deps) {
>>> + int dep_idx = w->idx + dep->target;
>>> +
>>> + igt_assert(dep_idx >= 0 && dep_idx < w->idx);
>>> + igt_assert(wrk->steps[dep_idx].type == BATCH);
>>> +
>>> + w->xe.exec.num_syncs++;
>>> + }
>>> + for_each_dep(dep, w->fence_deps) {
>>> + int dep_idx = w->idx + dep->target;
>>> +
>>> + igt_assert(dep_idx >= 0 && dep_idx < w->idx);
>>> + igt_assert(wrk->steps[dep_idx].type == SW_FENCE ||
>>> + wrk->steps[dep_idx].type == BATCH);
>>> +
>>> + w->xe.exec.num_syncs++;
>>> + }
>>> + w->xe.syncs = calloc(w->xe.exec.num_syncs, sizeof(*w->xe.syncs));
>>> + /* fill syncs */
>>> + i = 0;
>>> + /* out fence */
>>> + w->xe.syncs[i].handle = syncobj_create(fd, 0);
>>> + w->xe.syncs[i++].flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL;
>>> + /* in fence(s) */
>>> + for_each_dep(dep, w->data_deps) {
>>> + int dep_idx = w->idx + dep->target;
>>> +
>>> + igt_assert(wrk->steps[dep_idx].xe.syncs &&
>>> wrk->steps[dep_idx].xe.syncs[0].handle);
>>> + w->xe.syncs[i].handle = wrk->steps[dep_idx].xe.syncs[0].handle;
>>> + w->xe.syncs[i++].flags = DRM_XE_SYNC_SYNCOBJ;
>>> + }
>>> + for_each_dep(dep, w->fence_deps) {
>>> + int dep_idx = w->idx + dep->target;
>>> +
>>> + igt_assert(wrk->steps[dep_idx].xe.syncs &&
>>> wrk->steps[dep_idx].xe.syncs[0].handle);
>>> + w->xe.syncs[i].handle = wrk->steps[dep_idx].xe.syncs[0].handle;
>>> + w->xe.syncs[i++].flags = DRM_XE_SYNC_SYNCOBJ;
>>> + }
>>> + w->xe.exec.syncs = to_user_pointer(w->xe.syncs);
>>> +}
>>> +
>>> static bool set_priority(uint32_t ctx_id, int prio)
>>> {
>>> struct drm_i915_gem_context_param param = {
>>> @@ -1739,6 +1953,9 @@ static void measure_active_set(struct workload
>>> *wrk)
>>> batch_sizes += 4096;
>>> + if (is_xe)
>>> + continue;
>>
>> I guess you re-use data_deps for something with xe so you can't just
>> let it run the loop here and find no data deps, resulting in the same
>> zero result?
>
> data_deps is allowed for BATCH type dependency only (WORKING_SET is not
> implemented yet) and protects against "f,1.DEFAULT.1000.-1.0".
> As we do not share any buffer yet, I skip the loop for now, otherwise I
> would need other if for:
>
> _dep.target = wrk->steps[idx].i915.obj[0].handle;
>
>>
>>> +
>>> for_each_dep(dep, w->data_deps) {
>>> struct dep_entry _dep = *dep;
>>> @@ -1782,6 +1999,31 @@ static void measure_active_set(struct workload
>>> *wrk)
>>> #define alloca0(sz) ({ size_t sz__ = (sz); memset(alloca(sz__), 0,
>>> sz__); })
>>> +static void xe_vm_create_(struct xe_vm *vm)
>>> +{
>>> + uint32_t flags = 0;
>>> +
>>> + if (vm->compute_mode)
>>> + flags |= DRM_XE_VM_CREATE_ASYNC_BIND_OPS |
>>> + DRM_XE_VM_CREATE_COMPUTE_MODE;
>>> +
>>> + vm->id = xe_vm_create(fd, flags, 0);
>>> +}
>>> +
>>> +static void xe_exec_queue_create_(struct ctx *ctx, struct
>>> xe_exec_queue *eq)
>>> +{
>>> + struct drm_xe_exec_queue_create create = {
>>> + .vm_id = ctx->xe.vm->id,
>>> + .width = 1,
>>> + .num_placements = eq->nr_hwes,
>>> + .instances = to_user_pointer(eq->hwe_list),
>>> + };
>>> +
>>> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC_QUEUE_CREATE,
>>> &create), 0);
>>> +
>>> + eq->id = create.exec_queue_id;
>>> +}
>>> +
>>> static void allocate_contexts(unsigned int id, struct workload *wrk)
>>> {
>>> int max_ctx = -1;
>>> @@ -1984,6 +2226,140 @@ static int prepare_contexts(unsigned int id,
>>> struct workload *wrk)
>>> return 0;
>>> }
>>> +static int xe_prepare_contexts(unsigned int id, struct workload *wrk)
>>> +{
>>> + struct xe_exec_queue *eq;
>>> + struct w_step *w;
>>> + struct ctx *ctx;
>>> + unsigned int i;
>>> +
>>> + /* shortcut, create one vm */
>>> + wrk->xe.nr_vms = 1;
>>> + wrk->xe.vm_list = calloc(wrk->xe.nr_vms, sizeof(struct xe_vm));
>>> + wrk->xe.vm_list->compute_mode = false;
>>> + xe_vm_create_(wrk->xe.vm_list);
>>> + wrk->xe.vm_list->ahnd = intel_allocator_open(fd,
>>> wrk->xe.vm_list->id,
>>> + INTEL_ALLOCATOR_RELOC);
>>> +
>>> + for_each_ctx_ctx_idx(ctx, wrk, ctx_idx) {
>>> + /* link with vm */
>>> + ctx->xe.vm = wrk->xe.vm_list;
>>> + for_each_w_step(w, wrk) {
>>> + if (w->context != ctx_idx)
>>> + continue;
>>> + if (w->type == ENGINE_MAP) {
>>> + ctx->engine_map = w->engine_map;
>>> + ctx->engine_map_count = w->engine_map_count;
>>> + } else if (w->type == LOAD_BALANCE) {
>>> + if (!ctx->engine_map) {
>>> + wsim_err("Load balancing needs an engine map!\n");
>>> + return 1;
>>> + }
>>> + if (intel_gen(intel_get_drm_devid(fd)) < 11) {
>>> + wsim_err("Load balancing needs relative mmio
>>> support, gen11+!\n");
>>> + return 1;
>>> + }
>>
>> If xe supports gen12+ then you can drop this?
>
> good point.
>
>>
>>> + ctx->load_balance = w->load_balance;
>>> + }
>>> + }
>>> +
>>> + /* create exec queue for each referenced engine */
>>> + if (ctx->engine_map) {
>>> + ctx->xe.nr_queues = 1;
>>> + ctx->xe.queue_list = calloc(ctx->xe.nr_queues,
>>> sizeof(*ctx->xe.queue_list));
>>> + igt_assert(ctx->xe.queue_list);
>>> + eq = &ctx->xe.queue_list[ctx->xe.nr_queues - 1];
>>> + eq->nr_hwes = ctx->engine_map_count;
>>> + eq->hwe_list = calloc(eq->nr_hwes, sizeof(*eq->hwe_list));
>>> + for (i = 0; i < eq->nr_hwes; ++i) {
>>> + eq->hwe_list[i] = xe_get_engine(ctx->engine_map[i]);
>>> +
>>> + /* check no mixing classes and no duplicates */
>>> + for (int j = 0; j < i; ++j) {
>>> + if (eq->hwe_list[j].engine_class !=
>>> + eq->hwe_list[i].engine_class) {
>>> + free(eq->hwe_list);
>>> + eq->nr_hwes = 0;
>>> + wsim_err("Mixing of engine class not
>>> supported!\n");
>>> + return 1;
>>> + }
>>> +
>>> + if (eq->hwe_list[j].engine_instance ==
>>> + eq->hwe_list[i].engine_instance) {
>>> + free(eq->hwe_list);
>>> + eq->nr_hwes = 0;
>>> + wsim_err("Duplicate engine entry!\n");
>>> + return 1;
>>> + }
>>> + }
>>> +
>>> + if (verbose > 3)
>>> + printf("%u ctx[%d] %s [%u:%u:%u]\n",
>>> + id, ctx_idx, ring_str_map[ctx->engine_map[i]],
>>> + eq->hwe_list[i].engine_class,
>>> + eq->hwe_list[i].engine_instance,
>>> + eq->hwe_list[i].gt_id);
>>> + }
>>> +
>>> + xe_exec_queue_create_(ctx, eq);
>>> + } else {
>>> + int engine_classes[NUM_ENGINES] = {};
>>> +
>>> + ctx->xe.nr_queues = NUM_ENGINES;
>>> + ctx->xe.queue_list = calloc(ctx->xe.nr_queues,
>>> sizeof(*ctx->xe.queue_list));
>>> +
>>> + for_each_w_step(w, wrk) {
>>> + if (w->context != ctx_idx)
>>> + continue;
>>> + if (w->type == BATCH)
>>> + engine_classes[w->engine]++;
>>> + }
>>> +
>>> + for (i = 0; i < NUM_ENGINES; i++) {
>>> + if (engine_classes[i]) {
>>> + eq = &ctx->xe.queue_list[i];
>>> + eq->nr_hwes = 1;
>>> + eq->hwe_list = calloc(1, sizeof(*eq->hwe_list));
>>> +
>>> + if (i == DEFAULT) {
>>> + struct drm_xe_engine_class_instance *hwe;
>>> +
>>> + /* select first available engine */
>>
>> With no engine map you probably want to ensure this is rcs0 to ensure
>> cross driver workload compatibility. Maybe xe_for_each_hw_engine
>> already works like that, I don't know.
>
> DEFAULT works when no RCS is present (for i915). Maybe I should search
> for RCS and return whatever is first when not found, something like:
>
> /* select RCS0 or first available engine */
> eq->hwe_list[0] = *xe_hw_engine(fd, 0);
> xe_for_each_hw_engine(fd, hwe) {
> if (hwe->engine_class == DRM_XE_ENGINE_CLASS_RENDER &&
> hwe->engine_instance == 0) {
> eq->hwe_list[0] = *hwe;
> break;
> }
> }
>
Hm yes I think so. Sounds okay to define wsim's DEFAULT as first render
engine and not really care about platforms which don't have it.
Regards,
Tvrtko
>>
>>> + xe_for_each_hw_engine(fd, hwe) {
>>> + eq->hwe_list[0] = *hwe;
>>> + break;
>>> + }
>>> + } else if (i == VCS) {
>>> + eq->hwe_list[0] = xe_get_engine(VCS1);
>>> + } else {
>>> + eq->hwe_list[0] = xe_get_engine(i);
>>> + }
>>> +
>>> + if (verbose > 3)
>>> + printf("%u ctx[%d] %s [%u:%u:%u]\n",
>>> + id, ctx_idx, ring_str_map[i],
>>> + eq->hwe_list[0].engine_class,
>>> + eq->hwe_list[0].engine_instance,
>>> + eq->hwe_list[0].gt_id);
>>> +
>>> + xe_exec_queue_create_(ctx, eq);
>>> + }
>>> + engine_classes[i] = 0;
>>> + }
>>> + }
>>> + }
>>> +
>>> + /* create syncobjs for SW_FENCE */
>>> + for_each_w_step(w, wrk)
>>> + if (w->type == SW_FENCE) {
>>> + w->xe.syncs = calloc(1, sizeof(struct drm_xe_sync));
>>> + w->xe.syncs[0].handle = syncobj_create(fd, 0);
>>> + w->xe.syncs[0].flags = DRM_XE_SYNC_SYNCOBJ;
>>> + }
>>> +
>>> + return 0;
>>> +}
>>> +
>>> static void prepare_working_sets(unsigned int id, struct workload
>>> *wrk)
>>> {
>>> struct working_set **sets;
>>> @@ -2051,7 +2427,11 @@ static int prepare_workload(unsigned int id,
>>> struct workload *wrk)
>>> allocate_contexts(id, wrk);
>>> - ret = prepare_contexts(id, wrk);
>>> + if (is_xe)
>>> + ret = xe_prepare_contexts(id, wrk);
>>> + else
>>> + ret = prepare_contexts(id, wrk);
>>> +
>>> if (ret)
>>> return ret;
>>> @@ -2104,7 +2484,10 @@ static int prepare_workload(unsigned int id,
>>> struct workload *wrk)
>>> if (w->type != BATCH)
>>> continue;
>>> - alloc_step_batch(wrk, w);
>>> + if (is_xe)
>>> + xe_alloc_step_batch(wrk, w);
>>> + else
>>> + alloc_step_batch(wrk, w);
>>> }
>>> measure_active_set(wrk);
>>> @@ -2154,6 +2537,24 @@ static void w_sync_to(struct workload *wrk,
>>> struct w_step *w, int target)
>>> w_step_sync(&wrk->steps[target]);
>>> }
>>> +static void do_xe_exec(struct workload *wrk, struct w_step *w)
>>> +{
>>> + struct xe_exec_queue *eq = xe_get_eq(wrk, w);
>>> +
>>> + igt_assert(w->emit_fence <= 0);
>>> + if (w->emit_fence == -1)
>>> + syncobj_reset(fd, &w->xe.syncs[0].handle, 1);
>>> +
>>> + /* update duration if random */
>>> + if (w->duration.max != w->duration.min)
>>> + xe_spin_init_opts(&w->xe.data->spin,
>>> + .addr = w->xe.exec.address,
>>> + .preempt = (w->preempt_us > 0),
>>> + .ctx_ticks = duration_to_ctx_ticks(fd,
>>> eq->hwe_list[0].gt_id,
>>> + 1000LL * get_duration(wrk, w)));
>>> + xe_exec(fd, &w->xe.exec);
>>> +}
>>> +
>>> static void
>>> do_eb(struct workload *wrk, struct w_step *w, enum intel_engine_id
>>> engine)
>>> {
>>> @@ -2280,6 +2681,10 @@ static void *run_workload(void *data)
>>> sw_sync_timeline_create_fence(wrk->sync_timeline,
>>> cur_seqno + w->idx);
>>> igt_assert(w->emit_fence > 0);
>>> + if (is_xe)
>>> + /* Convert sync file to syncobj */
>>> + syncobj_import_sync_file(fd, w->xe.syncs[0].handle,
>>> + w->emit_fence);
>>> continue;
>>> } else if (w->type == SW_FENCE_SIGNAL) {
>>> int tgt = w->idx + w->target;
>>> @@ -2311,7 +2716,10 @@ static void *run_workload(void *data)
>>> igt_assert(wrk->steps[t_idx].type == BATCH);
>>> igt_assert(wrk->steps[t_idx].duration.unbound);
>>> - *wrk->steps[t_idx].i915.bb_duration = 0xffffffff;
>>> + if (is_xe)
>>> + xe_spin_end(&wrk->steps[t_idx].xe.data->spin);
>>> + else
>>> + *wrk->steps[t_idx].i915.bb_duration = 0xffffffff;
>>> __sync_synchronize();
>>> continue;
>>> } else if (w->type == SSEU) {
>>> @@ -2343,7 +2751,10 @@ static void *run_workload(void *data)
>>> if (throttle > 0)
>>> w_sync_to(wrk, w, w->idx - throttle);
>>> - do_eb(wrk, w, engine);
>>> + if (is_xe)
>>> + do_xe_exec(wrk, w);
>>> + else
>>> + do_eb(wrk, w, engine);
>>> if (w->request != -1) {
>>> igt_list_del(&w->rq_link);
>>> @@ -2389,6 +2800,10 @@ static void *run_workload(void *data)
>>> break;
>>> if (w->emit_fence > 0) {
>>> + if (is_xe) {
>>> + igt_assert(w->type == SW_FENCE);
>>> + syncobj_reset(fd, &w->xe.syncs[0].handle, 1);
>>> + }
>>> close(w->emit_fence);
>>> w->emit_fence = -1;
>>> }
>>> @@ -2403,6 +2818,23 @@ static void *run_workload(void *data)
>>> w_step_sync(w);
>>> }
>>> + if (is_xe) {
>>> + for_each_w_step(w, wrk) {
>>> + if (w->type == BATCH) {
>>> + w_step_sync(w);
>>> + syncobj_destroy(fd, w->xe.syncs[0].handle);
>>> + free(w->xe.syncs);
>>> + xe_vm_unbind_sync(fd, xe_get_vm(wrk, w)->id, 0,
>>> w->xe.exec.address,
>>> + PAGE_SIZE);
>>> + gem_munmap(w->xe.data, PAGE_SIZE);
>>> + gem_close(fd, w->bb_handle);
>>> + } else if (w->type == SW_FENCE) {
>>> + syncobj_destroy(fd, w->xe.syncs[0].handle);
>>> + free(w->xe.syncs);
>>> + }
>>> + }
>>> + }
>>> +
>>> clock_gettime(CLOCK_MONOTONIC, &t_end);
>>> if (wrk->print_stats) {
>>> @@ -2629,8 +3061,12 @@ int main(int argc, char **argv)
>>> ret = igt_device_find_first_i915_discrete_card(&card);
>>> if (!ret)
>>> ret = igt_device_find_integrated_card(&card);
>>> + if (!ret)
>>> + ret = igt_device_find_first_xe_discrete_card(&card);
>>> + if (!ret)
>>> + ret = igt_device_find_xe_integrated_card(&card);
>>> if (!ret) {
>>> - wsim_err("No device filter specified and no i915 devices
>>> found!\n");
>>> + wsim_err("No device filter specified and no intel
>>> devices found!\n");
>>> return EXIT_FAILURE;
>>> }
>>> }
>>> @@ -2653,6 +3089,10 @@ int main(int argc, char **argv)
>>> if (verbose > 1)
>>> printf("Using device %s\n", drm_dev);
>>> + is_xe = is_xe_device(fd);
>>> + if (is_xe)
>>> + xe_device_get(fd);
>>> +
>>> if (!nr_w_args) {
>>> wsim_err("No workload descriptor(s)!\n");
>>> goto err;
>>> @@ -2772,5 +3212,8 @@ int main(int argc, char **argv)
>>> out:
>>> exitcode = EXIT_SUCCESS;
>>> err:
>>> + if (is_xe)
>>> + xe_device_put(fd);
>>> +
>>> return exitcode;
>>> }
>>> diff --git a/benchmarks/wsim/README b/benchmarks/wsim/README
>>> index d4f3dd8ae..e43813335 100644
>>> --- a/benchmarks/wsim/README
>>> +++ b/benchmarks/wsim/README
>>> @@ -88,6 +88,19 @@ Batch durations can also be specified as infinite
>>> by using the '*' in the
>>> duration field. Such batches must be ended by the terminate command
>>> ('T')
>>> otherwise they will cause a GPU hang to be reported.
>>> +Xe and i915 differences
>>> +------------------------
>>> +
>>> +There are differences between Xe and i915, like not allowing a BO
>>> list to
>>> +be passed to an exec (and create implicit syncs). For more details see:
>>> +https://gitlab.freedesktop.org/drm/xe/kernel/-/blob/drm-xe-next/drivers/gpu/drm/xe/xe_exec.c
>>> +
>>> +Currently following batch steps are equal on Xe:
>>> +1.1000.-2.0 <==> 1.1000.f-2.0
>>> +and will create explicit sync fence dependency (via syncobjects).
>>> +
>>> +The data dependency need to wait for working sets implementation.
>>> +
>>> Sync (fd) fences
>>> ----------------
>>> @@ -131,7 +144,7 @@ runnable. When the second RCS batch completes the
>>> standalone fence is signaled
>>> which allows the two VCS batches to be executed. Finally we wait
>>> until the both
>>> VCS batches have completed before starting the (optional) next
>>> iteration.
>>> -Submit fences
>>> +Submit fences (i915 only)
>>> -------------
>>> Submit fences are a type of input fence which are signalled when
>>> the originating
>>> @@ -148,7 +161,7 @@ Submit fences have the identical syntax as the
>>> sync fences with the lower-case
>>> Here VCS1 and VCS2 batches will only be submitted for executing
>>> once the RCS
>>> batch enters the GPU.
>>> -Context priority
>>> +Context priority (i915 only)
>>> ----------------
>>> P.1.-1
>>> @@ -213,7 +226,7 @@ Example:
>>> This enables load balancing for context number one.
>>> -Engine bonds
>>> +Engine bonds (i915 only)
>>> ------------
>>> Engine bonds are extensions on load balanced contexts. They allow
>>> expressing
>>> @@ -261,7 +274,7 @@ then look like:
>>> 2.DEFAULT.1000.s-1.0
>>> a.-3
>>> -Context SSEU configuration
>>> +Context SSEU configuration (i915 only)
>>> --------------------------
>>> S.1.1
>>> @@ -281,7 +294,7 @@ Slice mask of -1 has a special meaning of "all
>>> slices". Otherwise any integer
>>> can be specifying as the slice mask, but beware any apart from 1
>>> and -1 can make
>>> the workload not portable between different GPUs.
>>> -Working sets
>>> +Working sets (i915 only)
>>> ------------
>>> When used plainly workload steps can create implicit data
>>> dependencies by
>>
>> Less than 500 lines, neat. Nothin offsensive jumps out, it all looks
>> cleanly organized. I did not do a detailed review of the new code so
>> from me just:
>>
>> Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>>
>> Regards,
>>
>> Tvrtko
^ permalink raw reply [flat|nested] 31+ messages in thread
end of thread, other threads:[~2023-10-09 8:38 UTC | newest]
Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-05 18:57 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 01/17] lib/igt_device_scan: added functions to get first Xe card Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 02/17] benchmarks/gem_wsim: reposition the unbound duration boolean Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 03/17] benchmarks/gem_wsim: fix duration range check Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 04/17] benchmarks/gem_wsim: extract duration parsing code to new function Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 05/17] benchmarks/gem_wsim: fix conflicting SSEU #define and enum Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 06/17] benchmarks/gem_wsim: cleanups Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 07/17] benchmarks/gem_wsim: reposition repeat_start variable Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 08/17] benchmarks/gem_wsim: use lib code to query engines Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 09/17] benchmarks/gem_wsim: allow comments in workload description files Marcin Bernatowicz
2023-10-06 8:37 ` Tvrtko Ursulin
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 10/17] benchmarks/gem_wsim: introduce w_step_sync function Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 11/17] benchmarks/gem_wsim: extract allocate and prepare contexts code to new functions Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 12/17] benchmarks/gem_wsim: extract prepare working sets code to new function Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 13/17] benchmarks/gem_wsim: group i915 fields Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 14/17] benchmarks/gem_wsim: for_each_dep macro Marcin Bernatowicz
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 15/17] benchmarks/gem_wsim: for_each_ctx macro Marcin Bernatowicz
2023-10-06 8:49 ` Tvrtko Ursulin
2023-10-06 10:49 ` Bernatowicz, Marcin
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 16/17] benchmarks/gem_wsim: for_each_w_step macro Marcin Bernatowicz
2023-10-06 11:19 ` Tvrtko Ursulin
2023-10-06 12:15 ` Bernatowicz, Marcin
2023-10-06 12:39 ` Tvrtko Ursulin
2023-10-05 18:57 ` [igt-dev] [PATCH i-g-t 17/17] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
2023-10-06 14:12 ` Tvrtko Ursulin
2023-10-06 15:43 ` Bernatowicz, Marcin
2023-10-09 8:38 ` Tvrtko Ursulin
2023-10-05 22:03 ` [igt-dev] ✓ Fi.CI.BAT: success for benchmarks/gem_wsim: added basic xe support (rev6) Patchwork
2023-10-06 0:10 ` [igt-dev] ✓ CI.xeBAT: " Patchwork
2023-10-06 12:23 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
-- strict thread matches above, loose matches on Subject: below --
2023-10-06 16:06 [igt-dev] [PATCH i-g-t 00/17] [RFC] benchmarks/gem_wsim: added basic xe support Marcin Bernatowicz
2023-10-06 16:06 ` [igt-dev] [PATCH i-g-t 05/17] benchmarks/gem_wsim: fix conflicting SSEU #define and enum Marcin Bernatowicz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox