[Mesa-dev] [PATCH] RFC: Workaround for pthread_setaffinity_np() seccomp filtering

Marc-André Lureau marcandre.lureau at redhat.com
Mon Mar 4 23:47:09 UTC 2019


Hi Drew

On Mon, Mar 4, 2019 at 8:01 PM Drew Davenport <ddavenport at chromium.org> wrote:
>
> We ran into a similar issue with this syscall in Chrome OS. This patch
> addressed the issue:
> https://lists.freedesktop.org/archives/mesa-dev/2019-February/215721.html
>
> Does it help in this case as well?

That doesn't work, since the default SIGSYS handler will core dump.

Furthermore, qemu will start using SCMP_ACT_KILL_PROCESS, which will
kill the entire process immediately.


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


More information about the mesa-dev mailing list