* [igt-dev] [PATCH i-g-t 0/2] Integrate igt_spin_new with Xe. @ 2023-05-25 5:55 sai.gowtham.ch 2023-05-25 5:55 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch ` (2 more replies) 0 siblings, 3 replies; 36+ messages in thread From: sai.gowtham.ch @ 2023-05-25 5:55 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Sai Gowtham Ch (2): lib/xe/xe_spin: Integrate igt_spin_new with Xe. tests/xe/xe_spin_batch: Add new test to exercise igt_spin_new for xe. lib/igt_dummyload.c | 24 +++++-- lib/igt_dummyload.h | 10 +++ lib/xe/xe_spin.c | 89 +++++++++++++++++++++++++ lib/xe/xe_spin.h | 7 ++ tests/meson.build | 1 + tests/xe/xe_spin_batch.c | 138 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 263 insertions(+), 6 deletions(-) create mode 100644 tests/xe/xe_spin_batch.c -- 2.39.1 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. 2023-05-25 5:55 [igt-dev] [PATCH i-g-t 0/2] Integrate igt_spin_new with Xe sai.gowtham.ch @ 2023-05-25 5:55 ` sai.gowtham.ch 2023-05-29 5:51 ` Zbigniew Kempczyński 2023-05-25 5:55 ` [igt-dev] [PATCH i-g-t 2/2] tests/xe/xe_spin_batch: Add new test to exercise igt_spin_new for xe sai.gowtham.ch 2023-05-25 6:07 ` [igt-dev] ✗ GitLab.Pipeline: warning for Integrate igt_spin_new with Xe. (rev2) Patchwork 2 siblings, 1 reply; 36+ messages in thread From: sai.gowtham.ch @ 2023-05-25 5:55 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> --- lib/igt_dummyload.c | 24 +++++++++--- lib/igt_dummyload.h | 10 +++++ lib/xe/xe_spin.c | 89 +++++++++++++++++++++++++++++++++++++++++++++ lib/xe/xe_spin.h | 7 ++++ 4 files changed, 124 insertions(+), 6 deletions(-) diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index 740a58f3..6e89b72d 100644 --- a/lib/igt_dummyload.c +++ b/lib/igt_dummyload.c @@ -46,6 +46,7 @@ #include "intel_reg.h" #include "ioctl_wrappers.h" #include "sw_sync.h" +#include "xe/xe_spin.h" /** * SECTION:igt_dummyload @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory *opts) igt_spin_t * __igt_spin_factory(int fd, const struct igt_spin_factory *opts) { - return spin_create(fd, opts); + if (is_xe_device(fd)) + return xe_spin_create(fd, opts); + else + return spin_create(fd, opts); } /** @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) { igt_spin_t *spin; + if (is_xe_device(fd)) { + spin = xe_spin_create(fd, opts); + return spin; + } + if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { unsigned int class; @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) if (!spin) return; - pthread_mutex_lock(&list_lock); - igt_list_del(&spin->link); - pthread_mutex_unlock(&list_lock); - - __igt_spin_free(fd, spin); + if (is_xe_device(fd)) { + xe_spin_free(fd, spin); + } else { + pthread_mutex_lock(&list_lock); + igt_list_del(&spin->link); + pthread_mutex_unlock(&list_lock); + __igt_spin_free(fd, spin); + } } void igt_terminate_spins(void) diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index b247ab02..7bcc7b56 100644 --- a/lib/igt_dummyload.h +++ b/lib/igt_dummyload.h @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { unsigned int flags; int fence; uint64_t ahnd; + struct drm_xe_engine_class_instance *hwe; + uint32_t vm; } igt_spin_factory_t; typedef struct igt_spin { @@ -83,6 +85,14 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 << 0) struct igt_spin_factory opts; + + struct xe_spin *xe_spin; + size_t bo_size; + uint64_t address; + unsigned int engine; + uint32_t vm; + uint32_t syncobj; + } igt_spin_t; diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index 856d0ba2..3a8c7bb3 100644 --- a/lib/xe/xe_spin.c +++ b/lib/xe/xe_spin.c @@ -15,6 +15,7 @@ #include "intel_reg.h" #include "xe_ioctl.h" #include "xe_spin.h" +#include "lib/igt_dummyload.h" /** * xe_spin_init: @@ -82,6 +83,94 @@ void xe_spin_end(struct xe_spin *spin) spin->end = 0; } +igt_spin_t * +xe_spin_create(int fd, const struct igt_spin_factory *opt) +{ + size_t bo_size = xe_get_default_alignment(fd); + uint32_t bo; + uint64_t ahnd = opt->ahnd, addr; + struct igt_spin *spin; + struct xe_spin *xe_spin; + struct drm_xe_sync sync = { + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, + }; + struct drm_xe_exec exec = { + .num_batch_buffer = 1, + .num_syncs = 1, + .syncs = to_user_pointer(&sync), + }; + + igt_assert(ahnd); + spin = calloc(1, sizeof(struct igt_spin)); + igt_assert(spin); + + spin->syncobj = syncobj_create(fd, 0); + if (opt->engine) { + spin->opts.engine = opt->engine; + spin->opts.vm = opt->vm; + + spin->handle = xe_bo_create(fd, 0, spin->opts.vm, bo_size); + xe_spin = xe_bo_map(fd, spin->handle, bo_size); + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); + xe_vm_bind_sync(fd, spin->opts.vm, spin->handle, 0, addr, bo_size); + + xe_spin_init(xe_spin, addr, true); + exec.engine_id = spin->opts.engine; + exec.address = addr; + } else { + spin->vm = xe_vm_create(fd, 0, 0); + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); + + bo = xe_bo_create(fd, 0, spin->vm, bo_size); + spin->handle = bo; + xe_spin = xe_bo_map(fd, spin->handle, bo_size); + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); + + xe_spin_init(xe_spin, addr, true); + exec.engine_id = spin->engine; + exec.address = addr; + } + sync.handle = spin->syncobj; + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); + xe_spin_wait_started(xe_spin); + igt_info("Spinner started\n"); + + spin->bo_size = bo_size; + spin->address = addr; + spin->xe_spin = xe_spin; + + return spin; +} + +void xe_spin_sync_wait(int fd, struct igt_spin *spin) +{ + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, + NULL)); +} + +void xe_spin_free(int fd, struct igt_spin *spin) +{ + xe_spin_end(spin->xe_spin); + xe_spin_sync_wait(fd, spin); + + if (!spin->opts.engine) { + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); + } else { + xe_vm_unbind_sync(fd, spin->opts.vm, 0, spin->address, spin->bo_size); + } + + syncobj_destroy(fd, spin->syncobj); + gem_munmap(spin->xe_spin, spin->bo_size); + gem_close(fd, spin->handle); + + if (!spin->opts.engine) { + xe_engine_destroy(fd, spin->engine); + xe_vm_destroy(fd, spin->vm); + } + free(spin); +} + void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, struct xe_cork *cork) { diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index 73f9a026..48867eb8 100644 --- a/lib/xe/xe_spin.h +++ b/lib/xe/xe_spin.h @@ -13,19 +13,26 @@ #include <stdbool.h> #include "xe_query.h" +#include "lib/igt_dummyload.h" /* Mapped GPU object */ + struct xe_spin { uint32_t batch[16]; uint64_t pad; uint32_t start; uint32_t end; + }; +igt_spin_t * +xe_spin_create(int fd, const struct igt_spin_factory *opt); void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); 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); void xe_spin_end(struct xe_spin *spin); +void xe_spin_free(int fd, struct igt_spin *spin); struct xe_cork { struct xe_spin *spin; -- 2.39.1 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. 2023-05-25 5:55 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch @ 2023-05-29 5:51 ` Zbigniew Kempczyński 2023-05-30 4:39 ` Ch, Sai Gowtham 0 siblings, 1 reply; 36+ messages in thread From: Zbigniew Kempczyński @ 2023-05-29 5:51 UTC (permalink / raw) To: sai.gowtham.ch; +Cc: igt-dev On Thu, May 25, 2023 at 11:25:18AM +0530, sai.gowtham.ch@intel.com wrote: > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > Extending the spin_create implementation and allocator handle support in xe, > where it submits dummy work loads to engine. This Implementation is wrapped > around vm_bind and unbind as we are supposed to do it manually for xe. > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > --- > lib/igt_dummyload.c | 24 +++++++++--- > lib/igt_dummyload.h | 10 +++++ > lib/xe/xe_spin.c | 89 +++++++++++++++++++++++++++++++++++++++++++++ > lib/xe/xe_spin.h | 7 ++++ > 4 files changed, 124 insertions(+), 6 deletions(-) > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c > index 740a58f3..6e89b72d 100644 > --- a/lib/igt_dummyload.c > +++ b/lib/igt_dummyload.c > @@ -46,6 +46,7 @@ > #include "intel_reg.h" > #include "ioctl_wrappers.h" > #include "sw_sync.h" > +#include "xe/xe_spin.h" > > /** > * SECTION:igt_dummyload > @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory *opts) > igt_spin_t * > __igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > - return spin_create(fd, opts); > + if (is_xe_device(fd)) > + return xe_spin_create(fd, opts); > + else > + return spin_create(fd, opts); > } > > /** > @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > igt_spin_t *spin; > > + if (is_xe_device(fd)) { > + spin = xe_spin_create(fd, opts); > + return spin; > + } > + > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { > unsigned int class; > > @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > if (!spin) > return; > > - pthread_mutex_lock(&list_lock); > - igt_list_del(&spin->link); > - pthread_mutex_unlock(&list_lock); > - > - __igt_spin_free(fd, spin); > + if (is_xe_device(fd)) { > + xe_spin_free(fd, spin); > + } else { > + pthread_mutex_lock(&list_lock); > + igt_list_del(&spin->link); > + pthread_mutex_unlock(&list_lock); > + __igt_spin_free(fd, spin); > + } > } > > void igt_terminate_spins(void) > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h > index b247ab02..7bcc7b56 100644 > --- a/lib/igt_dummyload.h > +++ b/lib/igt_dummyload.h > @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { > unsigned int flags; > int fence; > uint64_t ahnd; > + struct drm_xe_engine_class_instance *hwe; > + uint32_t vm; > } igt_spin_factory_t; > > typedef struct igt_spin { > @@ -83,6 +85,14 @@ typedef struct igt_spin { > #define SPIN_CLFLUSH (1 << 0) > > struct igt_spin_factory opts; > + > + struct xe_spin *xe_spin; > + size_t bo_size; > + uint64_t address; > + unsigned int engine; > + uint32_t vm; > + uint32_t syncobj; > + > } igt_spin_t; > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c > index 856d0ba2..3a8c7bb3 100644 > --- a/lib/xe/xe_spin.c > +++ b/lib/xe/xe_spin.c > @@ -15,6 +15,7 @@ > #include "intel_reg.h" > #include "xe_ioctl.h" > #include "xe_spin.h" > +#include "lib/igt_dummyload.h" > > /** > * xe_spin_init: > @@ -82,6 +83,94 @@ void xe_spin_end(struct xe_spin *spin) > spin->end = 0; > } > > +igt_spin_t * > +xe_spin_create(int fd, const struct igt_spin_factory *opt) > +{ > + size_t bo_size = xe_get_default_alignment(fd); > + uint32_t bo; > + uint64_t ahnd = opt->ahnd, addr; > + struct igt_spin *spin; > + struct xe_spin *xe_spin; > + struct drm_xe_sync sync = { > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > + }; > + struct drm_xe_exec exec = { > + .num_batch_buffer = 1, > + .num_syncs = 1, > + .syncs = to_user_pointer(&sync), > + }; > + > + igt_assert(ahnd); > + spin = calloc(1, sizeof(struct igt_spin)); > + igt_assert(spin); > + > + spin->syncobj = syncobj_create(fd, 0); > + if (opt->engine) { > + spin->opts.engine = opt->engine; > + spin->opts.vm = opt->vm; > + > + spin->handle = xe_bo_create(fd, 0, spin->opts.vm, bo_size); > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > + xe_vm_bind_sync(fd, spin->opts.vm, spin->handle, 0, addr, bo_size); > + > + xe_spin_init(xe_spin, addr, true); > + exec.engine_id = spin->opts.engine; > + exec.address = addr; > + } else { > + spin->vm = xe_vm_create(fd, 0, 0); > + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); > + > + bo = xe_bo_create(fd, 0, spin->vm, bo_size); > + spin->handle = bo; > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); > + > + xe_spin_init(xe_spin, addr, true); > + exec.engine_id = spin->engine; > + exec.address = addr; > + } I think you should support two variants of executing spinners: 1. hwe != NULL (in this case engine must be 0): if (!vm) -> create vm; create engine for vm according to hwe 2. engine != 0, vm must be vm on top of which engine was created hwe must be NULL in this case see Dominik answer about passing engine+vm in: https://patchwork.freedesktop.org/patch/539173/?series=118227&rev=2 And add support ALL_ENGINES flag (then iterate over all hw engines like Bhanu suggested). And track engine ownership - if caller is the engine/vm owner use it but don't destroy, if spinner code is creating engine you may freely destroy it in spinner free path(). -- Zbigniew > + sync.handle = spin->syncobj; > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > + xe_spin_wait_started(xe_spin); > + igt_info("Spinner started\n"); > + > + spin->bo_size = bo_size; > + spin->address = addr; > + spin->xe_spin = xe_spin; > + > + return spin; > +} > + > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) > +{ > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, > + NULL)); > +} > + > +void xe_spin_free(int fd, struct igt_spin *spin) > +{ > + xe_spin_end(spin->xe_spin); > + xe_spin_sync_wait(fd, spin); > + > + if (!spin->opts.engine) { > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); > + } else { > + xe_vm_unbind_sync(fd, spin->opts.vm, 0, spin->address, spin->bo_size); > + } > + > + syncobj_destroy(fd, spin->syncobj); > + gem_munmap(spin->xe_spin, spin->bo_size); > + gem_close(fd, spin->handle); > + > + if (!spin->opts.engine) { > + xe_engine_destroy(fd, spin->engine); > + xe_vm_destroy(fd, spin->vm); > + } > + free(spin); > +} > + > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > struct xe_cork *cork) > { > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h > index 73f9a026..48867eb8 100644 > --- a/lib/xe/xe_spin.h > +++ b/lib/xe/xe_spin.h > @@ -13,19 +13,26 @@ > #include <stdbool.h> > > #include "xe_query.h" > +#include "lib/igt_dummyload.h" > > /* Mapped GPU object */ > + > struct xe_spin { > uint32_t batch[16]; > uint64_t pad; > uint32_t start; > uint32_t end; > + > }; > > +igt_spin_t * > +xe_spin_create(int fd, const struct igt_spin_factory *opt); > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); > 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); > void xe_spin_end(struct xe_spin *spin); > +void xe_spin_free(int fd, struct igt_spin *spin); > > struct xe_cork { > struct xe_spin *spin; > -- > 2.39.1 > ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. 2023-05-29 5:51 ` Zbigniew Kempczyński @ 2023-05-30 4:39 ` Ch, Sai Gowtham 2023-05-30 4:43 ` Modem, Bhanuprakash 0 siblings, 1 reply; 36+ messages in thread From: Ch, Sai Gowtham @ 2023-05-30 4:39 UTC (permalink / raw) To: Kempczynski, Zbigniew, Modem, Bhanuprakash, Gandi, Ramadevi; +Cc: igt-dev > -----Original Message----- > From: Kempczynski, Zbigniew <zbigniew.kempczynski@intel.com> > Sent: Monday, May 29, 2023 11:21 AM > To: Ch, Sai Gowtham <sai.gowtham.ch@intel.com> > Cc: igt-dev@lists.freedesktop.org > Subject: Re: [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. > > On Thu, May 25, 2023 at 11:25:18AM +0530, sai.gowtham.ch@intel.com wrote: > > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > > > Extending the spin_create implementation and allocator handle support > > in xe, where it submits dummy work loads to engine. This > > Implementation is wrapped around vm_bind and unbind as we are supposed to > do it manually for xe. > > > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > --- > > lib/igt_dummyload.c | 24 +++++++++--- lib/igt_dummyload.h | 10 +++++ > > lib/xe/xe_spin.c | 89 +++++++++++++++++++++++++++++++++++++++++++++ > > lib/xe/xe_spin.h | 7 ++++ > > 4 files changed, 124 insertions(+), 6 deletions(-) > > > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index > > 740a58f3..6e89b72d 100644 > > --- a/lib/igt_dummyload.c > > +++ b/lib/igt_dummyload.c > > @@ -46,6 +46,7 @@ > > #include "intel_reg.h" > > #include "ioctl_wrappers.h" > > #include "sw_sync.h" > > +#include "xe/xe_spin.h" > > > > /** > > * SECTION:igt_dummyload > > @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory > > *opts) igt_spin_t * __igt_spin_factory(int fd, const struct > > igt_spin_factory *opts) { > > - return spin_create(fd, opts); > > + if (is_xe_device(fd)) > > + return xe_spin_create(fd, opts); > > + else > > + return spin_create(fd, opts); > > } > > > > /** > > @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct > > igt_spin_factory *opts) { > > igt_spin_t *spin; > > > > + if (is_xe_device(fd)) { > > + spin = xe_spin_create(fd, opts); > > + return spin; > > + } > > + > > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != > ALL_ENGINES) { > > unsigned int class; > > > > @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > > if (!spin) > > return; > > > > - pthread_mutex_lock(&list_lock); > > - igt_list_del(&spin->link); > > - pthread_mutex_unlock(&list_lock); > > - > > - __igt_spin_free(fd, spin); > > + if (is_xe_device(fd)) { > > + xe_spin_free(fd, spin); > > + } else { > > + pthread_mutex_lock(&list_lock); > > + igt_list_del(&spin->link); > > + pthread_mutex_unlock(&list_lock); > > + __igt_spin_free(fd, spin); > > + } > > } > > > > void igt_terminate_spins(void) > > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index > > b247ab02..7bcc7b56 100644 > > --- a/lib/igt_dummyload.h > > +++ b/lib/igt_dummyload.h > > @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { > > unsigned int flags; > > int fence; > > uint64_t ahnd; > > + struct drm_xe_engine_class_instance *hwe; > > + uint32_t vm; > > } igt_spin_factory_t; > > > > typedef struct igt_spin { > > @@ -83,6 +85,14 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 > > << 0) > > > > struct igt_spin_factory opts; > > + > > + struct xe_spin *xe_spin; > > + size_t bo_size; > > + uint64_t address; > > + unsigned int engine; > > + uint32_t vm; > > + uint32_t syncobj; > > + > > } igt_spin_t; > > > > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index > > 856d0ba2..3a8c7bb3 100644 > > --- a/lib/xe/xe_spin.c > > +++ b/lib/xe/xe_spin.c > > @@ -15,6 +15,7 @@ > > #include "intel_reg.h" > > #include "xe_ioctl.h" > > #include "xe_spin.h" > > +#include "lib/igt_dummyload.h" > > > > /** > > * xe_spin_init: > > @@ -82,6 +83,94 @@ void xe_spin_end(struct xe_spin *spin) > > spin->end = 0; > > } > > > > +igt_spin_t * > > +xe_spin_create(int fd, const struct igt_spin_factory *opt) { > > + size_t bo_size = xe_get_default_alignment(fd); > > + uint32_t bo; > > + uint64_t ahnd = opt->ahnd, addr; > > + struct igt_spin *spin; > > + struct xe_spin *xe_spin; > > + struct drm_xe_sync sync = { > > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > > + }; > > + struct drm_xe_exec exec = { > > + .num_batch_buffer = 1, > > + .num_syncs = 1, > > + .syncs = to_user_pointer(&sync), > > + }; > > + > > + igt_assert(ahnd); > > + spin = calloc(1, sizeof(struct igt_spin)); > > + igt_assert(spin); > > + > > + spin->syncobj = syncobj_create(fd, 0); > > + if (opt->engine) { > > + spin->opts.engine = opt->engine; > > + spin->opts.vm = opt->vm; > > + > > + spin->handle = xe_bo_create(fd, 0, spin->opts.vm, bo_size); > > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, > bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > > + xe_vm_bind_sync(fd, spin->opts.vm, spin->handle, 0, addr, > bo_size); > > + > > + xe_spin_init(xe_spin, addr, true); > > + exec.engine_id = spin->opts.engine; > > + exec.address = addr; > > + } else { > > + spin->vm = xe_vm_create(fd, 0, 0); > > + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); > > + > > + bo = xe_bo_create(fd, 0, spin->vm, bo_size); > > + spin->handle = bo; > > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, > bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); > > + > > + xe_spin_init(xe_spin, addr, true); > > + exec.engine_id = spin->engine; > > + exec.address = addr; > > + } > > I think you should support two variants of executing spinners: > > 1. hwe != NULL (in this case engine must be 0): > if (!vm) -> create vm; > create engine for vm according to hwe > > 2. engine != 0, vm must be vm on top of which engine was created > hwe must be NULL in this case > see Dominik answer about passing engine+vm in: > https://patchwork.freedesktop.org/patch/539173/?series=118227&rev=2 > > And add support ALL_ENGINES flag (then iterate over all hw engines like Bhanu > suggested). And track engine ownership - if caller is the engine/vm owner use it > but don't destroy, if spinner code is creating engine you may freely destroy it in > spinner free path(). > Do we have Driver support for ALL_ENGINES flag ?? I think what Bhanu asking for is as kms tests doesn’t need hwe, We have to pass hwe from the xe_spin_create it self. In that case we can add a support in xe_spin_create where hwe = 0 and engine = 0 ( Note this is only for kms tests) . I feel ALL_ENGINES support can be added later, Once kms tests are unblocked. Regarding igt_spin_free, I've already added support not to destroy vm and engines if they are passed from the igt test. Can you have a look at igt_spin_free (Verified it's working fine for me). ----- Gowtham > -- > Zbigniew > > > > + sync.handle = spin->syncobj; > > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > > + xe_spin_wait_started(xe_spin); > > + igt_info("Spinner started\n"); > > + > > + spin->bo_size = bo_size; > > + spin->address = addr; > > + spin->xe_spin = xe_spin; > > + > > + return spin; > > +} > > + > > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) { > > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, > > + NULL)); > > +} > > + > > +void xe_spin_free(int fd, struct igt_spin *spin) { > > + xe_spin_end(spin->xe_spin); > > + xe_spin_sync_wait(fd, spin); > > + > > + if (!spin->opts.engine) { > > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin- > >bo_size); > > + } else { > > + xe_vm_unbind_sync(fd, spin->opts.vm, 0, spin->address, spin- > >bo_size); > > + } > > + > > + syncobj_destroy(fd, spin->syncobj); > > + gem_munmap(spin->xe_spin, spin->bo_size); > > + gem_close(fd, spin->handle); > > + > > + if (!spin->opts.engine) { > > + xe_engine_destroy(fd, spin->engine); > > + xe_vm_destroy(fd, spin->vm); > > + } > > + free(spin); > > +} > > + > > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > > struct xe_cork *cork) > > { > > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index > > 73f9a026..48867eb8 100644 > > --- a/lib/xe/xe_spin.h > > +++ b/lib/xe/xe_spin.h > > @@ -13,19 +13,26 @@ > > #include <stdbool.h> > > > > #include "xe_query.h" > > +#include "lib/igt_dummyload.h" > > > > /* Mapped GPU object */ > > + > > struct xe_spin { > > uint32_t batch[16]; > > uint64_t pad; > > uint32_t start; > > uint32_t end; > > + > > }; > > > > +igt_spin_t * > > +xe_spin_create(int fd, const struct igt_spin_factory *opt); > > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); > > 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); void > > xe_spin_end(struct xe_spin *spin); > > +void xe_spin_free(int fd, struct igt_spin *spin); > > > > struct xe_cork { > > struct xe_spin *spin; > > -- > > 2.39.1 > > ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. 2023-05-30 4:39 ` Ch, Sai Gowtham @ 2023-05-30 4:43 ` Modem, Bhanuprakash 2023-05-30 5:04 ` Ch, Sai Gowtham 0 siblings, 1 reply; 36+ messages in thread From: Modem, Bhanuprakash @ 2023-05-30 4:43 UTC (permalink / raw) To: Ch, Sai Gowtham, Kempczynski, Zbigniew, Gandi, Ramadevi; +Cc: igt-dev Hi Sai, On Tue-30-05-2023 10:09 am, Ch, Sai Gowtham wrote: > > >> -----Original Message----- >> From: Kempczynski, Zbigniew <zbigniew.kempczynski@intel.com> >> Sent: Monday, May 29, 2023 11:21 AM >> To: Ch, Sai Gowtham <sai.gowtham.ch@intel.com> >> Cc: igt-dev@lists.freedesktop.org >> Subject: Re: [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. >> >> On Thu, May 25, 2023 at 11:25:18AM +0530, sai.gowtham.ch@intel.com wrote: >>> From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> >>> >>> Extending the spin_create implementation and allocator handle support >>> in xe, where it submits dummy work loads to engine. This >>> Implementation is wrapped around vm_bind and unbind as we are supposed to >> do it manually for xe. >>> >>> Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> >>> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> >>> --- >>> lib/igt_dummyload.c | 24 +++++++++--- lib/igt_dummyload.h | 10 +++++ >>> lib/xe/xe_spin.c | 89 +++++++++++++++++++++++++++++++++++++++++++++ >>> lib/xe/xe_spin.h | 7 ++++ >>> 4 files changed, 124 insertions(+), 6 deletions(-) >>> >>> diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index >>> 740a58f3..6e89b72d 100644 >>> --- a/lib/igt_dummyload.c >>> +++ b/lib/igt_dummyload.c >>> @@ -46,6 +46,7 @@ >>> #include "intel_reg.h" >>> #include "ioctl_wrappers.h" >>> #include "sw_sync.h" >>> +#include "xe/xe_spin.h" >>> >>> /** >>> * SECTION:igt_dummyload >>> @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory >>> *opts) igt_spin_t * __igt_spin_factory(int fd, const struct >>> igt_spin_factory *opts) { >>> - return spin_create(fd, opts); >>> + if (is_xe_device(fd)) >>> + return xe_spin_create(fd, opts); >>> + else >>> + return spin_create(fd, opts); >>> } >>> >>> /** >>> @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct >>> igt_spin_factory *opts) { >>> igt_spin_t *spin; >>> >>> + if (is_xe_device(fd)) { >>> + spin = xe_spin_create(fd, opts); >>> + return spin; >>> + } >>> + >>> if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != >> ALL_ENGINES) { >>> unsigned int class; >>> >>> @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) >>> if (!spin) >>> return; >>> >>> - pthread_mutex_lock(&list_lock); >>> - igt_list_del(&spin->link); >>> - pthread_mutex_unlock(&list_lock); >>> - >>> - __igt_spin_free(fd, spin); >>> + if (is_xe_device(fd)) { >>> + xe_spin_free(fd, spin); >>> + } else { >>> + pthread_mutex_lock(&list_lock); >>> + igt_list_del(&spin->link); >>> + pthread_mutex_unlock(&list_lock); >>> + __igt_spin_free(fd, spin); >>> + } >>> } >>> >>> void igt_terminate_spins(void) >>> diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index >>> b247ab02..7bcc7b56 100644 >>> --- a/lib/igt_dummyload.h >>> +++ b/lib/igt_dummyload.h >>> @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { >>> unsigned int flags; >>> int fence; >>> uint64_t ahnd; >>> + struct drm_xe_engine_class_instance *hwe; >>> + uint32_t vm; >>> } igt_spin_factory_t; >>> >>> typedef struct igt_spin { >>> @@ -83,6 +85,14 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 >>> << 0) >>> >>> struct igt_spin_factory opts; >>> + >>> + struct xe_spin *xe_spin; >>> + size_t bo_size; >>> + uint64_t address; >>> + unsigned int engine; >>> + uint32_t vm; >>> + uint32_t syncobj; >>> + >>> } igt_spin_t; >>> >>> >>> diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index >>> 856d0ba2..3a8c7bb3 100644 >>> --- a/lib/xe/xe_spin.c >>> +++ b/lib/xe/xe_spin.c >>> @@ -15,6 +15,7 @@ >>> #include "intel_reg.h" >>> #include "xe_ioctl.h" >>> #include "xe_spin.h" >>> +#include "lib/igt_dummyload.h" >>> >>> /** >>> * xe_spin_init: >>> @@ -82,6 +83,94 @@ void xe_spin_end(struct xe_spin *spin) >>> spin->end = 0; >>> } >>> >>> +igt_spin_t * >>> +xe_spin_create(int fd, const struct igt_spin_factory *opt) { >>> + size_t bo_size = xe_get_default_alignment(fd); >>> + uint32_t bo; >>> + uint64_t ahnd = opt->ahnd, addr; >>> + struct igt_spin *spin; >>> + struct xe_spin *xe_spin; >>> + struct drm_xe_sync sync = { >>> + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, >>> + }; >>> + struct drm_xe_exec exec = { >>> + .num_batch_buffer = 1, >>> + .num_syncs = 1, >>> + .syncs = to_user_pointer(&sync), >>> + }; >>> + >>> + igt_assert(ahnd); >>> + spin = calloc(1, sizeof(struct igt_spin)); >>> + igt_assert(spin); >>> + >>> + spin->syncobj = syncobj_create(fd, 0); >>> + if (opt->engine) { >>> + spin->opts.engine = opt->engine; >>> + spin->opts.vm = opt->vm; >>> + >>> + spin->handle = xe_bo_create(fd, 0, spin->opts.vm, bo_size); >>> + xe_spin = xe_bo_map(fd, spin->handle, bo_size); >>> + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, >> bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); >>> + xe_vm_bind_sync(fd, spin->opts.vm, spin->handle, 0, addr, >> bo_size); >>> + >>> + xe_spin_init(xe_spin, addr, true); >>> + exec.engine_id = spin->opts.engine; >>> + exec.address = addr; >>> + } else { >>> + spin->vm = xe_vm_create(fd, 0, 0); >>> + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); >>> + >>> + bo = xe_bo_create(fd, 0, spin->vm, bo_size); >>> + spin->handle = bo; >>> + xe_spin = xe_bo_map(fd, spin->handle, bo_size); >>> + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, >> bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); >>> + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); >>> + >>> + xe_spin_init(xe_spin, addr, true); >>> + exec.engine_id = spin->engine; >>> + exec.address = addr; >>> + } >> >> I think you should support two variants of executing spinners: >> >> 1. hwe != NULL (in this case engine must be 0): >> if (!vm) -> create vm; >> create engine for vm according to hwe >> >> 2. engine != 0, vm must be vm on top of which engine was created >> hwe must be NULL in this case >> see Dominik answer about passing engine+vm in: >> https://patchwork.freedesktop.org/patch/539173/?series=118227&rev=2 >> >> And add support ALL_ENGINES flag (then iterate over all hw engines like Bhanu >> suggested). And track engine ownership - if caller is the engine/vm owner use it >> but don't destroy, if spinner code is creating engine you may freely destroy it in >> spinner free path(). >> > Do we have Driver support for ALL_ENGINES flag ?? > > I think what Bhanu asking for is as kms tests doesn’t need hwe, We have to pass hwe from the xe_spin_create it self. > In that case we can add a support in xe_spin_create where hwe = 0 and engine = 0 ( Note this is only for kms tests) . Yes, KMS tests are not supposed to pass hwe or engines. - Bhanu > > I feel ALL_ENGINES support can be added later, Once kms tests are unblocked. > > Regarding igt_spin_free, I've already added support not to destroy vm and engines if they are passed from the igt test. Can you have a look at igt_spin_free (Verified it's working fine for me). > ----- > Gowtham >> -- >> Zbigniew >> >> >>> + sync.handle = spin->syncobj; >>> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); >>> + xe_spin_wait_started(xe_spin); >>> + igt_info("Spinner started\n"); >>> + >>> + spin->bo_size = bo_size; >>> + spin->address = addr; >>> + spin->xe_spin = xe_spin; >>> + >>> + return spin; >>> +} >>> + >>> +void xe_spin_sync_wait(int fd, struct igt_spin *spin) { >>> + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, >>> + NULL)); >>> +} >>> + >>> +void xe_spin_free(int fd, struct igt_spin *spin) { >>> + xe_spin_end(spin->xe_spin); >>> + xe_spin_sync_wait(fd, spin); >>> + >>> + if (!spin->opts.engine) { >>> + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin- >>> bo_size); >>> + } else { >>> + xe_vm_unbind_sync(fd, spin->opts.vm, 0, spin->address, spin- >>> bo_size); >>> + } >>> + >>> + syncobj_destroy(fd, spin->syncobj); >>> + gem_munmap(spin->xe_spin, spin->bo_size); >>> + gem_close(fd, spin->handle); >>> + >>> + if (!spin->opts.engine) { >>> + xe_engine_destroy(fd, spin->engine); >>> + xe_vm_destroy(fd, spin->vm); >>> + } >>> + free(spin); >>> +} >>> + >>> void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, >>> struct xe_cork *cork) >>> { >>> diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index >>> 73f9a026..48867eb8 100644 >>> --- a/lib/xe/xe_spin.h >>> +++ b/lib/xe/xe_spin.h >>> @@ -13,19 +13,26 @@ >>> #include <stdbool.h> >>> >>> #include "xe_query.h" >>> +#include "lib/igt_dummyload.h" >>> >>> /* Mapped GPU object */ >>> + >>> struct xe_spin { >>> uint32_t batch[16]; >>> uint64_t pad; >>> uint32_t start; >>> uint32_t end; >>> + >>> }; >>> >>> +igt_spin_t * >>> +xe_spin_create(int fd, const struct igt_spin_factory *opt); >>> void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); >>> 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); void >>> xe_spin_end(struct xe_spin *spin); >>> +void xe_spin_free(int fd, struct igt_spin *spin); >>> >>> struct xe_cork { >>> struct xe_spin *spin; >>> -- >>> 2.39.1 >>> ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. 2023-05-30 4:43 ` Modem, Bhanuprakash @ 2023-05-30 5:04 ` Ch, Sai Gowtham 0 siblings, 0 replies; 36+ messages in thread From: Ch, Sai Gowtham @ 2023-05-30 5:04 UTC (permalink / raw) To: Modem, Bhanuprakash, Kempczynski, Zbigniew, Gandi, Ramadevi; +Cc: igt-dev > -----Original Message----- > From: Modem, Bhanuprakash <bhanuprakash.modem@intel.com> > Sent: Tuesday, May 30, 2023 10:14 AM > To: Ch, Sai Gowtham <sai.gowtham.ch@intel.com>; Kempczynski, Zbigniew > <zbigniew.kempczynski@intel.com>; Gandi, Ramadevi > <ramadevi.gandi@intel.com> > Cc: igt-dev@lists.freedesktop.org > Subject: Re: [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. > > Hi Sai, > > On Tue-30-05-2023 10:09 am, Ch, Sai Gowtham wrote: > > > > > >> -----Original Message----- > >> From: Kempczynski, Zbigniew <zbigniew.kempczynski@intel.com> > >> Sent: Monday, May 29, 2023 11:21 AM > >> To: Ch, Sai Gowtham <sai.gowtham.ch@intel.com> > >> Cc: igt-dev@lists.freedesktop.org > >> Subject: Re: [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. > >> > >> On Thu, May 25, 2023 at 11:25:18AM +0530, sai.gowtham.ch@intel.com > wrote: > >>> From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > >>> > >>> Extending the spin_create implementation and allocator handle > >>> support in xe, where it submits dummy work loads to engine. This > >>> Implementation is wrapped around vm_bind and unbind as we are > >>> supposed to > >> do it manually for xe. > >>> > >>> Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > >>> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > >>> --- > >>> lib/igt_dummyload.c | 24 +++++++++--- lib/igt_dummyload.h | 10 +++++ > >>> lib/xe/xe_spin.c | 89 > +++++++++++++++++++++++++++++++++++++++++++++ > >>> lib/xe/xe_spin.h | 7 ++++ > >>> 4 files changed, 124 insertions(+), 6 deletions(-) > >>> > >>> diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index > >>> 740a58f3..6e89b72d 100644 > >>> --- a/lib/igt_dummyload.c > >>> +++ b/lib/igt_dummyload.c > >>> @@ -46,6 +46,7 @@ > >>> #include "intel_reg.h" > >>> #include "ioctl_wrappers.h" > >>> #include "sw_sync.h" > >>> +#include "xe/xe_spin.h" > >>> > >>> /** > >>> * SECTION:igt_dummyload > >>> @@ -447,7 +448,10 @@ spin_create(int fd, const struct > >>> igt_spin_factory > >>> *opts) igt_spin_t * __igt_spin_factory(int fd, const struct > >>> igt_spin_factory *opts) { > >>> - return spin_create(fd, opts); > >>> + if (is_xe_device(fd)) > >>> + return xe_spin_create(fd, opts); > >>> + else > >>> + return spin_create(fd, opts); > >>> } > >>> > >>> /** > >>> @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct > >>> igt_spin_factory *opts) { > >>> igt_spin_t *spin; > >>> > >>> + if (is_xe_device(fd)) { > >>> + spin = xe_spin_create(fd, opts); > >>> + return spin; > >>> + } > >>> + > >>> if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != > >> ALL_ENGINES) { > >>> unsigned int class; > >>> > >>> @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > >>> if (!spin) > >>> return; > >>> > >>> - pthread_mutex_lock(&list_lock); > >>> - igt_list_del(&spin->link); > >>> - pthread_mutex_unlock(&list_lock); > >>> - > >>> - __igt_spin_free(fd, spin); > >>> + if (is_xe_device(fd)) { > >>> + xe_spin_free(fd, spin); > >>> + } else { > >>> + pthread_mutex_lock(&list_lock); > >>> + igt_list_del(&spin->link); > >>> + pthread_mutex_unlock(&list_lock); > >>> + __igt_spin_free(fd, spin); > >>> + } > >>> } > >>> > >>> void igt_terminate_spins(void) > >>> diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index > >>> b247ab02..7bcc7b56 100644 > >>> --- a/lib/igt_dummyload.h > >>> +++ b/lib/igt_dummyload.h > >>> @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { > >>> unsigned int flags; > >>> int fence; > >>> uint64_t ahnd; > >>> + struct drm_xe_engine_class_instance *hwe; > >>> + uint32_t vm; > >>> } igt_spin_factory_t; > >>> > >>> typedef struct igt_spin { > >>> @@ -83,6 +85,14 @@ typedef struct igt_spin { #define SPIN_CLFLUSH > >>> (1 << 0) > >>> > >>> struct igt_spin_factory opts; > >>> + > >>> + struct xe_spin *xe_spin; > >>> + size_t bo_size; > >>> + uint64_t address; > >>> + unsigned int engine; > >>> + uint32_t vm; > >>> + uint32_t syncobj; > >>> + > >>> } igt_spin_t; > >>> > >>> > >>> diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index > >>> 856d0ba2..3a8c7bb3 100644 > >>> --- a/lib/xe/xe_spin.c > >>> +++ b/lib/xe/xe_spin.c > >>> @@ -15,6 +15,7 @@ > >>> #include "intel_reg.h" > >>> #include "xe_ioctl.h" > >>> #include "xe_spin.h" > >>> +#include "lib/igt_dummyload.h" > >>> > >>> /** > >>> * xe_spin_init: > >>> @@ -82,6 +83,94 @@ void xe_spin_end(struct xe_spin *spin) > >>> spin->end = 0; > >>> } > >>> > >>> +igt_spin_t * > >>> +xe_spin_create(int fd, const struct igt_spin_factory *opt) { > >>> + size_t bo_size = xe_get_default_alignment(fd); > >>> + uint32_t bo; > >>> + uint64_t ahnd = opt->ahnd, addr; > >>> + struct igt_spin *spin; > >>> + struct xe_spin *xe_spin; > >>> + struct drm_xe_sync sync = { > >>> + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > >>> + }; > >>> + struct drm_xe_exec exec = { > >>> + .num_batch_buffer = 1, > >>> + .num_syncs = 1, > >>> + .syncs = to_user_pointer(&sync), > >>> + }; > >>> + > >>> + igt_assert(ahnd); > >>> + spin = calloc(1, sizeof(struct igt_spin)); > >>> + igt_assert(spin); > >>> + > >>> + spin->syncobj = syncobj_create(fd, 0); > >>> + if (opt->engine) { > >>> + spin->opts.engine = opt->engine; > >>> + spin->opts.vm = opt->vm; > >>> + > >>> + spin->handle = xe_bo_create(fd, 0, spin->opts.vm, bo_size); > >>> + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > >>> + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, > >> bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > >>> + xe_vm_bind_sync(fd, spin->opts.vm, spin->handle, 0, addr, > >> bo_size); > >>> + > >>> + xe_spin_init(xe_spin, addr, true); > >>> + exec.engine_id = spin->opts.engine; > >>> + exec.address = addr; > >>> + } else { > >>> + spin->vm = xe_vm_create(fd, 0, 0); > >>> + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); > >>> + > >>> + bo = xe_bo_create(fd, 0, spin->vm, bo_size); > >>> + spin->handle = bo; > >>> + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > >>> + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, > >> bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > >>> + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); > >>> + > >>> + xe_spin_init(xe_spin, addr, true); > >>> + exec.engine_id = spin->engine; > >>> + exec.address = addr; > >>> + } > >> > >> I think you should support two variants of executing spinners: > >> > >> 1. hwe != NULL (in this case engine must be 0): > >> if (!vm) -> create vm; > >> create engine for vm according to hwe > >> > >> 2. engine != 0, vm must be vm on top of which engine was created > >> hwe must be NULL in this case > >> see Dominik answer about passing engine+vm in: > >> > >> https://patchwork.freedesktop.org/patch/539173/?series=118227&rev=2 > >> > >> And add support ALL_ENGINES flag (then iterate over all hw engines > >> like Bhanu suggested). And track engine ownership - if caller is the > >> engine/vm owner use it but don't destroy, if spinner code is creating > >> engine you may freely destroy it in spinner free path(). > >> > > Do we have Driver support for ALL_ENGINES flag ?? > > > > I think what Bhanu asking for is as kms tests doesn’t need hwe, We have to > pass hwe from the xe_spin_create it self. > > In that case we can add a support in xe_spin_create where hwe = 0 and engine > = 0 ( Note this is only for kms tests) . I just realised xe_spin_create with engine_id = 0 will not work, However is there a way to create engine without hwe ? - Gowtham > > Yes, KMS tests are not supposed to pass hwe or engines. > > - Bhanu > > > > > I feel ALL_ENGINES support can be added later, Once kms tests are unblocked. > > > > Regarding igt_spin_free, I've already added support not to destroy vm and > engines if they are passed from the igt test. Can you have a look at igt_spin_free > (Verified it's working fine for me). > > ----- > > Gowtham > >> -- > >> Zbigniew > >> > >> > >>> + sync.handle = spin->syncobj; > >>> + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > >>> + xe_spin_wait_started(xe_spin); > >>> + igt_info("Spinner started\n"); > >>> + > >>> + spin->bo_size = bo_size; > >>> + spin->address = addr; > >>> + spin->xe_spin = xe_spin; > >>> + > >>> + return spin; > >>> +} > >>> + > >>> +void xe_spin_sync_wait(int fd, struct igt_spin *spin) { > >>> + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, > >>> + NULL)); > >>> +} > >>> + > >>> +void xe_spin_free(int fd, struct igt_spin *spin) { > >>> + xe_spin_end(spin->xe_spin); > >>> + xe_spin_sync_wait(fd, spin); > >>> + > >>> + if (!spin->opts.engine) { > >>> + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin- > >>> bo_size); > >>> + } else { > >>> + xe_vm_unbind_sync(fd, spin->opts.vm, 0, spin->address, spin- > >>> bo_size); > >>> + } > >>> + > >>> + syncobj_destroy(fd, spin->syncobj); > >>> + gem_munmap(spin->xe_spin, spin->bo_size); > >>> + gem_close(fd, spin->handle); > >>> + > >>> + if (!spin->opts.engine) { > >>> + xe_engine_destroy(fd, spin->engine); > >>> + xe_vm_destroy(fd, spin->vm); > >>> + } > >>> + free(spin); > >>> +} > >>> + > >>> void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > >>> struct xe_cork *cork) > >>> { > >>> diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index > >>> 73f9a026..48867eb8 100644 > >>> --- a/lib/xe/xe_spin.h > >>> +++ b/lib/xe/xe_spin.h > >>> @@ -13,19 +13,26 @@ > >>> #include <stdbool.h> > >>> > >>> #include "xe_query.h" > >>> +#include "lib/igt_dummyload.h" > >>> > >>> /* Mapped GPU object */ > >>> + > >>> struct xe_spin { > >>> uint32_t batch[16]; > >>> uint64_t pad; > >>> uint32_t start; > >>> uint32_t end; > >>> + > >>> }; > >>> > >>> +igt_spin_t * > >>> +xe_spin_create(int fd, const struct igt_spin_factory *opt); > >>> void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool > >>> preempt); 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); void > >>> xe_spin_end(struct xe_spin *spin); > >>> +void xe_spin_free(int fd, struct igt_spin *spin); > >>> > >>> struct xe_cork { > >>> struct xe_spin *spin; > >>> -- > >>> 2.39.1 > >>> ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 2/2] tests/xe/xe_spin_batch: Add new test to exercise igt_spin_new for xe. 2023-05-25 5:55 [igt-dev] [PATCH i-g-t 0/2] Integrate igt_spin_new with Xe sai.gowtham.ch 2023-05-25 5:55 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch @ 2023-05-25 5:55 ` sai.gowtham.ch 2023-05-29 5:57 ` Zbigniew Kempczyński 2023-05-25 6:07 ` [igt-dev] ✗ GitLab.Pipeline: warning for Integrate igt_spin_new with Xe. (rev2) Patchwork 2 siblings, 1 reply; 36+ messages in thread From: sai.gowtham.ch @ 2023-05-25 5:55 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> xe_spin_batch test exercises basic igt_spin_new submissions and and with all engines. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> --- tests/meson.build | 1 + tests/xe/xe_spin_batch.c | 138 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 tests/xe/xe_spin_batch.c diff --git a/tests/meson.build b/tests/meson.build index f71be1db..e794b75a 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -268,6 +268,7 @@ xe_progs = [ 'xe_query', 'xe_vm', 'xe_waitfence', + 'xe_spin_batch', ] msm_progs = [ diff --git a/tests/xe/xe_spin_batch.c b/tests/xe/xe_spin_batch.c new file mode 100644 index 00000000..1b216199 --- /dev/null +++ b/tests/xe/xe_spin_batch.c @@ -0,0 +1,138 @@ +#include "igt.h" +#include "lib/intel_reg.h" +#include "xe_drm.h" +#include "xe/xe_ioctl.h" +#include "xe/xe_query.h" + +#define MAX_INSTANCE 9 +/** + * TEST:Test for spin batch submissons. + * + * SUBTEST: spin-batch + * Description: Test to submit spin batch with engines and vm. + * Run type: FULL + * TODO: change ``'Run type' == FULL`` to a better category + * + */ + +static void spin(int fd, struct drm_xe_engine_class_instance *hwe) +{ + uint64_t ahnd; + unsigned int engine; + uint32_t vm; + igt_spin_t *spin; + + vm = xe_vm_create(fd, 0, 0); + engine = xe_engine_create(fd, vm, hwe, 0); + ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_RELOC); + + spin = __igt_spin_new(fd, .ahnd = ahnd, .engine = engine, .vm = vm); + igt_assert(spin); + + igt_spin_free(fd, spin); + put_ahnd(ahnd); +} + +/** + * TEST: Basic test for spin batch submission. + * + * SUBTEST: spin-basic + * Description: Basic test which validates the functionality of spinner. + * Run type: FULL + * TODO: change ``'Run type' == FULL`` to a better category + * + */ +static void spin_basic(int fd, struct drm_xe_engine_class_instance *hwe) +{ + uint64_t ahnd; + igt_spin_t *spin; + + ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_RELOC); + spin = __igt_spin_new(fd, .ahnd = ahnd, .hwe = hwe); + igt_assert(spin); + + igt_spin_free(fd, spin); + put_ahnd(ahnd); +} + +/** + * TEST: Test for spin batch submissions. + * SUBTEST: spin-all + * Description: Spinner test to run on all the engines! + * Run type: FULL + * TODO: change ``'Run type' == FULL`` to a better category + * + */ + +static void spin_all (int fd, int gt, int class) +{ + uint64_t ahnd; + uint32_t engines[MAX_INSTANCE]; + uint32_t vm[MAX_INSTANCE]; + int i, num_placements = 0; + struct drm_xe_engine_class_instance eci[MAX_INSTANCE]; + igt_spin_t *spin[MAX_INSTANCE]; + struct drm_xe_engine_class_instance *hwe; + + ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_RELOC); + + xe_for_each_hw_engine(fd, hwe) { + if (hwe->engine_class != class || hwe->gt_id != gt) + continue; + eci[num_placements++] = *hwe; + } + if (num_placements < 2) + return; + + for (i = 0; i < num_placements; i++) { + struct drm_xe_engine_create create; + vm[i] = xe_vm_create(fd, 0, 0); + + create.vm_id = vm[i]; + create.width = 1; + create.num_placements = num_placements; + create.instances = to_user_pointer(eci); + + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_ENGINE_CREATE, + &create), 0); + engines[i] = create.engine_id; + spin[i] = __igt_spin_new(fd, .ahnd = ahnd, .engine = engines[i], .vm = vm[i]); + } + + for (i = 0; i < num_placements; i++) { + igt_assert(spin[i]); + igt_spin_free(fd, spin[i]); + } + put_ahnd(ahnd); +} + +igt_main +{ + struct drm_xe_engine_class_instance *hwe; + int fd; + int gt, class; + + igt_fixture { + fd = drm_open_driver(DRIVER_XE); + xe_device_get(fd); + } + + igt_subtest("spin-batch") + xe_for_each_hw_engine(fd, hwe) + spin(fd, hwe); + + igt_subtest("spin-basic") + xe_for_each_hw_engine(fd, hwe) + spin_basic(fd, hwe); + + igt_subtest("spin-all") { + xe_for_each_gt(fd, gt) + xe_for_each_hw_engine_class(class) + spin_all(fd, gt, class); + } + + igt_fixture { + xe_device_put(fd); + close(fd); + } +} -- 2.39.1 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 2/2] tests/xe/xe_spin_batch: Add new test to exercise igt_spin_new for xe. 2023-05-25 5:55 ` [igt-dev] [PATCH i-g-t 2/2] tests/xe/xe_spin_batch: Add new test to exercise igt_spin_new for xe sai.gowtham.ch @ 2023-05-29 5:57 ` Zbigniew Kempczyński 2023-05-29 11:02 ` Ch, Sai Gowtham 0 siblings, 1 reply; 36+ messages in thread From: Zbigniew Kempczyński @ 2023-05-29 5:57 UTC (permalink / raw) To: sai.gowtham.ch; +Cc: igt-dev On Thu, May 25, 2023 at 11:25:19AM +0530, sai.gowtham.ch@intel.com wrote: > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > xe_spin_batch test exercises basic igt_spin_new submissions and > and with all engines. > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > --- > tests/meson.build | 1 + > tests/xe/xe_spin_batch.c | 138 +++++++++++++++++++++++++++++++++++++++ > 2 files changed, 139 insertions(+) > create mode 100644 tests/xe/xe_spin_batch.c > > diff --git a/tests/meson.build b/tests/meson.build > index f71be1db..e794b75a 100644 > --- a/tests/meson.build > +++ b/tests/meson.build > @@ -268,6 +268,7 @@ xe_progs = [ > 'xe_query', > 'xe_vm', > 'xe_waitfence', > + 'xe_spin_batch', > ] > > msm_progs = [ > diff --git a/tests/xe/xe_spin_batch.c b/tests/xe/xe_spin_batch.c > new file mode 100644 > index 00000000..1b216199 > --- /dev/null > +++ b/tests/xe/xe_spin_batch.c > @@ -0,0 +1,138 @@ > +#include "igt.h" > +#include "lib/intel_reg.h" > +#include "xe_drm.h" > +#include "xe/xe_ioctl.h" > +#include "xe/xe_query.h" > + > +#define MAX_INSTANCE 9 > +/** > + * TEST:Test for spin batch submissons. > + * > + * SUBTEST: spin-batch > + * Description: Test to submit spin batch with engines and vm. > + * Run type: FULL > + * TODO: change ``'Run type' == FULL`` to a better category > + * > + */ > + > +static void spin(int fd, struct drm_xe_engine_class_instance *hwe) > +{ > + uint64_t ahnd; > + unsigned int engine; > + uint32_t vm; > + igt_spin_t *spin; > + > + vm = xe_vm_create(fd, 0, 0); > + engine = xe_engine_create(fd, vm, hwe, 0); > + ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_RELOC); > + > + spin = __igt_spin_new(fd, .ahnd = ahnd, .engine = engine, .vm = vm); > + igt_assert(spin); > + > + igt_spin_free(fd, spin); You shouldn't imo destroy engine/vm inside igt_spin_free(). Caller is the owner and they should stay intact. If instead .engine you'll pass .hwe you may create engine on top of vm (if passed, if not create new one) and destroy in igt_spin_free(). Resume: track the ownershipping. > + put_ahnd(ahnd); > +} > + > +/** > + * TEST: Basic test for spin batch submission. > + * > + * SUBTEST: spin-basic > + * Description: Basic test which validates the functionality of spinner. > + * Run type: FULL > + * TODO: change ``'Run type' == FULL`` to a better category > + * > + */ > +static void spin_basic(int fd, struct drm_xe_engine_class_instance *hwe) > +{ > + uint64_t ahnd; > + igt_spin_t *spin; > + > + ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_RELOC); > + spin = __igt_spin_new(fd, .ahnd = ahnd, .hwe = hwe); > + igt_assert(spin); > + > + igt_spin_free(fd, spin); > + put_ahnd(ahnd); > +} > + > +/** > + * TEST: Test for spin batch submissions. > + * SUBTEST: spin-all > + * Description: Spinner test to run on all the engines! > + * Run type: FULL > + * TODO: change ``'Run type' == FULL`` to a better category > + * > + */ > + > +static void spin_all (int fd, int gt, int class) > +{ > + uint64_t ahnd; > + uint32_t engines[MAX_INSTANCE]; > + uint32_t vm[MAX_INSTANCE]; > + int i, num_placements = 0; > + struct drm_xe_engine_class_instance eci[MAX_INSTANCE]; > + igt_spin_t *spin[MAX_INSTANCE]; > + struct drm_xe_engine_class_instance *hwe; > + > + ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_RELOC); > + > + xe_for_each_hw_engine(fd, hwe) { > + if (hwe->engine_class != class || hwe->gt_id != gt) > + continue; > + eci[num_placements++] = *hwe; > + } > + if (num_placements < 2) > + return; > + > + for (i = 0; i < num_placements; i++) { > + struct drm_xe_engine_create create; > + vm[i] = xe_vm_create(fd, 0, 0); > + > + create.vm_id = vm[i]; > + create.width = 1; > + create.num_placements = num_placements; > + create.instances = to_user_pointer(eci); > + > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_ENGINE_CREATE, > + &create), 0); > + engines[i] = create.engine_id; > + spin[i] = __igt_spin_new(fd, .ahnd = ahnd, .engine = engines[i], .vm = vm[i]); > + } > + > + for (i = 0; i < num_placements; i++) { > + igt_assert(spin[i]); > + igt_spin_free(fd, spin[i]); > + } > + put_ahnd(ahnd); > +} > + > +igt_main > +{ > + struct drm_xe_engine_class_instance *hwe; > + int fd; > + int gt, class; > + > + igt_fixture { > + fd = drm_open_driver(DRIVER_XE); > + xe_device_get(fd); > + } > + > + igt_subtest("spin-batch") > + xe_for_each_hw_engine(fd, hwe) > + spin(fd, hwe); Test both variants: with engine/vm created in the test and passed via .engine + .vm field and with passing .hwe only. Add also support for ALL_ENGINES flag. -- Zbigniew > + > + igt_subtest("spin-basic") > + xe_for_each_hw_engine(fd, hwe) > + spin_basic(fd, hwe); > + > + igt_subtest("spin-all") { > + xe_for_each_gt(fd, gt) > + xe_for_each_hw_engine_class(class) > + spin_all(fd, gt, class); > + } > + > + igt_fixture { > + xe_device_put(fd); > + close(fd); > + } > +} > -- > 2.39.1 > ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 2/2] tests/xe/xe_spin_batch: Add new test to exercise igt_spin_new for xe. 2023-05-29 5:57 ` Zbigniew Kempczyński @ 2023-05-29 11:02 ` Ch, Sai Gowtham 2023-05-30 19:12 ` Zbigniew Kempczyński 0 siblings, 1 reply; 36+ messages in thread From: Ch, Sai Gowtham @ 2023-05-29 11:02 UTC (permalink / raw) To: Kempczynski, Zbigniew; +Cc: igt-dev > -----Original Message----- > From: Kempczynski, Zbigniew <zbigniew.kempczynski@intel.com> > Sent: Monday, May 29, 2023 11:27 AM > To: Ch, Sai Gowtham <sai.gowtham.ch@intel.com> > Cc: igt-dev@lists.freedesktop.org > Subject: Re: [PATCH i-g-t 2/2] tests/xe/xe_spin_batch: Add new test to exercise > igt_spin_new for xe. > > On Thu, May 25, 2023 at 11:25:19AM +0530, sai.gowtham.ch@intel.com wrote: > > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > > > xe_spin_batch test exercises basic igt_spin_new submissions and and > > with all engines. > > > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > --- > > tests/meson.build | 1 + > > tests/xe/xe_spin_batch.c | 138 > > +++++++++++++++++++++++++++++++++++++++ > > 2 files changed, 139 insertions(+) > > create mode 100644 tests/xe/xe_spin_batch.c > > > > diff --git a/tests/meson.build b/tests/meson.build index > > f71be1db..e794b75a 100644 > > --- a/tests/meson.build > > +++ b/tests/meson.build > > @@ -268,6 +268,7 @@ xe_progs = [ > > 'xe_query', > > 'xe_vm', > > 'xe_waitfence', > > + 'xe_spin_batch', > > ] > > > > msm_progs = [ > > diff --git a/tests/xe/xe_spin_batch.c b/tests/xe/xe_spin_batch.c new > > file mode 100644 index 00000000..1b216199 > > --- /dev/null > > +++ b/tests/xe/xe_spin_batch.c > > @@ -0,0 +1,138 @@ > > +#include "igt.h" > > +#include "lib/intel_reg.h" > > +#include "xe_drm.h" > > +#include "xe/xe_ioctl.h" > > +#include "xe/xe_query.h" > > + > > +#define MAX_INSTANCE 9 > > +/** > > + * TEST:Test for spin batch submissons. > > + * > > + * SUBTEST: spin-batch > > + * Description: Test to submit spin batch with engines and vm. > > + * Run type: FULL > > + * TODO: change ``'Run type' == FULL`` to a better category > > + * > > + */ > > + > > +static void spin(int fd, struct drm_xe_engine_class_instance *hwe) { > > + uint64_t ahnd; > > + unsigned int engine; > > + uint32_t vm; > > + igt_spin_t *spin; > > + > > + vm = xe_vm_create(fd, 0, 0); > > + engine = xe_engine_create(fd, vm, hwe, 0); > > + ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_RELOC); > > + > > + spin = __igt_spin_new(fd, .ahnd = ahnd, .engine = engine, .vm = vm); > > + igt_assert(spin); > > + > > + igt_spin_free(fd, spin); > > You shouldn't imo destroy engine/vm inside igt_spin_free(). Caller is the owner > and they should stay intact. > > If instead .engine you'll pass .hwe you may create engine on top of vm (if > passed, if not create new one) and destroy in igt_spin_free(). > > Resume: track the ownershipping. I'm handling this in igt_spin_free itself, if you look at the igt_spin_free code that I've sent for review I'm checking if it's passed from the igt test or Is it created inside the xe_spin_create, I'm not destroying engine and vm when it's passed from igt test. > > > + put_ahnd(ahnd); > > +} > > + > > +/** > > + * TEST: Basic test for spin batch submission. > > + * > > + * SUBTEST: spin-basic > > + * Description: Basic test which validates the functionality of spinner. > > + * Run type: FULL > > + * TODO: change ``'Run type' == FULL`` to a better category > > + * > > + */ > > +static void spin_basic(int fd, struct drm_xe_engine_class_instance > > +*hwe) { > > + uint64_t ahnd; > > + igt_spin_t *spin; > > + > > + ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_RELOC); > > + spin = __igt_spin_new(fd, .ahnd = ahnd, .hwe = hwe); > > + igt_assert(spin); > > + > > + igt_spin_free(fd, spin); > > + put_ahnd(ahnd); > > +} > > + > > +/** > > + * TEST: Test for spin batch submissions. > > + * SUBTEST: spin-all > > + * Description: Spinner test to run on all the engines! > > + * Run type: FULL > > + * TODO: change ``'Run type' == FULL`` to a better category > > + * > > + */ > > + > > +static void spin_all (int fd, int gt, int class) { > > + uint64_t ahnd; > > + uint32_t engines[MAX_INSTANCE]; > > + uint32_t vm[MAX_INSTANCE]; > > + int i, num_placements = 0; > > + struct drm_xe_engine_class_instance eci[MAX_INSTANCE]; > > + igt_spin_t *spin[MAX_INSTANCE]; > > + struct drm_xe_engine_class_instance *hwe; > > + > > + ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_RELOC); > > + > > + xe_for_each_hw_engine(fd, hwe) { > > + if (hwe->engine_class != class || hwe->gt_id != gt) > > + continue; > > + eci[num_placements++] = *hwe; > > + } > > + if (num_placements < 2) > > + return; > > + > > + for (i = 0; i < num_placements; i++) { > > + struct drm_xe_engine_create create; > > + vm[i] = xe_vm_create(fd, 0, 0); > > + > > + create.vm_id = vm[i]; > > + create.width = 1; > > + create.num_placements = num_placements; > > + create.instances = to_user_pointer(eci); > > + > > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_ENGINE_CREATE, > > + &create), 0); > > + engines[i] = create.engine_id; > > + spin[i] = __igt_spin_new(fd, .ahnd = ahnd, .engine = engines[i], > .vm = vm[i]); > > + } > > + > > + for (i = 0; i < num_placements; i++) { > > + igt_assert(spin[i]); > > + igt_spin_free(fd, spin[i]); > > + } > > + put_ahnd(ahnd); > > +} > > + > > +igt_main > > +{ > > + struct drm_xe_engine_class_instance *hwe; > > + int fd; > > + int gt, class; > > + > > + igt_fixture { > > + fd = drm_open_driver(DRIVER_XE); > > + xe_device_get(fd); > > + } > > + > > + igt_subtest("spin-batch") > > + xe_for_each_hw_engine(fd, hwe) > > + spin(fd, hwe); > > Test both variants: with engine/vm created in the test and passed via .engine + > .vm field and with passing .hwe only. Add also support for ALL_ENGINES flag. > I think spin-batch already covers that, it passes both engine and vm to igt_spin_new which are created in the test. And spin-basic passes only .hwe to igt_spin_new. Thanks, Gowtham > -- > Zbigniew > > > + > > + igt_subtest("spin-basic") > > + xe_for_each_hw_engine(fd, hwe) > > + spin_basic(fd, hwe); > > + > > + igt_subtest("spin-all") { > > + xe_for_each_gt(fd, gt) > > + xe_for_each_hw_engine_class(class) > > + spin_all(fd, gt, class); > > + } > > + > > + igt_fixture { > > + xe_device_put(fd); > > + close(fd); > > + } > > +} > > -- > > 2.39.1 > > ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 2/2] tests/xe/xe_spin_batch: Add new test to exercise igt_spin_new for xe. 2023-05-29 11:02 ` Ch, Sai Gowtham @ 2023-05-30 19:12 ` Zbigniew Kempczyński 0 siblings, 0 replies; 36+ messages in thread From: Zbigniew Kempczyński @ 2023-05-30 19:12 UTC (permalink / raw) To: Ch, Sai Gowtham; +Cc: igt-dev On Mon, May 29, 2023 at 01:02:53PM +0200, Ch, Sai Gowtham wrote: > > > > -----Original Message----- > > From: Kempczynski, Zbigniew <zbigniew.kempczynski@intel.com> > > Sent: Monday, May 29, 2023 11:27 AM > > To: Ch, Sai Gowtham <sai.gowtham.ch@intel.com> > > Cc: igt-dev@lists.freedesktop.org > > Subject: Re: [PATCH i-g-t 2/2] tests/xe/xe_spin_batch: Add new test to exercise > > igt_spin_new for xe. > > > > On Thu, May 25, 2023 at 11:25:19AM +0530, sai.gowtham.ch@intel.com wrote: > > > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > > > > > xe_spin_batch test exercises basic igt_spin_new submissions and and > > > with all engines. > > > > > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > > > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > > --- > > > tests/meson.build | 1 + > > > tests/xe/xe_spin_batch.c | 138 > > > +++++++++++++++++++++++++++++++++++++++ > > > 2 files changed, 139 insertions(+) > > > create mode 100644 tests/xe/xe_spin_batch.c > > > > > > diff --git a/tests/meson.build b/tests/meson.build index > > > f71be1db..e794b75a 100644 > > > --- a/tests/meson.build > > > +++ b/tests/meson.build > > > @@ -268,6 +268,7 @@ xe_progs = [ > > > 'xe_query', > > > 'xe_vm', > > > 'xe_waitfence', > > > + 'xe_spin_batch', > > > ] > > > > > > msm_progs = [ > > > diff --git a/tests/xe/xe_spin_batch.c b/tests/xe/xe_spin_batch.c new > > > file mode 100644 index 00000000..1b216199 > > > --- /dev/null > > > +++ b/tests/xe/xe_spin_batch.c > > > @@ -0,0 +1,138 @@ > > > +#include "igt.h" > > > +#include "lib/intel_reg.h" > > > +#include "xe_drm.h" > > > +#include "xe/xe_ioctl.h" > > > +#include "xe/xe_query.h" > > > + > > > +#define MAX_INSTANCE 9 > > > +/** > > > + * TEST:Test for spin batch submissons. > > > + * > > > + * SUBTEST: spin-batch > > > + * Description: Test to submit spin batch with engines and vm. > > > + * Run type: FULL > > > + * TODO: change ``'Run type' == FULL`` to a better category > > > + * > > > + */ > > > + > > > +static void spin(int fd, struct drm_xe_engine_class_instance *hwe) { > > > + uint64_t ahnd; > > > + unsigned int engine; > > > + uint32_t vm; > > > + igt_spin_t *spin; > > > + > > > + vm = xe_vm_create(fd, 0, 0); > > > + engine = xe_engine_create(fd, vm, hwe, 0); > > > + ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_RELOC); > > > + > > > + spin = __igt_spin_new(fd, .ahnd = ahnd, .engine = engine, .vm = vm); > > > + igt_assert(spin); > > > + > > > + igt_spin_free(fd, spin); > > > > You shouldn't imo destroy engine/vm inside igt_spin_free(). Caller is the owner > > and they should stay intact. > > > > If instead .engine you'll pass .hwe you may create engine on top of vm (if > > passed, if not create new one) and destroy in igt_spin_free(). > > > > Resume: track the ownershipping. > I'm handling this in igt_spin_free itself, if you look at the igt_spin_free code that I've sent for review I'm checking if it's passed from the igt test or > Is it created inside the xe_spin_create, I'm not destroying engine and vm when it's passed from igt test. So in this case you should destroy it in the test, otherwise it will dangle when test is done. -- Zbigniew > > > > > + put_ahnd(ahnd); > > > +} > > > + > > > +/** > > > + * TEST: Basic test for spin batch submission. > > > + * > > > + * SUBTEST: spin-basic > > > + * Description: Basic test which validates the functionality of spinner. > > > + * Run type: FULL > > > + * TODO: change ``'Run type' == FULL`` to a better category > > > + * > > > + */ > > > +static void spin_basic(int fd, struct drm_xe_engine_class_instance > > > +*hwe) { > > > + uint64_t ahnd; > > > + igt_spin_t *spin; > > > + > > > + ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_RELOC); > > > + spin = __igt_spin_new(fd, .ahnd = ahnd, .hwe = hwe); > > > + igt_assert(spin); > > > + > > > + igt_spin_free(fd, spin); > > > + put_ahnd(ahnd); > > > +} > > > + > > > +/** > > > + * TEST: Test for spin batch submissions. > > > + * SUBTEST: spin-all > > > + * Description: Spinner test to run on all the engines! > > > + * Run type: FULL > > > + * TODO: change ``'Run type' == FULL`` to a better category > > > + * > > > + */ > > > + > > > +static void spin_all (int fd, int gt, int class) { > > > + uint64_t ahnd; > > > + uint32_t engines[MAX_INSTANCE]; > > > + uint32_t vm[MAX_INSTANCE]; > > > + int i, num_placements = 0; > > > + struct drm_xe_engine_class_instance eci[MAX_INSTANCE]; > > > + igt_spin_t *spin[MAX_INSTANCE]; > > > + struct drm_xe_engine_class_instance *hwe; > > > + > > > + ahnd = intel_allocator_open(fd, 0, INTEL_ALLOCATOR_RELOC); > > > + > > > + xe_for_each_hw_engine(fd, hwe) { > > > + if (hwe->engine_class != class || hwe->gt_id != gt) > > > + continue; > > > + eci[num_placements++] = *hwe; > > > + } > > > + if (num_placements < 2) > > > + return; > > > + > > > + for (i = 0; i < num_placements; i++) { > > > + struct drm_xe_engine_create create; > > > + vm[i] = xe_vm_create(fd, 0, 0); > > > + > > > + create.vm_id = vm[i]; > > > + create.width = 1; > > > + create.num_placements = num_placements; > > > + create.instances = to_user_pointer(eci); > > > + > > > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_ENGINE_CREATE, > > > + &create), 0); > > > + engines[i] = create.engine_id; > > > + spin[i] = __igt_spin_new(fd, .ahnd = ahnd, .engine = engines[i], > > .vm = vm[i]); > > > + } > > > + > > > + for (i = 0; i < num_placements; i++) { > > > + igt_assert(spin[i]); > > > + igt_spin_free(fd, spin[i]); > > > + } > > > + put_ahnd(ahnd); > > > +} > > > + > > > +igt_main > > > +{ > > > + struct drm_xe_engine_class_instance *hwe; > > > + int fd; > > > + int gt, class; > > > + > > > + igt_fixture { > > > + fd = drm_open_driver(DRIVER_XE); > > > + xe_device_get(fd); > > > + } > > > + > > > + igt_subtest("spin-batch") > > > + xe_for_each_hw_engine(fd, hwe) > > > + spin(fd, hwe); > > > > Test both variants: with engine/vm created in the test and passed via .engine + > > .vm field and with passing .hwe only. Add also support for ALL_ENGINES flag. > > > I think spin-batch already covers that, it passes both engine and vm to igt_spin_new which are created in the test. > And spin-basic passes only .hwe to igt_spin_new. > > Thanks, > Gowtham > > -- > > Zbigniew > > > > > + > > > + igt_subtest("spin-basic") > > > + xe_for_each_hw_engine(fd, hwe) > > > + spin_basic(fd, hwe); > > > + > > > + igt_subtest("spin-all") { > > > + xe_for_each_gt(fd, gt) > > > + xe_for_each_hw_engine_class(class) > > > + spin_all(fd, gt, class); > > > + } > > > + > > > + igt_fixture { > > > + xe_device_put(fd); > > > + close(fd); > > > + } > > > +} > > > -- > > > 2.39.1 > > > ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] ✗ GitLab.Pipeline: warning for Integrate igt_spin_new with Xe. (rev2) 2023-05-25 5:55 [igt-dev] [PATCH i-g-t 0/2] Integrate igt_spin_new with Xe sai.gowtham.ch 2023-05-25 5:55 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 2023-05-25 5:55 ` [igt-dev] [PATCH i-g-t 2/2] tests/xe/xe_spin_batch: Add new test to exercise igt_spin_new for xe sai.gowtham.ch @ 2023-05-25 6:07 ` Patchwork 2 siblings, 0 replies; 36+ messages in thread From: Patchwork @ 2023-05-25 6:07 UTC (permalink / raw) To: sai.gowtham.ch; +Cc: igt-dev == Series Details == Series: Integrate igt_spin_new with Xe. (rev2) URL : https://patchwork.freedesktop.org/series/118121/ State : warning == Summary == Pipeline status: FAILED. see https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/890115 for the overview. build-containers:build-debian has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/42415062): time="2023-05-25T06:02:24Z" level=fatal msg="Invalid status code returned when fetching blob 500 (Internal Server Error)" Building! STEP 1: FROM debian:buster Getting image source signatures Copying blob sha256:c722db24a050621ee87ea07acd5d066d3d6a94737c32012f27d73a1ad5cc645c Copying config sha256:8b5601a5a7f855241ac7f372ec0042e793b0b3eb3f3a601014845f22bd371c90 Writing manifest to image destination Storing signatures STEP 2: RUN apt-get update error running container: error creating container for [/bin/sh -c apt-get update]: time="2023-05-25T06:02:29Z" level=warning msg="signal: killed" time="2023-05-25T06:02:29Z" level=error msg="container_linux.go:346: starting container process caused \"process_linux.go:297: applying cgroup configuration for process caused \\\"mountpoint for cgroup not found\\\"\"\n" container_linux.go:346: starting container process caused "process_linux.go:297: applying cgroup configuration for process caused \"mountpoint for cgroup not found\"" : exit status 1 Error: error building at STEP "RUN apt-get update": error while running runtime: exit status 1 section_end:1684994551:step_script section_start:1684994551:cleanup_file_variables Cleaning up project directory and file based variables section_end:1684994552:cleanup_file_variables ERROR: Job failed: exit code 1 build-containers:build-debian-arm64 has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/42415064): time="2023-05-25T06:02:23Z" level=fatal msg="Invalid status code returned when fetching blob 500 (Internal Server Error)" Building! STEP 1: FROM debian:buster Getting image source signatures Copying blob sha256:c722db24a050621ee87ea07acd5d066d3d6a94737c32012f27d73a1ad5cc645c Copying config sha256:8b5601a5a7f855241ac7f372ec0042e793b0b3eb3f3a601014845f22bd371c90 Writing manifest to image destination Storing signatures STEP 2: RUN apt-get update error running container: error creating container for [/bin/sh -c apt-get update]: time="2023-05-25T06:02:26Z" level=warning msg="signal: killed" time="2023-05-25T06:02:26Z" level=error msg="container_linux.go:346: starting container process caused \"process_linux.go:297: applying cgroup configuration for process caused \\\"mountpoint for cgroup not found\\\"\"\n" container_linux.go:346: starting container process caused "process_linux.go:297: applying cgroup configuration for process caused \"mountpoint for cgroup not found\"" : exit status 1 Error: error building at STEP "RUN apt-get update": error while running runtime: exit status 1 section_end:1684994546:step_script section_start:1684994546:cleanup_file_variables Cleaning up project directory and file based variables section_end:1684994548:cleanup_file_variables ERROR: Job failed: exit code 1 build-containers:build-debian-armhf has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/42415063): time="2023-05-25T06:02:28Z" level=fatal msg="Invalid status code returned when fetching blob 500 (Internal Server Error)" Building! STEP 1: FROM debian:buster Getting image source signatures Copying blob sha256:c722db24a050621ee87ea07acd5d066d3d6a94737c32012f27d73a1ad5cc645c Copying config sha256:8b5601a5a7f855241ac7f372ec0042e793b0b3eb3f3a601014845f22bd371c90 Writing manifest to image destination Storing signatures STEP 2: RUN apt-get update error running container: error creating container for [/bin/sh -c apt-get update]: time="2023-05-25T06:02:32Z" level=warning msg="signal: killed" time="2023-05-25T06:02:32Z" level=error msg="container_linux.go:346: starting container process caused \"process_linux.go:297: applying cgroup configuration for process caused \\\"mountpoint for cgroup not found\\\"\"\n" container_linux.go:346: starting container process caused "process_linux.go:297: applying cgroup configuration for process caused \"mountpoint for cgroup not found\"" : exit status 1 Error: error building at STEP "RUN apt-get update": error while running runtime: exit status 1 section_end:1684994554:step_script section_start:1684994554:cleanup_file_variables Cleaning up project directory and file based variables section_end:1684994559:cleanup_file_variables ERROR: Job failed: exit code 1 build-containers:build-debian-mips has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/42415065): time="2023-05-25T06:02:24Z" level=fatal msg="Invalid status code returned when fetching blob 500 (Internal Server Error)" Building! STEP 1: FROM debian:buster Getting image source signatures Copying blob sha256:c722db24a050621ee87ea07acd5d066d3d6a94737c32012f27d73a1ad5cc645c Copying config sha256:8b5601a5a7f855241ac7f372ec0042e793b0b3eb3f3a601014845f22bd371c90 Writing manifest to image destination Storing signatures STEP 2: RUN apt-get update error running container: error creating container for [/bin/sh -c apt-get update]: time="2023-05-25T06:02:28Z" level=warning msg="signal: killed" time="2023-05-25T06:02:28Z" level=error msg="container_linux.go:346: starting container process caused \"process_linux.go:297: applying cgroup configuration for process caused \\\"mountpoint for cgroup not found\\\"\"\n" container_linux.go:346: starting container process caused "process_linux.go:297: applying cgroup configuration for process caused \"mountpoint for cgroup not found\"" : exit status 1 Error: error building at STEP "RUN apt-get update": error while running runtime: exit status 1 section_end:1684994549:step_script section_start:1684994549:cleanup_file_variables Cleaning up project directory and file based variables section_end:1684994550:cleanup_file_variables ERROR: Job failed: exit code 1 build-containers:build-fedora has failed (https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/jobs/42415066): time="2023-05-25T06:02:27Z" level=fatal msg="Invalid status code returned when fetching blob 500 (Internal Server Error)" Building! STEP 1: FROM fedora:31 Getting image source signatures Copying blob sha256:854946d575a439a894349addd141568875d7c1e673d3286b08250f3dde002e6a Copying config sha256:7e94ed77b448a8d2ff08b92d3ca743e4e862c744892d6886c73487581eb5863a Writing manifest to image destination Storing signatures STEP 2: RUN dnf install -y gcc flex bison libatomic meson ninja-build xdotool 'pkgconfig(libdrm)' 'pkgconfig(pciaccess)' 'pkgconfig(libkmod)' 'pkgconfig(libprocps)' 'pkgconfig(libunwind)' 'pkgconfig(libdw)' 'pkgconfig(pixman-1)' 'pkgconfig(valgrind)' 'pkgconfig(cairo)' 'pkgconfig(libudev)' 'pkgconfig(glib-2.0)' 'pkgconfig(gsl)' 'pkgconfig(alsa)' 'pkgconfig(xmlrpc)' 'pkgconfig(xmlrpc_util)' 'pkgconfig(xmlrpc_client)' 'pkgconfig(json-c)' 'pkgconfig(gtk-doc)' 'pkgconfig(xv)' 'pkgconfig(xrandr)' python3-docutils error running container: error creating container for [/bin/sh -c dnf install -y gcc flex bison libatomic meson ninja-build xdotool 'pkgconfig(libdrm)' 'pkgconfig(pciaccess)' 'pkgconfig(libkmod)' 'pkgconfig(libprocps)' 'pkgconfig(libunwind)' 'pkgconfig(libdw)' 'pkgconfig(pixman-1)' 'pkgconfig(valgrind)' 'pkgconfig(cairo)' 'pkgconfig(libudev)' 'pkgconfig(glib-2.0)' 'pkgconfig(gsl)' 'pkgconfig(alsa)' 'pkgconfig(xmlrpc)' 'pkgconfig(xmlrpc_util)' 'pkgconfig(xmlrpc_client)' 'pkgconfig(json-c)' 'pkgconfig(gtk-doc)' 'pkgconfig(xv)' 'pkgconfig(xrandr)' python3-docutils]: time="2023-05-25T06:02:31Z" level=warning msg="signal: killed" time="2023-05-25T06:02:31Z" level=error msg="container_linux.go:346: starting container process caused \"process_linux.go:297: applying cgroup configuration for process caused \\\"mountpoint for cgroup not found\\\"\"\n" container_linux.go:346: starting container process caused "process_linux.go:297: applying cgroup configuration for process caused \"mountpoint for cgroup not found\"" : exit status 1 Error: error building at STEP "RUN dnf install -y gcc flex bison libatomic meson ninja-build xdotool 'pkgconfig(libdrm)' 'pkgconfig(pciaccess)' 'pkgconfig(libkmod)' 'pkgconfig(libprocps)' 'pkgconfig(libunwind)' 'pkgconfig(libdw)' 'pkgconfig(pixman-1)' 'pkgconfig(valgrind)' 'pkgconfig(cairo)' 'pkgconfig(libudev)' 'pkgconfig(glib-2.0)' 'pkgconfig(gsl)' 'pkgconfig(alsa)' 'pkgconfig(xmlrpc)' 'pkgconfig(xmlrpc_util)' 'pkgconfig(xmlrpc_client)' 'pkgconfig(json-c)' 'pkgconfig(gtk-doc)' 'pkgconfig(xv)' 'pkgconfig(xrandr)' python3-docutils": error while running runtime: exit status 1 section_end:1684994552:step_script section_start:1684994552:cleanup_file_variables Cleaning up project directory and file based variables section_end:1684994554:cleanup_file_variables ERROR: Job failed: exit code 1 == Logs == For more details see: https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/-/pipelines/890115 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 0/2] Integrate igt_spin_new with Xe @ 2023-06-15 10:59 sai.gowtham.ch 2023-06-15 10:59 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 0 siblings, 1 reply; 36+ messages in thread From: sai.gowtham.ch @ 2023-06-15 10:59 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Sai Gowtham Ch (2): lib/xe/xe_spin: Integrate igt_spin_new with Xe tests/xe/xe_spin_batch: Add new test to exercise igt_spin_new for xe lib/igt_dummyload.c | 40 +++++++-- lib/igt_dummyload.h | 12 +++ lib/xe/xe_spin.c | 97 +++++++++++++++++++++ lib/xe/xe_spin.h | 5 +- tests/meson.build | 1 + tests/xe/xe_spin_batch.c | 179 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 328 insertions(+), 6 deletions(-) create mode 100644 tests/xe/xe_spin_batch.c -- 2.39.1 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe 2023-06-15 10:59 [igt-dev] [PATCH i-g-t 0/2] Integrate igt_spin_new with Xe sai.gowtham.ch @ 2023-06-15 10:59 ` sai.gowtham.ch 2023-06-16 6:19 ` Zbigniew Kempczyński 0 siblings, 1 reply; 36+ messages in thread From: sai.gowtham.ch @ 2023-06-15 10:59 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> --- lib/igt_dummyload.c | 40 ++++++++++++++++--- lib/igt_dummyload.h | 12 ++++++ lib/xe/xe_spin.c | 97 +++++++++++++++++++++++++++++++++++++++++++++ lib/xe/xe_spin.h | 5 ++- 4 files changed, 148 insertions(+), 6 deletions(-) diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index 740a58f3..9f941cef 100644 --- a/lib/igt_dummyload.c +++ b/lib/igt_dummyload.c @@ -46,6 +46,7 @@ #include "intel_reg.h" #include "ioctl_wrappers.h" #include "sw_sync.h" +#include "xe/xe_spin.h" /** * SECTION:igt_dummyload @@ -434,6 +435,7 @@ spin_create(int fd, const struct igt_spin_factory *opts) spin = calloc(1, sizeof(struct igt_spin)); igt_assert(spin); + spin->driver = INTEL_DRIVER_I915; spin->timerfd = -1; spin->out_fence = emit_recursive_batch(spin, fd, opts); @@ -447,7 +449,19 @@ spin_create(int fd, const struct igt_spin_factory *opts) igt_spin_t * __igt_spin_factory(int fd, const struct igt_spin_factory *opts) { - return spin_create(fd, opts); + if (is_xe_device(fd)) { + igt_spin_t *spin; + + spin = xe_spin_create(fd, opts); + + pthread_mutex_lock(&list_lock); + igt_list_add(&spin->link, &spin_list); + pthread_mutex_unlock(&list_lock); + + return spin; + } else { + return spin_create(fd, opts); + } } /** @@ -467,6 +481,16 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) { igt_spin_t *spin; + if (is_xe_device(fd)) { + spin = xe_spin_create(fd, opts); + + pthread_mutex_lock(&list_lock); + igt_list_add(&spin->link, &spin_list); + pthread_mutex_unlock(&list_lock); + + return spin; + } + if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { unsigned int class; @@ -597,8 +621,12 @@ void igt_spin_end(igt_spin_t *spin) if (!spin) return; - igt_gettime(&spin->last_signal); - sync_write(spin, MI_BATCH_BUFFER_END); + if (spin->driver == INTEL_DRIVER_XE) { + xe_spin_end(spin->xe_spin); + } else { + igt_gettime(&spin->last_signal); + sync_write(spin, MI_BATCH_BUFFER_END); + } } static void __igt_spin_free(int fd, igt_spin_t *spin) @@ -646,12 +674,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) { if (!spin) return; - pthread_mutex_lock(&list_lock); igt_list_del(&spin->link); pthread_mutex_unlock(&list_lock); - __igt_spin_free(fd, spin); + if (spin->driver == INTEL_DRIVER_XE) + xe_spin_free(fd, spin); + else + __igt_spin_free(fd, spin); } void igt_terminate_spins(void) diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index b247ab02..6eb3f2e6 100644 --- a/lib/igt_dummyload.h +++ b/lib/igt_dummyload.h @@ -28,6 +28,7 @@ #include <stdint.h> #include <time.h> +#include "drmtest.h" #include "igt_core.h" #include "igt_list.h" #include "i915_drm.h" @@ -54,6 +55,8 @@ typedef struct igt_spin_factory { unsigned int flags; int fence; uint64_t ahnd; + struct drm_xe_engine_class_instance *hwe; + uint32_t vm; } igt_spin_factory_t; typedef struct igt_spin { @@ -83,6 +86,15 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 << 0) struct igt_spin_factory opts; + + struct xe_spin *xe_spin; + enum intel_driver driver; + size_t bo_size; + uint64_t address; + unsigned int engine; + uint32_t vm; + uint32_t syncobj; + } igt_spin_t; diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index 856d0ba2..9f511e14 100644 --- a/lib/xe/xe_spin.c +++ b/lib/xe/xe_spin.c @@ -82,6 +82,103 @@ void xe_spin_end(struct xe_spin *spin) spin->end = 0; } +/** + * xe_spin_create: + *@opt: controlling options such as allocator handle, engine, vm etc + * + * igt_spin_new for xe, xe_spin_create submits a batch using xe_spin_init + * which wraps around vm bind and unbinding the object associated to it. + * This returs a spinner after submitting a dummy load. + * + */ +igt_spin_t * +xe_spin_create(int fd, const struct igt_spin_factory *opt) +{ + size_t bo_size = xe_get_default_alignment(fd); + uint64_t ahnd = opt->ahnd, addr; + struct igt_spin *spin; + struct xe_spin *xe_spin; + struct drm_xe_sync sync = { + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, + }; + struct drm_xe_exec exec = { + .num_batch_buffer = 1, + .num_syncs = 1, + .syncs = to_user_pointer(&sync), + }; + + igt_assert(ahnd); + spin = calloc(1, sizeof(struct igt_spin)); + igt_assert(spin); + + spin->driver = INTEL_DRIVER_XE; + spin->syncobj = syncobj_create(fd, 0); + spin->vm = opt->vm; + spin->engine = opt->engine; + + if (!spin->vm) + spin->vm = xe_vm_create(fd, 0, 0); + + if (!spin->engine) { + if (opt->hwe) + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); + else + spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_COPY); + } + + spin->handle = xe_bo_create(fd, 0, spin->vm, bo_size); + xe_spin = xe_bo_map(fd, spin->handle, bo_size); + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); + + xe_spin_init(xe_spin, addr, true); + exec.engine_id = spin->engine; + exec.address = addr; + sync.handle = spin->syncobj; + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); + xe_spin_wait_started(xe_spin); + + spin->bo_size = bo_size; + spin->address = addr; + spin->xe_spin = xe_spin; + spin->opts = *opt; + + return spin; +} + +void xe_spin_sync_wait(int fd, struct igt_spin *spin) +{ + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, NULL)); +} + +/* + * xe_spin_free: + *@spin: spin state from igt_spin_new() + * + * Wrapper to free spinner whhich is triggered by xe_spin_create. + * which distroys vm, engine and unbinds the vm which is binded to + * the engine and bo. + * + */ +void xe_spin_free(int fd, struct igt_spin *spin) +{ + igt_assert(spin->driver == INTEL_DRIVER_XE); + xe_spin_end(spin->xe_spin); + xe_spin_sync_wait(fd, spin); + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); + syncobj_destroy(fd, spin->syncobj); + gem_munmap(spin->xe_spin, spin->bo_size); + gem_close(fd, spin->handle); + + if (!spin->opts.engine) + xe_engine_destroy(fd, spin->engine); + + if (!spin->opts.vm) + xe_vm_destroy(fd, spin->vm); + + free(spin); +} + void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, struct xe_cork *cork) { diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index 73f9a026..54a52b40 100644 --- a/lib/xe/xe_spin.h +++ b/lib/xe/xe_spin.h @@ -13,6 +13,7 @@ #include <stdbool.h> #include "xe_query.h" +#include "lib/igt_dummyload.h" /* Mapped GPU object */ struct xe_spin { @@ -21,11 +22,13 @@ struct xe_spin { uint32_t start; uint32_t end; }; - +igt_spin_t *xe_spin_create(int fd, const struct igt_spin_factory *opt); void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); 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); void xe_spin_end(struct xe_spin *spin); +void xe_spin_free(int fd, struct igt_spin *spin); struct xe_cork { struct xe_spin *spin; -- 2.39.1 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe 2023-06-15 10:59 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch @ 2023-06-16 6:19 ` Zbigniew Kempczyński 0 siblings, 0 replies; 36+ messages in thread From: Zbigniew Kempczyński @ 2023-06-16 6:19 UTC (permalink / raw) To: sai.gowtham.ch; +Cc: igt-dev On Thu, Jun 15, 2023 at 04:29:53PM +0530, sai.gowtham.ch@intel.com wrote: > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > Extending the spin_create implementation and allocator handle support in xe, > where it submits dummy work loads to engine. This Implementation is wrapped > around vm_bind and unbind as we are supposed to do it manually for xe. > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > --- > lib/igt_dummyload.c | 40 ++++++++++++++++--- > lib/igt_dummyload.h | 12 ++++++ > lib/xe/xe_spin.c | 97 +++++++++++++++++++++++++++++++++++++++++++++ > lib/xe/xe_spin.h | 5 ++- > 4 files changed, 148 insertions(+), 6 deletions(-) > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c > index 740a58f3..9f941cef 100644 > --- a/lib/igt_dummyload.c > +++ b/lib/igt_dummyload.c > @@ -46,6 +46,7 @@ > #include "intel_reg.h" > #include "ioctl_wrappers.h" > #include "sw_sync.h" > +#include "xe/xe_spin.h" > > /** > * SECTION:igt_dummyload > @@ -434,6 +435,7 @@ spin_create(int fd, const struct igt_spin_factory *opts) > spin = calloc(1, sizeof(struct igt_spin)); > igt_assert(spin); > > + spin->driver = INTEL_DRIVER_I915; > spin->timerfd = -1; > spin->out_fence = emit_recursive_batch(spin, fd, opts); > > @@ -447,7 +449,19 @@ spin_create(int fd, const struct igt_spin_factory *opts) > igt_spin_t * > __igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > - return spin_create(fd, opts); > + if (is_xe_device(fd)) { > + igt_spin_t *spin; > + > + spin = xe_spin_create(fd, opts); > + > + pthread_mutex_lock(&list_lock); > + igt_list_add(&spin->link, &spin_list); > + pthread_mutex_unlock(&list_lock); > + > + return spin; > + } else { > + return spin_create(fd, opts); > + } > } > > /** > @@ -467,6 +481,16 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > igt_spin_t *spin; > > + if (is_xe_device(fd)) { > + spin = xe_spin_create(fd, opts); > + > + pthread_mutex_lock(&list_lock); > + igt_list_add(&spin->link, &spin_list); > + pthread_mutex_unlock(&list_lock); > + > + return spin; > + } > + > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { > unsigned int class; > > @@ -597,8 +621,12 @@ void igt_spin_end(igt_spin_t *spin) > if (!spin) > return; > > - igt_gettime(&spin->last_signal); > - sync_write(spin, MI_BATCH_BUFFER_END); > + if (spin->driver == INTEL_DRIVER_XE) { > + xe_spin_end(spin->xe_spin); > + } else { > + igt_gettime(&spin->last_signal); > + sync_write(spin, MI_BATCH_BUFFER_END); > + } > } > > static void __igt_spin_free(int fd, igt_spin_t *spin) > @@ -646,12 +674,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > { > if (!spin) > return; > - > pthread_mutex_lock(&list_lock); > igt_list_del(&spin->link); > pthread_mutex_unlock(&list_lock); > > - __igt_spin_free(fd, spin); > + if (spin->driver == INTEL_DRIVER_XE) > + xe_spin_free(fd, spin); > + else > + __igt_spin_free(fd, spin); > } > > void igt_terminate_spins(void) > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h > index b247ab02..6eb3f2e6 100644 > --- a/lib/igt_dummyload.h > +++ b/lib/igt_dummyload.h > @@ -28,6 +28,7 @@ > #include <stdint.h> > #include <time.h> > > +#include "drmtest.h" > #include "igt_core.h" > #include "igt_list.h" > #include "i915_drm.h" > @@ -54,6 +55,8 @@ typedef struct igt_spin_factory { > unsigned int flags; > int fence; > uint64_t ahnd; > + struct drm_xe_engine_class_instance *hwe; > + uint32_t vm; > } igt_spin_factory_t; > > typedef struct igt_spin { > @@ -83,6 +86,15 @@ typedef struct igt_spin { > #define SPIN_CLFLUSH (1 << 0) > > struct igt_spin_factory opts; > + > + struct xe_spin *xe_spin; > + enum intel_driver driver; > + size_t bo_size; > + uint64_t address; > + unsigned int engine; > + uint32_t vm; > + uint32_t syncobj; > + > } igt_spin_t; > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c > index 856d0ba2..9f511e14 100644 > --- a/lib/xe/xe_spin.c > +++ b/lib/xe/xe_spin.c > @@ -82,6 +82,103 @@ void xe_spin_end(struct xe_spin *spin) > spin->end = 0; > } > > +/** > + * xe_spin_create: > + *@opt: controlling options such as allocator handle, engine, vm etc > + * > + * igt_spin_new for xe, xe_spin_create submits a batch using xe_spin_init > + * which wraps around vm bind and unbinding the object associated to it. > + * This returs a spinner after submitting a dummy load. > + * > + */ > +igt_spin_t * > +xe_spin_create(int fd, const struct igt_spin_factory *opt) > +{ > + size_t bo_size = xe_get_default_alignment(fd); > + uint64_t ahnd = opt->ahnd, addr; > + struct igt_spin *spin; > + struct xe_spin *xe_spin; > + struct drm_xe_sync sync = { > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > + }; > + struct drm_xe_exec exec = { > + .num_batch_buffer = 1, > + .num_syncs = 1, > + .syncs = to_user_pointer(&sync), > + }; > + > + igt_assert(ahnd); > + spin = calloc(1, sizeof(struct igt_spin)); > + igt_assert(spin); > + > + spin->driver = INTEL_DRIVER_XE; > + spin->syncobj = syncobj_create(fd, 0); > + spin->vm = opt->vm; > + spin->engine = opt->engine; > + > + if (!spin->vm) > + spin->vm = xe_vm_create(fd, 0, 0); > + > + if (!spin->engine) { > + if (opt->hwe) > + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); > + else > + spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_COPY); > + } > + > + spin->handle = xe_bo_create(fd, 0, spin->vm, bo_size); > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); > + > + xe_spin_init(xe_spin, addr, true); > + exec.engine_id = spin->engine; > + exec.address = addr; > + sync.handle = spin->syncobj; > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > + xe_spin_wait_started(xe_spin); > + > + spin->bo_size = bo_size; > + spin->address = addr; > + spin->xe_spin = xe_spin; > + spin->opts = *opt; > + > + return spin; > +} > + > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) > +{ > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, NULL)); > +} > + > +/* > + * xe_spin_free: > + *@spin: spin state from igt_spin_new() > + * > + * Wrapper to free spinner whhich is triggered by xe_spin_create. > + * which distroys vm, engine and unbinds the vm which is binded to > + * the engine and bo. > + * > + */ > +void xe_spin_free(int fd, struct igt_spin *spin) > +{ > + igt_assert(spin->driver == INTEL_DRIVER_XE); > + xe_spin_end(spin->xe_spin); > + xe_spin_sync_wait(fd, spin); > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); > + syncobj_destroy(fd, spin->syncobj); > + gem_munmap(spin->xe_spin, spin->bo_size); > + gem_close(fd, spin->handle); > + > + if (!spin->opts.engine) > + xe_engine_destroy(fd, spin->engine); > + > + if (!spin->opts.vm) > + xe_vm_destroy(fd, spin->vm); > + > + free(spin); > +} > + > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > struct xe_cork *cork) > { > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h > index 73f9a026..54a52b40 100644 > --- a/lib/xe/xe_spin.h > +++ b/lib/xe/xe_spin.h > @@ -13,6 +13,7 @@ > #include <stdbool.h> > > #include "xe_query.h" > +#include "lib/igt_dummyload.h" > > /* Mapped GPU object */ > struct xe_spin { > @@ -21,11 +22,13 @@ struct xe_spin { > uint32_t start; > uint32_t end; > }; > - > +igt_spin_t *xe_spin_create(int fd, const struct igt_spin_factory *opt); > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); > 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); > void xe_spin_end(struct xe_spin *spin); > +void xe_spin_free(int fd, struct igt_spin *spin); > > struct xe_cork { > struct xe_spin *spin; > -- > 2.39.1 > Ok, now it looks good for me. If someone would need some additional feature we may add this later. Reviewed-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> -- Zbigniew ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 0/2] Integrate igt_spin_new with Xe @ 2023-06-13 12:42 sai.gowtham.ch 2023-06-13 12:42 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 0 siblings, 1 reply; 36+ messages in thread From: sai.gowtham.ch @ 2023-06-13 12:42 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Sai Gowtham Ch (2): lib/xe/xe_spin: Integrate igt_spin_new with Xe tests/xe/xe_spin_batch: Add new test to exercise igt_spin_new for xe lib/igt_dummyload.c | 38 ++++++-- lib/igt_dummyload.h | 11 +++ lib/xe/xe_spin.c | 96 +++++++++++++++++++++ lib/xe/xe_spin.h | 6 +- tests/meson.build | 1 + tests/xe/xe_spin_batch.c | 182 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 328 insertions(+), 6 deletions(-) create mode 100644 tests/xe/xe_spin_batch.c -- 2.39.1 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe 2023-06-13 12:42 [igt-dev] [PATCH i-g-t 0/2] " sai.gowtham.ch @ 2023-06-13 12:42 ` sai.gowtham.ch 2023-06-14 17:33 ` Zbigniew Kempczyński 0 siblings, 1 reply; 36+ messages in thread From: sai.gowtham.ch @ 2023-06-13 12:42 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> --- lib/igt_dummyload.c | 38 +++++++++++++++--- lib/igt_dummyload.h | 11 ++++++ lib/xe/xe_spin.c | 96 +++++++++++++++++++++++++++++++++++++++++++++ lib/xe/xe_spin.h | 6 ++- 4 files changed, 145 insertions(+), 6 deletions(-) diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index 740a58f3..2b2f2141 100644 --- a/lib/igt_dummyload.c +++ b/lib/igt_dummyload.c @@ -46,6 +46,7 @@ #include "intel_reg.h" #include "ioctl_wrappers.h" #include "sw_sync.h" +#include "xe/xe_spin.h" /** * SECTION:igt_dummyload @@ -447,7 +448,18 @@ spin_create(int fd, const struct igt_spin_factory *opts) igt_spin_t * __igt_spin_factory(int fd, const struct igt_spin_factory *opts) { - return spin_create(fd, opts); + if (is_xe_device(fd)) { + igt_spin_t *spin; + + spin = xe_spin_create(fd, opts); + + pthread_mutex_lock(&list_lock); + igt_list_add(&spin->link, &spin_list); + pthread_mutex_unlock(&list_lock); + + return spin; + } else + return spin_create(fd, opts); } /** @@ -467,6 +479,16 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) { igt_spin_t *spin; + if (is_xe_device(fd)) { + spin = xe_spin_create(fd, opts); + + pthread_mutex_lock(&list_lock); + igt_list_add(&spin->link, &spin_list); + pthread_mutex_unlock(&list_lock); + + return spin; + } + if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { unsigned int class; @@ -597,8 +619,12 @@ void igt_spin_end(igt_spin_t *spin) if (!spin) return; - igt_gettime(&spin->last_signal); - sync_write(spin, MI_BATCH_BUFFER_END); + if ((spin->driver == DRIVER_XE)) { + xe_spin_end(spin->xe_spin); + } else { + igt_gettime(&spin->last_signal); + sync_write(spin, MI_BATCH_BUFFER_END); + } } static void __igt_spin_free(int fd, igt_spin_t *spin) @@ -646,12 +672,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) { if (!spin) return; - pthread_mutex_lock(&list_lock); igt_list_del(&spin->link); pthread_mutex_unlock(&list_lock); - __igt_spin_free(fd, spin); + if (is_xe_device(fd)) + xe_spin_free(fd, spin); + else + __igt_spin_free(fd, spin); } void igt_terminate_spins(void) diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index b247ab02..ebed19bb 100644 --- a/lib/igt_dummyload.h +++ b/lib/igt_dummyload.h @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { unsigned int flags; int fence; uint64_t ahnd; + struct drm_xe_engine_class_instance *hwe; + uint32_t vm; } igt_spin_factory_t; typedef struct igt_spin { @@ -83,6 +85,15 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 << 0) struct igt_spin_factory opts; + + struct xe_spin *xe_spin; + int driver; + size_t bo_size; + uint64_t address; + unsigned int engine; + uint32_t vm; + uint32_t syncobj; + } igt_spin_t; diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index 856d0ba2..b375463a 100644 --- a/lib/xe/xe_spin.c +++ b/lib/xe/xe_spin.c @@ -82,6 +82,102 @@ void xe_spin_end(struct xe_spin *spin) spin->end = 0; } +/** + * xe_spin_create: + *@opt: controlling options such as allocator handle, engine, vmetc + * + * igt_spin_new for xe, xe_spin_create submits a batch using xe_spin_init + * which wraps around vm bind and unbinding the object associated to it. + * This returs a spinner after submitting a dummy load. + * + */ +igt_spin_t * +xe_spin_create(int fd, const struct igt_spin_factory *opt) +{ + size_t bo_size = xe_get_default_alignment(fd); + uint64_t ahnd = opt->ahnd, addr; + struct igt_spin *spin; + struct xe_spin *xe_spin; + struct drm_xe_sync sync = { + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, + }; + struct drm_xe_exec exec = { + .num_batch_buffer = 1, + .num_syncs = 1, + .syncs = to_user_pointer(&sync), + }; + + igt_assert(ahnd); + spin = calloc(1, sizeof(struct igt_spin)); + igt_assert(spin); + + spin->driver = DRIVER_XE; + spin->syncobj = syncobj_create(fd, 0); + spin->vm = opt->vm; + spin->engine = opt->engine; + + if (!spin->vm) + spin->vm = xe_vm_create(fd, 0, 0); + + if (!spin->engine) { + if (opt->hwe) + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); + else + spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_COPY); + } + + spin->handle = xe_bo_create(fd, 0, spin->vm, bo_size); + xe_spin = xe_bo_map(fd, spin->handle, bo_size); + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); + + xe_spin_init(xe_spin, addr, true); + exec.engine_id = spin->engine; + exec.address = addr; + sync.handle = spin->syncobj; + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); + xe_spin_wait_started(xe_spin); + + spin->bo_size = bo_size; + spin->address = addr; + spin->xe_spin = xe_spin; + spin->opts = *opt; + + return spin; +} + +void xe_spin_sync_wait(int fd, struct igt_spin *spin) +{ + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, NULL)); +} + +/* + * xe_spin_free: + *@spin: spin state from igt_spin_new() + * + * Wrapper to free spinner whhich is triggered by xe_spin_create. + * which distroys vm, engine and unbinds the vm which is binded to + * the engine and bo. + * + */ +void xe_spin_free(int fd, struct igt_spin *spin) +{ + xe_spin_end(spin->xe_spin); + xe_spin_sync_wait(fd, spin); + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); + syncobj_destroy(fd, spin->syncobj); + gem_munmap(spin->xe_spin, spin->bo_size); + gem_close(fd, spin->handle); + + if (!spin->opts.engine) + xe_engine_destroy(fd, spin->engine); + + if (!spin->opts.vm) + xe_vm_destroy(fd, spin->vm); + + free(spin); +} + void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, struct xe_cork *cork) { diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index 73f9a026..60f6e751 100644 --- a/lib/xe/xe_spin.h +++ b/lib/xe/xe_spin.h @@ -13,6 +13,7 @@ #include <stdbool.h> #include "xe_query.h" +#include "lib/igt_dummyload.h" /* Mapped GPU object */ struct xe_spin { @@ -21,11 +22,14 @@ struct xe_spin { uint32_t start; uint32_t end; }; - +void xe_spin_user_vm_engine(int fd, const struct igt_spin_factory *opt, struct igt_spin *spin); +igt_spin_t *xe_spin_create(int fd, const struct igt_spin_factory *opt); void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); 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); void xe_spin_end(struct xe_spin *spin); +void xe_spin_free(int fd, struct igt_spin *spin); struct xe_cork { struct xe_spin *spin; -- 2.39.1 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe 2023-06-13 12:42 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch @ 2023-06-14 17:33 ` Zbigniew Kempczyński 0 siblings, 0 replies; 36+ messages in thread From: Zbigniew Kempczyński @ 2023-06-14 17:33 UTC (permalink / raw) To: sai.gowtham.ch; +Cc: igt-dev On Tue, Jun 13, 2023 at 06:12:46PM +0530, sai.gowtham.ch@intel.com wrote: > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > Extending the spin_create implementation and allocator handle support in xe, > where it submits dummy work loads to engine. This Implementation is wrapped > around vm_bind and unbind as we are supposed to do it manually for xe. > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > --- > lib/igt_dummyload.c | 38 +++++++++++++++--- > lib/igt_dummyload.h | 11 ++++++ > lib/xe/xe_spin.c | 96 +++++++++++++++++++++++++++++++++++++++++++++ > lib/xe/xe_spin.h | 6 ++- > 4 files changed, 145 insertions(+), 6 deletions(-) > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c > index 740a58f3..2b2f2141 100644 > --- a/lib/igt_dummyload.c > +++ b/lib/igt_dummyload.c > @@ -46,6 +46,7 @@ > #include "intel_reg.h" > #include "ioctl_wrappers.h" > #include "sw_sync.h" > +#include "xe/xe_spin.h" > > /** > * SECTION:igt_dummyload > @@ -447,7 +448,18 @@ spin_create(int fd, const struct igt_spin_factory *opts) > igt_spin_t * > __igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > - return spin_create(fd, opts); > + if (is_xe_device(fd)) { > + igt_spin_t *spin; > + > + spin = xe_spin_create(fd, opts); > + > + pthread_mutex_lock(&list_lock); > + igt_list_add(&spin->link, &spin_list); > + pthread_mutex_unlock(&list_lock); > + > + return spin; > + } else Use { and } if one of the if/else block has more than single line: else { > + return spin_create(fd, opts); } > } > > /** > @@ -467,6 +479,16 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > igt_spin_t *spin; > > + if (is_xe_device(fd)) { > + spin = xe_spin_create(fd, opts); > + > + pthread_mutex_lock(&list_lock); > + igt_list_add(&spin->link, &spin_list); > + pthread_mutex_unlock(&list_lock); > + > + return spin; > + } > + > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { > unsigned int class; > > @@ -597,8 +619,12 @@ void igt_spin_end(igt_spin_t *spin) > if (!spin) > return; > > - igt_gettime(&spin->last_signal); > - sync_write(spin, MI_BATCH_BUFFER_END); > + if ((spin->driver == DRIVER_XE)) { You don't need double parentheses. Apart of that I wanted to use enum intel_driver defined in drmtest.h to have sth like this: if (spin->driver == INTEL_DRIVER_XE) ... > + xe_spin_end(spin->xe_spin); > + } else { > + igt_gettime(&spin->last_signal); > + sync_write(spin, MI_BATCH_BUFFER_END); > + } > } > > static void __igt_spin_free(int fd, igt_spin_t *spin) > @@ -646,12 +672,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > { > if (!spin) > return; > - > pthread_mutex_lock(&list_lock); > igt_list_del(&spin->link); > pthread_mutex_unlock(&list_lock); > > - __igt_spin_free(fd, spin); > + if (is_xe_device(fd)) Use if (spin->driver == INTEL_DRIVER_XE) instead > + xe_spin_free(fd, spin); > + else > + __igt_spin_free(fd, spin); > } > > void igt_terminate_spins(void) > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h > index b247ab02..ebed19bb 100644 > --- a/lib/igt_dummyload.h > +++ b/lib/igt_dummyload.h > @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { > unsigned int flags; > int fence; > uint64_t ahnd; > + struct drm_xe_engine_class_instance *hwe; > + uint32_t vm; > } igt_spin_factory_t; > > typedef struct igt_spin { > @@ -83,6 +85,15 @@ typedef struct igt_spin { > #define SPIN_CLFLUSH (1 << 0) > > struct igt_spin_factory opts; > + > + struct xe_spin *xe_spin; > + int driver; Use enum intel_driver instead. You need to include drmtest.h to achieve this. > + size_t bo_size; > + uint64_t address; > + unsigned int engine; > + uint32_t vm; > + uint32_t syncobj; > + > } igt_spin_t; > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c > index 856d0ba2..b375463a 100644 > --- a/lib/xe/xe_spin.c > +++ b/lib/xe/xe_spin.c > @@ -82,6 +82,102 @@ void xe_spin_end(struct xe_spin *spin) > spin->end = 0; > } > > +/** > + * xe_spin_create: > + *@opt: controlling options such as allocator handle, engine, vmetc s/vmetc/vm etc/ > + * > + * igt_spin_new for xe, xe_spin_create submits a batch using xe_spin_init > + * which wraps around vm bind and unbinding the object associated to it. > + * This returs a spinner after submitting a dummy load. > + * > + */ > +igt_spin_t * > +xe_spin_create(int fd, const struct igt_spin_factory *opt) > +{ > + size_t bo_size = xe_get_default_alignment(fd); > + uint64_t ahnd = opt->ahnd, addr; > + struct igt_spin *spin; > + struct xe_spin *xe_spin; > + struct drm_xe_sync sync = { > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > + }; > + struct drm_xe_exec exec = { > + .num_batch_buffer = 1, > + .num_syncs = 1, > + .syncs = to_user_pointer(&sync), > + }; > + > + igt_assert(ahnd); > + spin = calloc(1, sizeof(struct igt_spin)); > + igt_assert(spin); > + > + spin->driver = DRIVER_XE; I wanted to use directly enum intel_driver here to have: spin->driver = INTEL_DRIVER_XE; You should add appropriate initialization in i915 code to be consistent with all driver codepaths. > + spin->syncobj = syncobj_create(fd, 0); > + spin->vm = opt->vm; > + spin->engine = opt->engine; > + > + if (!spin->vm) > + spin->vm = xe_vm_create(fd, 0, 0); > + > + if (!spin->engine) { > + if (opt->hwe) > + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); > + else > + spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_COPY); > + } > + > + spin->handle = xe_bo_create(fd, 0, spin->vm, bo_size); > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); > + > + xe_spin_init(xe_spin, addr, true); > + exec.engine_id = spin->engine; > + exec.address = addr; > + sync.handle = spin->syncobj; > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > + xe_spin_wait_started(xe_spin); > + > + spin->bo_size = bo_size; > + spin->address = addr; > + spin->xe_spin = xe_spin; > + spin->opts = *opt; > + > + return spin; > +} > + > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) > +{ > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, NULL)); > +} > + > +/* > + * xe_spin_free: > + *@spin: spin state from igt_spin_new() > + * > + * Wrapper to free spinner whhich is triggered by xe_spin_create. > + * which distroys vm, engine and unbinds the vm which is binded to > + * the engine and bo. > + * > + */ > +void xe_spin_free(int fd, struct igt_spin *spin) > +{ I would also add: igt_assert(spin->driver == INTEL_DRIVER_XE); to catch unforseen paths for the future changes. Please change and resubmit. -- Zbigniew > + xe_spin_end(spin->xe_spin); > + xe_spin_sync_wait(fd, spin); > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); > + syncobj_destroy(fd, spin->syncobj); > + gem_munmap(spin->xe_spin, spin->bo_size); > + gem_close(fd, spin->handle); > + > + if (!spin->opts.engine) > + xe_engine_destroy(fd, spin->engine); > + > + if (!spin->opts.vm) > + xe_vm_destroy(fd, spin->vm); > + > + free(spin); > +} > + > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > struct xe_cork *cork) > { > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h > index 73f9a026..60f6e751 100644 > --- a/lib/xe/xe_spin.h > +++ b/lib/xe/xe_spin.h > @@ -13,6 +13,7 @@ > #include <stdbool.h> > > #include "xe_query.h" > +#include "lib/igt_dummyload.h" > > /* Mapped GPU object */ > struct xe_spin { > @@ -21,11 +22,14 @@ struct xe_spin { > uint32_t start; > uint32_t end; > }; > - > +void xe_spin_user_vm_engine(int fd, const struct igt_spin_factory *opt, struct igt_spin *spin); > +igt_spin_t *xe_spin_create(int fd, const struct igt_spin_factory *opt); > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); > 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); > void xe_spin_end(struct xe_spin *spin); > +void xe_spin_free(int fd, struct igt_spin *spin); > > struct xe_cork { > struct xe_spin *spin; > -- > 2.39.1 > ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 0/2] Integrate igt_spin_new with Xe @ 2023-06-12 8:59 sai.gowtham.ch 2023-06-12 8:59 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 0 siblings, 1 reply; 36+ messages in thread From: sai.gowtham.ch @ 2023-06-12 8:59 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Sai Gowtham Ch (2): lib/xe/xe_spin: Integrate igt_spin_new with Xe tests/xe/xe_spin_batch: Add new test to exercise igt_spin_new for xe lib/igt_dummyload.c | 38 +++++++-- lib/igt_dummyload.h | 11 +++ lib/xe/xe_spin.c | 96 +++++++++++++++++++++ lib/xe/xe_spin.h | 6 +- tests/meson.build | 1 + tests/xe/xe_spin_batch.c | 180 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 326 insertions(+), 6 deletions(-) create mode 100644 tests/xe/xe_spin_batch.c -- 2.39.1 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe 2023-06-12 8:59 [igt-dev] [PATCH i-g-t 0/2] " sai.gowtham.ch @ 2023-06-12 8:59 ` sai.gowtham.ch 2023-06-12 18:56 ` Zbigniew Kempczyński 0 siblings, 1 reply; 36+ messages in thread From: sai.gowtham.ch @ 2023-06-12 8:59 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> --- lib/igt_dummyload.c | 38 +++++++++++++++--- lib/igt_dummyload.h | 11 ++++++ lib/xe/xe_spin.c | 96 +++++++++++++++++++++++++++++++++++++++++++++ lib/xe/xe_spin.h | 6 ++- 4 files changed, 145 insertions(+), 6 deletions(-) diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index 740a58f3..60c4f679 100644 --- a/lib/igt_dummyload.c +++ b/lib/igt_dummyload.c @@ -46,6 +46,7 @@ #include "intel_reg.h" #include "ioctl_wrappers.h" #include "sw_sync.h" +#include "xe/xe_spin.h" /** * SECTION:igt_dummyload @@ -447,7 +448,18 @@ spin_create(int fd, const struct igt_spin_factory *opts) igt_spin_t * __igt_spin_factory(int fd, const struct igt_spin_factory *opts) { - return spin_create(fd, opts); + if (is_xe_device(fd)) { + igt_spin_t *spin; + + spin = xe_spin_create(fd, opts); + + pthread_mutex_lock(&list_lock); + igt_list_add(&spin->link, &spin_list); + pthread_mutex_unlock(&list_lock); + + return spin; + } else + return spin_create(fd, opts); } /** @@ -467,6 +479,16 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) { igt_spin_t *spin; + if (is_xe_device(fd)) { + spin = xe_spin_create(fd, opts); + + pthread_mutex_lock(&list_lock); + igt_list_add(&spin->link, &spin_list); + pthread_mutex_unlock(&list_lock); + + return spin; + } + if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { unsigned int class; @@ -597,8 +619,12 @@ void igt_spin_end(igt_spin_t *spin) if (!spin) return; - igt_gettime(&spin->last_signal); - sync_write(spin, MI_BATCH_BUFFER_END); + if ((spin->driver = DRIVER_XE)) { + xe_spin_end(spin->xe_spin); + } else { + igt_gettime(&spin->last_signal); + sync_write(spin, MI_BATCH_BUFFER_END); + } } static void __igt_spin_free(int fd, igt_spin_t *spin) @@ -646,12 +672,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) { if (!spin) return; - pthread_mutex_lock(&list_lock); igt_list_del(&spin->link); pthread_mutex_unlock(&list_lock); - __igt_spin_free(fd, spin); + if (is_xe_device(fd)) + xe_spin_free(fd, spin); + else + __igt_spin_free(fd, spin); } void igt_terminate_spins(void) diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index b247ab02..ebed19bb 100644 --- a/lib/igt_dummyload.h +++ b/lib/igt_dummyload.h @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { unsigned int flags; int fence; uint64_t ahnd; + struct drm_xe_engine_class_instance *hwe; + uint32_t vm; } igt_spin_factory_t; typedef struct igt_spin { @@ -83,6 +85,15 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 << 0) struct igt_spin_factory opts; + + struct xe_spin *xe_spin; + int driver; + size_t bo_size; + uint64_t address; + unsigned int engine; + uint32_t vm; + uint32_t syncobj; + } igt_spin_t; diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index 856d0ba2..b375463a 100644 --- a/lib/xe/xe_spin.c +++ b/lib/xe/xe_spin.c @@ -82,6 +82,102 @@ void xe_spin_end(struct xe_spin *spin) spin->end = 0; } +/** + * xe_spin_create: + *@opt: controlling options such as allocator handle, engine, vmetc + * + * igt_spin_new for xe, xe_spin_create submits a batch using xe_spin_init + * which wraps around vm bind and unbinding the object associated to it. + * This returs a spinner after submitting a dummy load. + * + */ +igt_spin_t * +xe_spin_create(int fd, const struct igt_spin_factory *opt) +{ + size_t bo_size = xe_get_default_alignment(fd); + uint64_t ahnd = opt->ahnd, addr; + struct igt_spin *spin; + struct xe_spin *xe_spin; + struct drm_xe_sync sync = { + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, + }; + struct drm_xe_exec exec = { + .num_batch_buffer = 1, + .num_syncs = 1, + .syncs = to_user_pointer(&sync), + }; + + igt_assert(ahnd); + spin = calloc(1, sizeof(struct igt_spin)); + igt_assert(spin); + + spin->driver = DRIVER_XE; + spin->syncobj = syncobj_create(fd, 0); + spin->vm = opt->vm; + spin->engine = opt->engine; + + if (!spin->vm) + spin->vm = xe_vm_create(fd, 0, 0); + + if (!spin->engine) { + if (opt->hwe) + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); + else + spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_COPY); + } + + spin->handle = xe_bo_create(fd, 0, spin->vm, bo_size); + xe_spin = xe_bo_map(fd, spin->handle, bo_size); + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); + + xe_spin_init(xe_spin, addr, true); + exec.engine_id = spin->engine; + exec.address = addr; + sync.handle = spin->syncobj; + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); + xe_spin_wait_started(xe_spin); + + spin->bo_size = bo_size; + spin->address = addr; + spin->xe_spin = xe_spin; + spin->opts = *opt; + + return spin; +} + +void xe_spin_sync_wait(int fd, struct igt_spin *spin) +{ + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, NULL)); +} + +/* + * xe_spin_free: + *@spin: spin state from igt_spin_new() + * + * Wrapper to free spinner whhich is triggered by xe_spin_create. + * which distroys vm, engine and unbinds the vm which is binded to + * the engine and bo. + * + */ +void xe_spin_free(int fd, struct igt_spin *spin) +{ + xe_spin_end(spin->xe_spin); + xe_spin_sync_wait(fd, spin); + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); + syncobj_destroy(fd, spin->syncobj); + gem_munmap(spin->xe_spin, spin->bo_size); + gem_close(fd, spin->handle); + + if (!spin->opts.engine) + xe_engine_destroy(fd, spin->engine); + + if (!spin->opts.vm) + xe_vm_destroy(fd, spin->vm); + + free(spin); +} + void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, struct xe_cork *cork) { diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index 73f9a026..60f6e751 100644 --- a/lib/xe/xe_spin.h +++ b/lib/xe/xe_spin.h @@ -13,6 +13,7 @@ #include <stdbool.h> #include "xe_query.h" +#include "lib/igt_dummyload.h" /* Mapped GPU object */ struct xe_spin { @@ -21,11 +22,14 @@ struct xe_spin { uint32_t start; uint32_t end; }; - +void xe_spin_user_vm_engine(int fd, const struct igt_spin_factory *opt, struct igt_spin *spin); +igt_spin_t *xe_spin_create(int fd, const struct igt_spin_factory *opt); void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); 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); void xe_spin_end(struct xe_spin *spin); +void xe_spin_free(int fd, struct igt_spin *spin); struct xe_cork { struct xe_spin *spin; -- 2.39.1 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe 2023-06-12 8:59 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch @ 2023-06-12 18:56 ` Zbigniew Kempczyński 0 siblings, 0 replies; 36+ messages in thread From: Zbigniew Kempczyński @ 2023-06-12 18:56 UTC (permalink / raw) To: sai.gowtham.ch; +Cc: igt-dev On Mon, Jun 12, 2023 at 02:29:47PM +0530, sai.gowtham.ch@intel.com wrote: > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > Extending the spin_create implementation and allocator handle support in xe, > where it submits dummy work loads to engine. This Implementation is wrapped > around vm_bind and unbind as we are supposed to do it manually for xe. > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > --- > lib/igt_dummyload.c | 38 +++++++++++++++--- > lib/igt_dummyload.h | 11 ++++++ > lib/xe/xe_spin.c | 96 +++++++++++++++++++++++++++++++++++++++++++++ > lib/xe/xe_spin.h | 6 ++- > 4 files changed, 145 insertions(+), 6 deletions(-) > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c > index 740a58f3..60c4f679 100644 > --- a/lib/igt_dummyload.c > +++ b/lib/igt_dummyload.c > @@ -46,6 +46,7 @@ > #include "intel_reg.h" > #include "ioctl_wrappers.h" > #include "sw_sync.h" > +#include "xe/xe_spin.h" > > /** > * SECTION:igt_dummyload > @@ -447,7 +448,18 @@ spin_create(int fd, const struct igt_spin_factory *opts) > igt_spin_t * > __igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > - return spin_create(fd, opts); > + if (is_xe_device(fd)) { > + igt_spin_t *spin; > + > + spin = xe_spin_create(fd, opts); > + > + pthread_mutex_lock(&list_lock); > + igt_list_add(&spin->link, &spin_list); > + pthread_mutex_unlock(&list_lock); > + > + return spin; > + } else > + return spin_create(fd, opts); > } > > /** > @@ -467,6 +479,16 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > igt_spin_t *spin; > > + if (is_xe_device(fd)) { > + spin = xe_spin_create(fd, opts); > + > + pthread_mutex_lock(&list_lock); > + igt_list_add(&spin->link, &spin_list); > + pthread_mutex_unlock(&list_lock); > + > + return spin; > + } > + > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { > unsigned int class; > > @@ -597,8 +619,12 @@ void igt_spin_end(igt_spin_t *spin) > if (!spin) > return; > > - igt_gettime(&spin->last_signal); > - sync_write(spin, MI_BATCH_BUFFER_END); > + if ((spin->driver = DRIVER_XE)) { Uaa, this hurts! -- Zbigniew > + xe_spin_end(spin->xe_spin); > + } else { > + igt_gettime(&spin->last_signal); > + sync_write(spin, MI_BATCH_BUFFER_END); > + } > } > > static void __igt_spin_free(int fd, igt_spin_t *spin) > @@ -646,12 +672,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > { > if (!spin) > return; > - > pthread_mutex_lock(&list_lock); > igt_list_del(&spin->link); > pthread_mutex_unlock(&list_lock); > > - __igt_spin_free(fd, spin); > + if (is_xe_device(fd)) > + xe_spin_free(fd, spin); > + else > + __igt_spin_free(fd, spin); > } > > void igt_terminate_spins(void) > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h > index b247ab02..ebed19bb 100644 > --- a/lib/igt_dummyload.h > +++ b/lib/igt_dummyload.h > @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { > unsigned int flags; > int fence; > uint64_t ahnd; > + struct drm_xe_engine_class_instance *hwe; > + uint32_t vm; > } igt_spin_factory_t; > > typedef struct igt_spin { > @@ -83,6 +85,15 @@ typedef struct igt_spin { > #define SPIN_CLFLUSH (1 << 0) > > struct igt_spin_factory opts; > + > + struct xe_spin *xe_spin; > + int driver; > + size_t bo_size; > + uint64_t address; > + unsigned int engine; > + uint32_t vm; > + uint32_t syncobj; > + > } igt_spin_t; > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c > index 856d0ba2..b375463a 100644 > --- a/lib/xe/xe_spin.c > +++ b/lib/xe/xe_spin.c > @@ -82,6 +82,102 @@ void xe_spin_end(struct xe_spin *spin) > spin->end = 0; > } > > +/** > + * xe_spin_create: > + *@opt: controlling options such as allocator handle, engine, vmetc > + * > + * igt_spin_new for xe, xe_spin_create submits a batch using xe_spin_init > + * which wraps around vm bind and unbinding the object associated to it. > + * This returs a spinner after submitting a dummy load. > + * > + */ > +igt_spin_t * > +xe_spin_create(int fd, const struct igt_spin_factory *opt) > +{ > + size_t bo_size = xe_get_default_alignment(fd); > + uint64_t ahnd = opt->ahnd, addr; > + struct igt_spin *spin; > + struct xe_spin *xe_spin; > + struct drm_xe_sync sync = { > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > + }; > + struct drm_xe_exec exec = { > + .num_batch_buffer = 1, > + .num_syncs = 1, > + .syncs = to_user_pointer(&sync), > + }; > + > + igt_assert(ahnd); > + spin = calloc(1, sizeof(struct igt_spin)); > + igt_assert(spin); > + > + spin->driver = DRIVER_XE; > + spin->syncobj = syncobj_create(fd, 0); > + spin->vm = opt->vm; > + spin->engine = opt->engine; > + > + if (!spin->vm) > + spin->vm = xe_vm_create(fd, 0, 0); > + > + if (!spin->engine) { > + if (opt->hwe) > + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); > + else > + spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_COPY); > + } > + > + spin->handle = xe_bo_create(fd, 0, spin->vm, bo_size); > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); > + > + xe_spin_init(xe_spin, addr, true); > + exec.engine_id = spin->engine; > + exec.address = addr; > + sync.handle = spin->syncobj; > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > + xe_spin_wait_started(xe_spin); > + > + spin->bo_size = bo_size; > + spin->address = addr; > + spin->xe_spin = xe_spin; > + spin->opts = *opt; > + > + return spin; > +} > + > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) > +{ > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, NULL)); > +} > + > +/* > + * xe_spin_free: > + *@spin: spin state from igt_spin_new() > + * > + * Wrapper to free spinner whhich is triggered by xe_spin_create. > + * which distroys vm, engine and unbinds the vm which is binded to > + * the engine and bo. > + * > + */ > +void xe_spin_free(int fd, struct igt_spin *spin) > +{ > + xe_spin_end(spin->xe_spin); > + xe_spin_sync_wait(fd, spin); > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); > + syncobj_destroy(fd, spin->syncobj); > + gem_munmap(spin->xe_spin, spin->bo_size); > + gem_close(fd, spin->handle); > + > + if (!spin->opts.engine) > + xe_engine_destroy(fd, spin->engine); > + > + if (!spin->opts.vm) > + xe_vm_destroy(fd, spin->vm); > + > + free(spin); > +} > + > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > struct xe_cork *cork) > { > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h > index 73f9a026..60f6e751 100644 > --- a/lib/xe/xe_spin.h > +++ b/lib/xe/xe_spin.h > @@ -13,6 +13,7 @@ > #include <stdbool.h> > > #include "xe_query.h" > +#include "lib/igt_dummyload.h" > > /* Mapped GPU object */ > struct xe_spin { > @@ -21,11 +22,14 @@ struct xe_spin { > uint32_t start; > uint32_t end; > }; > - > +void xe_spin_user_vm_engine(int fd, const struct igt_spin_factory *opt, struct igt_spin *spin); > +igt_spin_t *xe_spin_create(int fd, const struct igt_spin_factory *opt); > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); > 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); > void xe_spin_end(struct xe_spin *spin); > +void xe_spin_free(int fd, struct igt_spin *spin); > > struct xe_cork { > struct xe_spin *spin; > -- > 2.39.1 > ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 0/2] Integrate igt_spin_new with Xe @ 2023-06-06 8:50 sai.gowtham.ch 2023-06-06 8:50 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 0 siblings, 1 reply; 36+ messages in thread From: sai.gowtham.ch @ 2023-06-06 8:50 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Sai Gowtham Ch (2): lib/xe/xe_spin: Integrate igt_spin_new with Xe tests/xe/xe_spin_batch: Add new test to exercise igt_spin_new for xe lib/igt_dummyload.c | 38 +++++++-- lib/igt_dummyload.h | 11 +++ lib/xe/xe_spin.c | 97 ++++++++++++++++++++++ lib/xe/xe_spin.h | 6 +- tests/meson.build | 1 + tests/xe/xe_spin_batch.c | 168 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 315 insertions(+), 6 deletions(-) create mode 100644 tests/xe/xe_spin_batch.c -- 2.39.1 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe 2023-06-06 8:50 [igt-dev] [PATCH i-g-t 0/2] " sai.gowtham.ch @ 2023-06-06 8:50 ` sai.gowtham.ch 2023-06-06 19:27 ` Zbigniew Kempczyński 0 siblings, 1 reply; 36+ messages in thread From: sai.gowtham.ch @ 2023-06-06 8:50 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> --- lib/igt_dummyload.c | 38 +++++++++++++++--- lib/igt_dummyload.h | 11 +++++ lib/xe/xe_spin.c | 97 +++++++++++++++++++++++++++++++++++++++++++++ lib/xe/xe_spin.h | 6 ++- 4 files changed, 146 insertions(+), 6 deletions(-) diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index 740a58f3..0c2a2029 100644 --- a/lib/igt_dummyload.c +++ b/lib/igt_dummyload.c @@ -46,6 +46,7 @@ #include "intel_reg.h" #include "ioctl_wrappers.h" #include "sw_sync.h" +#include "xe/xe_spin.h" /** * SECTION:igt_dummyload @@ -447,7 +448,18 @@ spin_create(int fd, const struct igt_spin_factory *opts) igt_spin_t * __igt_spin_factory(int fd, const struct igt_spin_factory *opts) { - return spin_create(fd, opts); + if (is_xe_device(fd)) { + igt_spin_t *spin; + + spin = xe_spin_create(fd, opts); + + pthread_mutex_lock(&list_lock); + igt_list_add(&spin->link, &spin_list); + pthread_mutex_unlock(&list_lock); + + return spin; + } else + return spin_create(fd, opts); } /** @@ -467,6 +479,16 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) { igt_spin_t *spin; + if (is_xe_device(fd)) { + spin = xe_spin_create(fd, opts); + + pthread_mutex_lock(&list_lock); + igt_list_add(&spin->link, &spin_list); + pthread_mutex_unlock(&list_lock); + + return spin; + } + if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { unsigned int class; @@ -597,8 +619,12 @@ void igt_spin_end(igt_spin_t *spin) if (!spin) return; - igt_gettime(&spin->last_signal); - sync_write(spin, MI_BATCH_BUFFER_END); + if (is_xe_device(spin->fd)) + xe_spin_end(spin->xe_spin); + else { + igt_gettime(&spin->last_signal); + sync_write(spin, MI_BATCH_BUFFER_END); + } } static void __igt_spin_free(int fd, igt_spin_t *spin) @@ -646,12 +672,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) { if (!spin) return; - pthread_mutex_lock(&list_lock); igt_list_del(&spin->link); pthread_mutex_unlock(&list_lock); - __igt_spin_free(fd, spin); + if (is_xe_device(fd)) + xe_spin_free(fd, spin); + else + __igt_spin_free(fd, spin); } void igt_terminate_spins(void) diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index b247ab02..bfeb489d 100644 --- a/lib/igt_dummyload.h +++ b/lib/igt_dummyload.h @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { unsigned int flags; int fence; uint64_t ahnd; + struct drm_xe_engine_class_instance *hwe; + uint32_t vm; } igt_spin_factory_t; typedef struct igt_spin { @@ -83,6 +85,15 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 << 0) struct igt_spin_factory opts; + + struct xe_spin *xe_spin; + int fd; + size_t bo_size; + uint64_t address; + unsigned int engine; + uint32_t vm; + uint32_t syncobj; + } igt_spin_t; diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index 856d0ba2..43b4e691 100644 --- a/lib/xe/xe_spin.c +++ b/lib/xe/xe_spin.c @@ -82,6 +82,103 @@ void xe_spin_end(struct xe_spin *spin) spin->end = 0; } +/** + * xe_spin_create: + *@opt: controlling options such as allocator handle, engine, vmetc + * + * igt_spin_new for xe, xe_spin_create submits a batch using xe_spin_init + * which wraps around vm bind and unbinding the object associated to it. + * This returs a spinner after submitting a dummy load. + * + */ +igt_spin_t * +xe_spin_create(int fd, const struct igt_spin_factory *opt) +{ + size_t bo_size = xe_get_default_alignment(fd); + uint64_t ahnd = opt->ahnd, addr; + struct igt_spin *spin; + struct xe_spin *xe_spin; + struct drm_xe_sync sync = { + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, + }; + struct drm_xe_exec exec = { + .num_batch_buffer = 1, + .num_syncs = 1, + .syncs = to_user_pointer(&sync), + }; + + igt_assert(ahnd); + spin = calloc(1, sizeof(struct igt_spin)); + igt_assert(spin); + + spin->syncobj = syncobj_create(fd, 0); + spin->vm = opt->vm; + spin->engine = opt->engine; + + if (!spin->vm) + spin->vm = xe_vm_create(fd, 0, 0); + + if (!spin->engine) { + + if (opt->hwe) + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); + else + spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_COPY); + } + + spin->handle = xe_bo_create(fd, 0, spin->vm, bo_size); + xe_spin = xe_bo_map(fd, spin->handle, bo_size); + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); + + xe_spin_init(xe_spin, addr, true); + exec.engine_id = spin->engine; + exec.address = addr; + sync.handle = spin->syncobj; + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); + xe_spin_wait_started(xe_spin); + + spin->bo_size = bo_size; + spin->address = addr; + spin->xe_spin = xe_spin; + spin->fd = fd; + spin->opts = *opt; + + return spin; +} + +void xe_spin_sync_wait(int fd, struct igt_spin *spin) +{ + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, NULL)); +} + +/* + * xe_spin_free: + *@spin: spin state from igt_spin_new() + * + * Wrapper to free spinner whhich is triggered by xe_spin_create. + * which distroys vm, engine and unbinds the vm which is binded to + * the engine and bo. + * + */ +void xe_spin_free(int fd, struct igt_spin *spin) +{ + xe_spin_end(spin->xe_spin); + xe_spin_sync_wait(fd, spin); + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); + syncobj_destroy(fd, spin->syncobj); + gem_munmap(spin->xe_spin, spin->bo_size); + gem_close(fd, spin->handle); + + if (!spin->opts.engine) + xe_engine_destroy(fd, spin->engine); + + if (!spin->opts.vm) + xe_vm_destroy(fd, spin->vm); + + free(spin); +} + void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, struct xe_cork *cork) { diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index 73f9a026..60f6e751 100644 --- a/lib/xe/xe_spin.h +++ b/lib/xe/xe_spin.h @@ -13,6 +13,7 @@ #include <stdbool.h> #include "xe_query.h" +#include "lib/igt_dummyload.h" /* Mapped GPU object */ struct xe_spin { @@ -21,11 +22,14 @@ struct xe_spin { uint32_t start; uint32_t end; }; - +void xe_spin_user_vm_engine(int fd, const struct igt_spin_factory *opt, struct igt_spin *spin); +igt_spin_t *xe_spin_create(int fd, const struct igt_spin_factory *opt); void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); 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); void xe_spin_end(struct xe_spin *spin); +void xe_spin_free(int fd, struct igt_spin *spin); struct xe_cork { struct xe_spin *spin; -- 2.39.1 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe 2023-06-06 8:50 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch @ 2023-06-06 19:27 ` Zbigniew Kempczyński 2023-06-06 21:03 ` Ch, Sai Gowtham 0 siblings, 1 reply; 36+ messages in thread From: Zbigniew Kempczyński @ 2023-06-06 19:27 UTC (permalink / raw) To: sai.gowtham.ch; +Cc: igt-dev On Tue, Jun 06, 2023 at 02:20:14PM +0530, sai.gowtham.ch@intel.com wrote: > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > Extending the spin_create implementation and allocator handle support in xe, > where it submits dummy work loads to engine. This Implementation is wrapped > around vm_bind and unbind as we are supposed to do it manually for xe. > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > --- > lib/igt_dummyload.c | 38 +++++++++++++++--- > lib/igt_dummyload.h | 11 +++++ > lib/xe/xe_spin.c | 97 +++++++++++++++++++++++++++++++++++++++++++++ > lib/xe/xe_spin.h | 6 ++- > 4 files changed, 146 insertions(+), 6 deletions(-) > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c > index 740a58f3..0c2a2029 100644 > --- a/lib/igt_dummyload.c > +++ b/lib/igt_dummyload.c > @@ -46,6 +46,7 @@ > #include "intel_reg.h" > #include "ioctl_wrappers.h" > #include "sw_sync.h" > +#include "xe/xe_spin.h" > > /** > * SECTION:igt_dummyload > @@ -447,7 +448,18 @@ spin_create(int fd, const struct igt_spin_factory *opts) > igt_spin_t * > __igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > - return spin_create(fd, opts); > + if (is_xe_device(fd)) { > + igt_spin_t *spin; > + > + spin = xe_spin_create(fd, opts); > + > + pthread_mutex_lock(&list_lock); > + igt_list_add(&spin->link, &spin_list); > + pthread_mutex_unlock(&list_lock); > + > + return spin; > + } else > + return spin_create(fd, opts); > } > > /** > @@ -467,6 +479,16 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > igt_spin_t *spin; > > + if (is_xe_device(fd)) { > + spin = xe_spin_create(fd, opts); > + > + pthread_mutex_lock(&list_lock); > + igt_list_add(&spin->link, &spin_list); > + pthread_mutex_unlock(&list_lock); > + > + return spin; > + } > + > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { > unsigned int class; > > @@ -597,8 +619,12 @@ void igt_spin_end(igt_spin_t *spin) > if (!spin) > return; > > - igt_gettime(&spin->last_signal); > - sync_write(spin, MI_BATCH_BUFFER_END); > + if (is_xe_device(spin->fd)) Use { for both if/else sequence if any of it > 1 line. > + xe_spin_end(spin->xe_spin); This check may be called on already closed filedescriptor leading to SIGSEGV. I was a little bit surprised so I've added some debugging info to find out the reason: Program received signal SIGINT, Interrupt. 0x00007ffff7d2c51a in __GI___clock_nanosleep (clock_id=<optimized out>, clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7fffffffe070, rem=rem@entry=0x7fffffffe070) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:73 Download failed: Function not implemented. Continuing without source file ./time/../sysdeps/unix/sysv/linux/clock_nanosleep.c. 73 ../sysdeps/unix/sysv/linux/clock_nanosleep.c: No such file or directory. (gdb) bt #0 0x00007ffff7d2c51a in __GI___clock_nanosleep (clock_id=<optimized out>, clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7fffffffe070, rem=rem@entry=0x7fffffffe070) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:73 #1 0x00007ffff7d31ac7 in __GI___nanosleep (req=req@entry=0x7fffffffe070, rem=rem@entry=0x7fffffffe070) at ../sysdeps/unix/sysv/linux/nanosleep.c:25 #2 0x00007ffff7d319fe in __sleep (seconds=0) at ../sysdeps/posix/sleep.c:55 #3 0x00007ffff7f35eca in igt_spin_end (spin=0x5555555978a0) at ../lib/igt_dummyload.c:627 #4 0x00007ffff7f36192 in igt_terminate_spins () at ../lib/igt_dummyload.c:703 #5 0x00007ffff7f2c230 in call_exit_handlers (sig=0) at ../lib/igt_core.c:2825 #6 0x00007ffff7f2c2ac in igt_atexit_handler () at ../lib/igt_core.c:2845 #7 0x00007ffff7c98147 in __run_exit_handlers (status=0, listp=0x7ffff7e34738 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true, run_dtors=run_dtors@entry=true) at exit.c:108 #8 0x00007ffff7c982f0 in __GI_exit (status=<optimized out>) at exit.c:139 #9 0x00007ffff7f2b172 in igt_exit () at ../lib/igt_core.c:2319 #10 0x0000555555555e0b in main (argc=1, argv=0x7fffffffe2e8) at ../tests/xe/xe_spin_batch.c:157 (gdb) frame 3 #3 0x00007ffff7f35eca in igt_spin_end (spin=0x5555555978a0) at ../lib/igt_dummyload.c:627 627 sleep(100); (gdb) print *spin $1 = {link = {prev = 0x7ffff7fb2830 <spin_list>, next = 0x55555559a080}, handle = 10, poll_handle = 0, batch = 0x0, condition = 0x0, cmd_precondition = 0, poll = 0x0, last_signal = {tv_sec = 0, tv_nsec = 0}, timer_thread = 0, timerfd = 0, out_fence = 0, obj = {{handle = 0, relocation_count = 0, relocs_ptr = 0, alignment = 0, offset = 0, flags = 0, {rsvd1 = 0, pad_to_size = 0}, rsvd2 = 0}, {handle = 0, relocation_count = 0, relocs_ptr = 0, alignment = 0, offset = 0, flags = 0, {rsvd1 = 0, pad_to_size = 0}, rsvd2 = 0}}, execbuf = {buffers_ptr = 0, buffer_count = 0, batch_start_offset = 0, batch_len = 0, DR1 = 0, DR4 = 0, num_cliprects = 0, cliprects_ptr = 0, flags = 0, rsvd1 = 0, rsvd2 = 0}, flags = 0, opts = {ctx_id = 0, ctx = 0x0, dependency = 0, dependency_size = 0, engine = 0, flags = 0, fence = 0, ahnd = 1, hwe = 0x5555555987c6, vm = 1}, xe_spin = 0x7ffff5844000, fd = 3, bo_size = 65536, address = 851968, engine = 10, vm = 1, syncobj = 10} I think the best is to cache 'driver' in the spinner during creation. > + else { > + igt_gettime(&spin->last_signal); > + sync_write(spin, MI_BATCH_BUFFER_END); > + } > } > > static void __igt_spin_free(int fd, igt_spin_t *spin) > @@ -646,12 +672,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > { > if (!spin) > return; > - > pthread_mutex_lock(&list_lock); > igt_list_del(&spin->link); > pthread_mutex_unlock(&list_lock); > > - __igt_spin_free(fd, spin); > + if (is_xe_device(fd)) > + xe_spin_free(fd, spin); > + else > + __igt_spin_free(fd, spin); > } > > void igt_terminate_spins(void) > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h > index b247ab02..bfeb489d 100644 > --- a/lib/igt_dummyload.h > +++ b/lib/igt_dummyload.h > @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { > unsigned int flags; > int fence; > uint64_t ahnd; > + struct drm_xe_engine_class_instance *hwe; > + uint32_t vm; > } igt_spin_factory_t; > > typedef struct igt_spin { > @@ -83,6 +85,15 @@ typedef struct igt_spin { > #define SPIN_CLFLUSH (1 << 0) > > struct igt_spin_factory opts; > + > + struct xe_spin *xe_spin; > + int fd; > + size_t bo_size; > + uint64_t address; > + unsigned int engine; > + uint32_t vm; > + uint32_t syncobj; > + > } igt_spin_t; > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c > index 856d0ba2..43b4e691 100644 > --- a/lib/xe/xe_spin.c > +++ b/lib/xe/xe_spin.c > @@ -82,6 +82,103 @@ void xe_spin_end(struct xe_spin *spin) > spin->end = 0; > } > > +/** > + * xe_spin_create: > + *@opt: controlling options such as allocator handle, engine, vmetc > + * > + * igt_spin_new for xe, xe_spin_create submits a batch using xe_spin_init > + * which wraps around vm bind and unbinding the object associated to it. > + * This returs a spinner after submitting a dummy load. > + * > + */ > +igt_spin_t * > +xe_spin_create(int fd, const struct igt_spin_factory *opt) > +{ > + size_t bo_size = xe_get_default_alignment(fd); > + uint64_t ahnd = opt->ahnd, addr; > + struct igt_spin *spin; > + struct xe_spin *xe_spin; > + struct drm_xe_sync sync = { > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > + }; > + struct drm_xe_exec exec = { > + .num_batch_buffer = 1, > + .num_syncs = 1, > + .syncs = to_user_pointer(&sync), > + }; > + > + igt_assert(ahnd); > + spin = calloc(1, sizeof(struct igt_spin)); > + igt_assert(spin); > + > + spin->syncobj = syncobj_create(fd, 0); > + spin->vm = opt->vm; > + spin->engine = opt->engine; > + > + if (!spin->vm) > + spin->vm = xe_vm_create(fd, 0, 0); > + > + if (!spin->engine) { > + Unnecessary blank line. Rest looks fine for me. I think one respin and I'll accept it. -- Zbigniew > + if (opt->hwe) > + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); > + else > + spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_COPY); > + } > + > + spin->handle = xe_bo_create(fd, 0, spin->vm, bo_size); > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); > + > + xe_spin_init(xe_spin, addr, true); > + exec.engine_id = spin->engine; > + exec.address = addr; > + sync.handle = spin->syncobj; > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > + xe_spin_wait_started(xe_spin); > + > + spin->bo_size = bo_size; > + spin->address = addr; > + spin->xe_spin = xe_spin; > + spin->fd = fd; > + spin->opts = *opt; > + > + return spin; > +} > + > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) > +{ > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, NULL)); > +} > + > +/* > + * xe_spin_free: > + *@spin: spin state from igt_spin_new() > + * > + * Wrapper to free spinner whhich is triggered by xe_spin_create. > + * which distroys vm, engine and unbinds the vm which is binded to > + * the engine and bo. > + * > + */ > +void xe_spin_free(int fd, struct igt_spin *spin) > +{ > + xe_spin_end(spin->xe_spin); > + xe_spin_sync_wait(fd, spin); > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); > + syncobj_destroy(fd, spin->syncobj); > + gem_munmap(spin->xe_spin, spin->bo_size); > + gem_close(fd, spin->handle); > + > + if (!spin->opts.engine) > + xe_engine_destroy(fd, spin->engine); > + > + if (!spin->opts.vm) > + xe_vm_destroy(fd, spin->vm); > + > + free(spin); > +} > + > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > struct xe_cork *cork) > { > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h > index 73f9a026..60f6e751 100644 > --- a/lib/xe/xe_spin.h > +++ b/lib/xe/xe_spin.h > @@ -13,6 +13,7 @@ > #include <stdbool.h> > > #include "xe_query.h" > +#include "lib/igt_dummyload.h" > > /* Mapped GPU object */ > struct xe_spin { > @@ -21,11 +22,14 @@ struct xe_spin { > uint32_t start; > uint32_t end; > }; > - > +void xe_spin_user_vm_engine(int fd, const struct igt_spin_factory *opt, struct igt_spin *spin); > +igt_spin_t *xe_spin_create(int fd, const struct igt_spin_factory *opt); > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); > 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); > void xe_spin_end(struct xe_spin *spin); > +void xe_spin_free(int fd, struct igt_spin *spin); > > struct xe_cork { > struct xe_spin *spin; > -- > 2.39.1 > ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe 2023-06-06 19:27 ` Zbigniew Kempczyński @ 2023-06-06 21:03 ` Ch, Sai Gowtham 0 siblings, 0 replies; 36+ messages in thread From: Ch, Sai Gowtham @ 2023-06-06 21:03 UTC (permalink / raw) To: Kempczynski, Zbigniew; +Cc: igt-dev > -----Original Message----- > From: Kempczynski, Zbigniew <zbigniew.kempczynski@intel.com> > Sent: Wednesday, June 7, 2023 12:57 AM > To: Ch, Sai Gowtham <sai.gowtham.ch@intel.com> > Cc: igt-dev@lists.freedesktop.org > Subject: Re: [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe > > On Tue, Jun 06, 2023 at 02:20:14PM +0530, sai.gowtham.ch@intel.com wrote: > > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > > > Extending the spin_create implementation and allocator handle support > > in xe, where it submits dummy work loads to engine. This > > Implementation is wrapped around vm_bind and unbind as we are supposed to > do it manually for xe. > > > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > --- > > lib/igt_dummyload.c | 38 +++++++++++++++--- lib/igt_dummyload.h | 11 > > +++++ > > lib/xe/xe_spin.c | 97 +++++++++++++++++++++++++++++++++++++++++++++ > > lib/xe/xe_spin.h | 6 ++- > > 4 files changed, 146 insertions(+), 6 deletions(-) > > > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index > > 740a58f3..0c2a2029 100644 > > --- a/lib/igt_dummyload.c > > +++ b/lib/igt_dummyload.c > > @@ -46,6 +46,7 @@ > > #include "intel_reg.h" > > #include "ioctl_wrappers.h" > > #include "sw_sync.h" > > +#include "xe/xe_spin.h" > > > > /** > > * SECTION:igt_dummyload > > @@ -447,7 +448,18 @@ spin_create(int fd, const struct igt_spin_factory > > *opts) igt_spin_t * __igt_spin_factory(int fd, const struct > > igt_spin_factory *opts) { > > - return spin_create(fd, opts); > > + if (is_xe_device(fd)) { > > + igt_spin_t *spin; > > + > > + spin = xe_spin_create(fd, opts); > > + > > + pthread_mutex_lock(&list_lock); > > + igt_list_add(&spin->link, &spin_list); > > + pthread_mutex_unlock(&list_lock); > > + > > + return spin; > > + } else > > + return spin_create(fd, opts); > > } > > > > /** > > @@ -467,6 +479,16 @@ igt_spin_factory(int fd, const struct > > igt_spin_factory *opts) { > > igt_spin_t *spin; > > > > + if (is_xe_device(fd)) { > > + spin = xe_spin_create(fd, opts); > > + > > + pthread_mutex_lock(&list_lock); > > + igt_list_add(&spin->link, &spin_list); > > + pthread_mutex_unlock(&list_lock); > > + > > + return spin; > > + } > > + > > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != > ALL_ENGINES) { > > unsigned int class; > > > > @@ -597,8 +619,12 @@ void igt_spin_end(igt_spin_t *spin) > > if (!spin) > > return; > > > > - igt_gettime(&spin->last_signal); > > - sync_write(spin, MI_BATCH_BUFFER_END); > > + if (is_xe_device(spin->fd)) > > Use { for both if/else sequence if any of it > 1 line. > > > + xe_spin_end(spin->xe_spin); > > This check may be called on already closed filedescriptor leading to SIGSEGV. > I was a little bit surprised so I've added some debugging info to find out the > reason: > > Program received signal SIGINT, Interrupt. > 0x00007ffff7d2c51a in __GI___clock_nanosleep (clock_id=<optimized out>, > clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7fffffffe070, > rem=rem@entry=0x7fffffffe070) at > ../sysdeps/unix/sysv/linux/clock_nanosleep.c:73 > Download failed: Function not implemented. Continuing without source file > ./time/../sysdeps/unix/sysv/linux/clock_nanosleep.c. > 73 ../sysdeps/unix/sysv/linux/clock_nanosleep.c: No such file or directory. > (gdb) bt > #0 0x00007ffff7d2c51a in __GI___clock_nanosleep (clock_id=<optimized out>, > clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7fffffffe070, > rem=rem@entry=0x7fffffffe070) at > ../sysdeps/unix/sysv/linux/clock_nanosleep.c:73 > #1 0x00007ffff7d31ac7 in __GI___nanosleep (req=req@entry=0x7fffffffe070, > rem=rem@entry=0x7fffffffe070) at ../sysdeps/unix/sysv/linux/nanosleep.c:25 > #2 0x00007ffff7d319fe in __sleep (seconds=0) at ../sysdeps/posix/sleep.c:55 > #3 0x00007ffff7f35eca in igt_spin_end (spin=0x5555555978a0) at > ../lib/igt_dummyload.c:627 > #4 0x00007ffff7f36192 in igt_terminate_spins () at ../lib/igt_dummyload.c:703 > #5 0x00007ffff7f2c230 in call_exit_handlers (sig=0) at ../lib/igt_core.c:2825 > #6 0x00007ffff7f2c2ac in igt_atexit_handler () at ../lib/igt_core.c:2845 > #7 0x00007ffff7c98147 in __run_exit_handlers (status=0, listp=0x7ffff7e34738 > <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true, > run_dtors=run_dtors@entry=true) at exit.c:108 > #8 0x00007ffff7c982f0 in __GI_exit (status=<optimized out>) at exit.c:139 > #9 0x00007ffff7f2b172 in igt_exit () at ../lib/igt_core.c:2319 > #10 0x0000555555555e0b in main (argc=1, argv=0x7fffffffe2e8) at > ../tests/xe/xe_spin_batch.c:157 > (gdb) frame 3 > #3 0x00007ffff7f35eca in igt_spin_end (spin=0x5555555978a0) at > ../lib/igt_dummyload.c:627 > 627 sleep(100); > (gdb) print *spin > $1 = {link = {prev = 0x7ffff7fb2830 <spin_list>, next = 0x55555559a080}, handle > = 10, poll_handle = 0, batch = 0x0, condition = 0x0, cmd_precondition = 0, > poll = 0x0, last_signal = {tv_sec = 0, tv_nsec = 0}, timer_thread = 0, timerfd = 0, > out_fence = 0, obj = {{handle = 0, relocation_count = 0, relocs_ptr = 0, > alignment = 0, offset = 0, flags = 0, {rsvd1 = 0, pad_to_size = 0}, rsvd2 = 0}, > {handle = 0, relocation_count = 0, relocs_ptr = 0, alignment = 0, offset = 0, > flags = 0, {rsvd1 = 0, pad_to_size = 0}, rsvd2 = 0}}, execbuf = {buffers_ptr = 0, > buffer_count = 0, batch_start_offset = 0, batch_len = 0, DR1 = 0, DR4 = 0, > num_cliprects = 0, cliprects_ptr = 0, flags = 0, rsvd1 = 0, rsvd2 = 0}, flags = 0, > opts = {ctx_id = 0, ctx = 0x0, dependency = 0, dependency_size = 0, > engine = 0, flags = 0, fence = 0, ahnd = 1, hwe = 0x5555555987c6, vm = 1}, > xe_spin = 0x7ffff5844000, fd = 3, bo_size = 65536, address = 851968, engine = > 10, > vm = 1, syncobj = 10} > > I think the best is to cache 'driver' in the spinner during creation. > > > + else { > > + igt_gettime(&spin->last_signal); > > + sync_write(spin, MI_BATCH_BUFFER_END); > > + } > > } > > > > static void __igt_spin_free(int fd, igt_spin_t *spin) @@ -646,12 > > +672,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) { > > if (!spin) > > return; > > - > > pthread_mutex_lock(&list_lock); > > igt_list_del(&spin->link); > > pthread_mutex_unlock(&list_lock); > > > > - __igt_spin_free(fd, spin); > > + if (is_xe_device(fd)) > > + xe_spin_free(fd, spin); > > + else > > + __igt_spin_free(fd, spin); > > } > > > > void igt_terminate_spins(void) > > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index > > b247ab02..bfeb489d 100644 > > --- a/lib/igt_dummyload.h > > +++ b/lib/igt_dummyload.h > > @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { > > unsigned int flags; > > int fence; > > uint64_t ahnd; > > + struct drm_xe_engine_class_instance *hwe; > > + uint32_t vm; > > } igt_spin_factory_t; > > > > typedef struct igt_spin { > > @@ -83,6 +85,15 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 > > << 0) > > > > struct igt_spin_factory opts; > > + > > + struct xe_spin *xe_spin; > > + int fd; > > + size_t bo_size; > > + uint64_t address; > > + unsigned int engine; > > + uint32_t vm; > > + uint32_t syncobj; > > + > > } igt_spin_t; > > > > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index > > 856d0ba2..43b4e691 100644 > > --- a/lib/xe/xe_spin.c > > +++ b/lib/xe/xe_spin.c > > @@ -82,6 +82,103 @@ void xe_spin_end(struct xe_spin *spin) > > spin->end = 0; > > } > > > > +/** > > + * xe_spin_create: > > + *@opt: controlling options such as allocator handle, engine, vmetc > > + * > > + * igt_spin_new for xe, xe_spin_create submits a batch using > > +xe_spin_init > > + * which wraps around vm bind and unbinding the object associated to it. > > + * This returs a spinner after submitting a dummy load. > > + * > > + */ > > +igt_spin_t * > > +xe_spin_create(int fd, const struct igt_spin_factory *opt) { > > + size_t bo_size = xe_get_default_alignment(fd); > > + uint64_t ahnd = opt->ahnd, addr; > > + struct igt_spin *spin; > > + struct xe_spin *xe_spin; > > + struct drm_xe_sync sync = { > > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > > + }; > > + struct drm_xe_exec exec = { > > + .num_batch_buffer = 1, > > + .num_syncs = 1, > > + .syncs = to_user_pointer(&sync), > > + }; > > + > > + igt_assert(ahnd); > > + spin = calloc(1, sizeof(struct igt_spin)); > > + igt_assert(spin); > > + > > + spin->syncobj = syncobj_create(fd, 0); > > + spin->vm = opt->vm; > > + spin->engine = opt->engine; > > + > > + if (!spin->vm) > > + spin->vm = xe_vm_create(fd, 0, 0); > > + > > + if (!spin->engine) { > > + > > Unnecessary blank line. > > Rest looks fine for me. > > I think one respin and I'll accept it. > Sure I'll resend the patch, with this minor fix of storing DRIVER to use it in igt_spin_end. -- Gowtham > -- > Zbigniew > > > + if (opt->hwe) > > + spin->engine = xe_engine_create(fd, spin->vm, opt- > >hwe, 0); > > + else > > + spin->engine = xe_engine_create_class(fd, spin->vm, > DRM_XE_ENGINE_CLASS_COPY); > > + } > > + > > + spin->handle = xe_bo_create(fd, 0, spin->vm, bo_size); > > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, > 0, ALLOC_STRATEGY_LOW_TO_HIGH); > > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); > > + > > + xe_spin_init(xe_spin, addr, true); > > + exec.engine_id = spin->engine; > > + exec.address = addr; > > + sync.handle = spin->syncobj; > > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > > + xe_spin_wait_started(xe_spin); > > + > > + spin->bo_size = bo_size; > > + spin->address = addr; > > + spin->xe_spin = xe_spin; > > + spin->fd = fd; > > + spin->opts = *opt; > > + > > + return spin; > > +} > > + > > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) { > > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, NULL)); > > +} > > + > > +/* > > + * xe_spin_free: > > + *@spin: spin state from igt_spin_new() > > + * > > + * Wrapper to free spinner whhich is triggered by xe_spin_create. > > + * which distroys vm, engine and unbinds the vm which is binded to > > + * the engine and bo. > > + * > > + */ > > +void xe_spin_free(int fd, struct igt_spin *spin) { > > + xe_spin_end(spin->xe_spin); > > + xe_spin_sync_wait(fd, spin); > > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); > > + syncobj_destroy(fd, spin->syncobj); > > + gem_munmap(spin->xe_spin, spin->bo_size); > > + gem_close(fd, spin->handle); > > + > > + if (!spin->opts.engine) > > + xe_engine_destroy(fd, spin->engine); > > + > > + if (!spin->opts.vm) > > + xe_vm_destroy(fd, spin->vm); > > + > > + free(spin); > > +} > > + > > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > > struct xe_cork *cork) > > { > > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index > > 73f9a026..60f6e751 100644 > > --- a/lib/xe/xe_spin.h > > +++ b/lib/xe/xe_spin.h > > @@ -13,6 +13,7 @@ > > #include <stdbool.h> > > > > #include "xe_query.h" > > +#include "lib/igt_dummyload.h" > > > > /* Mapped GPU object */ > > struct xe_spin { > > @@ -21,11 +22,14 @@ struct xe_spin { > > uint32_t start; > > uint32_t end; > > }; > > - > > +void xe_spin_user_vm_engine(int fd, const struct igt_spin_factory > > +*opt, struct igt_spin *spin); igt_spin_t *xe_spin_create(int fd, > > +const struct igt_spin_factory *opt); > > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); > > 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); void > > xe_spin_end(struct xe_spin *spin); > > +void xe_spin_free(int fd, struct igt_spin *spin); > > > > struct xe_cork { > > struct xe_spin *spin; > > -- > > 2.39.1 > > ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 0/2] Integrate igt_spin_new with Xe @ 2023-06-04 19:58 sai.gowtham.ch 2023-06-04 19:58 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 0 siblings, 1 reply; 36+ messages in thread From: sai.gowtham.ch @ 2023-06-04 19:58 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch, janga.rahul.kumar, kamil.konieczny From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Sai Gowtham Ch (2): lib/xe/xe_spin: Integrate igt_spin_new with Xe tests/xe/xe_spin_batch: Add new test to exercise igt_spin_new for xe lib/igt_dummyload.c | 24 ++++-- lib/igt_dummyload.h | 12 +++ lib/xe/xe_spin.c | 121 ++++++++++++++++++++++++++++ lib/xe/xe_spin.h | 6 +- tests/meson.build | 1 + tests/xe/xe_spin_batch.c | 168 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 325 insertions(+), 7 deletions(-) create mode 100644 tests/xe/xe_spin_batch.c -- 2.39.1 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe 2023-06-04 19:58 [igt-dev] [PATCH i-g-t 0/2] " sai.gowtham.ch @ 2023-06-04 19:58 ` sai.gowtham.ch 2023-06-05 8:58 ` Kumar, Janga Rahul 2023-06-05 11:19 ` Zbigniew Kempczyński 0 siblings, 2 replies; 36+ messages in thread From: sai.gowtham.ch @ 2023-06-04 19:58 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch, janga.rahul.kumar, kamil.konieczny From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> --- lib/igt_dummyload.c | 24 ++++++--- lib/igt_dummyload.h | 12 +++++ lib/xe/xe_spin.c | 121 ++++++++++++++++++++++++++++++++++++++++++++ lib/xe/xe_spin.h | 6 ++- 4 files changed, 156 insertions(+), 7 deletions(-) diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index 740a58f3..6e89b72d 100644 --- a/lib/igt_dummyload.c +++ b/lib/igt_dummyload.c @@ -46,6 +46,7 @@ #include "intel_reg.h" #include "ioctl_wrappers.h" #include "sw_sync.h" +#include "xe/xe_spin.h" /** * SECTION:igt_dummyload @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory *opts) igt_spin_t * __igt_spin_factory(int fd, const struct igt_spin_factory *opts) { - return spin_create(fd, opts); + if (is_xe_device(fd)) + return xe_spin_create(fd, opts); + else + return spin_create(fd, opts); } /** @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) { igt_spin_t *spin; + if (is_xe_device(fd)) { + spin = xe_spin_create(fd, opts); + return spin; + } + if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { unsigned int class; @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) if (!spin) return; - pthread_mutex_lock(&list_lock); - igt_list_del(&spin->link); - pthread_mutex_unlock(&list_lock); - - __igt_spin_free(fd, spin); + if (is_xe_device(fd)) { + xe_spin_free(fd, spin); + } else { + pthread_mutex_lock(&list_lock); + igt_list_del(&spin->link); + pthread_mutex_unlock(&list_lock); + __igt_spin_free(fd, spin); + } } void igt_terminate_spins(void) diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index b247ab02..c5d7b993 100644 --- a/lib/igt_dummyload.h +++ b/lib/igt_dummyload.h @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { unsigned int flags; int fence; uint64_t ahnd; + struct drm_xe_engine_class_instance *hwe; + uint32_t vm; } igt_spin_factory_t; typedef struct igt_spin { @@ -83,6 +85,16 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 << 0) struct igt_spin_factory opts; + + struct xe_spin *xe_spin; + size_t bo_size; + uint64_t address; + unsigned int engine; + uint32_t vm; + uint32_t syncobj; + bool is_user_vm; + bool is_user_engine; + } igt_spin_t; diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index 856d0ba2..c5a4479b 100644 --- a/lib/xe/xe_spin.c +++ b/lib/xe/xe_spin.c @@ -82,6 +82,127 @@ void xe_spin_end(struct xe_spin *spin) spin->end = 0; } +/** + * xe_spin_user_vm_engine: + * @spin: spin state from igt_spin_new() + * @opt: controlling options such as allocator handle, engine, vm etc + * + * Wrapper function collects the vm and engine data from the user, + * if engine is not given from the user, engine will be created. + * + */ +void xe_spin_user_vm_engine(int fd, const struct igt_spin_factory *opt, struct igt_spin *spin) +{ + spin->vm = opt->vm; + spin->is_user_vm = true; + if (opt->engine) { + spin->engine = opt->engine; + spin->is_user_engine = true; + } else { + if (opt->hwe) + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); + else + spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_COPY); + + spin->is_user_engine = false; + } +} + +/** + * xe_spin_create: + *@opt: controlling options such as allocator handle, engine, vmetc + * + * igt_spin_new for xe, xe_spin_create submits a batch using xe_spin_init + * which wraps around vm bind and unbinding the object associated to it. + * This returs a spinner after submitting a dummy load. + * + */ +igt_spin_t * +xe_spin_create(int fd, const struct igt_spin_factory *opt) +{ + size_t bo_size = xe_get_default_alignment(fd); + uint64_t ahnd = opt->ahnd, addr; + struct igt_spin *spin; + struct xe_spin *xe_spin; + struct drm_xe_sync sync = { + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, + }; + struct drm_xe_exec exec = { + .num_batch_buffer = 1, + .num_syncs = 1, + .syncs = to_user_pointer(&sync), + }; + + igt_assert(ahnd); + spin = calloc(1, sizeof(struct igt_spin)); + igt_assert(spin); + + spin->syncobj = syncobj_create(fd, 0); + + if (opt->vm) { + xe_spin_user_vm_engine(fd, opt, spin); + + } else { + spin->vm = xe_vm_create(fd, 0, 0); + if (opt->hwe) + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); + else + spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_COPY); + spin->is_user_vm = false; + spin->is_user_engine = false; + } + + spin->handle = xe_bo_create(fd, 0, spin->vm, bo_size); + xe_spin = xe_bo_map(fd, spin->handle, bo_size); + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); + + xe_spin_init(xe_spin, addr, true); + exec.engine_id = spin->engine; + exec.address = addr; + sync.handle = spin->syncobj; + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); + xe_spin_wait_started(xe_spin); + + spin->bo_size = bo_size; + spin->address = addr; + spin->xe_spin = xe_spin; + + return spin; +} + +void xe_spin_sync_wait(int fd, struct igt_spin *spin) +{ + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, NULL)); +} + +/* + * xe_spin_free: + *@spin: spin state from igt_spin_new() + * + * Wrapper to free spinner whhich is triggered by xe_spin_create. + * which distroys vm, engine and unbinds the vm which is binded to + * the engine and bo. + * + */ +void xe_spin_free(int fd, struct igt_spin *spin) +{ + xe_spin_end(spin->xe_spin); + xe_spin_sync_wait(fd, spin); + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); + syncobj_destroy(fd, spin->syncobj); + gem_munmap(spin->xe_spin, spin->bo_size); + gem_close(fd, spin->handle); + + if (!spin->is_user_engine) + xe_engine_destroy(fd, spin->engine); + + if (!spin->is_user_vm) + xe_vm_destroy(fd, spin->vm); + + free(spin); +} + void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, struct xe_cork *cork) { diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index 73f9a026..60f6e751 100644 --- a/lib/xe/xe_spin.h +++ b/lib/xe/xe_spin.h @@ -13,6 +13,7 @@ #include <stdbool.h> #include "xe_query.h" +#include "lib/igt_dummyload.h" /* Mapped GPU object */ struct xe_spin { @@ -21,11 +22,14 @@ struct xe_spin { uint32_t start; uint32_t end; }; - +void xe_spin_user_vm_engine(int fd, const struct igt_spin_factory *opt, struct igt_spin *spin); +igt_spin_t *xe_spin_create(int fd, const struct igt_spin_factory *opt); void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); 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); void xe_spin_end(struct xe_spin *spin); +void xe_spin_free(int fd, struct igt_spin *spin); struct xe_cork { struct xe_spin *spin; -- 2.39.1 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe 2023-06-04 19:58 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch @ 2023-06-05 8:58 ` Kumar, Janga Rahul 2023-06-05 11:19 ` Zbigniew Kempczyński 1 sibling, 0 replies; 36+ messages in thread From: Kumar, Janga Rahul @ 2023-06-05 8:58 UTC (permalink / raw) To: Ch, Sai Gowtham, igt-dev, Kempczynski, Zbigniew, kamil.konieczny > -----Original Message----- > From: Ch, Sai Gowtham <sai.gowtham.ch@intel.com> > Sent: 05 June 2023 01:28 > To: igt-dev@lists.freedesktop.org; Kempczynski, Zbigniew > <zbigniew.kempczynski@intel.com>; Ch, Sai Gowtham > <sai.gowtham.ch@intel.com>; Kumar, Janga Rahul > <janga.rahul.kumar@intel.com>; kamil.konieczny@linux.intel.com > Subject: [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe > > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > Extending the spin_create implementation and allocator handle support in xe, > where it submits dummy work loads to engine. This Implementation is wrapped > around vm_bind and unbind as we are supposed to do it manually for xe. > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > --- > lib/igt_dummyload.c | 24 ++++++--- > lib/igt_dummyload.h | 12 +++++ > lib/xe/xe_spin.c | 121 ++++++++++++++++++++++++++++++++++++++++++++ > lib/xe/xe_spin.h | 6 ++- > 4 files changed, 156 insertions(+), 7 deletions(-) > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index > 740a58f3..6e89b72d 100644 > --- a/lib/igt_dummyload.c > +++ b/lib/igt_dummyload.c > @@ -46,6 +46,7 @@ > #include "intel_reg.h" > #include "ioctl_wrappers.h" > #include "sw_sync.h" > +#include "xe/xe_spin.h" > > /** > * SECTION:igt_dummyload > @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory *opts) > igt_spin_t * __igt_spin_factory(int fd, const struct igt_spin_factory *opts) { > - return spin_create(fd, opts); > + if (is_xe_device(fd)) > + return xe_spin_create(fd, opts); > + else > + return spin_create(fd, opts); > } > > /** > @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct igt_spin_factory > *opts) { > igt_spin_t *spin; > > + if (is_xe_device(fd)) { > + spin = xe_spin_create(fd, opts); > + return spin; > + } > + > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != > ALL_ENGINES) { > unsigned int class; > > @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > if (!spin) > return; > > - pthread_mutex_lock(&list_lock); > - igt_list_del(&spin->link); > - pthread_mutex_unlock(&list_lock); > - > - __igt_spin_free(fd, spin); > + if (is_xe_device(fd)) { > + xe_spin_free(fd, spin); > + } else { > + pthread_mutex_lock(&list_lock); > + igt_list_del(&spin->link); > + pthread_mutex_unlock(&list_lock); > + __igt_spin_free(fd, spin); > + } > } > > void igt_terminate_spins(void) > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index > b247ab02..c5d7b993 100644 > --- a/lib/igt_dummyload.h > +++ b/lib/igt_dummyload.h > @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { > unsigned int flags; > int fence; > uint64_t ahnd; > + struct drm_xe_engine_class_instance *hwe; > + uint32_t vm; > } igt_spin_factory_t; > > typedef struct igt_spin { > @@ -83,6 +85,16 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 << 0) > > struct igt_spin_factory opts; > + > + struct xe_spin *xe_spin; > + size_t bo_size; > + uint64_t address; > + unsigned int engine; > + uint32_t vm; > + uint32_t syncobj; > + bool is_user_vm; > + bool is_user_engine; > + > } igt_spin_t; > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index 856d0ba2..c5a4479b > 100644 > --- a/lib/xe/xe_spin.c > +++ b/lib/xe/xe_spin.c > @@ -82,6 +82,127 @@ void xe_spin_end(struct xe_spin *spin) > spin->end = 0; > } > > +/** > + * xe_spin_user_vm_engine: > + * @spin: spin state from igt_spin_new() > + * @opt: controlling options such as allocator handle, engine, vm etc > + * > + * Wrapper function collects the vm and engine data from the user, > + * if engine is not given from the user, engine will be created. > + * > + */ > +void xe_spin_user_vm_engine(int fd, const struct igt_spin_factory *opt, > +struct igt_spin *spin) { > + spin->vm = opt->vm; > + spin->is_user_vm = true; > + if (opt->engine) { > + spin->engine = opt->engine; > + spin->is_user_engine = true; > + } else { > + if (opt->hwe) > + spin->engine = xe_engine_create(fd, spin->vm, opt- > >hwe, 0); > + else > + spin->engine = xe_engine_create_class(fd, spin->vm, > +DRM_XE_ENGINE_CLASS_COPY); > + > + spin->is_user_engine = false; > + } > +} > + > +/** > + * xe_spin_create: > + *@opt: controlling options such as allocator handle, engine, vmetc > + * > + * igt_spin_new for xe, xe_spin_create submits a batch using > +xe_spin_init > + * which wraps around vm bind and unbinding the object associated to it. > + * This returs a spinner after submitting a dummy load. > + * > + */ > +igt_spin_t * > +xe_spin_create(int fd, const struct igt_spin_factory *opt) { > + size_t bo_size = xe_get_default_alignment(fd); > + uint64_t ahnd = opt->ahnd, addr; > + struct igt_spin *spin; > + struct xe_spin *xe_spin; > + struct drm_xe_sync sync = { > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > + }; > + struct drm_xe_exec exec = { > + .num_batch_buffer = 1, > + .num_syncs = 1, > + .syncs = to_user_pointer(&sync), > + }; > + > + igt_assert(ahnd); > + spin = calloc(1, sizeof(struct igt_spin)); > + igt_assert(spin); > + > + spin->syncobj = syncobj_create(fd, 0); > + > + if (opt->vm) { > + xe_spin_user_vm_engine(fd, opt, spin); > + Remove above extra line > + } else { > + spin->vm = xe_vm_create(fd, 0, 0); > + if (opt->hwe) > + spin->engine = xe_engine_create(fd, spin->vm, opt- > >hwe, 0); > + else > + spin->engine = xe_engine_create_class(fd, spin->vm, > DRM_XE_ENGINE_CLASS_COPY); > + spin->is_user_vm = false; > + spin->is_user_engine = false; > + } > + > + spin->handle = xe_bo_create(fd, 0, spin->vm, bo_size); > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, > 0, ALLOC_STRATEGY_LOW_TO_HIGH); > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); > + > + xe_spin_init(xe_spin, addr, true); > + exec.engine_id = spin->engine; > + exec.address = addr; > + sync.handle = spin->syncobj; > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > + xe_spin_wait_started(xe_spin); > + > + spin->bo_size = bo_size; > + spin->address = addr; > + spin->xe_spin = xe_spin; > + > + return spin; > +} > + > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) { > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, NULL)); } > + > +/* > + * xe_spin_free: > + *@spin: spin state from igt_spin_new() > + * > + * Wrapper to free spinner whhich is triggered by xe_spin_create. > + * which distroys vm, engine and unbinds the vm which is binded to > + * the engine and bo. > + * > + */ > +void xe_spin_free(int fd, struct igt_spin *spin) { > + xe_spin_end(spin->xe_spin); > + xe_spin_sync_wait(fd, spin); > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); > + syncobj_destroy(fd, spin->syncobj); > + gem_munmap(spin->xe_spin, spin->bo_size); > + gem_close(fd, spin->handle); > + > + if (!spin->is_user_engine) > + xe_engine_destroy(fd, spin->engine); > + > + if (!spin->is_user_vm) > + xe_vm_destroy(fd, spin->vm); > + > + free(spin); > +} > + > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > struct xe_cork *cork) > { > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index 73f9a026..60f6e751 100644 > --- a/lib/xe/xe_spin.h > +++ b/lib/xe/xe_spin.h > @@ -13,6 +13,7 @@ > #include <stdbool.h> > > #include "xe_query.h" > +#include "lib/igt_dummyload.h" > > /* Mapped GPU object */ > struct xe_spin { > @@ -21,11 +22,14 @@ struct xe_spin { > uint32_t start; > uint32_t end; > }; > - > +void +(int fd, const struct igt_spin_factory *opt, > +struct igt_spin *spin); igt_spin_t *xe_spin_create(int fd, const struct > +igt_spin_factory *opt); > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); 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); void xe_spin_end(struct > xe_spin *spin); > +void xe_spin_free(int fd, struct igt_spin *spin); > > struct xe_cork { > struct xe_spin *spin; > -- > 2.39.1 LGTM Acked-by: Janga Rahul Kumar <janga.rahul.kumar@intel.com> ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe 2023-06-04 19:58 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 2023-06-05 8:58 ` Kumar, Janga Rahul @ 2023-06-05 11:19 ` Zbigniew Kempczyński 1 sibling, 0 replies; 36+ messages in thread From: Zbigniew Kempczyński @ 2023-06-05 11:19 UTC (permalink / raw) To: sai.gowtham.ch; +Cc: igt-dev On Mon, Jun 05, 2023 at 01:28:10AM +0530, sai.gowtham.ch@intel.com wrote: > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > Extending the spin_create implementation and allocator handle support in xe, > where it submits dummy work loads to engine. This Implementation is wrapped > around vm_bind and unbind as we are supposed to do it manually for xe. > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > --- > lib/igt_dummyload.c | 24 ++++++--- > lib/igt_dummyload.h | 12 +++++ > lib/xe/xe_spin.c | 121 ++++++++++++++++++++++++++++++++++++++++++++ > lib/xe/xe_spin.h | 6 ++- > 4 files changed, 156 insertions(+), 7 deletions(-) > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c > index 740a58f3..6e89b72d 100644 > --- a/lib/igt_dummyload.c > +++ b/lib/igt_dummyload.c > @@ -46,6 +46,7 @@ > #include "intel_reg.h" > #include "ioctl_wrappers.h" > #include "sw_sync.h" > +#include "xe/xe_spin.h" > > /** > * SECTION:igt_dummyload > @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory *opts) > igt_spin_t * > __igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > - return spin_create(fd, opts); > + if (is_xe_device(fd)) > + return xe_spin_create(fd, opts); Add spinner to spin_list to handle igt_terminate_spins() in igt_core.c. If test will fail you cannot leave dangling spinners. Add 'intel_driver' to the struct and store which driver executed the spinner, you'll need it in igt_spin_end(). > + else > + return spin_create(fd, opts); > } > > /** > @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > igt_spin_t *spin; > > + if (is_xe_device(fd)) { > + spin = xe_spin_create(fd, opts); > + return spin; > + } In this path too, you may create some wrapper if you want to avoid code duplication in __igt_spin_factory() and igt_spin_factory(). > + > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { > unsigned int class; > > @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > if (!spin) > return; > > - pthread_mutex_lock(&list_lock); > - igt_list_del(&spin->link); > - pthread_mutex_unlock(&list_lock); This can stay here, will handle both i915 and xe spinners. > - > - __igt_spin_free(fd, spin); > + if (is_xe_device(fd)) { > + xe_spin_free(fd, spin); > + } else { > + pthread_mutex_lock(&list_lock); > + igt_list_del(&spin->link); > + pthread_mutex_unlock(&list_lock); > + __igt_spin_free(fd, spin); > + } > } > > void igt_terminate_spins(void) > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h > index b247ab02..c5d7b993 100644 > --- a/lib/igt_dummyload.h > +++ b/lib/igt_dummyload.h > @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { > unsigned int flags; > int fence; > uint64_t ahnd; > + struct drm_xe_engine_class_instance *hwe; > + uint32_t vm; > } igt_spin_factory_t; > > typedef struct igt_spin { > @@ -83,6 +85,16 @@ typedef struct igt_spin { > #define SPIN_CLFLUSH (1 << 0) > > struct igt_spin_factory opts; > + > + struct xe_spin *xe_spin; > + size_t bo_size; > + uint64_t address; > + unsigned int engine; > + uint32_t vm; > + uint32_t syncobj; > + bool is_user_vm; > + bool is_user_engine; Those two vars are not necessary, reuse opts, see below. > + > } igt_spin_t; > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c > index 856d0ba2..c5a4479b 100644 > --- a/lib/xe/xe_spin.c > +++ b/lib/xe/xe_spin.c > @@ -82,6 +82,127 @@ void xe_spin_end(struct xe_spin *spin) > spin->end = 0; > } > > +/** > + * xe_spin_user_vm_engine: > + * @spin: spin state from igt_spin_new() > + * @opt: controlling options such as allocator handle, engine, vm etc > + * > + * Wrapper function collects the vm and engine data from the user, > + * if engine is not given from the user, engine will be created. > + * > + */ > +void xe_spin_user_vm_engine(int fd, const struct igt_spin_factory *opt, struct igt_spin *spin) > +{ > + spin->vm = opt->vm; > + spin->is_user_vm = true; > + if (opt->engine) { > + spin->engine = opt->engine; > + spin->is_user_engine = true; > + } else { > + if (opt->hwe) > + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); > + else > + spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_COPY); > + > + spin->is_user_engine = false; > + } > +} Too complicated, especially you don't need is_user_ variables, maybe: @@ -139,17 +113,17 @@ xe_spin_create(int fd, const struct igt_spin_factory *opt) spin->syncobj = syncobj_create(fd, 0); - if (opt->vm) { - xe_spin_user_vm_engine(fd, opt, spin); + spin->vm = opt->vm; + spin->engine = opt->engine; - } else { + if (!spin->vm) spin->vm = xe_vm_create(fd, 0, 0); + + if (!spin->engine) { if (opt->hwe) spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); else spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_COPY); - spin->is_user_vm = false; - spin->is_user_engine = false; } spin->handle = xe_bo_create(fd, 0, spin->vm, bo_size); @@ -167,6 +141,7 @@ xe_spin_create(int fd, const struct igt_spin_factory *opt) spin->bo_size = bo_size; spin->address = addr; spin->xe_spin = xe_spin; + spin->opts = *opt; return spin; } @@ -194,10 +169,10 @@ void xe_spin_free(int fd, struct igt_spin *spin) gem_munmap(spin->xe_spin, spin->bo_size); gem_close(fd, spin->handle); - if (!spin->is_user_engine) + if (!spin->opts.engine) xe_engine_destroy(fd, spin->engine); - if (!spin->is_user_vm) + if (!spin->opts.vm) xe_vm_destroy(fd, spin->vm); free(spin); -- Zbigniew > + > +/** > + * xe_spin_create: > + *@opt: controlling options such as allocator handle, engine, vmetc > + * > + * igt_spin_new for xe, xe_spin_create submits a batch using xe_spin_init > + * which wraps around vm bind and unbinding the object associated to it. > + * This returs a spinner after submitting a dummy load. > + * > + */ > +igt_spin_t * > +xe_spin_create(int fd, const struct igt_spin_factory *opt) > +{ > + size_t bo_size = xe_get_default_alignment(fd); > + uint64_t ahnd = opt->ahnd, addr; > + struct igt_spin *spin; > + struct xe_spin *xe_spin; > + struct drm_xe_sync sync = { > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > + }; > + struct drm_xe_exec exec = { > + .num_batch_buffer = 1, > + .num_syncs = 1, > + .syncs = to_user_pointer(&sync), > + }; > + > + igt_assert(ahnd); > + spin = calloc(1, sizeof(struct igt_spin)); > + igt_assert(spin); > + > + spin->syncobj = syncobj_create(fd, 0); > + > + if (opt->vm) { > + xe_spin_user_vm_engine(fd, opt, spin); > + > + } else { > + spin->vm = xe_vm_create(fd, 0, 0); > + if (opt->hwe) > + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); > + else > + spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_COPY); > + spin->is_user_vm = false; > + spin->is_user_engine = false; > + } > + > + spin->handle = xe_bo_create(fd, 0, spin->vm, bo_size); > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); > + > + xe_spin_init(xe_spin, addr, true); > + exec.engine_id = spin->engine; > + exec.address = addr; > + sync.handle = spin->syncobj; > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > + xe_spin_wait_started(xe_spin); > + > + spin->bo_size = bo_size; > + spin->address = addr; > + spin->xe_spin = xe_spin; > + > + return spin; > +} > + > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) > +{ > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, NULL)); > +} > + > +/* > + * xe_spin_free: > + *@spin: spin state from igt_spin_new() > + * > + * Wrapper to free spinner whhich is triggered by xe_spin_create. > + * which distroys vm, engine and unbinds the vm which is binded to > + * the engine and bo. > + * > + */ > +void xe_spin_free(int fd, struct igt_spin *spin) > +{ > + xe_spin_end(spin->xe_spin); > + xe_spin_sync_wait(fd, spin); > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); > + syncobj_destroy(fd, spin->syncobj); > + gem_munmap(spin->xe_spin, spin->bo_size); > + gem_close(fd, spin->handle); > + > + if (!spin->is_user_engine) > + xe_engine_destroy(fd, spin->engine); > + > + if (!spin->is_user_vm) > + xe_vm_destroy(fd, spin->vm); > + > + free(spin); > +} > + > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > struct xe_cork *cork) > { > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h > index 73f9a026..60f6e751 100644 > --- a/lib/xe/xe_spin.h > +++ b/lib/xe/xe_spin.h > @@ -13,6 +13,7 @@ > #include <stdbool.h> > > #include "xe_query.h" > +#include "lib/igt_dummyload.h" > > /* Mapped GPU object */ > struct xe_spin { > @@ -21,11 +22,14 @@ struct xe_spin { > uint32_t start; > uint32_t end; > }; > - > +void xe_spin_user_vm_engine(int fd, const struct igt_spin_factory *opt, struct igt_spin *spin); > +igt_spin_t *xe_spin_create(int fd, const struct igt_spin_factory *opt); > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); > 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); > void xe_spin_end(struct xe_spin *spin); > +void xe_spin_free(int fd, struct igt_spin *spin); > > struct xe_cork { > struct xe_spin *spin; > -- > 2.39.1 > ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 0/2] Integrate igt_spin_new with Xe @ 2023-06-04 19:16 sai.gowtham.ch 2023-06-04 19:16 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 0 siblings, 1 reply; 36+ messages in thread From: sai.gowtham.ch @ 2023-06-04 19:16 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch, janga.rahul.kumar, kamil.konieczny From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Sai Gowtham Ch (2): lib/xe/xe_spin: Integrate igt_spin_new with Xe tests/xe/xe_spin_batch: Add new test to exercise igt_spin_new for xe lib/igt_dummyload.c | 24 ++++-- lib/igt_dummyload.h | 12 +++ lib/xe/xe_spin.c | 121 ++++++++++++++++++++++++++++ lib/xe/xe_spin.h | 6 +- tests/meson.build | 1 + tests/xe/xe_spin_batch.c | 168 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 325 insertions(+), 7 deletions(-) create mode 100644 tests/xe/xe_spin_batch.c -- 2.39.1 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe 2023-06-04 19:16 [igt-dev] [PATCH i-g-t 0/2] " sai.gowtham.ch @ 2023-06-04 19:16 ` sai.gowtham.ch 2023-06-04 19:59 ` Ch, Sai Gowtham 0 siblings, 1 reply; 36+ messages in thread From: sai.gowtham.ch @ 2023-06-04 19:16 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch, janga.rahul.kumar, kamil.konieczny From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Cc: Janga Rahul Kumar <janga.rahul.kumar@intel.com> Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> --- lib/igt_dummyload.c | 24 ++++++--- lib/igt_dummyload.h | 12 +++++ lib/xe/xe_spin.c | 121 ++++++++++++++++++++++++++++++++++++++++++++ lib/xe/xe_spin.h | 6 ++- 4 files changed, 156 insertions(+), 7 deletions(-) diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index 740a58f3..6e89b72d 100644 --- a/lib/igt_dummyload.c +++ b/lib/igt_dummyload.c @@ -46,6 +46,7 @@ #include "intel_reg.h" #include "ioctl_wrappers.h" #include "sw_sync.h" +#include "xe/xe_spin.h" /** * SECTION:igt_dummyload @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory *opts) igt_spin_t * __igt_spin_factory(int fd, const struct igt_spin_factory *opts) { - return spin_create(fd, opts); + if (is_xe_device(fd)) + return xe_spin_create(fd, opts); + else + return spin_create(fd, opts); } /** @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) { igt_spin_t *spin; + if (is_xe_device(fd)) { + spin = xe_spin_create(fd, opts); + return spin; + } + if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { unsigned int class; @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) if (!spin) return; - pthread_mutex_lock(&list_lock); - igt_list_del(&spin->link); - pthread_mutex_unlock(&list_lock); - - __igt_spin_free(fd, spin); + if (is_xe_device(fd)) { + xe_spin_free(fd, spin); + } else { + pthread_mutex_lock(&list_lock); + igt_list_del(&spin->link); + pthread_mutex_unlock(&list_lock); + __igt_spin_free(fd, spin); + } } void igt_terminate_spins(void) diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index b247ab02..c5d7b993 100644 --- a/lib/igt_dummyload.h +++ b/lib/igt_dummyload.h @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { unsigned int flags; int fence; uint64_t ahnd; + struct drm_xe_engine_class_instance *hwe; + uint32_t vm; } igt_spin_factory_t; typedef struct igt_spin { @@ -83,6 +85,16 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 << 0) struct igt_spin_factory opts; + + struct xe_spin *xe_spin; + size_t bo_size; + uint64_t address; + unsigned int engine; + uint32_t vm; + uint32_t syncobj; + bool is_user_vm; + bool is_user_engine; + } igt_spin_t; diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index 856d0ba2..b1ff6fe9 100644 --- a/lib/xe/xe_spin.c +++ b/lib/xe/xe_spin.c @@ -82,6 +82,127 @@ void xe_spin_end(struct xe_spin *spin) spin->end = 0; } +/** + * xe_spin_user_vm_engine: + * @spin: spin state from igt_spin_new() + * @opt: controlling options such as allocator handle, engine, vm etc + * + * Wrapper function collects the vm and engine data from the user, + * if engine is not given from the user, engine will be created. + * + */ +void xe_spin_user_vm_engine(int fd, const struct igt_spin_factory *opt, struct igt_spin *spin) +{ + spin->vm = opt->vm; + spin->is_user_vm = true; + if (opt->engine) { + spin->engine = opt->engine; + spin->is_user_engine = true; + } else { + if (opt->hwe) + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); + else + spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_COPY); + + spin->is_user_engine = false; + } +} + +/** + * xe_spin_create: + *@opt: controlling options such as allocator handle, engine, vmetc + * + * igt_spin_new for xe, xe_spin_create submits a batch using xe_spin_init + * which wraps around vm bind and unbinding the object associated to it. + * This returs a spinner after submitting a dummy load. + * + */ +igt_spin_t * +xe_spin_create(int fd, const struct igt_spin_factory *opt) +{ + size_t bo_size = xe_get_default_alignment(fd); + uint64_t ahnd = opt->ahnd, addr; + struct igt_spin *spin; + struct xe_spin *xe_spin; + struct drm_xe_sync sync = { + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, + }; + struct drm_xe_exec exec = { + .num_batch_buffer = 1, + .num_syncs = 1, + .syncs = to_user_pointer(&sync), + }; + + igt_assert(ahnd); + spin = calloc(1, sizeof(struct igt_spin)); + igt_assert(spin); + + spin->syncobj = syncobj_create(fd, 0); + + if (opt->vm) { + xe_spin_user_vm_engine(fd, opt, spin); + + } else { + spin->vm = xe_vm_create(fd, 0, 0); + if (opt->hwe) + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); + else + spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_RENDER); + spin->is_user_vm = false; + spin->is_user_engine = false; + } + + spin->handle = xe_bo_create(fd, 0, spin->vm, bo_size); + xe_spin = xe_bo_map(fd, spin->handle, bo_size); + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); + + xe_spin_init(xe_spin, addr, true); + exec.engine_id = spin->engine; + exec.address = addr; + sync.handle = spin->syncobj; + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); + xe_spin_wait_started(xe_spin); + + spin->bo_size = bo_size; + spin->address = addr; + spin->xe_spin = xe_spin; + + return spin; +} + +void xe_spin_sync_wait(int fd, struct igt_spin *spin) +{ + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, NULL)); +} + +/* + * xe_spin_free: + *@spin: spin state from igt_spin_new() + * + * Wrapper to free spinner whhich is triggered by xe_spin_create. + * which distroys vm, engine and unbinds the vm which is binded to + * the engine and bo. + * + */ +void xe_spin_free(int fd, struct igt_spin *spin) +{ + xe_spin_end(spin->xe_spin); + xe_spin_sync_wait(fd, spin); + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); + syncobj_destroy(fd, spin->syncobj); + gem_munmap(spin->xe_spin, spin->bo_size); + gem_close(fd, spin->handle); + + if (!spin->is_user_vm) + xe_vm_destroy(fd, spin->vm); + + if (!spin->is_user_engine) + xe_engine_destroy(fd, spin->engine); + + free(spin); +} + void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, struct xe_cork *cork) { diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index 73f9a026..60f6e751 100644 --- a/lib/xe/xe_spin.h +++ b/lib/xe/xe_spin.h @@ -13,6 +13,7 @@ #include <stdbool.h> #include "xe_query.h" +#include "lib/igt_dummyload.h" /* Mapped GPU object */ struct xe_spin { @@ -21,11 +22,14 @@ struct xe_spin { uint32_t start; uint32_t end; }; - +void xe_spin_user_vm_engine(int fd, const struct igt_spin_factory *opt, struct igt_spin *spin); +igt_spin_t *xe_spin_create(int fd, const struct igt_spin_factory *opt); void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); 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); void xe_spin_end(struct xe_spin *spin); +void xe_spin_free(int fd, struct igt_spin *spin); struct xe_cork { struct xe_spin *spin; -- 2.39.1 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe 2023-06-04 19:16 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch @ 2023-06-04 19:59 ` Ch, Sai Gowtham 0 siblings, 0 replies; 36+ messages in thread From: Ch, Sai Gowtham @ 2023-06-04 19:59 UTC (permalink / raw) To: igt-dev, Kempczynski, Zbigniew, Kumar, Janga Rahul, kamil.konieczny Please ignore this patch it has few corrections, I've resent a patch with corrections. > -----Original Message----- > From: Ch, Sai Gowtham <sai.gowtham.ch@intel.com> > Sent: Monday, June 5, 2023 12:46 AM > To: igt-dev@lists.freedesktop.org; Kempczynski, Zbigniew > <zbigniew.kempczynski@intel.com>; Ch, Sai Gowtham > <sai.gowtham.ch@intel.com>; Kumar, Janga Rahul > <janga.rahul.kumar@intel.com>; kamil.konieczny@linux.intel.com > Subject: [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe > > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > Extending the spin_create implementation and allocator handle support in xe, > where it submits dummy work loads to engine. This Implementation is wrapped > around vm_bind and unbind as we are supposed to do it manually for xe. > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > Cc: Janga Rahul Kumar <janga.rahul.kumar@intel.com> > Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com> > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > --- > lib/igt_dummyload.c | 24 ++++++--- > lib/igt_dummyload.h | 12 +++++ > lib/xe/xe_spin.c | 121 ++++++++++++++++++++++++++++++++++++++++++++ > lib/xe/xe_spin.h | 6 ++- > 4 files changed, 156 insertions(+), 7 deletions(-) > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index > 740a58f3..6e89b72d 100644 > --- a/lib/igt_dummyload.c > +++ b/lib/igt_dummyload.c > @@ -46,6 +46,7 @@ > #include "intel_reg.h" > #include "ioctl_wrappers.h" > #include "sw_sync.h" > +#include "xe/xe_spin.h" > > /** > * SECTION:igt_dummyload > @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory *opts) > igt_spin_t * __igt_spin_factory(int fd, const struct igt_spin_factory *opts) { > - return spin_create(fd, opts); > + if (is_xe_device(fd)) > + return xe_spin_create(fd, opts); > + else > + return spin_create(fd, opts); > } > > /** > @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct igt_spin_factory > *opts) { > igt_spin_t *spin; > > + if (is_xe_device(fd)) { > + spin = xe_spin_create(fd, opts); > + return spin; > + } > + > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != > ALL_ENGINES) { > unsigned int class; > > @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > if (!spin) > return; > > - pthread_mutex_lock(&list_lock); > - igt_list_del(&spin->link); > - pthread_mutex_unlock(&list_lock); > - > - __igt_spin_free(fd, spin); > + if (is_xe_device(fd)) { > + xe_spin_free(fd, spin); > + } else { > + pthread_mutex_lock(&list_lock); > + igt_list_del(&spin->link); > + pthread_mutex_unlock(&list_lock); > + __igt_spin_free(fd, spin); > + } > } > > void igt_terminate_spins(void) > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index > b247ab02..c5d7b993 100644 > --- a/lib/igt_dummyload.h > +++ b/lib/igt_dummyload.h > @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { > unsigned int flags; > int fence; > uint64_t ahnd; > + struct drm_xe_engine_class_instance *hwe; > + uint32_t vm; > } igt_spin_factory_t; > > typedef struct igt_spin { > @@ -83,6 +85,16 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 << 0) > > struct igt_spin_factory opts; > + > + struct xe_spin *xe_spin; > + size_t bo_size; > + uint64_t address; > + unsigned int engine; > + uint32_t vm; > + uint32_t syncobj; > + bool is_user_vm; > + bool is_user_engine; > + > } igt_spin_t; > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index 856d0ba2..b1ff6fe9 100644 > --- a/lib/xe/xe_spin.c > +++ b/lib/xe/xe_spin.c > @@ -82,6 +82,127 @@ void xe_spin_end(struct xe_spin *spin) > spin->end = 0; > } > > +/** > + * xe_spin_user_vm_engine: > + * @spin: spin state from igt_spin_new() > + * @opt: controlling options such as allocator handle, engine, vm etc > + * > + * Wrapper function collects the vm and engine data from the user, > + * if engine is not given from the user, engine will be created. > + * > + */ > +void xe_spin_user_vm_engine(int fd, const struct igt_spin_factory *opt, > +struct igt_spin *spin) { > + spin->vm = opt->vm; > + spin->is_user_vm = true; > + if (opt->engine) { > + spin->engine = opt->engine; > + spin->is_user_engine = true; > + } else { > + if (opt->hwe) > + spin->engine = xe_engine_create(fd, spin->vm, opt- > >hwe, 0); > + else > + spin->engine = xe_engine_create_class(fd, spin->vm, > +DRM_XE_ENGINE_CLASS_COPY); > + > + spin->is_user_engine = false; > + } > +} > + > +/** > + * xe_spin_create: > + *@opt: controlling options such as allocator handle, engine, vmetc > + * > + * igt_spin_new for xe, xe_spin_create submits a batch using > +xe_spin_init > + * which wraps around vm bind and unbinding the object associated to it. > + * This returs a spinner after submitting a dummy load. > + * > + */ > +igt_spin_t * > +xe_spin_create(int fd, const struct igt_spin_factory *opt) { > + size_t bo_size = xe_get_default_alignment(fd); > + uint64_t ahnd = opt->ahnd, addr; > + struct igt_spin *spin; > + struct xe_spin *xe_spin; > + struct drm_xe_sync sync = { > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > + }; > + struct drm_xe_exec exec = { > + .num_batch_buffer = 1, > + .num_syncs = 1, > + .syncs = to_user_pointer(&sync), > + }; > + > + igt_assert(ahnd); > + spin = calloc(1, sizeof(struct igt_spin)); > + igt_assert(spin); > + > + spin->syncobj = syncobj_create(fd, 0); > + > + if (opt->vm) { > + xe_spin_user_vm_engine(fd, opt, spin); > + > + } else { > + spin->vm = xe_vm_create(fd, 0, 0); > + if (opt->hwe) > + spin->engine = xe_engine_create(fd, spin->vm, opt- > >hwe, 0); > + else > + spin->engine = xe_engine_create_class(fd, spin->vm, > DRM_XE_ENGINE_CLASS_RENDER); > + spin->is_user_vm = false; > + spin->is_user_engine = false; > + } > + > + spin->handle = xe_bo_create(fd, 0, spin->vm, bo_size); > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, > 0, ALLOC_STRATEGY_LOW_TO_HIGH); > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); > + > + xe_spin_init(xe_spin, addr, true); > + exec.engine_id = spin->engine; > + exec.address = addr; > + sync.handle = spin->syncobj; > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > + xe_spin_wait_started(xe_spin); > + > + spin->bo_size = bo_size; > + spin->address = addr; > + spin->xe_spin = xe_spin; > + > + return spin; > +} > + > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) { > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, NULL)); } > + > +/* > + * xe_spin_free: > + *@spin: spin state from igt_spin_new() > + * > + * Wrapper to free spinner whhich is triggered by xe_spin_create. > + * which distroys vm, engine and unbinds the vm which is binded to > + * the engine and bo. > + * > + */ > +void xe_spin_free(int fd, struct igt_spin *spin) { > + xe_spin_end(spin->xe_spin); > + xe_spin_sync_wait(fd, spin); > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); > + syncobj_destroy(fd, spin->syncobj); > + gem_munmap(spin->xe_spin, spin->bo_size); > + gem_close(fd, spin->handle); > + > + if (!spin->is_user_vm) > + xe_vm_destroy(fd, spin->vm); > + > + if (!spin->is_user_engine) > + xe_engine_destroy(fd, spin->engine); > + > + free(spin); > +} > + > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > struct xe_cork *cork) > { > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index 73f9a026..60f6e751 100644 > --- a/lib/xe/xe_spin.h > +++ b/lib/xe/xe_spin.h > @@ -13,6 +13,7 @@ > #include <stdbool.h> > > #include "xe_query.h" > +#include "lib/igt_dummyload.h" > > /* Mapped GPU object */ > struct xe_spin { > @@ -21,11 +22,14 @@ struct xe_spin { > uint32_t start; > uint32_t end; > }; > - > +void xe_spin_user_vm_engine(int fd, const struct igt_spin_factory *opt, > +struct igt_spin *spin); igt_spin_t *xe_spin_create(int fd, const struct > +igt_spin_factory *opt); > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); 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); void xe_spin_end(struct > xe_spin *spin); > +void xe_spin_free(int fd, struct igt_spin *spin); > > struct xe_cork { > struct xe_spin *spin; > -- > 2.39.1 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 0/2] Integrate igt_spin_new with Xe. @ 2023-05-30 10:08 sai.gowtham.ch 2023-05-30 10:08 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 0 siblings, 1 reply; 36+ messages in thread From: sai.gowtham.ch @ 2023-05-30 10:08 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Sai Gowtham Ch (2): lib/xe/xe_spin: Integrate igt_spin_new with Xe. tests/xe/xe_spin_batch: Add new test to exercise igt_spin_new for xe. lib/igt_dummyload.c | 24 ++++-- lib/igt_dummyload.h | 10 +++ lib/xe/xe_spin.c | 91 +++++++++++++++++++++ lib/xe/xe_spin.h | 7 ++ tests/meson.build | 1 + tests/xe/xe_spin_batch.c | 168 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 295 insertions(+), 6 deletions(-) create mode 100644 tests/xe/xe_spin_batch.c -- 2.39.1 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. 2023-05-30 10:08 [igt-dev] [PATCH i-g-t 0/2] " sai.gowtham.ch @ 2023-05-30 10:08 ` sai.gowtham.ch 2023-05-30 19:39 ` Zbigniew Kempczyński 2023-06-01 5:11 ` Kamil Konieczny 0 siblings, 2 replies; 36+ messages in thread From: sai.gowtham.ch @ 2023-05-30 10:08 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> --- lib/igt_dummyload.c | 24 +++++++++--- lib/igt_dummyload.h | 10 +++++ lib/xe/xe_spin.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ lib/xe/xe_spin.h | 7 ++++ 4 files changed, 126 insertions(+), 6 deletions(-) diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index 740a58f3..6e89b72d 100644 --- a/lib/igt_dummyload.c +++ b/lib/igt_dummyload.c @@ -46,6 +46,7 @@ #include "intel_reg.h" #include "ioctl_wrappers.h" #include "sw_sync.h" +#include "xe/xe_spin.h" /** * SECTION:igt_dummyload @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory *opts) igt_spin_t * __igt_spin_factory(int fd, const struct igt_spin_factory *opts) { - return spin_create(fd, opts); + if (is_xe_device(fd)) + return xe_spin_create(fd, opts); + else + return spin_create(fd, opts); } /** @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) { igt_spin_t *spin; + if (is_xe_device(fd)) { + spin = xe_spin_create(fd, opts); + return spin; + } + if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { unsigned int class; @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) if (!spin) return; - pthread_mutex_lock(&list_lock); - igt_list_del(&spin->link); - pthread_mutex_unlock(&list_lock); - - __igt_spin_free(fd, spin); + if (is_xe_device(fd)) { + xe_spin_free(fd, spin); + } else { + pthread_mutex_lock(&list_lock); + igt_list_del(&spin->link); + pthread_mutex_unlock(&list_lock); + __igt_spin_free(fd, spin); + } } void igt_terminate_spins(void) diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index b247ab02..7bcc7b56 100644 --- a/lib/igt_dummyload.h +++ b/lib/igt_dummyload.h @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { unsigned int flags; int fence; uint64_t ahnd; + struct drm_xe_engine_class_instance *hwe; + uint32_t vm; } igt_spin_factory_t; typedef struct igt_spin { @@ -83,6 +85,14 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 << 0) struct igt_spin_factory opts; + + struct xe_spin *xe_spin; + size_t bo_size; + uint64_t address; + unsigned int engine; + uint32_t vm; + uint32_t syncobj; + } igt_spin_t; diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index 856d0ba2..bc0fbcc6 100644 --- a/lib/xe/xe_spin.c +++ b/lib/xe/xe_spin.c @@ -15,6 +15,7 @@ #include "intel_reg.h" #include "xe_ioctl.h" #include "xe_spin.h" +#include "lib/igt_dummyload.h" /** * xe_spin_init: @@ -82,6 +83,96 @@ void xe_spin_end(struct xe_spin *spin) spin->end = 0; } +igt_spin_t * +xe_spin_create(int fd, const struct igt_spin_factory *opt) +{ + size_t bo_size = xe_get_default_alignment(fd); + uint32_t bo; + uint64_t ahnd = opt->ahnd, addr; + struct igt_spin *spin; + struct xe_spin *xe_spin; + struct drm_xe_sync sync = { + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, + }; + struct drm_xe_exec exec = { + .num_batch_buffer = 1, + .num_syncs = 1, + .syncs = to_user_pointer(&sync), + }; + + igt_assert(ahnd); + spin = calloc(1, sizeof(struct igt_spin)); + igt_assert(spin); + + spin->syncobj = syncobj_create(fd, 0); + if (opt->engine) { + spin->opts.engine = opt->engine; + spin->opts.vm = opt->vm; + + spin->handle = xe_bo_create(fd, 0, spin->opts.vm, bo_size); + xe_spin = xe_bo_map(fd, spin->handle, bo_size); + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); + xe_vm_bind_sync(fd, spin->opts.vm, spin->handle, 0, addr, bo_size); + + xe_spin_init(xe_spin, addr, true); + exec.engine_id = spin->opts.engine; + exec.address = addr; + } else { + spin->vm = xe_vm_create(fd, 0, 0); + if (!opt->hwe) + spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_RENDER); + else + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); + + bo = xe_bo_create(fd, 0, spin->vm, bo_size); + spin->handle = bo; + xe_spin = xe_bo_map(fd, spin->handle, bo_size); + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); + + xe_spin_init(xe_spin, addr, true); + exec.engine_id = spin->engine; + exec.address = addr; + } + sync.handle = spin->syncobj; + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); + xe_spin_wait_started(xe_spin); + igt_info("Spinner started\n"); + + spin->bo_size = bo_size; + spin->address = addr; + spin->xe_spin = xe_spin; + + return spin; +} + +void xe_spin_sync_wait(int fd, struct igt_spin *spin) +{ + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, + NULL)); +} + +void xe_spin_free(int fd, struct igt_spin *spin) +{ + xe_spin_end(spin->xe_spin); + xe_spin_sync_wait(fd, spin); + + if (!spin->opts.vm) + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); + else + xe_vm_unbind_sync(fd, spin->opts.vm, 0, spin->address, spin->bo_size); + + syncobj_destroy(fd, spin->syncobj); + gem_munmap(spin->xe_spin, spin->bo_size); + gem_close(fd, spin->handle); + + if (!spin->opts.engine) { + xe_engine_destroy(fd, spin->engine); + xe_vm_destroy(fd, spin->vm); + } + free(spin); +} + void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, struct xe_cork *cork) { diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index 73f9a026..48867eb8 100644 --- a/lib/xe/xe_spin.h +++ b/lib/xe/xe_spin.h @@ -13,19 +13,26 @@ #include <stdbool.h> #include "xe_query.h" +#include "lib/igt_dummyload.h" /* Mapped GPU object */ + struct xe_spin { uint32_t batch[16]; uint64_t pad; uint32_t start; uint32_t end; + }; +igt_spin_t * +xe_spin_create(int fd, const struct igt_spin_factory *opt); void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); 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); void xe_spin_end(struct xe_spin *spin); +void xe_spin_free(int fd, struct igt_spin *spin); struct xe_cork { struct xe_spin *spin; -- 2.39.1 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. 2023-05-30 10:08 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch @ 2023-05-30 19:39 ` Zbigniew Kempczyński 2023-06-01 5:11 ` Kamil Konieczny 1 sibling, 0 replies; 36+ messages in thread From: Zbigniew Kempczyński @ 2023-05-30 19:39 UTC (permalink / raw) To: sai.gowtham.ch; +Cc: igt-dev On Tue, May 30, 2023 at 03:38:04PM +0530, sai.gowtham.ch@intel.com wrote: > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > Extending the spin_create implementation and allocator handle support in xe, > where it submits dummy work loads to engine. This Implementation is wrapped > around vm_bind and unbind as we are supposed to do it manually for xe. > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > --- > lib/igt_dummyload.c | 24 +++++++++--- > lib/igt_dummyload.h | 10 +++++ > lib/xe/xe_spin.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ > lib/xe/xe_spin.h | 7 ++++ > 4 files changed, 126 insertions(+), 6 deletions(-) > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c > index 740a58f3..6e89b72d 100644 > --- a/lib/igt_dummyload.c > +++ b/lib/igt_dummyload.c > @@ -46,6 +46,7 @@ > #include "intel_reg.h" > #include "ioctl_wrappers.h" > #include "sw_sync.h" > +#include "xe/xe_spin.h" > > /** > * SECTION:igt_dummyload > @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory *opts) > igt_spin_t * > __igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > - return spin_create(fd, opts); > + if (is_xe_device(fd)) > + return xe_spin_create(fd, opts); > + else > + return spin_create(fd, opts); > } > > /** > @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > igt_spin_t *spin; > > + if (is_xe_device(fd)) { > + spin = xe_spin_create(fd, opts); > + return spin; > + } > + > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { > unsigned int class; > > @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > if (!spin) > return; > > - pthread_mutex_lock(&list_lock); > - igt_list_del(&spin->link); > - pthread_mutex_unlock(&list_lock); > - > - __igt_spin_free(fd, spin); > + if (is_xe_device(fd)) { > + xe_spin_free(fd, spin); > + } else { > + pthread_mutex_lock(&list_lock); > + igt_list_del(&spin->link); > + pthread_mutex_unlock(&list_lock); > + __igt_spin_free(fd, spin); > + } At the moment I'm not sure but I think for failed subtests we may have spinners running and not cleared from igt_terminate_spinners(). I think you may add xe spinner to the list and handle this case. > } > > void igt_terminate_spins(void) > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h > index b247ab02..7bcc7b56 100644 > --- a/lib/igt_dummyload.h > +++ b/lib/igt_dummyload.h > @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { > unsigned int flags; > int fence; > uint64_t ahnd; > + struct drm_xe_engine_class_instance *hwe; > + uint32_t vm; > } igt_spin_factory_t; > > typedef struct igt_spin { > @@ -83,6 +85,14 @@ typedef struct igt_spin { > #define SPIN_CLFLUSH (1 << 0) > > struct igt_spin_factory opts; > + > + struct xe_spin *xe_spin; > + size_t bo_size; > + uint64_t address; > + unsigned int engine; > + uint32_t vm; > + uint32_t syncobj; > + > } igt_spin_t; > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c > index 856d0ba2..bc0fbcc6 100644 > --- a/lib/xe/xe_spin.c > +++ b/lib/xe/xe_spin.c > @@ -15,6 +15,7 @@ > #include "intel_reg.h" > #include "xe_ioctl.h" > #include "xe_spin.h" > +#include "lib/igt_dummyload.h" > > /** > * xe_spin_init: > @@ -82,6 +83,96 @@ void xe_spin_end(struct xe_spin *spin) > spin->end = 0; > } > > +igt_spin_t * > +xe_spin_create(int fd, const struct igt_spin_factory *opt) > +{ > + size_t bo_size = xe_get_default_alignment(fd); > + uint32_t bo; > + uint64_t ahnd = opt->ahnd, addr; > + struct igt_spin *spin; > + struct xe_spin *xe_spin; > + struct drm_xe_sync sync = { > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > + }; > + struct drm_xe_exec exec = { > + .num_batch_buffer = 1, > + .num_syncs = 1, > + .syncs = to_user_pointer(&sync), > + }; > + > + igt_assert(ahnd); > + spin = calloc(1, sizeof(struct igt_spin)); > + igt_assert(spin); > + > + spin->syncobj = syncobj_create(fd, 0); > + if (opt->engine) { > + spin->opts.engine = opt->engine; > + spin->opts.vm = opt->vm; You may copy opt -> spin->opts (see how emit_recursive_batch() is doing this). If user passed engine ensure vm is also not zeroed. > + > + spin->handle = xe_bo_create(fd, 0, spin->opts.vm, bo_size); > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > + xe_vm_bind_sync(fd, spin->opts.vm, spin->handle, 0, addr, bo_size); > + > + xe_spin_init(xe_spin, addr, true); > + exec.engine_id = spin->opts.engine; > + exec.address = addr; > + } else { > + spin->vm = xe_vm_create(fd, 0, 0); > + if (!opt->hwe) > + spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_RENDER); On PVC there's no RENDER engine. > + else > + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); opt->engine == 0 and opt->hwe == NULL -> SIGSEGV. > + > + bo = xe_bo_create(fd, 0, spin->vm, bo_size); > + spin->handle = bo; > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); > + > + xe_spin_init(xe_spin, addr, true); > + exec.engine_id = spin->engine; > + exec.address = addr; A lot of code is duplicated in if/else. Avoid this duplication. > + } > + sync.handle = spin->syncobj; > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > + xe_spin_wait_started(xe_spin); > + igt_info("Spinner started\n"); Unnecessary noise. > + > + spin->bo_size = bo_size; > + spin->address = addr; > + spin->xe_spin = xe_spin; > + > + return spin; > +} > + > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) > +{ > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, > + NULL)); > +} > + > +void xe_spin_free(int fd, struct igt_spin *spin) > +{ > + xe_spin_end(spin->xe_spin); > + xe_spin_sync_wait(fd, spin); > + > + if (!spin->opts.vm) > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); > + else > + xe_vm_unbind_sync(fd, spin->opts.vm, 0, spin->address, spin->bo_size); Hint: Assing spin->vm = spin->opts.vm always. If it will be 0 just create it then use hwe to create on top of it. And as you still have spin->opts available (I assume you'll copy it on spinner creation) you can use it when vm should be destroyed in spinner code. And above if/else may be totally dropped to single xe_vm_unbind_sync() line. + @Bhanu Take a look to kms usecases Bhanu mentioned, I assume there're: kms_busy.c: t = igt_spin_new(dpy->drm_fd, .ahnd = ahnd, .fence = fence, .dependency = fb->gem_handle, .flags = IGT_SPIN_FENCE_IN); igt_spin_t *t = igt_spin_new(dpy->drm_fd, .ahnd = ahnd, .dependency = busy_fb->gem_handle, .flags = IGT_SPIN_NO_PREEMPTION); or in kms_cursor_legacy.c: spin = igt_spin_new(display->drm_fd, .ahnd = ahnd, .dependency = fb_info[1].gem_handle, .dependency_size = fb_info[1].size); I'm not sure about prime_busy.c. I think above usecases should be handled by xe spinner. Bhanu - may you confirm my concerns? -- Zbigniew > + > + syncobj_destroy(fd, spin->syncobj); > + gem_munmap(spin->xe_spin, spin->bo_size); > + gem_close(fd, spin->handle); > + > + if (!spin->opts.engine) { > + xe_engine_destroy(fd, spin->engine); > + xe_vm_destroy(fd, spin->vm); > + } > + free(spin); > +} > + > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > struct xe_cork *cork) > { > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h > index 73f9a026..48867eb8 100644 > --- a/lib/xe/xe_spin.h > +++ b/lib/xe/xe_spin.h > @@ -13,19 +13,26 @@ > #include <stdbool.h> > > #include "xe_query.h" > +#include "lib/igt_dummyload.h" > > /* Mapped GPU object */ > + > struct xe_spin { > uint32_t batch[16]; > uint64_t pad; > uint32_t start; > uint32_t end; > + > }; > > +igt_spin_t * > +xe_spin_create(int fd, const struct igt_spin_factory *opt); > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); > 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); > void xe_spin_end(struct xe_spin *spin); > +void xe_spin_free(int fd, struct igt_spin *spin); > > struct xe_cork { > struct xe_spin *spin; > -- > 2.39.1 > ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. 2023-05-30 10:08 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 2023-05-30 19:39 ` Zbigniew Kempczyński @ 2023-06-01 5:11 ` Kamil Konieczny 2023-06-01 7:59 ` Kumar, Janga Rahul 1 sibling, 1 reply; 36+ messages in thread From: Kamil Konieczny @ 2023-06-01 5:11 UTC (permalink / raw) To: igt-dev; +Cc: sai.gowtham.ch Hi Sai, On 2023-05-30 at 15:38:04 +0530, sai.gowtham.ch@intel.com wrote: > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > please remove dot from end of Subject line: [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. --------------------------------------------------------------- ^ so it will be: [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe The same follows for your second patch. I have few more nits, see below. > Extending the spin_create implementation and allocator handle support in xe, > where it submits dummy work loads to engine. This Implementation is wrapped > around vm_bind and unbind as we are supposed to do it manually for xe. > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > --- > lib/igt_dummyload.c | 24 +++++++++--- > lib/igt_dummyload.h | 10 +++++ > lib/xe/xe_spin.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ > lib/xe/xe_spin.h | 7 ++++ > 4 files changed, 126 insertions(+), 6 deletions(-) > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c > index 740a58f3..6e89b72d 100644 > --- a/lib/igt_dummyload.c > +++ b/lib/igt_dummyload.c > @@ -46,6 +46,7 @@ > #include "intel_reg.h" > #include "ioctl_wrappers.h" > #include "sw_sync.h" > +#include "xe/xe_spin.h" > > /** > * SECTION:igt_dummyload > @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory *opts) > igt_spin_t * > __igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > - return spin_create(fd, opts); > + if (is_xe_device(fd)) > + return xe_spin_create(fd, opts); > + else > + return spin_create(fd, opts); > } > > /** > @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > igt_spin_t *spin; > > + if (is_xe_device(fd)) { > + spin = xe_spin_create(fd, opts); > + return spin; > + } > + > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { > unsigned int class; > > @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > if (!spin) > return; > > - pthread_mutex_lock(&list_lock); > - igt_list_del(&spin->link); > - pthread_mutex_unlock(&list_lock); > - > - __igt_spin_free(fd, spin); > + if (is_xe_device(fd)) { > + xe_spin_free(fd, spin); > + } else { > + pthread_mutex_lock(&list_lock); > + igt_list_del(&spin->link); > + pthread_mutex_unlock(&list_lock); > + __igt_spin_free(fd, spin); > + } > } > > void igt_terminate_spins(void) > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h > index b247ab02..7bcc7b56 100644 > --- a/lib/igt_dummyload.h > +++ b/lib/igt_dummyload.h > @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { > unsigned int flags; > int fence; > uint64_t ahnd; > + struct drm_xe_engine_class_instance *hwe; > + uint32_t vm; > } igt_spin_factory_t; > > typedef struct igt_spin { > @@ -83,6 +85,14 @@ typedef struct igt_spin { > #define SPIN_CLFLUSH (1 << 0) > > struct igt_spin_factory opts; > + > + struct xe_spin *xe_spin; > + size_t bo_size; > + uint64_t address; > + unsigned int engine; > + uint32_t vm; > + uint32_t syncobj; > + > } igt_spin_t; > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c > index 856d0ba2..bc0fbcc6 100644 > --- a/lib/xe/xe_spin.c > +++ b/lib/xe/xe_spin.c > @@ -15,6 +15,7 @@ > #include "intel_reg.h" > #include "xe_ioctl.h" > #include "xe_spin.h" > +#include "lib/igt_dummyload.h" ------------ ^ Do we need "lib/" here ? Please also put this in alphabetical order. > > /** > * xe_spin_init: > @@ -82,6 +83,96 @@ void xe_spin_end(struct xe_spin *spin) > spin->end = 0; > } > Please describe each new public function you added. > +igt_spin_t * > +xe_spin_create(int fd, const struct igt_spin_factory *opt) > +{ > + size_t bo_size = xe_get_default_alignment(fd); > + uint32_t bo; > + uint64_t ahnd = opt->ahnd, addr; > + struct igt_spin *spin; > + struct xe_spin *xe_spin; > + struct drm_xe_sync sync = { > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > + }; > + struct drm_xe_exec exec = { > + .num_batch_buffer = 1, > + .num_syncs = 1, > + .syncs = to_user_pointer(&sync), > + }; > + > + igt_assert(ahnd); > + spin = calloc(1, sizeof(struct igt_spin)); > + igt_assert(spin); > + > + spin->syncobj = syncobj_create(fd, 0); > + if (opt->engine) { > + spin->opts.engine = opt->engine; > + spin->opts.vm = opt->vm; > + > + spin->handle = xe_bo_create(fd, 0, spin->opts.vm, bo_size); > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > + xe_vm_bind_sync(fd, spin->opts.vm, spin->handle, 0, addr, bo_size); > + > + xe_spin_init(xe_spin, addr, true); > + exec.engine_id = spin->opts.engine; > + exec.address = addr; > + } else { > + spin->vm = xe_vm_create(fd, 0, 0); > + if (!opt->hwe) > + spin->engine = xe_engine_create_class(fd, spin->vm, DRM_XE_ENGINE_CLASS_RENDER); > + else > + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); > + > + bo = xe_bo_create(fd, 0, spin->vm, bo_size); > + spin->handle = bo; > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); > + > + xe_spin_init(xe_spin, addr, true); > + exec.engine_id = spin->engine; > + exec.address = addr; > + } Put newline here. > + sync.handle = spin->syncobj; > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > + xe_spin_wait_started(xe_spin); > + igt_info("Spinner started\n"); > + > + spin->bo_size = bo_size; > + spin->address = addr; > + spin->xe_spin = xe_spin; > + > + return spin; > +} > + Write description. > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) > +{ > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, > + NULL)); imho you can have it in one line: igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, NULL)); > +} > + Write description. > +void xe_spin_free(int fd, struct igt_spin *spin) > +{ > + xe_spin_end(spin->xe_spin); > + xe_spin_sync_wait(fd, spin); > + > + if (!spin->opts.vm) > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); > + else > + xe_vm_unbind_sync(fd, spin->opts.vm, 0, spin->address, spin->bo_size); > + > + syncobj_destroy(fd, spin->syncobj); > + gem_munmap(spin->xe_spin, spin->bo_size); > + gem_close(fd, spin->handle); > + > + if (!spin->opts.engine) { > + xe_engine_destroy(fd, spin->engine); > + xe_vm_destroy(fd, spin->vm); > + } Put newline here. > + free(spin); > +} > + > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > struct xe_cork *cork) > { > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h > index 73f9a026..48867eb8 100644 > --- a/lib/xe/xe_spin.h > +++ b/lib/xe/xe_spin.h > @@ -13,19 +13,26 @@ > #include <stdbool.h> > > #include "xe_query.h" > +#include "lib/igt_dummyload.h" > > /* Mapped GPU object */ > + Please do not make cleanups when adding new functionality, remove this newline. > struct xe_spin { > uint32_t batch[16]; > uint64_t pad; > uint32_t start; > uint32_t end; > + Same here, remove this line. > }; > > +igt_spin_t * -- ^ > +xe_spin_create(int fd, const struct igt_spin_factory *opt); -- ^ imho here one-liner is better: igt_spin_t *xe_spin_create(int fd, const struct igt_spin_factory *opt); Regards, Kamil > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); > 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); > void xe_spin_end(struct xe_spin *spin); > +void xe_spin_free(int fd, struct igt_spin *spin); > > struct xe_cork { > struct xe_spin *spin; > -- > 2.39.1 > ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. 2023-06-01 5:11 ` Kamil Konieczny @ 2023-06-01 7:59 ` Kumar, Janga Rahul 2023-06-01 8:11 ` Ch, Sai Gowtham 2023-06-02 8:24 ` Zbigniew Kempczyński 0 siblings, 2 replies; 36+ messages in thread From: Kumar, Janga Rahul @ 2023-06-01 7:59 UTC (permalink / raw) To: igt-dev, Ch, Sai Gowtham > -----Original Message----- > From: igt-dev <igt-dev-bounces@lists.freedesktop.org> On Behalf Of Kamil > Konieczny > Sent: 01 June 2023 10:42 > To: igt-dev@lists.freedesktop.org > Cc: Ch, Sai Gowtham <sai.gowtham.ch@intel.com> > Subject: Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate > igt_spin_new with Xe. > > Hi Sai, > > On 2023-05-30 at 15:38:04 +0530, sai.gowtham.ch@intel.com wrote: > > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > > > please remove dot from end of Subject line: > > [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. > --------------------------------------------------------------- ^ > > so it will be: > > [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe > > The same follows for your second patch. I have few more nits, see below. > > > Extending the spin_create implementation and allocator handle support > > in xe, where it submits dummy work loads to engine. This > > Implementation is wrapped around vm_bind and unbind as we are > supposed to do it manually for xe. > > > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > --- > > lib/igt_dummyload.c | 24 +++++++++--- lib/igt_dummyload.h | 10 +++++ > > lib/xe/xe_spin.c | 91 > +++++++++++++++++++++++++++++++++++++++++++++ > > lib/xe/xe_spin.h | 7 ++++ > > 4 files changed, 126 insertions(+), 6 deletions(-) > > > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index > > 740a58f3..6e89b72d 100644 > > --- a/lib/igt_dummyload.c > > +++ b/lib/igt_dummyload.c > > @@ -46,6 +46,7 @@ > > #include "intel_reg.h" > > #include "ioctl_wrappers.h" > > #include "sw_sync.h" > > +#include "xe/xe_spin.h" > > > > /** > > * SECTION:igt_dummyload > > @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory > > *opts) igt_spin_t * __igt_spin_factory(int fd, const struct > > igt_spin_factory *opts) { > > - return spin_create(fd, opts); > > + if (is_xe_device(fd)) > > + return xe_spin_create(fd, opts); > > + else > > + return spin_create(fd, opts); > > } > > > > /** > > @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct > > igt_spin_factory *opts) { > > igt_spin_t *spin; > > > > + if (is_xe_device(fd)) { > > + spin = xe_spin_create(fd, opts); > > + return spin; > > + } > > + > > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != > ALL_ENGINES) { > > unsigned int class; > > > > @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > > if (!spin) > > return; > > > > - pthread_mutex_lock(&list_lock); > > - igt_list_del(&spin->link); > > - pthread_mutex_unlock(&list_lock); > > - > > - __igt_spin_free(fd, spin); > > + if (is_xe_device(fd)) { > > + xe_spin_free(fd, spin); > > + } else { > > + pthread_mutex_lock(&list_lock); > > + igt_list_del(&spin->link); > > + pthread_mutex_unlock(&list_lock); > > + __igt_spin_free(fd, spin); > > + } > > } > > > > void igt_terminate_spins(void) > > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index > > b247ab02..7bcc7b56 100644 > > --- a/lib/igt_dummyload.h > > +++ b/lib/igt_dummyload.h > > @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { > > unsigned int flags; > > int fence; > > uint64_t ahnd; > > + struct drm_xe_engine_class_instance *hwe; > > + uint32_t vm; Add description of newly added variables > > } igt_spin_factory_t; > > > > typedef struct igt_spin { > > @@ -83,6 +85,14 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 > > << 0) > > > > struct igt_spin_factory opts; > > + > > + struct xe_spin *xe_spin; > > + size_t bo_size; > > + uint64_t address; > > + unsigned int engine; > > + uint32_t vm; vm defined inside spin_factory as well, can we avoid this if it is redundant Thanks, Rahul > > + uint32_t syncobj; > > + > > } igt_spin_t; > > > > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index > > 856d0ba2..bc0fbcc6 100644 > > --- a/lib/xe/xe_spin.c > > +++ b/lib/xe/xe_spin.c > > @@ -15,6 +15,7 @@ > > #include "intel_reg.h" > > #include "xe_ioctl.h" > > #include "xe_spin.h" > > +#include "lib/igt_dummyload.h" > ------------ ^ > Do we need "lib/" here ? Please also put this in alphabetical order. > > > > > /** > > * xe_spin_init: > > @@ -82,6 +83,96 @@ void xe_spin_end(struct xe_spin *spin) > > spin->end = 0; > > } > > > > Please describe each new public function you added. > > > +igt_spin_t * > > +xe_spin_create(int fd, const struct igt_spin_factory *opt) { > > + size_t bo_size = xe_get_default_alignment(fd); > > + uint32_t bo; > > + uint64_t ahnd = opt->ahnd, addr; > > + struct igt_spin *spin; > > + struct xe_spin *xe_spin; > > + struct drm_xe_sync sync = { > > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > > + }; > > + struct drm_xe_exec exec = { > > + .num_batch_buffer = 1, > > + .num_syncs = 1, > > + .syncs = to_user_pointer(&sync), > > + }; > > + > > + igt_assert(ahnd); > > + spin = calloc(1, sizeof(struct igt_spin)); > > + igt_assert(spin); > > + > > + spin->syncobj = syncobj_create(fd, 0); > > + if (opt->engine) { > > + spin->opts.engine = opt->engine; > > + spin->opts.vm = opt->vm; > > + > > + spin->handle = xe_bo_create(fd, 0, spin->opts.vm, bo_size); > > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > > + addr = intel_allocator_alloc_with_strategy(ahnd, spin- > >handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > > + xe_vm_bind_sync(fd, spin->opts.vm, spin->handle, 0, addr, > bo_size); > > + > > + xe_spin_init(xe_spin, addr, true); > > + exec.engine_id = spin->opts.engine; > > + exec.address = addr; > > + } else { > > + spin->vm = xe_vm_create(fd, 0, 0); > > + if (!opt->hwe) > > + spin->engine = xe_engine_create_class(fd, spin- > >vm, DRM_XE_ENGINE_CLASS_RENDER); > > + else > > + spin->engine = xe_engine_create(fd, spin->vm, opt- > >hwe, 0); > > + > > + bo = xe_bo_create(fd, 0, spin->vm, bo_size); > > + spin->handle = bo; > > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > > + addr = intel_allocator_alloc_with_strategy(ahnd, spin- > >handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, > bo_size); > > + > > + xe_spin_init(xe_spin, addr, true); > > + exec.engine_id = spin->engine; > > + exec.address = addr; > > + } > > Put newline here. > > > + sync.handle = spin->syncobj; > > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > > + xe_spin_wait_started(xe_spin); > > + igt_info("Spinner started\n"); > > + > > + spin->bo_size = bo_size; > > + spin->address = addr; > > + spin->xe_spin = xe_spin; > > + > > + return spin; > > +} > > + > > Write description. > > > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) { > > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, > > + NULL)); > > imho you can have it in one line: > > igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, > NULL)); > > > +} > > + > > Write description. > > > +void xe_spin_free(int fd, struct igt_spin *spin) { > > + xe_spin_end(spin->xe_spin); > > + xe_spin_sync_wait(fd, spin); > > + > > + if (!spin->opts.vm) > > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin- > >bo_size); > > + else > > + xe_vm_unbind_sync(fd, spin->opts.vm, 0, spin->address, > > +spin->bo_size); > > + > > + syncobj_destroy(fd, spin->syncobj); > > + gem_munmap(spin->xe_spin, spin->bo_size); > > + gem_close(fd, spin->handle); > > + > > + if (!spin->opts.engine) { > > + xe_engine_destroy(fd, spin->engine); > > + xe_vm_destroy(fd, spin->vm); > > + } > > Put newline here. > > > + free(spin); > > +} > > + > > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > > struct xe_cork *cork) > > { > > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index > > 73f9a026..48867eb8 100644 > > --- a/lib/xe/xe_spin.h > > +++ b/lib/xe/xe_spin.h > > @@ -13,19 +13,26 @@ > > #include <stdbool.h> > > > > #include "xe_query.h" > > +#include "lib/igt_dummyload.h" > > > > /* Mapped GPU object */ > > + > > Please do not make cleanups when adding new functionality, remove this > newline. > > > struct xe_spin { > > uint32_t batch[16]; > > uint64_t pad; > > uint32_t start; > > uint32_t end; > > + > > Same here, remove this line. > > > }; > > > > +igt_spin_t * > -- ^ > > +xe_spin_create(int fd, const struct igt_spin_factory *opt); > -- ^ > > imho here one-liner is better: > > igt_spin_t *xe_spin_create(int fd, const struct igt_spin_factory *opt); > > Regards, > Kamil > > > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); > > 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); void > > xe_spin_end(struct xe_spin *spin); > > +void xe_spin_free(int fd, struct igt_spin *spin); > > > > struct xe_cork { > > struct xe_spin *spin; > > -- > > 2.39.1 > > ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. 2023-06-01 7:59 ` Kumar, Janga Rahul @ 2023-06-01 8:11 ` Ch, Sai Gowtham 2023-06-02 8:24 ` Zbigniew Kempczyński 1 sibling, 0 replies; 36+ messages in thread From: Ch, Sai Gowtham @ 2023-06-01 8:11 UTC (permalink / raw) To: Kumar, Janga Rahul, igt-dev Hi Kamil, Rahul, Thanks for the review comments, I'm sending a new patch which addresses few corrections and addressing your comments. Thanks, Gowtham > -----Original Message----- > From: Kumar, Janga Rahul <janga.rahul.kumar@intel.com> > Sent: Thursday, June 1, 2023 1:30 PM > To: igt-dev@lists.freedesktop.org; Ch, Sai Gowtham > <sai.gowtham.ch@intel.com> > Cc: Kamil Konieczny <kamil.konieczny@linux.intel.com> > Subject: RE: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new > with Xe. > > > > > -----Original Message----- > > From: igt-dev <igt-dev-bounces@lists.freedesktop.org> On Behalf Of > > Kamil Konieczny > > Sent: 01 June 2023 10:42 > > To: igt-dev@lists.freedesktop.org > > Cc: Ch, Sai Gowtham <sai.gowtham.ch@intel.com> > > Subject: Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate > > igt_spin_new with Xe. > > > > Hi Sai, > > > > On 2023-05-30 at 15:38:04 +0530, sai.gowtham.ch@intel.com wrote: > > > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > > > > > > please remove dot from end of Subject line: > > > > [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. > > --------------------------------------------------------------- ^ > > > > so it will be: > > > > [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe > > > > The same follows for your second patch. I have few more nits, see below. > > > > > Extending the spin_create implementation and allocator handle > > > support in xe, where it submits dummy work loads to engine. This > > > Implementation is wrapped around vm_bind and unbind as we are > > supposed to do it manually for xe. > > > > > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > > > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > > --- > > > lib/igt_dummyload.c | 24 +++++++++--- lib/igt_dummyload.h | 10 +++++ > > > lib/xe/xe_spin.c | 91 > > +++++++++++++++++++++++++++++++++++++++++++++ > > > lib/xe/xe_spin.h | 7 ++++ > > > 4 files changed, 126 insertions(+), 6 deletions(-) > > > > > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index > > > 740a58f3..6e89b72d 100644 > > > --- a/lib/igt_dummyload.c > > > +++ b/lib/igt_dummyload.c > > > @@ -46,6 +46,7 @@ > > > #include "intel_reg.h" > > > #include "ioctl_wrappers.h" > > > #include "sw_sync.h" > > > +#include "xe/xe_spin.h" > > > > > > /** > > > * SECTION:igt_dummyload > > > @@ -447,7 +448,10 @@ spin_create(int fd, const struct > > > igt_spin_factory > > > *opts) igt_spin_t * __igt_spin_factory(int fd, const struct > > > igt_spin_factory *opts) { > > > - return spin_create(fd, opts); > > > + if (is_xe_device(fd)) > > > + return xe_spin_create(fd, opts); > > > + else > > > + return spin_create(fd, opts); > > > } > > > > > > /** > > > @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct > > > igt_spin_factory *opts) { > > > igt_spin_t *spin; > > > > > > + if (is_xe_device(fd)) { > > > + spin = xe_spin_create(fd, opts); > > > + return spin; > > > + } > > > + > > > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != > > ALL_ENGINES) { > > > unsigned int class; > > > > > > @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > > > if (!spin) > > > return; > > > > > > - pthread_mutex_lock(&list_lock); > > > - igt_list_del(&spin->link); > > > - pthread_mutex_unlock(&list_lock); > > > - > > > - __igt_spin_free(fd, spin); > > > + if (is_xe_device(fd)) { > > > + xe_spin_free(fd, spin); > > > + } else { > > > + pthread_mutex_lock(&list_lock); > > > + igt_list_del(&spin->link); > > > + pthread_mutex_unlock(&list_lock); > > > + __igt_spin_free(fd, spin); > > > + } > > > } > > > > > > void igt_terminate_spins(void) > > > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index > > > b247ab02..7bcc7b56 100644 > > > --- a/lib/igt_dummyload.h > > > +++ b/lib/igt_dummyload.h > > > @@ -54,6 +54,8 @@ typedef struct igt_spin_factory { > > > unsigned int flags; > > > int fence; > > > uint64_t ahnd; > > > + struct drm_xe_engine_class_instance *hwe; > > > + uint32_t vm; > Add description of newly added variables > > > > } igt_spin_factory_t; > > > > > > typedef struct igt_spin { > > > @@ -83,6 +85,14 @@ typedef struct igt_spin { #define SPIN_CLFLUSH > > > (1 << 0) > > > > > > struct igt_spin_factory opts; > > > + > > > + struct xe_spin *xe_spin; > > > + size_t bo_size; > > > + uint64_t address; > > > + unsigned int engine; > > > + uint32_t vm; > vm defined inside spin_factory as well, can we avoid this if it is redundant > > Thanks, > Rahul > > > > + uint32_t syncobj; > > > + > > > } igt_spin_t; > > > > > > > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index > > > 856d0ba2..bc0fbcc6 100644 > > > --- a/lib/xe/xe_spin.c > > > +++ b/lib/xe/xe_spin.c > > > @@ -15,6 +15,7 @@ > > > #include "intel_reg.h" > > > #include "xe_ioctl.h" > > > #include "xe_spin.h" > > > +#include "lib/igt_dummyload.h" > > ------------ ^ > > Do we need "lib/" here ? Please also put this in alphabetical order. > > > > > > > > /** > > > * xe_spin_init: > > > @@ -82,6 +83,96 @@ void xe_spin_end(struct xe_spin *spin) > > > spin->end = 0; > > > } > > > > > > > Please describe each new public function you added. > > > > > +igt_spin_t * > > > +xe_spin_create(int fd, const struct igt_spin_factory *opt) { > > > + size_t bo_size = xe_get_default_alignment(fd); > > > + uint32_t bo; > > > + uint64_t ahnd = opt->ahnd, addr; > > > + struct igt_spin *spin; > > > + struct xe_spin *xe_spin; > > > + struct drm_xe_sync sync = { > > > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > > > + }; > > > + struct drm_xe_exec exec = { > > > + .num_batch_buffer = 1, > > > + .num_syncs = 1, > > > + .syncs = to_user_pointer(&sync), > > > + }; > > > + > > > + igt_assert(ahnd); > > > + spin = calloc(1, sizeof(struct igt_spin)); > > > + igt_assert(spin); > > > + > > > + spin->syncobj = syncobj_create(fd, 0); > > > + if (opt->engine) { > > > + spin->opts.engine = opt->engine; > > > + spin->opts.vm = opt->vm; > > > + > > > + spin->handle = xe_bo_create(fd, 0, spin->opts.vm, bo_size); > > > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > > > + addr = intel_allocator_alloc_with_strategy(ahnd, spin- > > >handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > > > + xe_vm_bind_sync(fd, spin->opts.vm, spin->handle, 0, addr, > > bo_size); > > > + > > > + xe_spin_init(xe_spin, addr, true); > > > + exec.engine_id = spin->opts.engine; > > > + exec.address = addr; > > > + } else { > > > + spin->vm = xe_vm_create(fd, 0, 0); > > > + if (!opt->hwe) > > > + spin->engine = xe_engine_create_class(fd, spin- > > >vm, DRM_XE_ENGINE_CLASS_RENDER); > > > + else > > > + spin->engine = xe_engine_create(fd, spin->vm, opt- > > >hwe, 0); > > > + > > > + bo = xe_bo_create(fd, 0, spin->vm, bo_size); > > > + spin->handle = bo; > > > + xe_spin = xe_bo_map(fd, spin->handle, bo_size); > > > + addr = intel_allocator_alloc_with_strategy(ahnd, spin- > > >handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > > > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, > > bo_size); > > > + > > > + xe_spin_init(xe_spin, addr, true); > > > + exec.engine_id = spin->engine; > > > + exec.address = addr; > > > + } > > > > Put newline here. > > > > > + sync.handle = spin->syncobj; > > > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > > > + xe_spin_wait_started(xe_spin); > > > + igt_info("Spinner started\n"); > > > + > > > + spin->bo_size = bo_size; > > > + spin->address = addr; > > > + spin->xe_spin = xe_spin; > > > + > > > + return spin; > > > +} > > > + > > > > Write description. > > > > > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) { > > > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, > > > + NULL)); > > > > imho you can have it in one line: > > > > igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, NULL)); > > > > > +} > > > + > > > > Write description. > > > > > +void xe_spin_free(int fd, struct igt_spin *spin) { > > > + xe_spin_end(spin->xe_spin); > > > + xe_spin_sync_wait(fd, spin); > > > + > > > + if (!spin->opts.vm) > > > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin- > > >bo_size); > > > + else > > > + xe_vm_unbind_sync(fd, spin->opts.vm, 0, spin->address, > > > +spin->bo_size); > > > + > > > + syncobj_destroy(fd, spin->syncobj); > > > + gem_munmap(spin->xe_spin, spin->bo_size); > > > + gem_close(fd, spin->handle); > > > + > > > + if (!spin->opts.engine) { > > > + xe_engine_destroy(fd, spin->engine); > > > + xe_vm_destroy(fd, spin->vm); > > > + } > > > > Put newline here. > > > > > + free(spin); > > > +} > > > + > > > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > > > struct xe_cork *cork) > > > { > > > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index > > > 73f9a026..48867eb8 100644 > > > --- a/lib/xe/xe_spin.h > > > +++ b/lib/xe/xe_spin.h > > > @@ -13,19 +13,26 @@ > > > #include <stdbool.h> > > > > > > #include "xe_query.h" > > > +#include "lib/igt_dummyload.h" > > > > > > /* Mapped GPU object */ > > > + > > > > Please do not make cleanups when adding new functionality, remove this > > newline. > > > > > struct xe_spin { > > > uint32_t batch[16]; > > > uint64_t pad; > > > uint32_t start; > > > uint32_t end; > > > + > > > > Same here, remove this line. > > > > > }; > > > > > > +igt_spin_t * > > -- ^ > > > +xe_spin_create(int fd, const struct igt_spin_factory *opt); > > -- ^ > > > > imho here one-liner is better: > > > > igt_spin_t *xe_spin_create(int fd, const struct igt_spin_factory > > *opt); > > > > Regards, > > Kamil > > > > > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool > > > preempt); 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); void > > > xe_spin_end(struct xe_spin *spin); > > > +void xe_spin_free(int fd, struct igt_spin *spin); > > > > > > struct xe_cork { > > > struct xe_spin *spin; > > > -- > > > 2.39.1 > > > ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. 2023-06-01 7:59 ` Kumar, Janga Rahul 2023-06-01 8:11 ` Ch, Sai Gowtham @ 2023-06-02 8:24 ` Zbigniew Kempczyński 1 sibling, 0 replies; 36+ messages in thread From: Zbigniew Kempczyński @ 2023-06-02 8:24 UTC (permalink / raw) To: Kumar, Janga Rahul; +Cc: igt-dev, Ch, Sai Gowtham On Thu, Jun 01, 2023 at 07:59:49AM +0000, Kumar, Janga Rahul wrote: <cut> > > > typedef struct igt_spin { > > > @@ -83,6 +85,14 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 > > > << 0) > > > > > > struct igt_spin_factory opts; > > > + > > > + struct xe_spin *xe_spin; > > > + size_t bo_size; > > > + uint64_t address; > > > + unsigned int engine; > > > + uint32_t vm; > vm defined inside spin_factory as well, can we avoid this if it is redundant I think it can be useful to assign external vm or create a new one in it. Then on free path you're destroying only vm you own. -- Zbigniew > > Thanks, > Rahul > > > > + uint32_t syncobj; ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 0/2] Integrate igt_spin_new with Xe. @ 2023-05-22 12:36 sai.gowtham.ch 2023-05-22 12:36 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 0 siblings, 1 reply; 36+ messages in thread From: sai.gowtham.ch @ 2023-05-22 12:36 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Sai Gowtham Ch (2): lib/xe/xe_spin: Integrate igt_spin_new with Xe. tests/xe/xe_spin_batch: Add new test to exercise igt_spin_new for xe. lib/igt_dummyload.c | 24 ++++++--- lib/igt_dummyload.h | 11 ++++ lib/xe/xe_spin.c | 68 +++++++++++++++++++++++ lib/xe/xe_spin.h | 7 +++ tests/meson.build | 1 + tests/xe/xe_spin_batch.c | 113 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 218 insertions(+), 6 deletions(-) create mode 100644 tests/xe/xe_spin_batch.c -- 2.39.1 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. 2023-05-22 12:36 [igt-dev] [PATCH i-g-t 0/2] " sai.gowtham.ch @ 2023-05-22 12:36 ` sai.gowtham.ch 2023-05-22 16:19 ` Zbigniew Kempczyński 2023-05-23 15:58 ` Zbigniew Kempczyński 0 siblings, 2 replies; 36+ messages in thread From: sai.gowtham.ch @ 2023-05-22 12:36 UTC (permalink / raw) To: igt-dev, zbigniew.kempczynski, sai.gowtham.ch From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> Extending the spin_create implementation and allocator handle support in xe, where it submits dummy work loads to engine. This Implementation is wrapped around vm_bind and unbind as we are supposed to do it manually for xe. Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> --- lib/igt_dummyload.c | 24 ++++++++++++---- lib/igt_dummyload.h | 11 ++++++++ lib/xe/xe_spin.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ lib/xe/xe_spin.h | 7 +++++ 4 files changed, 104 insertions(+), 6 deletions(-) diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index 740a58f3..6e89b72d 100644 --- a/lib/igt_dummyload.c +++ b/lib/igt_dummyload.c @@ -46,6 +46,7 @@ #include "intel_reg.h" #include "ioctl_wrappers.h" #include "sw_sync.h" +#include "xe/xe_spin.h" /** * SECTION:igt_dummyload @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory *opts) igt_spin_t * __igt_spin_factory(int fd, const struct igt_spin_factory *opts) { - return spin_create(fd, opts); + if (is_xe_device(fd)) + return xe_spin_create(fd, opts); + else + return spin_create(fd, opts); } /** @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) { igt_spin_t *spin; + if (is_xe_device(fd)) { + spin = xe_spin_create(fd, opts); + return spin; + } + if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { unsigned int class; @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) if (!spin) return; - pthread_mutex_lock(&list_lock); - igt_list_del(&spin->link); - pthread_mutex_unlock(&list_lock); - - __igt_spin_free(fd, spin); + if (is_xe_device(fd)) { + xe_spin_free(fd, spin); + } else { + pthread_mutex_lock(&list_lock); + igt_list_del(&spin->link); + pthread_mutex_unlock(&list_lock); + __igt_spin_free(fd, spin); + } } void igt_terminate_spins(void) diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index b247ab02..4da4e5a5 100644 --- a/lib/igt_dummyload.h +++ b/lib/igt_dummyload.h @@ -51,8 +51,10 @@ typedef struct igt_spin_factory { uint32_t dependency; uint64_t dependency_size; unsigned int engine; + struct drm_xe_engine_class_instance *hwe; unsigned int flags; int fence; + uint32_t vm; uint64_t ahnd; } igt_spin_factory_t; @@ -83,6 +85,15 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 << 0) struct igt_spin_factory opts; + + uint32_t start; + uint32_t end; + size_t bo_size; + uint64_t address; + unsigned int engine; + uint32_t vm; + uint32_t syncobj; + } igt_spin_t; diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index 856d0ba2..9a4fbeb8 100644 --- a/lib/xe/xe_spin.c +++ b/lib/xe/xe_spin.c @@ -15,6 +15,7 @@ #include "intel_reg.h" #include "xe_ioctl.h" #include "xe_spin.h" +#include "lib/igt_dummyload.h" /** * xe_spin_init: @@ -82,6 +83,73 @@ void xe_spin_end(struct xe_spin *spin) spin->end = 0; } +igt_spin_t * +xe_spin_create(int fd, const struct igt_spin_factory *opt) +{ + size_t bo_size = xe_get_default_alignment(fd); + uint32_t bo; + uint64_t ahnd = opt->ahnd, addr; + struct igt_spin *spin; + struct xe_spin *xe_spin; + struct drm_xe_sync sync = { + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, + }; + struct drm_xe_exec exec = { + .num_batch_buffer = 1, + .num_syncs = 1, + .syncs = to_user_pointer(&sync), + }; + + igt_assert(ahnd); + xe_spin = calloc(1, sizeof(struct xe_spin)); + igt_assert(xe_spin); + spin = calloc(1, sizeof(struct igt_spin)); + igt_assert(spin); + + if (opt->engine) { + spin->engine = opt->engine; + spin->vm = opt->vm; + } else { + spin->vm = xe_vm_create(fd, 0, 0); + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); + } + + bo = xe_bo_create(fd, opt->hwe->gt_id, spin->vm, bo_size); + spin->handle = bo; + spin->syncobj = syncobj_create(fd, 0); + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); + + xe_spin_init(xe_spin, addr, true); + exec.engine_id = spin->engine; + exec.address = addr; + sync.handle = spin->syncobj; + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); + + spin->batch = xe_spin->batch; + spin->start = xe_spin->start; + spin->end = xe_spin->end; + spin->bo_size = bo_size; + spin->address = addr; + return spin; + +} + +void xe_spin_sync_wait(int fd, struct igt_spin *spin) +{ + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, + NULL)); +} + +void xe_spin_free(int fd, struct igt_spin *spin) +{ + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); + spin->end = 0; + syncobj_destroy(fd, spin->syncobj); + xe_engine_destroy(fd, spin->engine); + gem_close(fd, spin->handle); +} + void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, struct xe_cork *cork) { diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index 73f9a026..48867eb8 100644 --- a/lib/xe/xe_spin.h +++ b/lib/xe/xe_spin.h @@ -13,19 +13,26 @@ #include <stdbool.h> #include "xe_query.h" +#include "lib/igt_dummyload.h" /* Mapped GPU object */ + struct xe_spin { uint32_t batch[16]; uint64_t pad; uint32_t start; uint32_t end; + }; +igt_spin_t * +xe_spin_create(int fd, const struct igt_spin_factory *opt); void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); 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); void xe_spin_end(struct xe_spin *spin); +void xe_spin_free(int fd, struct igt_spin *spin); struct xe_cork { struct xe_spin *spin; -- 2.39.1 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. 2023-05-22 12:36 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch @ 2023-05-22 16:19 ` Zbigniew Kempczyński 2023-05-23 8:41 ` Ch, Sai Gowtham 2023-05-23 15:58 ` Zbigniew Kempczyński 1 sibling, 1 reply; 36+ messages in thread From: Zbigniew Kempczyński @ 2023-05-22 16:19 UTC (permalink / raw) To: sai.gowtham.ch; +Cc: igt-dev On Mon, May 22, 2023 at 06:06:04PM +0530, sai.gowtham.ch@intel.com wrote: > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > Extending the spin_create implementation and allocator handle support in xe, > where it submits dummy work loads to engine. This Implementation is wrapped > around vm_bind and unbind as we are supposed to do it manually for xe. > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > --- > lib/igt_dummyload.c | 24 ++++++++++++---- > lib/igt_dummyload.h | 11 ++++++++ > lib/xe/xe_spin.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ > lib/xe/xe_spin.h | 7 +++++ > 4 files changed, 104 insertions(+), 6 deletions(-) > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c > index 740a58f3..6e89b72d 100644 > --- a/lib/igt_dummyload.c > +++ b/lib/igt_dummyload.c > @@ -46,6 +46,7 @@ > #include "intel_reg.h" > #include "ioctl_wrappers.h" > #include "sw_sync.h" > +#include "xe/xe_spin.h" > > /** > * SECTION:igt_dummyload > @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory *opts) > igt_spin_t * > __igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > - return spin_create(fd, opts); > + if (is_xe_device(fd)) > + return xe_spin_create(fd, opts); > + else > + return spin_create(fd, opts); > } > > /** > @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > igt_spin_t *spin; > > + if (is_xe_device(fd)) { > + spin = xe_spin_create(fd, opts); > + return spin; > + } > + > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { > unsigned int class; > > @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > if (!spin) > return; > > - pthread_mutex_lock(&list_lock); > - igt_list_del(&spin->link); > - pthread_mutex_unlock(&list_lock); > - > - __igt_spin_free(fd, spin); > + if (is_xe_device(fd)) { > + xe_spin_free(fd, spin); > + } else { > + pthread_mutex_lock(&list_lock); > + igt_list_del(&spin->link); > + pthread_mutex_unlock(&list_lock); > + __igt_spin_free(fd, spin); > + } > } > > void igt_terminate_spins(void) > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h > index b247ab02..4da4e5a5 100644 > --- a/lib/igt_dummyload.h > +++ b/lib/igt_dummyload.h > @@ -51,8 +51,10 @@ typedef struct igt_spin_factory { > uint32_t dependency; > uint64_t dependency_size; > unsigned int engine; > + struct drm_xe_engine_class_instance *hwe; > unsigned int flags; > int fence; > + uint32_t vm; > uint64_t ahnd; > } igt_spin_factory_t; > > @@ -83,6 +85,15 @@ typedef struct igt_spin { > #define SPIN_CLFLUSH (1 << 0) > > struct igt_spin_factory opts; > + > + uint32_t start; > + uint32_t end; > + size_t bo_size; > + uint64_t address; > + unsigned int engine; > + uint32_t vm; > + uint32_t syncobj; > + > } igt_spin_t; > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c > index 856d0ba2..9a4fbeb8 100644 > --- a/lib/xe/xe_spin.c > +++ b/lib/xe/xe_spin.c > @@ -15,6 +15,7 @@ > #include "intel_reg.h" > #include "xe_ioctl.h" > #include "xe_spin.h" > +#include "lib/igt_dummyload.h" > > /** > * xe_spin_init: > @@ -82,6 +83,73 @@ void xe_spin_end(struct xe_spin *spin) > spin->end = 0; > } > > +igt_spin_t * > +xe_spin_create(int fd, const struct igt_spin_factory *opt) > +{ > + size_t bo_size = xe_get_default_alignment(fd); > + uint32_t bo; > + uint64_t ahnd = opt->ahnd, addr; > + struct igt_spin *spin; > + struct xe_spin *xe_spin; > + struct drm_xe_sync sync = { > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > + }; > + struct drm_xe_exec exec = { > + .num_batch_buffer = 1, > + .num_syncs = 1, > + .syncs = to_user_pointer(&sync), > + }; > + > + igt_assert(ahnd); > + xe_spin = calloc(1, sizeof(struct xe_spin)); > + igt_assert(xe_spin); What is happening with xe_spin later? I mean it is allocated and? > + spin = calloc(1, sizeof(struct igt_spin)); > + igt_assert(spin); > + > + if (opt->engine) { > + spin->engine = opt->engine; > + spin->vm = opt->vm; > + } else { > + spin->vm = xe_vm_create(fd, 0, 0); > + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); > + } > + > + bo = xe_bo_create(fd, opt->hwe->gt_id, spin->vm, bo_size); > + spin->handle = bo; > + spin->syncobj = syncobj_create(fd, 0); > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); > + > + xe_spin_init(xe_spin, addr, true); > + exec.engine_id = spin->engine; > + exec.address = addr; > + sync.handle = spin->syncobj; > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); This code submits the job, but there're no instructions in bo dmesg complains with errors. Check your spin is not starting by adding here: xe_spin_wait_started(xe_spin); cpu will stuck waiting for uncompleted store-dword. Hint: check your bo. -- Zbigniew > + > + spin->batch = xe_spin->batch; > + spin->start = xe_spin->start; > + spin->end = xe_spin->end; > + spin->bo_size = bo_size; > + spin->address = addr; > + return spin; > + > +} > + > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) > +{ > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, > + NULL)); > +} > + > +void xe_spin_free(int fd, struct igt_spin *spin) > +{ > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); > + spin->end = 0; > + syncobj_destroy(fd, spin->syncobj); > + xe_engine_destroy(fd, spin->engine); > + gem_close(fd, spin->handle); > +} > + > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > struct xe_cork *cork) > { > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h > index 73f9a026..48867eb8 100644 > --- a/lib/xe/xe_spin.h > +++ b/lib/xe/xe_spin.h > @@ -13,19 +13,26 @@ > #include <stdbool.h> > > #include "xe_query.h" > +#include "lib/igt_dummyload.h" > > /* Mapped GPU object */ > + > struct xe_spin { > uint32_t batch[16]; > uint64_t pad; > uint32_t start; > uint32_t end; > + > }; > > +igt_spin_t * > +xe_spin_create(int fd, const struct igt_spin_factory *opt); > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); > 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); > void xe_spin_end(struct xe_spin *spin); > +void xe_spin_free(int fd, struct igt_spin *spin); > > struct xe_cork { > struct xe_spin *spin; > -- > 2.39.1 > ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. 2023-05-22 16:19 ` Zbigniew Kempczyński @ 2023-05-23 8:41 ` Ch, Sai Gowtham 2023-05-23 11:29 ` Zbigniew Kempczyński 0 siblings, 1 reply; 36+ messages in thread From: Ch, Sai Gowtham @ 2023-05-23 8:41 UTC (permalink / raw) To: Kempczynski, Zbigniew; +Cc: igt-dev > -----Original Message----- > From: Kempczynski, Zbigniew <zbigniew.kempczynski@intel.com> > Sent: Monday, May 22, 2023 9:50 PM > To: Ch, Sai Gowtham <sai.gowtham.ch@intel.com> > Cc: igt-dev@lists.freedesktop.org > Subject: Re: [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. > > On Mon, May 22, 2023 at 06:06:04PM +0530, sai.gowtham.ch@intel.com > wrote: > > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > > > Extending the spin_create implementation and allocator handle support > > in xe, where it submits dummy work loads to engine. This > > Implementation is wrapped around vm_bind and unbind as we are supposed to > do it manually for xe. > > > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > --- > > lib/igt_dummyload.c | 24 ++++++++++++---- lib/igt_dummyload.h | 11 > > ++++++++ > > lib/xe/xe_spin.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ > > lib/xe/xe_spin.h | 7 +++++ > > 4 files changed, 104 insertions(+), 6 deletions(-) > > > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index > > 740a58f3..6e89b72d 100644 > > --- a/lib/igt_dummyload.c > > +++ b/lib/igt_dummyload.c > > @@ -46,6 +46,7 @@ > > #include "intel_reg.h" > > #include "ioctl_wrappers.h" > > #include "sw_sync.h" > > +#include "xe/xe_spin.h" > > > > /** > > * SECTION:igt_dummyload > > @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory > > *opts) igt_spin_t * __igt_spin_factory(int fd, const struct > > igt_spin_factory *opts) { > > - return spin_create(fd, opts); > > + if (is_xe_device(fd)) > > + return xe_spin_create(fd, opts); > > + else > > + return spin_create(fd, opts); > > } > > > > /** > > @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct > > igt_spin_factory *opts) { > > igt_spin_t *spin; > > > > + if (is_xe_device(fd)) { > > + spin = xe_spin_create(fd, opts); > > + return spin; > > + } > > + > > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != > ALL_ENGINES) { > > unsigned int class; > > > > @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > > if (!spin) > > return; > > > > - pthread_mutex_lock(&list_lock); > > - igt_list_del(&spin->link); > > - pthread_mutex_unlock(&list_lock); > > - > > - __igt_spin_free(fd, spin); > > + if (is_xe_device(fd)) { > > + xe_spin_free(fd, spin); > > + } else { > > + pthread_mutex_lock(&list_lock); > > + igt_list_del(&spin->link); > > + pthread_mutex_unlock(&list_lock); > > + __igt_spin_free(fd, spin); > > + } > > } > > > > void igt_terminate_spins(void) > > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index > > b247ab02..4da4e5a5 100644 > > --- a/lib/igt_dummyload.h > > +++ b/lib/igt_dummyload.h > > @@ -51,8 +51,10 @@ typedef struct igt_spin_factory { > > uint32_t dependency; > > uint64_t dependency_size; > > unsigned int engine; > > + struct drm_xe_engine_class_instance *hwe; > > unsigned int flags; > > int fence; > > + uint32_t vm; > > uint64_t ahnd; > > } igt_spin_factory_t; > > > > @@ -83,6 +85,15 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 > > << 0) > > > > struct igt_spin_factory opts; > > + > > + uint32_t start; > > + uint32_t end; > > + size_t bo_size; > > + uint64_t address; > > + unsigned int engine; > > + uint32_t vm; > > + uint32_t syncobj; > > + > > } igt_spin_t; > > > > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index > > 856d0ba2..9a4fbeb8 100644 > > --- a/lib/xe/xe_spin.c > > +++ b/lib/xe/xe_spin.c > > @@ -15,6 +15,7 @@ > > #include "intel_reg.h" > > #include "xe_ioctl.h" > > #include "xe_spin.h" > > +#include "lib/igt_dummyload.h" > > > > /** > > * xe_spin_init: > > @@ -82,6 +83,73 @@ void xe_spin_end(struct xe_spin *spin) > > spin->end = 0; > > } > > > > +igt_spin_t * > > +xe_spin_create(int fd, const struct igt_spin_factory *opt) { > > + size_t bo_size = xe_get_default_alignment(fd); > > + uint32_t bo; > > + uint64_t ahnd = opt->ahnd, addr; > > + struct igt_spin *spin; > > + struct xe_spin *xe_spin; > > + struct drm_xe_sync sync = { > > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > > + }; > > + struct drm_xe_exec exec = { > > + .num_batch_buffer = 1, > > + .num_syncs = 1, > > + .syncs = to_user_pointer(&sync), > > + }; > > + > > + igt_assert(ahnd); > > + xe_spin = calloc(1, sizeof(struct xe_spin)); > > + igt_assert(xe_spin); > > What is happening with xe_spin later? I mean it is allocated and? > > > + spin = calloc(1, sizeof(struct igt_spin)); > > + igt_assert(spin); > > + > > + if (opt->engine) { > > + spin->engine = opt->engine; > > + spin->vm = opt->vm; > > + } else { > > + spin->vm = xe_vm_create(fd, 0, 0); > > + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); > > + } > > + > > + bo = xe_bo_create(fd, opt->hwe->gt_id, spin->vm, bo_size); > > + spin->handle = bo; > > + spin->syncobj = syncobj_create(fd, 0); > > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, > 0, ALLOC_STRATEGY_LOW_TO_HIGH); > > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); > > + > > + xe_spin_init(xe_spin, addr, true); > > + exec.engine_id = spin->engine; > > + exec.address = addr; > > + sync.handle = spin->syncobj; > > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > > This code submits the job, but there're no instructions in bo dmesg complains > with errors. Check your spin is not starting by adding here: > I'm trying to understand more here, what do you mean by no instructions in bo ? > xe_spin_wait_started(xe_spin); > Do you mean we have to wait spin for uncompleted store-dword after submitting exec ? > cpu will stuck waiting for uncompleted store-dword. > > Hint: check your bo. > > -- > Zbigniew > > > + > > + spin->batch = xe_spin->batch; > > + spin->start = xe_spin->start; > > + spin->end = xe_spin->end; > > + spin->bo_size = bo_size; > > + spin->address = addr; > > + return spin; > > + > > +} > > + > > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) { > > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, > > + NULL)); > > +} > > + > > +void xe_spin_free(int fd, struct igt_spin *spin) { > > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); > > + spin->end = 0; > > + syncobj_destroy(fd, spin->syncobj); > > + xe_engine_destroy(fd, spin->engine); > > + gem_close(fd, spin->handle); > > +} > > + > > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > > struct xe_cork *cork) > > { > > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index > > 73f9a026..48867eb8 100644 > > --- a/lib/xe/xe_spin.h > > +++ b/lib/xe/xe_spin.h > > @@ -13,19 +13,26 @@ > > #include <stdbool.h> > > > > #include "xe_query.h" > > +#include "lib/igt_dummyload.h" > > > > /* Mapped GPU object */ > > + > > struct xe_spin { > > uint32_t batch[16]; > > uint64_t pad; > > uint32_t start; > > uint32_t end; > > + > > }; > > > > +igt_spin_t * > > +xe_spin_create(int fd, const struct igt_spin_factory *opt); > > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); > > 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); void > > xe_spin_end(struct xe_spin *spin); > > +void xe_spin_free(int fd, struct igt_spin *spin); > > > > struct xe_cork { > > struct xe_spin *spin; > > -- > > 2.39.1 > > ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. 2023-05-23 8:41 ` Ch, Sai Gowtham @ 2023-05-23 11:29 ` Zbigniew Kempczyński 0 siblings, 0 replies; 36+ messages in thread From: Zbigniew Kempczyński @ 2023-05-23 11:29 UTC (permalink / raw) To: Ch, Sai Gowtham; +Cc: igt-dev On Tue, May 23, 2023 at 10:41:08AM +0200, Ch, Sai Gowtham wrote: > > > > -----Original Message----- > > From: Kempczynski, Zbigniew <zbigniew.kempczynski@intel.com> > > Sent: Monday, May 22, 2023 9:50 PM > > To: Ch, Sai Gowtham <sai.gowtham.ch@intel.com> > > Cc: igt-dev@lists.freedesktop.org > > Subject: Re: [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. > > > > On Mon, May 22, 2023 at 06:06:04PM +0530, sai.gowtham.ch@intel.com > > wrote: > > > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > > > > > Extending the spin_create implementation and allocator handle support > > > in xe, where it submits dummy work loads to engine. This > > > Implementation is wrapped around vm_bind and unbind as we are supposed to > > do it manually for xe. > > > > > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > > > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > > --- > > > lib/igt_dummyload.c | 24 ++++++++++++---- lib/igt_dummyload.h | 11 > > > ++++++++ > > > lib/xe/xe_spin.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ > > > lib/xe/xe_spin.h | 7 +++++ > > > 4 files changed, 104 insertions(+), 6 deletions(-) > > > > > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c index > > > 740a58f3..6e89b72d 100644 > > > --- a/lib/igt_dummyload.c > > > +++ b/lib/igt_dummyload.c > > > @@ -46,6 +46,7 @@ > > > #include "intel_reg.h" > > > #include "ioctl_wrappers.h" > > > #include "sw_sync.h" > > > +#include "xe/xe_spin.h" > > > > > > /** > > > * SECTION:igt_dummyload > > > @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory > > > *opts) igt_spin_t * __igt_spin_factory(int fd, const struct > > > igt_spin_factory *opts) { > > > - return spin_create(fd, opts); > > > + if (is_xe_device(fd)) > > > + return xe_spin_create(fd, opts); > > > + else > > > + return spin_create(fd, opts); > > > } > > > > > > /** > > > @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct > > > igt_spin_factory *opts) { > > > igt_spin_t *spin; > > > > > > + if (is_xe_device(fd)) { > > > + spin = xe_spin_create(fd, opts); > > > + return spin; > > > + } > > > + > > > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != > > ALL_ENGINES) { > > > unsigned int class; > > > > > > @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > > > if (!spin) > > > return; > > > > > > - pthread_mutex_lock(&list_lock); > > > - igt_list_del(&spin->link); > > > - pthread_mutex_unlock(&list_lock); > > > - > > > - __igt_spin_free(fd, spin); > > > + if (is_xe_device(fd)) { > > > + xe_spin_free(fd, spin); > > > + } else { > > > + pthread_mutex_lock(&list_lock); > > > + igt_list_del(&spin->link); > > > + pthread_mutex_unlock(&list_lock); > > > + __igt_spin_free(fd, spin); > > > + } > > > } > > > > > > void igt_terminate_spins(void) > > > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h index > > > b247ab02..4da4e5a5 100644 > > > --- a/lib/igt_dummyload.h > > > +++ b/lib/igt_dummyload.h > > > @@ -51,8 +51,10 @@ typedef struct igt_spin_factory { > > > uint32_t dependency; > > > uint64_t dependency_size; > > > unsigned int engine; > > > + struct drm_xe_engine_class_instance *hwe; > > > unsigned int flags; > > > int fence; > > > + uint32_t vm; > > > uint64_t ahnd; > > > } igt_spin_factory_t; > > > > > > @@ -83,6 +85,15 @@ typedef struct igt_spin { #define SPIN_CLFLUSH (1 > > > << 0) > > > > > > struct igt_spin_factory opts; > > > + > > > + uint32_t start; > > > + uint32_t end; > > > + size_t bo_size; > > > + uint64_t address; > > > + unsigned int engine; > > > + uint32_t vm; > > > + uint32_t syncobj; > > > + > > > } igt_spin_t; > > > > > > > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c index > > > 856d0ba2..9a4fbeb8 100644 > > > --- a/lib/xe/xe_spin.c > > > +++ b/lib/xe/xe_spin.c > > > @@ -15,6 +15,7 @@ > > > #include "intel_reg.h" > > > #include "xe_ioctl.h" > > > #include "xe_spin.h" > > > +#include "lib/igt_dummyload.h" > > > > > > /** > > > * xe_spin_init: > > > @@ -82,6 +83,73 @@ void xe_spin_end(struct xe_spin *spin) > > > spin->end = 0; > > > } > > > > > > +igt_spin_t * > > > +xe_spin_create(int fd, const struct igt_spin_factory *opt) { > > > + size_t bo_size = xe_get_default_alignment(fd); > > > + uint32_t bo; > > > + uint64_t ahnd = opt->ahnd, addr; > > > + struct igt_spin *spin; > > > + struct xe_spin *xe_spin; > > > + struct drm_xe_sync sync = { > > > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > > > + }; > > > + struct drm_xe_exec exec = { > > > + .num_batch_buffer = 1, > > > + .num_syncs = 1, > > > + .syncs = to_user_pointer(&sync), > > > + }; > > > + > > > + igt_assert(ahnd); > > > + xe_spin = calloc(1, sizeof(struct xe_spin)); > > > + igt_assert(xe_spin); > > > > What is happening with xe_spin later? I mean it is allocated and? > > > > > + spin = calloc(1, sizeof(struct igt_spin)); > > > + igt_assert(spin); > > > + > > > + if (opt->engine) { > > > + spin->engine = opt->engine; > > > + spin->vm = opt->vm; > > > + } else { > > > + spin->vm = xe_vm_create(fd, 0, 0); > > > + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); > > > + } > > > + > > > + bo = xe_bo_create(fd, opt->hwe->gt_id, spin->vm, bo_size); > > > + spin->handle = bo; > > > + spin->syncobj = syncobj_create(fd, 0); > > > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, > > 0, ALLOC_STRATEGY_LOW_TO_HIGH); > > > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); > > > + > > > + xe_spin_init(xe_spin, addr, true); > > > + exec.engine_id = spin->engine; > > > + exec.address = addr; > > > + sync.handle = spin->syncobj; > > > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > > > > This code submits the job, but there're no instructions in bo dmesg complains > > with errors. Check your spin is not starting by adding here: > > > I'm trying to understand more here, what do you mean by no instructions in bo ? Map your 'bo' (batch), dump 16 instructions and see what's there. > > xe_spin_wait_started(xe_spin); > > > Do you mean we have to wait spin for uncompleted store-dword after submitting exec ? Yes, this will reveal you're stucking here with current code. -- Zbigniew > > cpu will stuck waiting for uncompleted store-dword. > > > > Hint: check your bo. > > > > -- > > Zbigniew > > > > > + > > > + spin->batch = xe_spin->batch; > > > + spin->start = xe_spin->start; > > > + spin->end = xe_spin->end; > > > + spin->bo_size = bo_size; > > > + spin->address = addr; > > > + return spin; > > > + > > > +} > > > + > > > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) { > > > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, > > > + NULL)); > > > +} > > > + > > > +void xe_spin_free(int fd, struct igt_spin *spin) { > > > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); > > > + spin->end = 0; > > > + syncobj_destroy(fd, spin->syncobj); > > > + xe_engine_destroy(fd, spin->engine); > > > + gem_close(fd, spin->handle); > > > +} > > > + > > > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > > > struct xe_cork *cork) > > > { > > > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h index > > > 73f9a026..48867eb8 100644 > > > --- a/lib/xe/xe_spin.h > > > +++ b/lib/xe/xe_spin.h > > > @@ -13,19 +13,26 @@ > > > #include <stdbool.h> > > > > > > #include "xe_query.h" > > > +#include "lib/igt_dummyload.h" > > > > > > /* Mapped GPU object */ > > > + > > > struct xe_spin { > > > uint32_t batch[16]; > > > uint64_t pad; > > > uint32_t start; > > > uint32_t end; > > > + > > > }; > > > > > > +igt_spin_t * > > > +xe_spin_create(int fd, const struct igt_spin_factory *opt); > > > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); > > > 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); void > > > xe_spin_end(struct xe_spin *spin); > > > +void xe_spin_free(int fd, struct igt_spin *spin); > > > > > > struct xe_cork { > > > struct xe_spin *spin; > > > -- > > > 2.39.1 > > > ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: Integrate igt_spin_new with Xe. 2023-05-22 12:36 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 2023-05-22 16:19 ` Zbigniew Kempczyński @ 2023-05-23 15:58 ` Zbigniew Kempczyński 1 sibling, 0 replies; 36+ messages in thread From: Zbigniew Kempczyński @ 2023-05-23 15:58 UTC (permalink / raw) To: sai.gowtham.ch; +Cc: igt-dev On Mon, May 22, 2023 at 06:06:04PM +0530, sai.gowtham.ch@intel.com wrote: > From: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > > Extending the spin_create implementation and allocator handle support in xe, > where it submits dummy work loads to engine. This Implementation is wrapped > around vm_bind and unbind as we are supposed to do it manually for xe. > > Cc: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com> > Signed-off-by: Sai Gowtham Ch <sai.gowtham.ch@intel.com> > --- > lib/igt_dummyload.c | 24 ++++++++++++---- > lib/igt_dummyload.h | 11 ++++++++ > lib/xe/xe_spin.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ > lib/xe/xe_spin.h | 7 +++++ > 4 files changed, 104 insertions(+), 6 deletions(-) > > diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c > index 740a58f3..6e89b72d 100644 > --- a/lib/igt_dummyload.c > +++ b/lib/igt_dummyload.c > @@ -46,6 +46,7 @@ > #include "intel_reg.h" > #include "ioctl_wrappers.h" > #include "sw_sync.h" > +#include "xe/xe_spin.h" > > /** > * SECTION:igt_dummyload > @@ -447,7 +448,10 @@ spin_create(int fd, const struct igt_spin_factory *opts) > igt_spin_t * > __igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > - return spin_create(fd, opts); > + if (is_xe_device(fd)) > + return xe_spin_create(fd, opts); > + else > + return spin_create(fd, opts); > } You may use enum intel_driver and cache what's the device underneath to avoid this check in free path. See __intel_bb_create() as a reference. > > /** > @@ -467,6 +471,11 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts) > { > igt_spin_t *spin; > > + if (is_xe_device(fd)) { > + spin = xe_spin_create(fd, opts); > + return spin; > + } > + > if ((opts->flags & IGT_SPIN_POLL_RUN) && opts->engine != ALL_ENGINES) { > unsigned int class; > > @@ -647,11 +656,14 @@ void igt_spin_free(int fd, igt_spin_t *spin) > if (!spin) > return; > > - pthread_mutex_lock(&list_lock); > - igt_list_del(&spin->link); > - pthread_mutex_unlock(&list_lock); > - > - __igt_spin_free(fd, spin); > + if (is_xe_device(fd)) { > + xe_spin_free(fd, spin); > + } else { > + pthread_mutex_lock(&list_lock); > + igt_list_del(&spin->link); > + pthread_mutex_unlock(&list_lock); > + __igt_spin_free(fd, spin); > + } > } > > void igt_terminate_spins(void) > diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h > index b247ab02..4da4e5a5 100644 > --- a/lib/igt_dummyload.h > +++ b/lib/igt_dummyload.h > @@ -51,8 +51,10 @@ typedef struct igt_spin_factory { > uint32_t dependency; > uint64_t dependency_size; > unsigned int engine; > + struct drm_xe_engine_class_instance *hwe; > unsigned int flags; > int fence; > + uint32_t vm; > uint64_t ahnd; Keep xe arguments on the end. > } igt_spin_factory_t; > > @@ -83,6 +85,15 @@ typedef struct igt_spin { > #define SPIN_CLFLUSH (1 << 0) > > struct igt_spin_factory opts; > + > + uint32_t start; > + uint32_t end; > + size_t bo_size; > + uint64_t address; > + unsigned int engine; > + uint32_t vm; > + uint32_t syncobj; > + start and end are not necessary. Use struct xe_spin *xe_spin instead. Other fields are ok. > } igt_spin_t; > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c > index 856d0ba2..9a4fbeb8 100644 > --- a/lib/xe/xe_spin.c > +++ b/lib/xe/xe_spin.c > @@ -15,6 +15,7 @@ > #include "intel_reg.h" > #include "xe_ioctl.h" > #include "xe_spin.h" > +#include "lib/igt_dummyload.h" > > /** > * xe_spin_init: > @@ -82,6 +83,73 @@ void xe_spin_end(struct xe_spin *spin) > spin->end = 0; > } > > +igt_spin_t * > +xe_spin_create(int fd, const struct igt_spin_factory *opt) > +{ > + size_t bo_size = xe_get_default_alignment(fd); > + uint32_t bo; > + uint64_t ahnd = opt->ahnd, addr; > + struct igt_spin *spin; > + struct xe_spin *xe_spin; > + struct drm_xe_sync sync = { > + .flags = DRM_XE_SYNC_SYNCOBJ | DRM_XE_SYNC_SIGNAL, > + }; > + struct drm_xe_exec exec = { > + .num_batch_buffer = 1, > + .num_syncs = 1, > + .syncs = to_user_pointer(&sync), > + }; > + > + igt_assert(ahnd); > + xe_spin = calloc(1, sizeof(struct xe_spin)); > + igt_assert(xe_spin); > + spin = calloc(1, sizeof(struct igt_spin)); > + igt_assert(spin); > + > + if (opt->engine) { > + spin->engine = opt->engine; > + spin->vm = opt->vm; > + } else { > + spin->vm = xe_vm_create(fd, 0, 0); > + spin->engine = xe_engine_create(fd, spin->vm, opt->hwe, 0); > + } > + > + bo = xe_bo_create(fd, opt->hwe->gt_id, spin->vm, bo_size); > + spin->handle = bo; > + spin->syncobj = syncobj_create(fd, 0); > + addr = intel_allocator_alloc_with_strategy(ahnd, spin->handle, bo_size, 0, ALLOC_STRATEGY_LOW_TO_HIGH); > + xe_vm_bind_sync(fd, spin->vm, spin->handle, 0, addr, bo_size); > + > + xe_spin_init(xe_spin, addr, true); > + exec.engine_id = spin->engine; > + exec.address = addr; > + sync.handle = spin->syncobj; > + igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC, &exec), 0); > + > + spin->batch = xe_spin->batch; > + spin->start = xe_spin->start; > + spin->end = xe_spin->end; > + spin->bo_size = bo_size; > + spin->address = addr; Blank line here will make this code more readable. > + return spin; > + And this blank line is unnecessary. > +} > + > +void xe_spin_sync_wait(int fd, struct igt_spin *spin) > +{ > + igt_assert(syncobj_wait(fd, &spin->syncobj, 1, INT64_MAX, 0, > + NULL)); > +} > + > +void xe_spin_free(int fd, struct igt_spin *spin) > +{ > + xe_vm_unbind_sync(fd, spin->vm, 0, spin->address, spin->bo_size); > + spin->end = 0; Are you really sure you want to unbind then stop the spinner? And use xe_spin_end() for stopping the spinner. > + syncobj_destroy(fd, spin->syncobj); > + xe_engine_destroy(fd, spin->engine); > + gem_close(fd, spin->handle); Spin memory will leak here. -- Zbigniew > +} > + > void xe_cork_init(int fd, struct drm_xe_engine_class_instance *hwe, > struct xe_cork *cork) > { > diff --git a/lib/xe/xe_spin.h b/lib/xe/xe_spin.h > index 73f9a026..48867eb8 100644 > --- a/lib/xe/xe_spin.h > +++ b/lib/xe/xe_spin.h > @@ -13,19 +13,26 @@ > #include <stdbool.h> > > #include "xe_query.h" > +#include "lib/igt_dummyload.h" > > /* Mapped GPU object */ > + > struct xe_spin { > uint32_t batch[16]; > uint64_t pad; > uint32_t start; > uint32_t end; > + > }; > > +igt_spin_t * > +xe_spin_create(int fd, const struct igt_spin_factory *opt); > void xe_spin_init(struct xe_spin *spin, uint64_t addr, bool preempt); > 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); > void xe_spin_end(struct xe_spin *spin); > +void xe_spin_free(int fd, struct igt_spin *spin); > > struct xe_cork { > struct xe_spin *spin; > -- > 2.39.1 > ^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2023-06-16 6:19 UTC | newest] Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-05-25 5:55 [igt-dev] [PATCH i-g-t 0/2] Integrate igt_spin_new with Xe sai.gowtham.ch 2023-05-25 5:55 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 2023-05-29 5:51 ` Zbigniew Kempczyński 2023-05-30 4:39 ` Ch, Sai Gowtham 2023-05-30 4:43 ` Modem, Bhanuprakash 2023-05-30 5:04 ` Ch, Sai Gowtham 2023-05-25 5:55 ` [igt-dev] [PATCH i-g-t 2/2] tests/xe/xe_spin_batch: Add new test to exercise igt_spin_new for xe sai.gowtham.ch 2023-05-29 5:57 ` Zbigniew Kempczyński 2023-05-29 11:02 ` Ch, Sai Gowtham 2023-05-30 19:12 ` Zbigniew Kempczyński 2023-05-25 6:07 ` [igt-dev] ✗ GitLab.Pipeline: warning for Integrate igt_spin_new with Xe. (rev2) Patchwork -- strict thread matches above, loose matches on Subject: below -- 2023-06-15 10:59 [igt-dev] [PATCH i-g-t 0/2] Integrate igt_spin_new with Xe sai.gowtham.ch 2023-06-15 10:59 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 2023-06-16 6:19 ` Zbigniew Kempczyński 2023-06-13 12:42 [igt-dev] [PATCH i-g-t 0/2] " sai.gowtham.ch 2023-06-13 12:42 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 2023-06-14 17:33 ` Zbigniew Kempczyński 2023-06-12 8:59 [igt-dev] [PATCH i-g-t 0/2] " sai.gowtham.ch 2023-06-12 8:59 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 2023-06-12 18:56 ` Zbigniew Kempczyński 2023-06-06 8:50 [igt-dev] [PATCH i-g-t 0/2] " sai.gowtham.ch 2023-06-06 8:50 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 2023-06-06 19:27 ` Zbigniew Kempczyński 2023-06-06 21:03 ` Ch, Sai Gowtham 2023-06-04 19:58 [igt-dev] [PATCH i-g-t 0/2] " sai.gowtham.ch 2023-06-04 19:58 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 2023-06-05 8:58 ` Kumar, Janga Rahul 2023-06-05 11:19 ` Zbigniew Kempczyński 2023-06-04 19:16 [igt-dev] [PATCH i-g-t 0/2] " sai.gowtham.ch 2023-06-04 19:16 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 2023-06-04 19:59 ` Ch, Sai Gowtham 2023-05-30 10:08 [igt-dev] [PATCH i-g-t 0/2] " sai.gowtham.ch 2023-05-30 10:08 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 2023-05-30 19:39 ` Zbigniew Kempczyński 2023-06-01 5:11 ` Kamil Konieczny 2023-06-01 7:59 ` Kumar, Janga Rahul 2023-06-01 8:11 ` Ch, Sai Gowtham 2023-06-02 8:24 ` Zbigniew Kempczyński 2023-05-22 12:36 [igt-dev] [PATCH i-g-t 0/2] " sai.gowtham.ch 2023-05-22 12:36 ` [igt-dev] [PATCH i-g-t 1/2] lib/xe/xe_spin: " sai.gowtham.ch 2023-05-22 16:19 ` Zbigniew Kempczyński 2023-05-23 8:41 ` Ch, Sai Gowtham 2023-05-23 11:29 ` Zbigniew Kempczyński 2023-05-23 15:58 ` Zbigniew Kempczyński
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.