Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752475AbbBXDao (ORCPT ); Mon, 23 Feb 2015 22:30:44 -0500 Received: from ozlabs.org ([103.22.144.67]:38611 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752401AbbBXDal (ORCPT ); Mon, 23 Feb 2015 22:30:41 -0500 From: Anton Blanchard To: Andrew Morton , Steven Rostedt , Michael Ellerman , Paul Mackerras , Benjamin Herrenschmidt , sam.bobroff@au1.ibm.com, Thomas Gleixner , Ingo Molnar , hpa@zytor.com, Russell King , peterz@infradead.org, Don Zickus Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, x86@kernel.org Subject: [PATCH 1/7] Add die_spin_lock_{irqsave,irqrestore} Date: Tue, 24 Feb 2015 14:30:28 +1100 Message-Id: <1424748634-9153-2-git-send-email-anton@samba.org> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1424748634-9153-1-git-send-email-anton@samba.org> References: <1424748634-9153-1-git-send-email-anton@samba.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3262 Lines: 113 Many architectures have their own oops locking code that allows the lock to be taken recursively. Create a common version. Avoid creating generic locking functions, so they can't be abused in other parts of the kernel. Signed-off-by: Anton Blanchard --- include/linux/die_lock.h | 23 +++++++++++++++++++++++ lib/Makefile | 1 + lib/die_lock.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 include/linux/die_lock.h create mode 100644 lib/die_lock.c diff --git a/include/linux/die_lock.h b/include/linux/die_lock.h new file mode 100644 index 0000000..540d09d --- /dev/null +++ b/include/linux/die_lock.h @@ -0,0 +1,23 @@ +#ifndef __LINUX_DIE_LOCK_H +#define __LINUX_DIE_LOCK_H + +#include + +/** + * die_spin_lock_irqsave - lock die spinlock + * @flags: interrupt state is saved here + * + * The die spinlock is used to serialise output during oopses, BUGs and + * WARNs. It can be taken recursively so that nested oopses will not + * lock up. + */ +unsigned long __die_spin_lock_irqsave(void); +#define die_spin_lock_irqsave(flags) \ + do { \ + typecheck(unsigned long, flags); \ + flags = __die_spin_lock_irqsave(); \ + } while (0) + +void die_spin_unlock_irqrestore(unsigned long flags); + +#endif /* __LINUX_DIE_LOCK_H */ diff --git a/lib/Makefile b/lib/Makefile index 3c3b30b..7d87a80 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -28,6 +28,7 @@ obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \ percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o obj-y += string_helpers.o +obj-y += die_lock.o obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o obj-y += kstrtox.o obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o diff --git a/lib/die_lock.c b/lib/die_lock.c new file mode 100644 index 0000000..5d2de2e --- /dev/null +++ b/lib/die_lock.c @@ -0,0 +1,43 @@ +#include +#include + +static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED; +static int die_owner = -1; +static unsigned int die_nest_count; + +unsigned long __die_spin_lock_irqsave(void) +{ + unsigned long flags; + int cpu; + + /* racy, but better than risking deadlock. */ + raw_local_irq_save(flags); + + cpu = smp_processor_id(); + if (!arch_spin_trylock(&die_lock)) { + if (cpu != die_owner) + arch_spin_lock(&die_lock); + } + die_nest_count++; + die_owner = cpu; + + return flags; +} + +/** + * die_spin_unlock_irqrestore - Unlock die spinlock + * @flags: interrupt state to restore + * + * Unlock die spinlock and restore interrupt state. This must be + * paired with die_spin_lock_irqsave. + */ +void die_spin_unlock_irqrestore(unsigned long flags) +{ + die_nest_count--; + if (!die_nest_count) { + die_owner = -1; + /* Nest count reaches zero, release the lock. */ + arch_spin_unlock(&die_lock); + } + raw_local_irq_restore(flags); +} -- 2.1.0 -- 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/