Messages in this thread | | Date | Thu, 21 May 2015 18:58:52 +0000 (UTC) | From | Mathieu Desnoyers <> | Subject | Re: [RFC PATCH] percpu system call: fast userspace percpu critical sections |
| |
----- Original Message ----- > On Thu, May 21, 2015 at 10:44:47AM -0400, Mathieu Desnoyers wrote: > > Expose a new system call allowing userspace threads to register > > a TLS area used as an ABI between the kernel and userspace to > > share information required to create efficient per-cpu critical > > sections in user-space. > > > > This ABI consists of a thread-local structure containing: > > > > - a nesting count surrounding the critical section, > > - a signal number to be sent to the thread when preempting a thread > > with non-zero nesting count, > > - a flag indicating whether the signal has been sent within the > > critical section, > > - an integer where to store the current CPU number, updated whenever > > the thread is preempted. This CPU number cache is not strictly > > needed, but performs better than getcpu vdso. > > > > This approach is inspired by Paul Turner and Andrew Hunter's work > > on percpu atomics, which lets the kernel handle restart of critical > > sections, ref. > > http://www.linuxplumbersconf.org/2013/ocw/system/presentations/1695/original/LPC%20-%20PerCpu%20Atomics.pdf > > > > What is done differently here compared to percpu atomics: we track > > a single nesting counter per thread rather than many ranges of > > instruction pointer values. We deliver a signal to user-space and > > let the logic of restart be handled in user-space, thus moving > > the complexity out of the kernel. The nesting counter approach > > allows us to skip the complexity of interacting with signals that > > would be otherwise needed with the percpu atomics approach, which > > needs to know which instruction pointers are preempted, including > > when preemption occurs on a signal handler nested over an instruction > > pointer of interest. > > > > Advantages of this approach over percpu atomics: > > - kernel code is relatively simple: complexity of restart sections > > is in user-space, > > - easy to port to other architectures: just need to reserve a new > > system call, > > - for threads which have registered a TLS structure, the fast-path > > at preemption is only a nesting counter check, along with the > > optional store of the current CPU number, rather than comparing > > instruction pointer with possibly many registered ranges, > > > > Caveats of this approach compared to the percpu atomics: > > - We need a signal number for this, so it cannot be done without > > designing the application accordingly, > > - Handling restart in user-space is currently performed with page > > protection, for which we install a SIGSEGV signal handler. Again, > > this requires designing the application accordingly, especially > > if the application installs its own segmentation fault handler, > > - It cannot be used for tracing of processes by injection of code > > into their address space, due to interactions with application > > signal handlers. > > > > The user-space proof of concept code implementing the restart section > > can be found here: https://github.com/compudj/percpu-dev > > > > Benchmarking sched_getcpu() vs tls cache approach. Getting the > > current CPU number: > > > > - With Linux vdso: 12.7 ns > > - With TLS-cached cpu number: 0.3 ns > > > > We will use the TLS-cached cpu number for the following > > benchmarks. > > > > On an Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz, comparison > > with a baseline running very few load/stores (no locking, > > no getcpu, assuming one thread per CPU with affinity), > > against locking scheme based on "lock; cmpxchg", "cmpxchg" > > (using restart signal), load-store (using restart signal). > > This is performed with 32 threads on a 16-core, hyperthread > > system: > > > > ns/loop overhead (ns) > > Baseline: 3.7 0.0 > > lock; cmpxchg: 22.0 18.3 > > cmpxchg: 11.1 7.4 > > load-store: 9.4 5.7 > > > > Therefore, the load-store scheme has a speedup of 3.2x over the > > "lock; cmpxchg" scheme if both are using the tls-cache for the > > CPU number. If we use Linux sched_getcpu() for "lock; cmpxchg" > > we reach of speedup of 5.4x for load-store+tls-cache vs > > "lock; cmpxchg"+vdso-getcpu. > > > > I'm sending this out to trigger discussion, and hopefully to see > > Paul and Andrew's patches being posted publicly at some point, so > > we can compare our approaches. > > The idea seems sensible. One quick comment: as with any new syscall, > please include a flags argument.
Sure, I'll add it right away. Thanks for the feedback!
Mathieu
-- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com
| |