[PATCH i-g-t v2 15/66] tests/xe_eudebug: Race discovery against eudebug attach.
Piatkowski, Dominik Karol
dominik.karol.piatkowski at intel.com
Thu Aug 1 12:08:41 UTC 2024
Comment below.
Thanks,
Dominik Karol
> -----Original Message-----
> From: Manszewski, Christoph <christoph.manszewski at intel.com>
> Sent: Tuesday, July 30, 2024 1:45 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 15/66] tests/xe_eudebug: Race discovery against
> eudebug attach.
>
> From: Dominik Grzegorzek <dominik.grzegorzek at intel.com>
>
> Validate eu debug resource discovery in a pretty cruel way.
> Add subtests:
>
> 1) discovery-race - spawns N client proccesses, which create
> N+N*N resources each, then it creates M debugger
> threads competing for an access to the client proccess. After
> successful attach, with probability of 0.5 read and assert
> discovered resources, immediately detach otherwise.
>
> 2) discovery-empty[|-clients] - same as 1#, but destroy
> resources in flight (explicetly or by closing the client).
Typo: explicitly
> Expect the last discovery not sending any events.
>
> Currently N = 4, M = 3.
>
> Signed-off-by: Dominik Grzegorzek <dominik.grzegorzek at intel.com>
> Signed-off-by: Karolina Stolarek <karolina.stolarek at intel.com>
> Cc: Christoph Manszewski <christoph.manszewski at intel.com>
> ---
> tests/intel/xe_eudebug.c | 254
> +++++++++++++++++++++++++++++++++++++++
> 1 file changed, 254 insertions(+)
>
> diff --git a/tests/intel/xe_eudebug.c b/tests/intel/xe_eudebug.c index
> 7c1c21a33..d97e7914e 100644
> --- a/tests/intel/xe_eudebug.c
> +++ b/tests/intel/xe_eudebug.c
> @@ -282,6 +282,251 @@ static void test_basic_sessions(int fd, unsigned int
> flags, int count)
> xe_eudebug_session_destroy(s[i]);
> }
>
> +#define RESOURCE_COUNT 16
> +#define PRIMARY_THREAD (1 << 0)
> +#define DISCOVERY_CLOSE_CLIENT (1 << 1)
> +#define DISCOVERY_DESTROY_RESOURCES (1 << 2)
> +static void run_discovery_client(struct xe_eudebug_client *c) {
> + int fd[RESOURCE_COUNT], i;
> + bool skip_sleep = c->flags & (DISCOVERY_DESTROY_RESOURCES |
> +DISCOVERY_CLOSE_CLIENT);
> +
> + srand(getpid());
> +
> + for (i = 0; i < RESOURCE_COUNT; i++) {
> + fd[i] = xe_eudebug_client_open_driver(c);
> +
> + /*
> + * Give the debugger a break in event stream after every
> + * other client, that allows to read discovery and dettach in
> quiet.
> + */
> + if (random() % 2 == 0 && !skip_sleep)
> + sleep(1);
> +
> + for (int j = 0; j < RESOURCE_COUNT; j++) {
> + uint32_t vm = xe_eudebug_client_vm_create(c, fd[i],
> 0, 0);
> +
> + if (c->flags & DISCOVERY_DESTROY_RESOURCES)
> + xe_eudebug_client_vm_destroy(c, fd[i], vm);
> + }
> +
> + if (c->flags & DISCOVERY_CLOSE_CLIENT)
> + xe_eudebug_client_close_driver(c, fd[i]);
> + }
> +}
> +
> +/**
> + * SUBTEST: discovery-%s
> + * Description: Race discovery against %arg[1] and the debugger dettach.
> + *
> + * arg[1]:
> + *
> + * @race: resources creation
> + * @empty: resources destruction
> + * @empty-clients: client closure
> + */
> +static void *discovery_race_thread(void *data) {
> + struct {
> + uint64_t client_handle;
> + int vm_count;
> + } clients[RESOURCE_COUNT];
> + struct xe_eudebug_session *s = data;
> + int expected = RESOURCE_COUNT * (1 + RESOURCE_COUNT);
> + const int tries = 100;
> + bool done = false;
> + int ret = 0;
> +
> + for (int try = 0; try < tries && !done; try++) {
> +
> + ret = xe_eudebug_debugger_attach(s->d, s->c);
> +
> + if (ret == -EBUSY) {
> + usleep(100000);
> + continue;
> + }
> +
> + igt_assert_eq(ret, 0);
> +
> + if (random() % 2) {
> + struct drm_xe_eudebug_event *e = NULL;
> + int i = -1;
> +
> + xe_eudebug_debugger_start_worker(s->d);
> + sleep(1);
> + xe_eudebug_debugger_stop_worker(s->d, 1);
> + igt_debug("Resources discovered: %lu\n", s->d-
> >event_count);
> +
> + xe_eudebug_for_each_event(e, s->d->log) {
> + if (e->type ==
> DRM_XE_EUDEBUG_EVENT_OPEN) {
> + struct drm_xe_eudebug_event_client
> *eo = (void *)e;
> +
> + if (i >= 0) {
> +
> igt_assert_eq(clients[i].vm_count,
> +
> RESOURCE_COUNT);
> + }
> +
> + igt_assert(++i < RESOURCE_COUNT);
> + clients[i].client_handle = eo-
> >client_handle;
> + clients[i].vm_count = 0;
> + }
> +
> + if (e->type ==
> DRM_XE_EUDEBUG_EVENT_VM)
> + clients[i].vm_count++;
> + };
> +
> + igt_assert_lte(0, i);
> +
> + for (int j = 0; j < i; j++)
> + for (int k = 0; k < i; k++) {
> + if (k == j)
> + continue;
> +
> +
> igt_assert_neq(clients[j].client_handle,
> + clients[k].client_handle);
> + }
> +
> + if (s->d->event_count >= expected)
> + done = true;
> + }
> +
> + xe_eudebug_debugger_dettach(s->d);
> + s->d->log->head = 0;
> + s->d->event_count = 0;
> + }
> +
> + /* Primary thread must read everything */
> + if (s->flags & PRIMARY_THREAD) {
> + while ((ret = xe_eudebug_debugger_attach(s->d, s->c)) == -
> EBUSY)
> + usleep(100000);
> +
> + igt_assert_eq(ret, 0);
> +
> + xe_eudebug_debugger_start_worker(s->d);
> + xe_eudebug_client_wait_done(s->c);
> +
> + if (READ_ONCE(s->d->event_count) != expected)
> + sleep(5);
> +
> + xe_eudebug_debugger_stop_worker(s->d, 1);
> + xe_eudebug_debugger_dettach(s->d);
> + }
> +
> + return NULL;
> +}
> +
> +static void test_race_discovery(int fd, unsigned int flags, int
> +clients) {
> + const int debuggers_per_client = 3;
> + int count = clients * debuggers_per_client;
> + struct xe_eudebug_session *sessions, *s;
> + struct xe_eudebug_client *c;
> + pthread_t *threads;
> + int i, j;
> +
> + sessions = calloc(count, sizeof(*sessions));
> + threads = calloc(count, sizeof(*threads));
> +
> + for (i = 0; i < clients; i++) {
> + c = xe_eudebug_client_create(fd, run_discovery_client, flags,
> NULL);
> + for (j = 0; j < debuggers_per_client; j++) {
> + s = &sessions[i * debuggers_per_client + j];
> + s->c = c;
> + s->d = xe_eudebug_debugger_create(fd, flags, NULL);
> + s->flags = flags | (!j ? PRIMARY_THREAD : 0);
> + }
> + }
> +
> + for (i = 0; i < count; i++) {
> + if (sessions[i].flags & PRIMARY_THREAD)
> + xe_eudebug_client_start(sessions[i].c);
> +
> + pthread_create(&threads[i], NULL, discovery_race_thread,
> &sessions[i]);
> + }
> +
> + for (i = 0; i < count; i++)
> + pthread_join(threads[i], NULL);
> +
> + for (i = count - 1; i > 0; i--) {
> + if (sessions[i].flags & PRIMARY_THREAD) {
> + igt_assert_eq(sessions[i].c->seqno-1, sessions[i].d-
> >event_count);
> +
> + xe_eudebug_event_log_compare(sessions[0].d->log,
> + sessions[i].d->log, 0);
> +
> + xe_eudebug_client_destroy(sessions[i].c);
> + }
> + xe_eudebug_debugger_destroy(sessions[i].d);
> + }
> +}
> +
> +static void *attach_dettach_thread(void *data) {
> + struct xe_eudebug_session *s = data;
> + const int tries = 100;
> + int ret = 0;
> +
> + for (int try = 0; try < tries; try++) {
> +
> + ret = xe_eudebug_debugger_attach(s->d, s->c);
> +
> + if (ret == -EBUSY) {
> + usleep(100000);
> + continue;
> + }
> +
> + igt_assert_eq(ret, 0);
> +
> + if (random() % 2 == 0) {
> + xe_eudebug_debugger_start_worker(s->d);
> + xe_eudebug_debugger_stop_worker(s->d, 1);
> + }
> +
> + xe_eudebug_debugger_dettach(s->d);
> + s->d->log->head = 0;
> + s->d->event_count = 0;
> + }
> +
> + return NULL;
> +}
> +
> +static void test_empty_discovery(int fd, unsigned int flags, int
> +clients) {
> + struct xe_eudebug_session **s;
> + pthread_t *threads;
> + int i, expected = flags & DISCOVERY_CLOSE_CLIENT ? 0 :
> RESOURCE_COUNT;
> +
> + igt_assert(flags & (DISCOVERY_DESTROY_RESOURCES |
> +DISCOVERY_CLOSE_CLIENT));
> +
> + s = calloc(clients, sizeof(struct xe_eudebug_session *));
> + threads = calloc(clients, sizeof(*threads));
> +
> + for (i = 0; i < clients; i++)
> + s[i] = xe_eudebug_session_create(fd, run_discovery_client,
> flags,
> +NULL);
> +
> + for (i = 0; i < clients; i++) {
> + xe_eudebug_client_start(s[i]->c);
> +
> + pthread_create(&threads[i], NULL, attach_dettach_thread,
> s[i]);
> + }
> +
> + for (i = 0; i < clients; i++)
> + pthread_join(threads[i], NULL);
> +
> + for (i = 0; i < clients; i++) {
> + xe_eudebug_client_wait_done(s[i]->c);
> + igt_assert_eq(xe_eudebug_debugger_attach(s[i]->d, s[i]->c),
> 0);
> +
> + xe_eudebug_debugger_start_worker(s[i]->d);
> + xe_eudebug_debugger_stop_worker(s[i]->d, 5);
> + xe_eudebug_debugger_dettach(s[i]->d);
> +
> + igt_assert_eq(s[i]->d->event_count, expected);
> +
> + xe_eudebug_session_destroy(s[i]);
> + }
> +}
> +
> igt_main
> {
> int fd;
> @@ -308,6 +553,15 @@ igt_main
> igt_subtest("basic-vms")
> test_basic_sessions(fd, CREATE_VMS, 1);
>
> + igt_subtest("discovery-race")
> + test_race_discovery(fd, 0, 4);
> +
> + igt_subtest("discovery-empty")
> + test_empty_discovery(fd, DISCOVERY_CLOSE_CLIENT, 16);
> +
> + igt_subtest("discovery-empty-clients")
> + test_empty_discovery(fd, DISCOVERY_DESTROY_RESOURCES,
> 16);
> +
> igt_fixture
> drm_close_driver(fd);
> }
> --
> 2.34.1
More information about the igt-dev
mailing list