* [igt-dev] [PATCH] lib/igt_dummyload: Use timerfd rather than SIGEV_THREAD
@ 2020-03-31 11:19 Michał Winiarski
2020-03-31 11:27 ` Chris Wilson
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Michał Winiarski @ 2020-03-31 11:19 UTC (permalink / raw)
To: igt-dev; +Cc: Michał Winiarski, Chris Wilson
From: Michał Winiarski <michal.winiarski@intel.com>
Since timer_delete doesn't give us any guarantees that the thread and
its notify_function isn't currently running, we can hit a use-after-free
in a race condition scenario.
This causes a seemingly random segfault when igt_spin_end from notify
thread is called after igt_spin_free was already called from the main
thread.
Let's fix that by using timerfd and managing the timer thread ourselves.
Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
lib/igt_dummyload.c | 42 +++++++++++++++++++++++++-----------------
lib/igt_dummyload.h | 3 ++-
2 files changed, 27 insertions(+), 18 deletions(-)
diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c
index 657c3c64..694d907d 100644
--- a/lib/igt_dummyload.c
+++ b/lib/igt_dummyload.c
@@ -26,6 +26,7 @@
#include <signal.h>
#include <pthread.h>
#include <sys/poll.h>
+#include <sys/timerfd.h>
#include <i915_drm.h>
@@ -394,11 +395,20 @@ igt_spin_factory(int fd, const struct igt_spin_factory *opts)
return spin;
}
-static void notify(union sigval arg)
+static void *timer_thread(void *data)
{
- igt_spin_t *spin = arg.sival_ptr;
+ igt_spin_t *spin = data;
+ struct pollfd pfd;
+ int ret;
- igt_spin_end(spin);
+ pfd.fd = spin->timerfd;
+ pfd.events = POLLIN;
+
+ ret = poll(&pfd, 1, -1);
+ if (ret >= 0)
+ igt_spin_end(spin);
+
+ return NULL;
}
/**
@@ -412,29 +422,24 @@ static void notify(union sigval arg)
*/
void igt_spin_set_timeout(igt_spin_t *spin, int64_t ns)
{
- timer_t timer;
- struct sigevent sev;
struct itimerspec its;
+ int timerfd;
igt_assert(ns > 0);
if (!spin)
return;
- igt_assert(!spin->timer);
+ igt_assert(!spin->timerfd);
+ timerfd = timerfd_create(CLOCK_MONOTONIC, 0);
+ igt_assert(timerfd >= 0);
+ spin->timerfd = timerfd;
- memset(&sev, 0, sizeof(sev));
- sev.sigev_notify = SIGEV_THREAD;
- sev.sigev_value.sival_ptr = spin;
- sev.sigev_notify_function = notify;
- igt_assert(timer_create(CLOCK_MONOTONIC, &sev, &timer) == 0);
- igt_assert(timer);
+ pthread_create(&spin->timer_thread, NULL, timer_thread, spin);
memset(&its, 0, sizeof(its));
its.it_value.tv_sec = ns / NSEC_PER_SEC;
its.it_value.tv_nsec = ns % NSEC_PER_SEC;
- igt_assert(timer_settime(timer, 0, &its, NULL) == 0);
-
- spin->timer = timer;
+ igt_assert(timerfd_settime(timerfd, 0, &its, NULL) == 0);
}
/**
@@ -484,8 +489,11 @@ void igt_spin_free(int fd, igt_spin_t *spin)
igt_list_del(&spin->link);
pthread_mutex_unlock(&list_lock);
- if (spin->timer)
- timer_delete(spin->timer);
+ if (spin->timerfd) {
+ pthread_cancel(spin->timer_thread);
+ igt_assert(pthread_join(spin->timer_thread, NULL) == 0);
+ close(spin->timerfd);
+ }
igt_spin_end(spin);
gem_munmap((void *)((unsigned long)spin->condition & (~4095UL)),
diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h
index cb696009..dfba123c 100644
--- a/lib/igt_dummyload.h
+++ b/lib/igt_dummyload.h
@@ -34,7 +34,8 @@
typedef struct igt_spin {
unsigned int handle;
- timer_t timer;
+ int timerfd;
+ pthread_t timer_thread;
struct igt_list_head link;
uint32_t *condition;
--
2.26.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [igt-dev] [PATCH] lib/igt_dummyload: Use timerfd rather than SIGEV_THREAD
2020-03-31 11:19 [igt-dev] [PATCH] lib/igt_dummyload: Use timerfd rather than SIGEV_THREAD Michał Winiarski
@ 2020-03-31 11:27 ` Chris Wilson
2020-03-31 11:41 ` Chris Wilson
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Chris Wilson @ 2020-03-31 11:27 UTC (permalink / raw)
To: michal, igt-dev; +Cc: michal.winiarski
Quoting Michał Winiarski (2020-03-31 12:19:11)
> From: Michał Winiarski <michal.winiarski@intel.com>
>
> Since timer_delete doesn't give us any guarantees that the thread and
> its notify_function isn't currently running, we can hit a use-after-free
> in a race condition scenario.
> This causes a seemingly random segfault when igt_spin_end from notify
> thread is called after igt_spin_free was already called from the main
> thread.
> Let's fix that by using timerfd and managing the timer thread ourselves.
Off hand, do you have a feeling on how accurate this method is? I keep
running in situations where the SIGEV_THREAD did not seem reliable and
the spinner never terminated -- so I welcome a chance to do something
different (even if using timerfd + thread is effectively what glibc is
doing behind the scenes, and why I didn't really concern myself with
trying to do better.)
-Chris
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [igt-dev] [PATCH] lib/igt_dummyload: Use timerfd rather than SIGEV_THREAD
2020-03-31 11:19 [igt-dev] [PATCH] lib/igt_dummyload: Use timerfd rather than SIGEV_THREAD Michał Winiarski
2020-03-31 11:27 ` Chris Wilson
@ 2020-03-31 11:41 ` Chris Wilson
2020-03-31 12:43 ` [igt-dev] ✗ Fi.CI.BAT: failure for " Patchwork
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Chris Wilson @ 2020-03-31 11:41 UTC (permalink / raw)
To: michal, igt-dev; +Cc: michal.winiarski
Quoting Michał Winiarski (2020-03-31 12:19:11)
> -static void notify(union sigval arg)
> +static void *timer_thread(void *data)
> {
> - igt_spin_t *spin = arg.sival_ptr;
> + igt_spin_t *spin = data;
> + struct pollfd pfd;
> + int ret;
>
> - igt_spin_end(spin);
> + pfd.fd = spin->timerfd;
> + pfd.events = POLLIN;
> +
> + ret = poll(&pfd, 1, -1);
> + if (ret >= 0)
> + igt_spin_end(spin);
uint64_t count;
if (read(spin->timer_fd, &count, sizeof(count)) > 0)
igt_spin_end(spin);
would suffice. Not sure of the comparative latency.
However, that would allow us to close(spin->timerfd) first in
cancellation, would should report -ECANCELLED quickest.
So overall, I'm left with the worry of a thread per timeout. Though we
do typically only use one spinner timeout at a time, so it's merely the
overhead of creating a thread which should not be significant.
Ok, so just the question of poll() vs read() [and corresponding cleanup
order] and we're good.
-Chris
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 6+ messages in thread
* [igt-dev] ✗ Fi.CI.BAT: failure for lib/igt_dummyload: Use timerfd rather than SIGEV_THREAD
2020-03-31 11:19 [igt-dev] [PATCH] lib/igt_dummyload: Use timerfd rather than SIGEV_THREAD Michał Winiarski
2020-03-31 11:27 ` Chris Wilson
2020-03-31 11:41 ` Chris Wilson
@ 2020-03-31 12:43 ` Patchwork
2020-03-31 13:52 ` [igt-dev] [PATCH] " Chris Wilson
2020-04-01 2:41 ` [igt-dev] ✗ Fi.CI.BAT: failure for lib/igt_dummyload: Use timerfd rather than SIGEV_THREAD (rev2) Patchwork
4 siblings, 0 replies; 6+ messages in thread
From: Patchwork @ 2020-03-31 12:43 UTC (permalink / raw)
To: Michał Winiarski; +Cc: igt-dev
== Series Details ==
Series: lib/igt_dummyload: Use timerfd rather than SIGEV_THREAD
URL : https://patchwork.freedesktop.org/series/75309/
State : failure
== Summary ==
CI Bug Log - changes from IGT_5548 -> IGTPW_4380
====================================================
Summary
-------
**FAILURE**
Serious unknown changes coming with IGTPW_4380 absolutely need to be
verified manually.
If you think the reported changes have nothing to do with the changes
introduced in IGTPW_4380, please notify your bug team to allow them
to document this new failure mode, which will reduce false positives in CI.
External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4380/index.html
Possible new issues
-------------------
Here are the unknown changes that may have been introduced in IGTPW_4380:
### IGT changes ###
#### Possible regressions ####
* igt@i915_selftest@live@execlists:
- fi-icl-y: [PASS][1] -> [INCOMPLETE][2]
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5548/fi-icl-y/igt@i915_selftest@live@execlists.html
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4380/fi-icl-y/igt@i915_selftest@live@execlists.html
Known issues
------------
Here are the changes found in IGTPW_4380 that come from known issues:
### IGT changes ###
#### Possible fixes ####
* igt@i915_selftest@live@execlists:
- fi-kbl-7500u: [INCOMPLETE][3] ([CI#80] / [i915#656]) -> [PASS][4]
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5548/fi-kbl-7500u/igt@i915_selftest@live@execlists.html
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4380/fi-kbl-7500u/igt@i915_selftest@live@execlists.html
[CI#80]: https://gitlab.freedesktop.org/gfx-ci/i915-infra/issues/80
[i915#656]: https://gitlab.freedesktop.org/drm/intel/issues/656
Participating hosts (47 -> 43)
------------------------------
Additional (1): fi-bsw-n3050
Missing (5): fi-hsw-4200u fi-skl-6770hq fi-bsw-cyan fi-ctg-p8600 fi-bdw-samus
Build changes
-------------
* CI: CI-20190529 -> None
* IGT: IGT_5548 -> IGTPW_4380
CI-20190529: 20190529
CI_DRM_8222: 6970d295e51e3b03d7ee3f781522398402d3a35d @ git://anongit.freedesktop.org/gfx-ci/linux
IGTPW_4380: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4380/index.html
IGT_5548: d9e70dc1b35633b7d5c81cbfa165e331189eb260 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4380/index.html
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [igt-dev] [PATCH] lib/igt_dummyload: Use timerfd rather than SIGEV_THREAD
2020-03-31 11:19 [igt-dev] [PATCH] lib/igt_dummyload: Use timerfd rather than SIGEV_THREAD Michał Winiarski
` (2 preceding siblings ...)
2020-03-31 12:43 ` [igt-dev] ✗ Fi.CI.BAT: failure for " Patchwork
@ 2020-03-31 13:52 ` Chris Wilson
2020-04-01 2:41 ` [igt-dev] ✗ Fi.CI.BAT: failure for lib/igt_dummyload: Use timerfd rather than SIGEV_THREAD (rev2) Patchwork
4 siblings, 0 replies; 6+ messages in thread
From: Chris Wilson @ 2020-03-31 13:52 UTC (permalink / raw)
To: michal, igt-dev; +Cc: michal.winiarski
Quoting Michał Winiarski (2020-03-31 12:19:11)
> From: Michał Winiarski <michal.winiarski@intel.com>
>
> Since timer_delete doesn't give us any guarantees that the thread and
> its notify_function isn't currently running, we can hit a use-after-free
> in a race condition scenario.
> This causes a seemingly random segfault when igt_spin_end from notify
> thread is called after igt_spin_free was already called from the main
> thread.
> Let's fix that by using timerfd and managing the timer thread ourselves.
>
> Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
Seems I was confused with the meaning of timerfd_canceled() and imbued
it with properties it did not have,
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 6+ messages in thread
* [igt-dev] ✗ Fi.CI.BAT: failure for lib/igt_dummyload: Use timerfd rather than SIGEV_THREAD (rev2)
2020-03-31 11:19 [igt-dev] [PATCH] lib/igt_dummyload: Use timerfd rather than SIGEV_THREAD Michał Winiarski
` (3 preceding siblings ...)
2020-03-31 13:52 ` [igt-dev] [PATCH] " Chris Wilson
@ 2020-04-01 2:41 ` Patchwork
4 siblings, 0 replies; 6+ messages in thread
From: Patchwork @ 2020-04-01 2:41 UTC (permalink / raw)
To: Michał Winiarski; +Cc: igt-dev
== Series Details ==
Series: lib/igt_dummyload: Use timerfd rather than SIGEV_THREAD (rev2)
URL : https://patchwork.freedesktop.org/series/75309/
State : failure
== Summary ==
Series 75309 revision 2 was fully merged or fully failed: no git log
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2020-04-01 2:41 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-31 11:19 [igt-dev] [PATCH] lib/igt_dummyload: Use timerfd rather than SIGEV_THREAD Michał Winiarski
2020-03-31 11:27 ` Chris Wilson
2020-03-31 11:41 ` Chris Wilson
2020-03-31 12:43 ` [igt-dev] ✗ Fi.CI.BAT: failure for " Patchwork
2020-03-31 13:52 ` [igt-dev] [PATCH] " Chris Wilson
2020-04-01 2:41 ` [igt-dev] ✗ Fi.CI.BAT: failure for lib/igt_dummyload: Use timerfd rather than SIGEV_THREAD (rev2) Patchwork
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.