[PATCH i-g-t 5/8] lib/xe: Split nsec to ticks abstraction
Lucas De Marchi
lucas.demarchi at intel.com
Sat Jan 4 07:15:45 UTC 2025
There are 2 things happening here: one is converting time in nanoseconds
to ticks by using the refclock, and another asserting a spin duration is
not so close to the maximum duration since there needs to be room for
context switch.
Move the time conversion to xe_util.c and adjust it to maintain
namespace and have better names. Places that do the time conversion to
pass to xe_spin then use the xe_spin_nsec_to_ticks() wrapper to
calculate the ticks.
Signed-off-by: Lucas De Marchi <lucas.demarchi at intel.com>
---
benchmarks/gem_wsim.c | 8 +++---
lib/xe/xe_spin.c | 47 +++++++++------------------------
lib/xe/xe_spin.h | 9 +++----
lib/xe/xe_util.c | 40 ++++++++++++++++++++++++++++
lib/xe/xe_util.h | 2 ++
tests/intel/xe_exec_mix_modes.c | 3 ++-
tests/intel/xe_spin_batch.c | 2 +-
7 files changed, 66 insertions(+), 45 deletions(-)
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index c4fd00a6a..454b6f017 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -1797,8 +1797,8 @@ xe_alloc_step_batch(struct workload *wrk, struct w_step *w)
xe_vm_bind_sync(fd, vm->id, w->bb_handle, 0, w->xe.exec.address, w->bb_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)));
+ .ctx_ticks = xe_spin_nsec_to_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 */
@@ -2655,8 +2655,8 @@ static void do_xe_exec(struct workload *wrk, struct w_step *w)
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)));
+ .ctx_ticks = xe_spin_nsec_to_ticks(fd, eq->hwe_list[0].gt_id,
+ 1000LL * get_duration(wrk, w)));
xe_exec(fd, &w->xe.exec);
}
diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c
index 2bde55856..333f8d7d8 100644
--- a/lib/xe/xe_spin.c
+++ b/lib/xe/xe_spin.c
@@ -13,43 +13,12 @@
#include "igt_core.h"
#include "igt_syncobj.h"
#include "intel_reg.h"
+
#include "xe_ioctl.h"
#include "xe_spin.h"
+#include "xe_util.h"
-static uint32_t read_timestamp_frequency(int fd, int gt_id)
-{
- struct xe_device *dev = xe_device_get(fd);
-
- igt_assert(dev && dev->gt_list && dev->gt_list->num_gt);
- igt_assert(gt_id >= 0 && gt_id <= dev->gt_list->num_gt);
-
- return dev->gt_list->gt_list[gt_id].reference_clock;
-}
-
-static uint64_t div64_u64_round_up(const uint64_t x, const uint64_t y)
-{
- igt_assert(y > 0);
- igt_assert_lte_u64(x, UINT64_MAX - (y - 1));
-
- return (x + y - 1) / y;
-}
-
-/**
- * duration_to_ctx_ticks:
- * @fd: opened device
- * @gt_id: tile id
- * @duration_ns: duration in nanoseconds to be converted to context timestamp ticks
- * @return: duration converted to context timestamp ticks.
- */
-uint32_t duration_to_ctx_ticks(int fd, int gt_id, uint64_t duration_ns)
-{
- uint32_t f = read_timestamp_frequency(fd, gt_id);
- uint64_t ctx_ticks = div64_u64_round_up(duration_ns * f, NSEC_PER_SEC);
-
- igt_assert_lt_u64(ctx_ticks, XE_SPIN_MAX_CTX_TICKS);
-
- return ctx_ticks;
-}
+#define XE_SPIN_MAX_CTX_TICKS (UINT32_MAX - 1000)
#define MI_SRM_CS_MMIO (1 << 19)
#define MI_LRI_CS_MMIO (1 << 19)
@@ -60,6 +29,16 @@ uint32_t duration_to_ctx_ticks(int fd, int gt_id, uint64_t duration_ns)
enum { START_TS, NOW_TS };
+
+uint32_t xe_spin_nsec_to_ticks(int fd, int gt_id, uint64_t nsec)
+{
+ uint32_t ticks = xe_nsec_to_ticks(fd, gt_id, nsec);
+
+ igt_assert_lt_u64(ticks, XE_SPIN_MAX_CTX_TICKS);
+
+ return ticks;
+}
+
/**
* xe_spin_init:
* @spin: pointer to mapped bo in which spinner code will be written
diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h
index 593065bc0..01f45eaeb 100644
--- a/lib/xe/xe_spin.h
+++ b/lib/xe/xe_spin.h
@@ -15,10 +15,8 @@
#include "xe_query.h"
#include "lib/igt_dummyload.h"
-#define XE_SPIN_MAX_CTX_TICKS (UINT32_MAX - 1000)
-
-/** struct xe_spin_opts
- *
+/**
+ * struct xe_spin_opts
* @addr: offset of spinner within vm
* @preempt: allow spinner to be preempted or not
* @ctx_ticks: number of ticks after which spinner is stopped, applied if > 0
@@ -68,7 +66,6 @@ struct xe_cork {
};
igt_spin_t *xe_spin_create(int fd, const struct igt_spin_factory *opt);
-uint32_t duration_to_ctx_ticks(int fd, int gt_id, uint64_t ns);
void xe_spin_init(struct xe_spin *spin, struct xe_spin_opts *opts);
struct xe_cork *
xe_cork_create(int fd, struct drm_xe_engine_class_instance *hwe, uint32_t vm,
@@ -82,6 +79,8 @@ void xe_cork_destroy(int fd, struct xe_cork *ctx);
#define xe_spin_init_opts(fd, ...) \
xe_spin_init(fd, &((struct xe_spin_opts){__VA_ARGS__}))
+uint32_t xe_spin_nsec_to_ticks(int fd, int gt_id, uint64_t nsec);
+
bool xe_spin_started(struct xe_spin *spin);
void xe_spin_sync_wait(int fd, struct igt_spin *spin);
void xe_spin_wait_started(struct xe_spin *spin);
diff --git a/lib/xe/xe_util.c b/lib/xe/xe_util.c
index f0b6bbb2d..06b378ce0 100644
--- a/lib/xe/xe_util.c
+++ b/lib/xe/xe_util.c
@@ -4,9 +4,11 @@
*/
#include "igt.h"
+#include "igt_core.h"
#include "igt_syncobj.h"
#include "igt_sysfs.h"
#include "intel_pat.h"
+
#include "xe/xe_ioctl.h"
#include "xe/xe_query.h"
#include "xe/xe_util.h"
@@ -235,3 +237,41 @@ void xe_bind_unbind_async(int xe, uint32_t vm, uint32_t bind_engine,
free(bind_ops);
}
+
+static uint32_t reference_clock(int fd, int gt_id)
+{
+ struct xe_device *dev = xe_device_get(fd);
+ uint32_t refclock;
+
+ igt_assert(dev && dev->gt_list && dev->gt_list->num_gt);
+ igt_assert(gt_id >= 0 && gt_id <= dev->gt_list->num_gt);
+
+ refclock = dev->gt_list->gt_list[gt_id].reference_clock;
+
+ igt_assert_lt(0, refclock);
+
+ return refclock;
+}
+
+static uint64_t div64_u64_round_up(const uint64_t x, const uint64_t y)
+{
+ igt_assert(y > 0);
+ igt_assert_lte_u64(x, UINT64_MAX - (y - 1));
+
+ return (x + y - 1) / y;
+}
+
+/**
+ * xe_nsec_to_ticks: convert time in nanoseconds to timestamp ticks
+ * @fd: opened device
+ * @gt_id: tile id
+ * @nsec: time in nanoseconds
+ *
+ * Return: Time converted to context timestamp ticks.
+ */
+uint32_t xe_nsec_to_ticks(int fd, int gt_id, uint64_t nsec)
+{
+ uint32_t refclock = reference_clock(fd, gt_id);
+
+ return div64_u64_round_up(nsec * refclock, NSEC_PER_SEC);
+}
diff --git a/lib/xe/xe_util.h b/lib/xe/xe_util.h
index c544d912f..06ebd3c2a 100644
--- a/lib/xe/xe_util.h
+++ b/lib/xe/xe_util.h
@@ -47,4 +47,6 @@ void xe_bind_unbind_async(int fd, uint32_t vm, uint32_t bind_engine,
struct igt_list_head *obj_list,
uint32_t sync_in, uint32_t sync_out);
+uint32_t xe_nsec_to_ticks(int fd, int gt_id, uint64_t ns);
+
#endif /* XE_UTIL_H */
diff --git a/tests/intel/xe_exec_mix_modes.c b/tests/intel/xe_exec_mix_modes.c
index eeae9d122..0bcd49cc0 100644
--- a/tests/intel/xe_exec_mix_modes.c
+++ b/tests/intel/xe_exec_mix_modes.c
@@ -22,6 +22,7 @@
#include "xe/xe_ioctl.h"
#include "xe/xe_query.h"
#include "xe/xe_spin.h"
+#include "xe/xe_util.h"
#include <string.h>
#define FLAG_EXEC_MODE_LR (0x1 << 0)
@@ -132,7 +133,7 @@ run_job(int fd, struct drm_xe_engine_class_instance *hwe,
if (job_type == SPINNER_INTERRUPTED) {
spin_opts.addr = addr + (char *)&data[SPIN_DATA].spin - (char *)data;
- spin_opts.ctx_ticks = duration_to_ctx_ticks(fd, 0, duration_ns);
+ spin_opts.ctx_ticks = xe_spin_nsec_to_ticks(fd, 0, duration_ns);
xe_spin_init(&data[SPIN_DATA].spin, &spin_opts);
if (engine_execution_mode == EXEC_MODE_LR)
sync[0].addr = addr + (char *)&data[SPIN_DATA].exec_sync - (char *)data;
diff --git a/tests/intel/xe_spin_batch.c b/tests/intel/xe_spin_batch.c
index 0ad2490a0..5d9afaf3d 100644
--- a/tests/intel/xe_spin_batch.c
+++ b/tests/intel/xe_spin_batch.c
@@ -277,7 +277,7 @@ static void xe_spin_fixed_duration(int fd, int gt, int class, int flags)
xe_vm_bind_sync(fd, vm, bo, 0, spin_addr, bo_size);
xe_spin_init_opts(spin, .addr = spin_addr,
.preempt = true,
- .ctx_ticks = duration_to_ctx_ticks(fd, 0, duration_ns));
+ .ctx_ticks = xe_spin_nsec_to_ticks(fd, 0, duration_ns));
exec.address = spin_addr;
exec.exec_queue_id = exec_queue;
--
2.47.0
More information about the igt-dev
mailing list