[PATCH i-g-t v5 11/17] lib/xe_eudebug: Introduce eu debug testing framework
Zbigniew Kempczyński
zbigniew.kempczynski at intel.com
Tue Sep 3 06:21:08 UTC 2024
On Thu, Aug 29, 2024 at 04:45:41PM +0200, Christoph Manszewski wrote:
<cut>
> diff --git a/lib/xe/xe_eudebug.h b/lib/xe/xe_eudebug.h
> new file mode 100644
> index 000000000..d6c37d8f2
> --- /dev/null
> +++ b/lib/xe/xe_eudebug.h
> @@ -0,0 +1,212 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2023 Intel Corporation
> + */
> +#include <fcntl.h>
> +#include <pthread.h>
> +#include <stdint.h>
> +#include <xe_drm.h>
> +#include <xe_drm_eudebug.h>
> +
> +#include "igt_list.h"
> +
> +struct xe_eudebug_event_log {
> + uint8_t *log;
> + unsigned int head;
> + unsigned int max_size;
> + char name[80];
> + pthread_mutex_t lock;
> +};
> +
> +struct xe_eudebug_debugger {
> + int fd;
> + uint64_t flags;
> +
> + /* Used to smuggle private data */
> + void *ptr;
> +
> + struct xe_eudebug_event_log *log;
> +
> + uint64_t event_count;
> +
> + uint64_t target_pid;
uint64_t
> +
> + struct igt_list_head triggers;
> +
> + int master_fd;
> +
> + pthread_t worker_thread;
> + int worker_state;
> +
> + int p_client[2];
> +};
> +
> +struct xe_eudebug_client {
> + int pid;
int, I think you should use int or pid_t for both.
It would be good to add some comments how this library part is working
and how to use it.
> + uint64_t seqno;
> + uint64_t flags;
> +
> + /* Used to smuggle private data */
> + void *ptr;
> +
> + struct xe_eudebug_event_log *log;
> +
> + int done;
> + int p_in[2];
> + int p_out[2];
> +
> + /* Used to pickup right device (the one used in debugger) */
> + int master_fd;
> +
> + int timeout_ms;
> +};
> +
> +struct xe_eudebug_session {
> + uint64_t flags;
> + struct xe_eudebug_client *c;
> + struct xe_eudebug_debugger *d;
> +};
> +
> +typedef void (*xe_eudebug_client_work_fn)(struct xe_eudebug_client *);
> +typedef void (*xe_eudebug_trigger_fn)(struct xe_eudebug_debugger *,
> + struct drm_xe_eudebug_event *);
> +
> +#define xe_eudebug_for_each_engine(fd__, hwe__) \
> + xe_for_each_engine(fd__, hwe__) \
> + if (hwe__->engine_class == DRM_XE_ENGINE_CLASS_RENDER || \
> + hwe__->engine_class == DRM_XE_ENGINE_CLASS_COMPUTE)
> +
> +#define xe_eudebug_for_each_event(_e, _log) \
> + for ((_e) = (_e) ? (void *)(uint8_t *)(_e) + (_e)->len : \
> + (void *)(_log)->log; \
> + (uint8_t *)(_e) < (_log)->log + (_log)->head; \
> + (_e) = (void *)(uint8_t *)(_e) + (_e)->len)
> +
> +#define xe_eudebug_assert(d, c) \
> + do { \
> + if (!(c)) { \
> + xe_eudebug_event_log_print((d)->log, true); \
> + igt_assert(c); \
> + } \
> + } while (0)
> +
> +#define xe_eudebug_assert_f(d, c, f...) \
> + do { \
> + if (!(c)) { \
> + xe_eudebug_event_log_print((d)->log, true); \
> + igt_assert_f(c, f); \
> + } \
> + } while (0)
> +
> +#define XE_EUDEBUG_EVENT_STRING_MAX_LEN 4096
> +
> +/*
> + * Default abort timeout to use across xe_eudebug lib and tests if no specific
> + * timeout value is required.
> + */
> +#define XE_EUDEBUG_DEFAULT_TIMEOUT_SEC 25ULL
> +
> +#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_EUDEBUG_FILTER_ALL GENMASK(DRM_XE_EUDEBUG_EVENT_MAX_EVENT, 0)
> +#define XE_EUDEBUG_EVENT_IS_FILTERED(_e, _f) ((1UL << (_e)) & (_f))
> +
> +int xe_eudebug_connect(int fd, pid_t pid, uint32_t flags);
> +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);
> +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,
> + 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, uint32_t filter);
> +
> +bool xe_eudebug_debugger_available(int fd);
> +struct xe_eudebug_debugger *
> +xe_eudebug_debugger_create(int xe, uint64_t flags, void *data);
> +void xe_eudebug_debugger_destroy(struct xe_eudebug_debugger *d);
> +int xe_eudebug_debugger_attach(struct xe_eudebug_debugger *d, struct xe_eudebug_client *c);
> +void xe_eudebug_debugger_start_worker(struct xe_eudebug_debugger *d);
> +void xe_eudebug_debugger_stop_worker(struct xe_eudebug_debugger *d, int timeout_s);
> +void xe_eudebug_debugger_dettach(struct xe_eudebug_debugger *d);
> +void xe_eudebug_debugger_set_data(struct xe_eudebug_debugger *c, void *ptr);
> +void xe_eudebug_debugger_add_trigger(struct xe_eudebug_debugger *d, int type,
> + xe_eudebug_trigger_fn fn);
> +void xe_eudebug_debugger_signal_stage(struct xe_eudebug_debugger *d, uint64_t stage);
> +void xe_eudebug_debugger_wait_stage(struct xe_eudebug_session *s, uint64_t stage);
> +
> +struct xe_eudebug_client *
> +xe_eudebug_client_create(int xe, xe_eudebug_client_work_fn work, uint64_t flags, void *data);
> +void xe_eudebug_client_destroy(struct xe_eudebug_client *c);
> +void xe_eudebug_client_start(struct xe_eudebug_client *c);
> +void xe_eudebug_client_stop(struct xe_eudebug_client *c);
> +void xe_eudebug_client_wait_done(struct xe_eudebug_client *c);
> +void xe_eudebug_client_signal_stage(struct xe_eudebug_client *c, uint64_t stage);
> +void xe_eudebug_client_wait_stage(struct xe_eudebug_client *c, uint64_t stage);
> +
> +uint64_t xe_eudebug_client_get_seqno(struct xe_eudebug_client *c);
> +void xe_eudebug_client_set_data(struct xe_eudebug_client *c, void *ptr);
> +
> +bool xe_eudebug_enable(int fd, bool enable);
> +
> +int xe_eudebug_client_open_driver(struct xe_eudebug_client *c);
> +void xe_eudebug_client_close_driver(struct xe_eudebug_client *c, int fd);
> +uint32_t xe_eudebug_client_vm_create(struct xe_eudebug_client *c, int fd,
> + uint32_t flags, uint64_t ext);
> +void xe_eudebug_client_vm_destroy(struct xe_eudebug_client *c, int fd, uint32_t vm);
> +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_ack_ufence(int debugfd,
> + const struct drm_xe_eudebug_event_vm_bind_ufence *f);
> +
> +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);
> +
> +uint32_t xe_eudebug_client_metadata_create(struct xe_eudebug_client *c, int fd,
> + int type, size_t len, void *data);
> +void xe_eudebug_client_metadata_destroy(struct xe_eudebug_client *c, int fd,
> + uint32_t id, int type, size_t len);
> +
> +struct xe_eudebug_session *xe_eudebug_session_create(int fd,
> + xe_eudebug_client_work_fn work,
> + unsigned int flags,
> + 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, uint32_t filter);
> diff --git a/meson.build b/meson.build
> index 25bf1e442..207b5819b 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -90,9 +90,11 @@ build_chamelium = get_option('chamelium')
> build_docs = get_option('docs')
> build_tests = not get_option('tests').disabled()
> build_xe = not get_option('xe_driver').disabled()
> +build_xe_eudebug = get_option('xe_eudebug').enabled()
> with_libdrm = get_option('libdrm_drivers')
>
> build_info = ['Build type: ' + get_option('buildtype')]
> +build_info += 'Build Xe EU debugger test framework: @0@'.format(build_xe_eudebug)
>
> inc = include_directories('include', 'include/drm-uapi', 'include/linux-uapi', 'lib', 'lib/stubs/syscalls', '.')
>
> diff --git a/meson_options.txt b/meson_options.txt
> index 6a9493ea6..11922523b 100644
> --- a/meson_options.txt
> +++ b/meson_options.txt
> @@ -42,6 +42,11 @@ option('xe_driver',
> value : 'enabled',
> description : 'Build tests for Xe driver')
>
> +option('xe_eudebug',
> + type : 'feature',
> + value : 'disabled',
> + description : 'Build library for Xe EU debugger')
> +
Good. You've hidden the code behind the option. We may improve it later
but before I'll give my ack here I would like to know more about the
seqno duplicates issue mentioned in my previous email.
--
Zbigniew
> option('libdrm_drivers',
> type : 'array',
> value : ['auto'],
> --
> 2.34.1
>
More information about the igt-dev
mailing list