<div dir="ltr"><div>I'd rather have something more robust than an env var, like catching SIGSYS.<br></div><div><br></div><div>Marek<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Feb 27, 2019 at 6:13 PM <<a href="mailto:marcandre.lureau@redhat.com">marcandre.lureau@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">From: Marc-André Lureau <<a href="mailto:marcandre.lureau@redhat.com" target="_blank">marcandre.lureau@redhat.com</a>><br>
<br>
Since commit d877451b48a59ab0f9a4210fc736f51da5851c9a ("util/u_queue:<br>
add UTIL_QUEUE_INIT_SET_FULL_THREAD_AFFINITY"), mesa calls<br>
sched_setaffinity syscall. Unfortunately, qemu crashes with SIGSYS<br>
when sandboxing is enabled (by default with libvirt), as this syscall<br>
is filtered.<br>
<br>
There doesn't seem to be a way to check for the seccomp rule other<br>
than doing a call, which may result in various behaviour depending on<br>
seccomp actions. There is a PTRACE_SECCOMP_GET_FILTER, but it is<br>
low-level and a priviledged operation (but there might be a way to use<br>
it?). A safe way would be to try the call in a subprocess,<br>
unfortunately, qemu also prohibits fork(). Also this could be subject<br>
to TOCTOU.<br>
<br>
There seems to be few solutions, but the issue can be considered a<br>
regression for various libvirt/Boxes users.<br>
<br>
Introduce MESA_NO_THREAD_AFFINITY environment variable to prevent the<br>
offending call. Wrap pthread_setaffinity_np() in a utility function<br>
u_pthread_setaffinity_np(), returning a EACCESS error if the variable<br>
is set.<br>
<br>
Note: one call is left with a FIXME, as I didn't investigate how to<br>
build and test it, help welcome!<br>
<br>
See also:<br>
<a href="https://bugs.freedesktop.org/show_bug.cgi?id=109695" rel="noreferrer" target="_blank">https://bugs.freedesktop.org/show_bug.cgi?id=109695</a><br>
<br>
Signed-off-by: Marc-André Lureau <<a href="mailto:marcandre.lureau@redhat.com" target="_blank">marcandre.lureau@redhat.com</a>><br>
---<br>
.../drivers/swr/rasterizer/core/threads.cpp | 1 +<br>
src/util/u_queue.c | 2 +-<br>
src/util/u_thread.h | 15 ++++++++++++++-<br>
3 files changed, 16 insertions(+), 2 deletions(-)<br>
<br>
diff --git a/src/gallium/drivers/swr/rasterizer/core/threads.cpp b/src/gallium/drivers/swr/rasterizer/core/threads.cpp<br>
index e30c1170568..d10c79512a1 100644<br>
--- a/src/gallium/drivers/swr/rasterizer/core/threads.cpp<br>
+++ b/src/gallium/drivers/swr/rasterizer/core/threads.cpp<br>
@@ -364,6 +364,7 @@ void bindThread(SWR_CONTEXT* pContext,<br>
CPU_ZERO(&cpuset);<br>
CPU_SET(threadId, &cpuset);<br>
<br>
+ /* FIXME: use u_pthread_setaffinity_np() if possible */<br>
int err = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);<br>
if (err != 0)<br>
{<br>
diff --git a/src/util/u_queue.c b/src/util/u_queue.c<br>
index 3812c824b6d..dea8d2bb4ae 100644<br>
--- a/src/util/u_queue.c<br>
+++ b/src/util/u_queue.c<br>
@@ -249,7 +249,7 @@ util_queue_thread_func(void *input)<br>
for (unsigned i = 0; i < CPU_SETSIZE; i++)<br>
CPU_SET(i, &cpuset);<br>
<br>
- pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset);<br>
+ u_pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset);<br>
}<br>
#endif<br>
<br>
diff --git a/src/util/u_thread.h b/src/util/u_thread.h<br>
index a46c18d3db2..a4e6dbae5d7 100644<br>
--- a/src/util/u_thread.h<br>
+++ b/src/util/u_thread.h<br>
@@ -70,6 +70,19 @@ static inline void u_thread_setname( const char *name )<br>
(void)name;<br>
}<br>
<br>
+#if defined(HAVE_PTHREAD_SETAFFINITY)<br>
+static inline int u_pthread_setaffinity_np(pthread_t thread, size_t cpusetsize,<br>
+ const cpu_set_t *cpuset)<br>
+{<br>
+ if (getenv("MESA_NO_THREAD_AFFINITY")) {<br>
+ errno = EACCES;<br>
+ return -1;<br>
+ }<br>
+<br>
+ return pthread_setaffinity_np(thread, cpusetsize, cpuset);<br>
+}<br>
+#endif<br>
+<br>
/**<br>
* An AMD Zen CPU consists of multiple modules where each module has its own L3<br>
* cache. Inter-thread communication such as locks and atomics between modules<br>
@@ -89,7 +102,7 @@ util_pin_thread_to_L3(thrd_t thread, unsigned L3_index, unsigned cores_per_L3)<br>
CPU_ZERO(&cpuset);<br>
for (unsigned i = 0; i < cores_per_L3; i++)<br>
CPU_SET(L3_index * cores_per_L3 + i, &cpuset);<br>
- pthread_setaffinity_np(thread, sizeof(cpuset), &cpuset);<br>
+ u_pthread_setaffinity_np(thread, sizeof(cpuset), &cpuset);<br>
#endif<br>
}<br>
<br>
-- <br>
2.21.0<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a></blockquote></div>