Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756138AbbEUPrK (ORCPT ); Thu, 21 May 2015 11:47:10 -0400 Received: from relay6-d.mail.gandi.net ([217.70.183.198]:42319 "EHLO relay6-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755198AbbEUPrG (ORCPT ); Thu, 21 May 2015 11:47:06 -0400 X-Originating-IP: 50.43.43.179 Date: Thu, 21 May 2015 08:46:55 -0700 From: Josh Triplett To: Mathieu Desnoyers Cc: Paul Turner , Andrew Hunter , Ben Maurer , linux-kernel@vger.kernel.org, Peter Zijlstra , Ingo Molnar , Steven Rostedt , "Paul E. McKenney" , Lai Jiangshan , Linus Torvalds , Andrew Morton Subject: Re: [RFC PATCH] percpu system call: fast userspace percpu critical sections Message-ID: <20150521154655.GA17956@x> References: <1432219487-13364-1-git-send-email-mathieu.desnoyers@efficios.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1432219487-13364-1-git-send-email-mathieu.desnoyers@efficios.com> User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4573 Lines: 98 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. - Josh Triplett -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/