<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>