From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760136AbdACSBa (ORCPT ); Tue, 3 Jan 2017 13:01:30 -0500 Received: from mx1.redhat.com ([209.132.183.28]:49884 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759597AbdACSBP (ORCPT ); Tue, 3 Jan 2017 13:01:15 -0500 From: Waiman Long To: Peter Zijlstra , Ingo Molnar , Thomas Gleixner , "H. Peter Anvin" Cc: linux-kernel@vger.kernel.org, Waiman Long Subject: [RFC PATCH 0/7] locking/rtqspinlock: Realtime queued spinlocks Date: Tue, 3 Jan 2017 13:00:23 -0500 Message-Id: <1483466430-8028-1-git-send-email-longman@redhat.com> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Tue, 03 Jan 2017 18:01:16 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patchset introduces a new variant of queued spinlocks - the realtime queued spinlocks. The purpose of this new variant is to support real spinlock in a realtime environment where high priority RT tasks should be allowed to complete its work ASAP. This means as little waiting time for spinlocks as possible. Non-RT tasks will wait for spinlocks in the MCS waiting queue as usual. RT tasks and interrupts will spin directly on the spinlocks and use the priority value in the pending byte to arbitrate who get the lock first. Patch 1 removes the unused spin_lock_bh_nested() API. Patch 2 introduces the basic realtime queued spinlocks where the pending byte is used for storing the priority of the highest priority RT task that is waiting on the spinlock. All the RT tasks will spin directly on the spinlock instead of waiting in the queue. Patch 3 moves all interrupt context lock waiters to RT spinning. Patch 4 overrides the spin_lock_nested() call with special code to enabled RT lock spinning for nested spinlock. Patch 5 handles priority boosting by periodically checking its priority and unqueuing from the waiting queue and do RT spinning if applicable. Patch 6 allows voluntary CPU preemption to happen when a CPU is waiting for a spinlock. Patch 7 enables event counts to be collected by the qspinlock stat package so that we could monitor what have happened within the kernel. With a locking microbenchmark running on a 2-socket 36-core E5-2699 v3 system, the elapsed times to complete 2M locking loop per non-RT thread were as follows: # of threads qspinlock rt-qspinlock % change ------------ --------- ------------ -------- 2 0.29s 1.97s +580% 3 1.46s 2.05s +40% 4 1.81s 2.38s +31% 5 2.36s 2.87s +22% 6 2.73s 3.58s +31% 7 3.17s 3.74s +18% 8 3.67s 4.70s +28% 9 3.89s 5.28s +36% 10 4.35s 6.58s +51% The RT qspinlock is slower than the non-RT qspinlock which is expected. This patchset hasn't included any patch to modify the call sites of spin_lock_nested() to include the outer lock of the nest spinlock pair yet. That will be included in a later version of this patchset once it is determined that RT qspinlocks is worth pursuing. Only minimal testing to build and boot the patched kernel was done. More extensive testing will be done with later versions of this patchset. Waiman Long (7): locking/spinlock: Remove the unused spin_lock_bh_nested API locking/rtqspinlock: Introduce realtime queued spinlocks locking/rtqspinlock: Use static RT priority when in interrupt context locking/rtqspinlock: Override spin_lock_nested with special RT variants locking/rtqspinlock: Handle priority boosting locking/rtqspinlock: Voluntarily yield CPU when need_sched() locking/rtqspinlock: Enable collection of event counts arch/x86/Kconfig | 18 +- include/linux/spinlock.h | 43 +++- include/linux/spinlock_api_smp.h | 9 +- include/linux/spinlock_api_up.h | 1 - kernel/Kconfig.locks | 9 + kernel/locking/qspinlock.c | 51 +++- kernel/locking/qspinlock_rt.h | 543 +++++++++++++++++++++++++++++++++++++++ kernel/locking/qspinlock_stat.h | 81 +++++- kernel/locking/spinlock.c | 8 - 9 files changed, 721 insertions(+), 42 deletions(-) create mode 100644 kernel/locking/qspinlock_rt.h -- 1.8.3.1