[PATCH i-g-t v2 08/66] lib/xe_eudebug: Add support for vm_bind events
Piatkowski, Dominik Karol
dominik.karol.piatkowski at intel.com
Thu Aug 1 11:28:35 UTC 2024
Comments below.
Thanks,
Dominik Karol
> -----Original Message-----
> From: Manszewski, Christoph <christoph.manszewski at intel.com>
> Sent: Tuesday, July 30, 2024 1:44 PM
> To: igt-dev at lists.freedesktop.org
> Cc: Kempczynski, Zbigniew <zbigniew.kempczynski at intel.com>; Kamil
> Konieczny <kamil.konieczny at linux.intel.com>; Grzegorzek, Dominik
> <dominik.grzegorzek at intel.com>; Patelczyk, Maciej
> <maciej.patelczyk at intel.com>; Piatkowski, Dominik Karol
> <dominik.karol.piatkowski at intel.com>; Sikora, Pawel
> <pawel.sikora at intel.com>; Hajda, Andrzej <andrzej.hajda at intel.com>;
> Kolanupaka Naveena <kolanupaka.naveena at intel.com>; Kuoppala, Mika
> <mika.kuoppala at intel.com>; Mun, Gwan-gyeong <gwan-
> gyeong.mun at intel.com>
> Subject: [PATCH i-g-t v2 08/66] lib/xe_eudebug: Add support for vm_bind
> events
>
> Add support for logging and filtering vm_bind events.
>
> Signed-off-by: Christoph Manszewski <christoph.manszewski at intel.com>
> Signed-off-by: Maciej Patelczyk <maciej.patelczyk at intel.com>
> Signed-off-by: Mika Kuoppala <mika.kuoppala at linux.intel.com>
> Cc: Dominik Grzegorzek <dominik.grzegorzek at intel.com>
> ---
> lib/xe/xe_eudebug.c | 488
> +++++++++++++++++++++++++++++++++++++++++---
> lib/xe/xe_eudebug.h | 45 +++-
> 2 files changed, 507 insertions(+), 26 deletions(-)
>
> diff --git a/lib/xe/xe_eudebug.c b/lib/xe/xe_eudebug.c index
> 8a57aaae3..2d1a7092c 100644
> --- a/lib/xe/xe_eudebug.c
> +++ b/lib/xe/xe_eudebug.c
> @@ -11,6 +11,7 @@
> #include <sys/wait.h>
>
> #include "igt.h"
> +#include "intel_pat.h"
> #include "xe_eudebug.h"
> #include "xe_ioctl.h"
>
> @@ -29,6 +30,12 @@ struct match_dto {
> struct drm_xe_eudebug_event *target;
> struct igt_list_head *seqno_list;
> uint64_t client_handle;
> + uint32_t filter;
> +
> + /* store latest 'EVENT_VM_BIND' seqno */
> + uint64_t *bind_seqno;
> + /* latest vm_bind_op seqno matching bind_seqno */
> + uint64_t *bind_op_seqno;
> };
>
> #define CLIENT_PID 1
> @@ -56,6 +63,12 @@ static const char *type_to_str(unsigned int type)
> return "exec_queue";
> case DRM_XE_EUDEBUG_EVENT_EU_ATTENTION:
> return "attention";
> + case DRM_XE_EUDEBUG_EVENT_VM_BIND:
> + return "vm_bind";
> + case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP:
> + return "vm_bind_op";
> + case DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE:
> + return "vm_bind_ufence";
> }
>
> return "UNKNOWN";
> @@ -70,15 +83,20 @@ static const char *event_type_to_str(struct
> drm_xe_eudebug_event *e, char *buf)
>
> static const char *flags_to_str(unsigned int flags) {
> - if (flags & DRM_XE_EUDEBUG_EVENT_CREATE)
> - return "create";
> -
> + if (flags & DRM_XE_EUDEBUG_EVENT_CREATE) {
> + if (flags & DRM_XE_EUDEBUG_EVENT_NEED_ACK)
> + return "create|ack";
> + else
> + return "create";
> + }
> if (flags & DRM_XE_EUDEBUG_EVENT_DESTROY)
> return "destroy";
>
> if (flags & DRM_XE_EUDEBUG_EVENT_STATE_CHANGE)
> return "state-change";
>
> + igt_assert(!(flags & DRM_XE_EUDEBUG_EVENT_NEED_ACK));
> +
> return "flags unknown";
> }
>
> @@ -116,6 +134,26 @@ static const char *event_members_to_str(struct
> drm_xe_eudebug_event *e, char *b)
> ea->lrc_handle, ea->bitmask_size);
> break;
> }
> + case DRM_XE_EUDEBUG_EVENT_VM_BIND: {
> + struct drm_xe_eudebug_event_vm_bind *evmb = (void *)e;
> +
> + sprintf(b, "client_handle=%llu, vm_handle=%llu, flags=0x%x,
> num_binds=%u",
> + evmb->client_handle, evmb->vm_handle, evmb-
> >flags, evmb->num_binds);
> + break;
> + }
> + case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP: {
> + struct drm_xe_eudebug_event_vm_bind_op *op = (void *)e;
> +
> + sprintf(b, "vm_bind_ref_seqno=%lld, addr=%016llx,
> range=%llu num_extensions=%llu",
> + op->vm_bind_ref_seqno, op->addr, op->range, op-
> >num_extensions);
> + break;
> + }
> + case DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE: {
> + struct drm_xe_eudebug_event_vm_bind_ufence *f = (void
> *)e;
> +
> + sprintf(b, "vm_bind_ref_seqno=%lld", f-
> >vm_bind_ref_seqno);
> + break;
> + }
> default:
> strcpy(b, "<...>");
> }
> @@ -362,6 +400,23 @@ static int match_fields(struct
> drm_xe_eudebug_event *a, void *data)
> ret = 1;
> break;
> }
> + case DRM_XE_EUDEBUG_EVENT_VM_BIND: {
> + struct drm_xe_eudebug_event_vm_bind *ea = (void *)a;
> + struct drm_xe_eudebug_event_vm_bind *eb = (void *)b;
> +
> + if (ea->num_binds == eb->num_binds)
> + ret = 1;
> + break;
> + }
> + case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP: {
> + struct drm_xe_eudebug_event_vm_bind_op *ea = (void *)a;
> + struct drm_xe_eudebug_event_vm_bind_op *eb = (void *)b;
> +
> + if (ea->addr == eb->addr && ea->range == eb->range &&
> + ea->num_extensions == eb->num_extensions)
> + ret = 1;
> + break;
> + }
> default:
> ret = 1;
> break;
> @@ -372,7 +427,13 @@ static int match_fields(struct
> drm_xe_eudebug_event *a, void *data)
>
> static int match_client_handle(struct drm_xe_eudebug_event *e, void *data)
> {
> - uint64_t h = *(uint64_t *)data;
> + struct match_dto *md = (void *)data;
> + uint64_t *bind_seqno = md->bind_seqno;
> + uint64_t *bind_op_seqno = md->bind_op_seqno;
> + uint64_t h = md->client_handle;
> +
> + if (XE_EUDEBUG_EVENT_IS_FILTERED(e->type, md->filter))
> + return 0;
>
> switch (e->type) {
> case DRM_XE_EUDEBUG_EVENT_OPEN: {
> @@ -396,6 +457,32 @@ static int match_client_handle(struct
> drm_xe_eudebug_event *e, void *data)
> return 1;
> break;
> }
> + case DRM_XE_EUDEBUG_EVENT_VM_BIND: {
> + struct drm_xe_eudebug_event_vm_bind *evmb = (struct
> +drm_xe_eudebug_event_vm_bind *)e;
> +
> + if (evmb->client_handle == h) {
> + *bind_seqno = evmb->base.seqno;
> + return 1;
> + }
> + break;
> + }
> + case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP: {
> + struct drm_xe_eudebug_event_vm_bind_op *eo = (struct
> +drm_xe_eudebug_event_vm_bind_op *)e;
> +
> + if (eo->vm_bind_ref_seqno == *bind_seqno) {
> + *bind_op_seqno = eo->base.seqno;
> + return 1;
> + }
> + break;
> + }
> + case DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE: {
> + struct drm_xe_eudebug_event_vm_bind_ufence *ef = (struct
> +drm_xe_eudebug_event_vm_bind_ufence *)e;
> +
> + if (ef->vm_bind_ref_seqno == *bind_seqno)
> + return 1;
> +
> + break;
> + }
> default:
> break;
> }
> @@ -410,6 +497,7 @@ static int match_opposite_resource(struct
> drm_xe_eudebug_event *e, void *data)
> int ret;
>
> d->flags ^= DRM_XE_EUDEBUG_EVENT_CREATE |
> DRM_XE_EUDEBUG_EVENT_DESTROY;
> + d->flags &= ~(DRM_XE_EUDEBUG_EVENT_NEED_ACK);
> ret = match_type_and_flags(e, data);
> d->flags ^= DRM_XE_EUDEBUG_EVENT_CREATE |
> DRM_XE_EUDEBUG_EVENT_DESTROY;
>
> @@ -441,6 +529,24 @@ static int match_opposite_resource(struct
> drm_xe_eudebug_event *e, void *data)
> return 1;
> break;
> }
> + case DRM_XE_EUDEBUG_EVENT_VM_BIND: {
> + struct drm_xe_eudebug_event_vm_bind *evmb = (void *)e;
> + struct drm_xe_eudebug_event_vm_bind *filter = (struct
> +drm_xe_eudebug_event_vm_bind *)data;
> +
> + if (evmb->vm_handle == filter->vm_handle &&
> + evmb->num_binds == filter->num_binds)
> + return 1;
> + break;
> + }
> + case DRM_XE_EUDEBUG_EVENT_VM_BIND_OP: {
> + struct drm_xe_eudebug_event_vm_bind_op *avmb = (void
> *)e;
> + struct drm_xe_eudebug_event_vm_bind_op *filter = (struct
> +drm_xe_eudebug_event_vm_bind_op *)data;
> +
> + if (avmb->addr == filter->addr &&
> + avmb->range == filter->range)
> + return 1;
> + break;
> + }
> default:
> break;
> }
> @@ -454,7 +560,7 @@ static int match_full(struct drm_xe_eudebug_event
> *e, void *data)
> struct match_dto *md = (void *)data;
> int ret = 0;
>
> - ret = match_client_handle(e, &md->client_handle);
> + ret = match_client_handle(e, md);
> if (!ret)
> return 0;
>
> @@ -472,51 +578,67 @@ static int match_full(struct
> drm_xe_eudebug_event *e, void *data)
>
> static struct drm_xe_eudebug_event *
> event_type_match(struct xe_eudebug_event_log *l,
> - struct drm_xe_eudebug_event *filter,
> + struct drm_xe_eudebug_event *target,
> struct drm_xe_eudebug_event *current) {
> - return event_cmp(l, current, match_type_and_flags, filter);
> + return event_cmp(l, current, match_type_and_flags, target);
> }
>
> static struct drm_xe_eudebug_event *
> client_match(struct xe_eudebug_event_log *l,
> uint64_t client_handle,
> - struct drm_xe_eudebug_event *current)
> + struct drm_xe_eudebug_event *current,
> + uint32_t filter,
> + uint64_t *bind_seqno,
> + uint64_t *bind_op_seqno)
> {
> - return event_cmp(l, current, match_client_handle, &client_handle);
> + struct match_dto md = {
> + .client_handle = client_handle,
> + .filter = filter,
> + .bind_seqno = bind_seqno,
> + .bind_op_seqno = bind_op_seqno,
> + };
> +
> + return event_cmp(l, current, match_client_handle, &md);
> }
>
> static struct drm_xe_eudebug_event *
> opposite_event_match(struct xe_eudebug_event_log *l,
> - struct drm_xe_eudebug_event *filter,
> + struct drm_xe_eudebug_event *target,
> struct drm_xe_eudebug_event *current) {
> - return event_cmp(l, current, match_opposite_resource, filter);
> + return event_cmp(l, current, match_opposite_resource, target);
> }
>
> static struct drm_xe_eudebug_event *
> event_match(struct xe_eudebug_event_log *l,
> struct drm_xe_eudebug_event *target,
> uint64_t client_handle,
> - struct igt_list_head *seqno_list)
> + struct igt_list_head *seqno_list,
> + uint64_t *bind_seqno,
> + uint64_t *bind_op_seqno)
> {
> struct match_dto md = {
> .target = target,
> .client_handle = client_handle,
> .seqno_list = seqno_list,
> + .bind_seqno = bind_seqno,
> + .bind_op_seqno = bind_op_seqno,
> };
>
> return event_cmp(l, NULL, match_full, &md); }
>
> static void compare_client(struct xe_eudebug_event_log *c, struct
> drm_xe_eudebug_event *_ce,
> - struct xe_eudebug_event_log *d, struct
> drm_xe_eudebug_event *_de)
> + struct xe_eudebug_event_log *d, struct
> drm_xe_eudebug_event *_de,
> + uint32_t filter)
> {
> struct drm_xe_eudebug_event_client *ce = (void *)_ce;
> struct drm_xe_eudebug_event_client *de = (void *)_de;
> - struct drm_xe_eudebug_event *hc, *hd;
> + uint64_t cbs = 0, dbs = 0, cbso = 0, dbso = 0;
>
> struct igt_list_head matched_seqno_list;
> + struct drm_xe_eudebug_event *hc, *hd;
> struct seqno_list_entry *entry, *tmp;
>
> igt_assert(ce);
> @@ -529,11 +651,11 @@ static void compare_client(struct
> xe_eudebug_event_log *c, struct drm_xe_eudebug
> IGT_INIT_LIST_HEAD(&matched_seqno_list);
>
> do {
> - hc = client_match(c, ce->client_handle, hc);
> + hc = client_match(c, ce->client_handle, hc, filter, &cbs, &cbso);
> if (!hc)
> break;
>
> - hd = event_match(d, hc, de->client_handle,
> &matched_seqno_list);
> + hd = event_match(d, hc, de->client_handle,
> &matched_seqno_list, &dbs,
> +&dbso);
>
> igt_assert_f(hd, "%s (%llu): no matching event type %u found
> for client %llu\n",
> c->name,
> @@ -720,11 +842,15 @@ xe_eudebug_event_log_print(struct
> xe_eudebug_event_log *l, bool debug)
> * xe_eudebug_event_log_compare:
> * @a: event log pointer
> * @b: event log pointer
> + * @filter: mask that represents events to be skipped during
> + comparison, useful
> + * for events like 'VM_BIND' since they can be asymmetric. Note that
> + * 'DRM_XE_EUDEUBG_EVENT_OPEN' will always be matched.
Typo: DRM_XE_EUDEBUG_EVENT_OPEN
> *
> * Compares and asserts event logs @a, @b if the event
> * sequence matches.
> */
> -void xe_eudebug_event_log_compare(struct xe_eudebug_event_log *a,
> struct xe_eudebug_event_log *b)
> +void xe_eudebug_event_log_compare(struct xe_eudebug_event_log *a,
> struct xe_eudebug_event_log *b,
> + uint32_t filter)
> {
> struct drm_xe_eudebug_event *ae = NULL;
> struct drm_xe_eudebug_event *be = NULL; @@ -734,8 +860,8 @@
> void xe_eudebug_event_log_compare(struct xe_eudebug_event_log *a, struct
> xe_eude
> ae->flags & DRM_XE_EUDEBUG_EVENT_CREATE) {
> be = event_type_match(b, ae, be);
>
> - compare_client(a, ae, b, be);
> - compare_client(b, be, a, ae);
> + compare_client(a, ae, b, be, filter);
> + compare_client(b, be, a, ae, filter);
> }
> }
> }
> @@ -743,11 +869,13 @@ void xe_eudebug_event_log_compare(struct
> xe_eudebug_event_log *a, struct xe_eude
> /**
> * xe_eudebug_event_log_match_opposite:
> * @l: event log pointer
> + * @filter: mask that represents events to be skipped during
> + comparison, useful
> + * for events like 'VM_BIND' since they can be asymmetric
> *
> * Matches and asserts content of all opposite events (create vs destroy).
> */
> void
> -xe_eudebug_event_log_match_opposite(struct xe_eudebug_event_log *l)
> +xe_eudebug_event_log_match_opposite(struct xe_eudebug_event_log *l,
> +uint32_t filter)
> {
> struct drm_xe_eudebug_event *ce = NULL;
> struct drm_xe_eudebug_event *de = NULL; @@ -757,6 +885,14 @@
> xe_eudebug_event_log_match_opposite(struct xe_eudebug_event_log *l)
> uint8_t offset = sizeof(struct
> drm_xe_eudebug_event);
> int opposite_matching;
>
> + if (XE_EUDEBUG_EVENT_IS_FILTERED(ce->type, filter))
> + continue;
> +
> + /* No opposite matching for binds */
> + if (ce->type >= DRM_XE_EUDEBUG_EVENT_VM_BIND
> &&
> + ce->type <=
> DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE)
> + continue;
> +
> de = opposite_event_match(l, ce, ce);
>
> igt_assert_f(de, "no opposite event of type %u
> found\n", ce->type); @@ -1267,15 +1403,17 @@ void
> xe_eudebug_session_run(struct xe_eudebug_session *s)
> * @s: pointer to xe_eudebug_session structure
> * @match_opposite: indicates whether check should match all
> * create and destroy events.
> + * @filter: mask that represents events to be skipped during
> + comparison, useful
> + * for events like 'VM_BIND' since they can be asymmetric
> *
> * Validate debugger's log against the log created by the client.
> */
> -void xe_eudebug_session_check(struct xe_eudebug_session *s, bool
> match_opposite)
> +void xe_eudebug_session_check(struct xe_eudebug_session *s, bool
> +match_opposite, uint32_t filter)
> {
> - xe_eudebug_event_log_compare(s->c->log, s->d->log);
> + xe_eudebug_event_log_compare(s->c->log, s->d->log, filter);
>
> if (match_opposite)
> - xe_eudebug_event_log_match_opposite(s->d->log);
> + xe_eudebug_event_log_match_opposite(s->d->log, filter);
> }
>
> /**
> @@ -1467,3 +1605,307 @@ void
> xe_eudebug_client_exec_queue_destroy(struct xe_eudebug_client *c, int fd,
>
> igt_assert_eq(igt_ioctl(fd, DRM_IOCTL_XE_EXEC_QUEUE_DESTROY,
> &destroy), 0); }
> +
> +/**
> + * xe_eudebug_client_vm_bind_event:
> + * @c: pointer to xe_eudebug_client structure
> + * @event_flags: base event flags
> + * @fd: xe client
> + * @vm: vm handle
> + * @bind_flags: bind flags of vm_bind_event
> + * @num_binds: number of bind (operations) for event
> + * @ref_seqno: base vm bind reference seqno
> + * Logs vm bind event in client's event log.
> + */
> +void xe_eudebug_client_vm_bind_event(struct xe_eudebug_client *c,
> + uint32_t event_flags, int fd,
> + uint32_t vm, uint32_t bind_flags,
> + uint32_t num_binds, u64 *ref_seqno) {
> + struct drm_xe_eudebug_event_vm_bind evmb;
> +
> + base_event(c, to_base(evmb),
> DRM_XE_EUDEBUG_EVENT_VM_BIND,
> + event_flags, sizeof(evmb));
> + evmb.client_handle = fd;
> + evmb.vm_handle = vm;
> + evmb.flags = bind_flags;
> + evmb.num_binds = num_binds;
> +
> + *ref_seqno = evmb.base.seqno;
> +
> + xe_eudebug_event_log_write(c->log, (void *)&evmb); }
> +
> +/**
> + * xe_eudebug_client_vm_bind_op_event:
> + * @c: pointer to xe_eudebug_client structure
> + * @event_flags: base event flags
> + * @bind_ref_seqno: base vm bind reference seqno
> + * @op_ref_seqno: output, the vm_bind_op event seqno
> + * @addr: ppgtt address
> + * @size: size of the binding
> + * @num_extensions: number of vm bind op extensions
> + *
> + * Logs vm bind op event in client's event log.
> + */
> +void xe_eudebug_client_vm_bind_op_event(struct xe_eudebug_client *c,
> uint32_t event_flags,
> + uint64_t bind_ref_seqno, uint64_t
> *op_ref_seqno,
> + uint64_t addr, uint64_t range,
> + uint64_t num_extensions)
> +{
> + struct drm_xe_eudebug_event_vm_bind_op op;
> +
> + base_event(c, to_base(op),
> DRM_XE_EUDEBUG_EVENT_VM_BIND_OP,
> + event_flags, sizeof(op));
> + op.vm_bind_ref_seqno = bind_ref_seqno;
> + op.addr = addr;
> + op.range = range;
> + op.num_extensions = num_extensions;
> +
> + *op_ref_seqno = op.base.seqno;
> +
> + xe_eudebug_event_log_write(c->log, (void *)&op); }
> +
> +/**
> + * xe_eudebug_client_vm_bind_op_metadata_event:
> + * @c: pointer to xe_eudebug_client structure
> + * @event_flags: base event flags
> + * @op_ref_seqno: base vm bind op reference seqno
> + * @metadata_handle: metadata handle
> + * @metadata_cookie: metadata cookie
> + *
> + * Logs vm bind op metadata event in client's event log.
> + */
> +void xe_eudebug_client_vm_bind_op_metadata_event(struct
> xe_eudebug_client *c,
> + uint32_t event_flags,
> uint64_t op_ref_seqno,
> + uint64_t metadata_handle,
> uint64_t metadata_cookie) {
> + struct drm_xe_eudebug_event_vm_bind_op_metadata op;
> +
> + base_event(c, to_base(op),
> DRM_XE_EUDEBUG_EVENT_VM_BIND_OP_METADATA,
> + event_flags, sizeof(op));
> + op.vm_bind_op_ref_seqno = op_ref_seqno;
> + op.metadata_handle = metadata_handle;
> + op.metadata_cookie = metadata_cookie;
> +
> + xe_eudebug_event_log_write(c->log, (void *)&op); }
> +
> +/**
> + * xe_eudebug_client_vm_bind_ufence_event:
> + * @c: pointer to xe_eudebug_client structure
> + * @event_flags: base event flags
> + * @ref_seqno: base vm bind event seqno
> + *
> + * Logs vm bind ufence event in client's event log.
> + */
> +void xe_eudebug_client_vm_bind_ufence_event(struct xe_eudebug_client
> *c, uint32_t event_flags,
> + uint64_t ref_seqno)
> +{
> + struct drm_xe_eudebug_event_vm_bind_ufence f;
> +
> + base_event(c, to_base(f),
> DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE,
> + event_flags, sizeof(f));
> + f.vm_bind_ref_seqno = ref_seqno;
> +
> + xe_eudebug_event_log_write(c->log, (void *)&f); }
> +
> +static bool has_user_fence(const struct drm_xe_sync *sync, uint32_t
> +num_syncs) {
> + while (num_syncs--)
> + if (sync[num_syncs].type ==
> DRM_XE_SYNC_TYPE_USER_FENCE)
> + return true;
> +
> + return false;
> +}
> +
> +#define for_each_metadata(__m, __ext)
> \
> + for ((__m) = from_user_pointer(__ext); \
> + (__m); \
> + (__m) = from_user_pointer((__m)->base.next_extension)) \
> + if ((__m)->base.name ==
> XE_VM_BIND_OP_EXTENSIONS_ATTACH_DEBUG)
> +
> +static int __xe_eudebug_client_vm_bind(struct xe_eudebug_client *c,
> + int fd, uint32_t vm, uint32_t
> exec_queue,
> + uint32_t bo, uint64_t offset,
> + uint64_t addr, uint64_t size,
> + uint32_t op, uint32_t flags,
> + struct drm_xe_sync *sync,
> + uint32_t num_syncs,
> + uint32_t prefetch_region,
> + uint8_t pat_index, uint64_t op_ext) {
> + struct drm_xe_vm_bind_op_ext_attach_debug *metadata;
> + const bool ufence = has_user_fence(sync, num_syncs);
> + const uint32_t bind_flags = ufence ?
> + DRM_XE_EUDEBUG_EVENT_VM_BIND_FLAG_UFENCE : 0;
> + uint64_t seqno = 0, op_seqno = 0, num_metadata = 0;
> + uint32_t bind_base_flags = 0;
> + int ret;
> +
> + for_each_metadata(metadata, op_ext)
> + num_metadata++;
> +
> + switch (op) {
> + case DRM_XE_VM_BIND_OP_MAP:
> + bind_base_flags = DRM_XE_EUDEBUG_EVENT_CREATE;
> + break;
> + case DRM_XE_VM_BIND_OP_UNMAP:
> + bind_base_flags = DRM_XE_EUDEBUG_EVENT_DESTROY;
> + igt_assert_eq(num_metadata, 0);
> + igt_assert_eq(ufence, false);
> + break;
> + default:
> + /* XXX unmap all? */
> + igt_assert(op);
> + break;
> + }
> +
> + ret = ___xe_vm_bind(fd, vm, exec_queue, bo, offset, addr, size,
> + op, flags, sync, num_syncs, prefetch_region,
> + pat_index, 0, op_ext);
> +
> + if (ret)
> + return ret;
> +
> + if (!bind_base_flags)
> + return -EINVAL;
> +
> + xe_eudebug_client_vm_bind_event(c,
> DRM_XE_EUDEBUG_EVENT_STATE_CHANGE,
> + fd, vm, bind_flags, 1, &seqno);
> + xe_eudebug_client_vm_bind_op_event(c, bind_base_flags,
> + seqno, &op_seqno, addr, size,
> + num_metadata);
> +
> + for_each_metadata(metadata, op_ext)
> + xe_eudebug_client_vm_bind_op_metadata_event(c,
> +
> DRM_XE_EUDEBUG_EVENT_CREATE,
> + op_seqno,
> + metadata-
> >metadata_id,
> + metadata->cookie);
> + if (ufence)
> + xe_eudebug_client_vm_bind_ufence_event(c,
> DRM_XE_EUDEBUG_EVENT_CREATE |
> +
> DRM_XE_EUDEBUG_EVENT_NEED_ACK,
> + seqno);
> + return ret;
> +}
> +
> +static void _xe_eudebug_client_vm_bind(struct xe_eudebug_client *c, int fd,
> + uint32_t vm, uint32_t bo,
> + uint64_t offset, uint64_t addr, uint64_t
> size,
> + uint32_t op,
> + uint32_t flags,
> + struct drm_xe_sync *sync,
> + uint32_t num_syncs,
> + uint64_t op_ext)
> +{
> + const uint32_t exec_queue_id = 0;
> + const uint32_t prefetch_region = 0;
> +
> + igt_assert_eq(__xe_eudebug_client_vm_bind(c, fd, vm,
> exec_queue_id, bo, offset,
> + addr, size, op, flags,
> + sync, num_syncs,
> prefetch_region,
> + DEFAULT_PAT_INDEX,
> op_ext),
> + 0);
> +}
> +
> +/**
> + * xe_eudebug_client_vm_bind_flags
> + * @c: pointer to xe_eudebug_client structure
> + * @fd: xe client
> + * @vm: vm handle
> + * @bo: buffer object handle
> + * @offset: offset within buffer object
> + * @addr: ppgtt address
> + * @size: size of the binding
> + * @flags: vm_bind flags
> + * @sync: sync objects
> + * @num_syncs: number of sync objects
> + * @op_ext: BIND_OP extensions
> + *
> + * Calls xe vm_bind ioctl and logs the corresponding event in client's event log.
> + */
> +void xe_eudebug_client_vm_bind_flags(struct xe_eudebug_client *c, int fd,
> uint32_t vm,
> + uint32_t bo, uint64_t offset,
> + uint64_t addr, uint64_t size, uint32_t flags,
> + struct drm_xe_sync *sync, uint32_t
> num_syncs,
> + uint64_t op_ext)
> +{
> + _xe_eudebug_client_vm_bind(c, fd, vm, bo, offset, addr, size,
> + DRM_XE_VM_BIND_OP_MAP, flags,
> + sync, num_syncs, op_ext);
> +}
> +
> +/**
> + * xe_eudebug_client_vm_bind
> + * @c: pointer to xe_eudebug_client structure
> + * @fd: xe client
> + * @vm: vm handle
> + * @bo: buffer object handle
> + * @offset: offset within buffer object
> + * @addr: ppgtt address
> + * @size: size of the binding
> + *
> + * Calls xe vm_bind ioctl and logs the corresponding event in client's event log.
> + */
> +void xe_eudebug_client_vm_bind(struct xe_eudebug_client *c, int fd,
> uint32_t vm,
> + uint32_t bo, uint64_t offset,
> + uint64_t addr, uint64_t size) {
> + const uint32_t flags = 0;
> + struct drm_xe_sync *sync = NULL;
> + const uint32_t num_syncs = 0;
> + const uint64_t op_ext = 0;
> +
> + xe_eudebug_client_vm_bind_flags(c, fd, vm, bo, offset, addr, size,
> + flags,
> + sync, num_syncs, op_ext);
> +}
> +
> +/**
> + * xe_eudebug_client_vm_unbind_flags
> + * @c: pointer to xe_eudebug_client structure
> + * @fd: xe client
> + * @vm: vm handle
> + * @offset: offset
> + * @addr: ppgtt address
> + * @size: size of the binding
> + * @flags: vm_bind flags
> + * @sync: sync objects
> + * @num_syncs: number of sync objects
> + *
> + * Calls xe vm_unbind ioctl and logs the corresponding event in client's event
> log.
> + */
> +void xe_eudebug_client_vm_unbind_flags(struct xe_eudebug_client *c, int
> fd,
> + uint32_t vm, uint64_t offset,
> + uint64_t addr, uint64_t size, uint32_t
> flags,
> + struct drm_xe_sync *sync, uint32_t
> num_syncs) {
> + _xe_eudebug_client_vm_bind(c, fd, vm, 0, offset, addr, size,
> + DRM_XE_VM_BIND_OP_UNMAP, flags,
> + sync, num_syncs, 0);
> +}
> +
> +/**
> + * xe_eudebug_client_vm_unbind
> + * @c: pointer to xe_eudebug_client structure
> + * @fd: xe client
> + * @vm: vm handle
> + * @offset: offset
> + * @addr: ppgtt address
> + * @size: size of the binding
> + *
> + * Calls xe vm_unbind ioctl and logs the corresponding event in client's event
> log.
> + */
> +void xe_eudebug_client_vm_unbind(struct xe_eudebug_client *c, int fd,
> uint32_t vm,
> + uint64_t offset, uint64_t addr, uint64_t size)
> {
> + const uint32_t flags = 0;
> + struct drm_xe_sync *sync = NULL;
> + const uint32_t num_syncs = 0;
> +
> + xe_eudebug_client_vm_unbind_flags(c, fd, vm, offset, addr, size,
> + flags, sync, num_syncs);
> +}
> diff --git a/lib/xe/xe_eudebug.h b/lib/xe/xe_eudebug.h index
> 8dc153d27..1592704ab 100644
> --- a/lib/xe/xe_eudebug.h
> +++ b/lib/xe/xe_eudebug.h
> @@ -99,6 +99,18 @@ typedef void (*xe_eudebug_trigger_fn)(struct
> xe_eudebug_debugger *,
> */
> #define XE_EUDEBUG_DEFAULT_TIMEOUT_MS 25000ULL
>
> +#define XE_EUDEBUG_FILTER_EVENT_NONE
> BIT(DRM_XE_EUDEBUG_EVENT_NONE)
> +#define XE_EUDEBUG_FILTER_EVENT_READ
> BIT(DRM_XE_EUDEBUG_EVENT_READ)
> +#define XE_EUDEBUG_FILTER_EVENT_OPEN
> BIT(DRM_XE_EUDEBUG_EVENT_OPEN)
> +#define XE_EUDEBUG_FILTER_EVENT_VM
> BIT(DRM_XE_EUDEBUG_EVENT_VM)
> +#define XE_EUDEBUG_FILTER_EVENT_EXEC_QUEUE
> BIT(DRM_XE_EUDEBUG_EVENT_EXEC_QUEUE)
> +#define XE_EUDEBUG_FILTER_EVENT_EU_ATTENTION
> BIT(DRM_XE_EUDEBUG_EVENT_EU_ATTENTION)
> +#define XE_EUDEBUG_FILTER_EVENT_VM_BIND
> BIT(DRM_XE_EUDEBUG_EVENT_VM_BIND)
> +#define XE_EUDEBUG_FILTER_EVENT_VM_BIND_OP
> BIT(DRM_XE_EUDEBUG_EVENT_VM_BIND_OP)
> +#define XE_EUDEBUG_FILTER_EVENT_VM_BIND_UFENCE
> BIT(DRM_XE_EUDEBUG_EVENT_VM_BIND_UFENCE)
> +#define XE_EUDEUBG_FILTER_ALL
Typo: XE_EUDEBUG_FILTER_ALL
> GENMASK(DRM_XE_EUDEBUG_EVENT_MAX_EVENT, 0)
> +#define XE_EUDEBUG_EVENT_IS_FILTERED(_e, _f) ((1UL << _e) & _f)
> +
> const char *xe_eudebug_event_to_str(struct drm_xe_eudebug_event *e,
> char *buf, size_t len); struct drm_xe_eudebug_event *
> xe_eudebug_event_log_find_seqno(struct xe_eudebug_event_log *l, uint64_t
> seqno); @@ -106,9 +118,10 @@ struct xe_eudebug_event_log *
> xe_eudebug_event_log_create(const char *name, unsigned int max_size);
> void xe_eudebug_event_log_destroy(struct xe_eudebug_event_log *l); void
> xe_eudebug_event_log_print(struct xe_eudebug_event_log *l, bool debug); -
> void xe_eudebug_event_log_compare(struct xe_eudebug_event_log *c, struct
> xe_eudebug_event_log *d);
> +void xe_eudebug_event_log_compare(struct xe_eudebug_event_log *c,
> struct xe_eudebug_event_log *d,
> + uint32_t filter);
> void xe_eudebug_event_log_write(struct xe_eudebug_event_log *l, struct
> drm_xe_eudebug_event *e); -void
> xe_eudebug_event_log_match_opposite(struct xe_eudebug_event_log *l);
> +void xe_eudebug_event_log_match_opposite(struct xe_eudebug_event_log
> +*l, uint32_t filter);
>
> struct xe_eudebug_debugger *
> xe_eudebug_debugger_create(int xe, uint64_t flags, void *data); @@ -142,6
> +155,32 @@ uint32_t xe_eudebug_client_exec_queue_create(struct
> xe_eudebug_client *c, int fd
> struct drm_xe_exec_queue_create
> *create); void xe_eudebug_client_exec_queue_destroy(struct
> xe_eudebug_client *c, int fd,
> struct drm_xe_exec_queue_create
> *create);
> +void xe_eudebug_client_vm_bind_event(struct xe_eudebug_client *c,
> uint32_t event_flags, int fd,
> + uint32_t vm, uint32_t bind_flags,
> + uint32_t num_ops, uint64_t *ref_seqno);
> void
> +xe_eudebug_client_vm_bind_op_event(struct xe_eudebug_client *c,
> uint32_t event_flags,
> + uint64_t ref_seqno, uint64_t
> *op_ref_seqno,
> + uint64_t addr, uint64_t range,
> + uint64_t num_extensions);
> +void xe_eudebug_client_vm_bind_op_metadata_event(struct
> xe_eudebug_client *c,
> + uint32_t event_flags,
> uint64_t op_ref_seqno,
> + uint64_t metadata_handle,
> uint64_t metadata_cookie); void
> +xe_eudebug_client_vm_bind_ufence_event(struct xe_eudebug_client *c,
> uint32_t event_flags,
> + uint64_t ref_seqno);
> +void xe_eudebug_client_vm_bind_flags(struct xe_eudebug_client *c, int fd,
> uint32_t vm,
> + uint32_t bo, uint64_t offset,
> + uint64_t addr, uint64_t size, uint32_t flags,
> + struct drm_xe_sync *sync, uint32_t
> num_syncs,
> + uint64_t op_ext);
> +void xe_eudebug_client_vm_bind(struct xe_eudebug_client *c, int fd,
> uint32_t vm,
> + uint32_t bo, uint64_t offset,
> + uint64_t addr, uint64_t size); void
> +xe_eudebug_client_vm_unbind_flags(struct xe_eudebug_client *c, int fd,
> + uint32_t vm, uint64_t offset,
> + uint64_t addr, uint64_t size, uint32_t
> flags,
> + struct drm_xe_sync *sync, uint32_t
> num_syncs); void
> +xe_eudebug_client_vm_unbind(struct xe_eudebug_client *c, int fd, uint32_t
> vm,
> + uint64_t offset, uint64_t addr, uint64_t size);
>
> struct xe_eudebug_session *xe_eudebug_session_create(int fd,
>
> xe_eudebug_client_work_fn work, @@ -149,4 +188,4 @@ struct
> xe_eudebug_session *xe_eudebug_session_create(int fd,
> void *test_private);
> void xe_eudebug_session_destroy(struct xe_eudebug_session *s); void
> xe_eudebug_session_run(struct xe_eudebug_session *s); -void
> xe_eudebug_session_check(struct xe_eudebug_session *s, bool
> match_opposite);
> +void xe_eudebug_session_check(struct xe_eudebug_session *s, bool
> +match_opposite, uint32_t filter);
> --
> 2.34.1
More information about the igt-dev
mailing list