From patchwork Mon Nov 19 18:55:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Waiman Long X-Patchwork-Id: 10689335 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0E4745A4 for ; Mon, 19 Nov 2018 18:58:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F1D412A45B for ; Mon, 19 Nov 2018 18:58:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E5A7F2A470; Mon, 19 Nov 2018 18:58:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 586752A45B for ; Mon, 19 Nov 2018 18:58:00 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 9BE216B1BF8; Mon, 19 Nov 2018 13:57:50 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 96D7E6B1BF9; Mon, 19 Nov 2018 13:57:50 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 838E06B1BFA; Mon, 19 Nov 2018 13:57:50 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) by kanga.kvack.org (Postfix) with ESMTP id 56FB86B1BF8 for ; Mon, 19 Nov 2018 13:57:50 -0500 (EST) Received: by mail-qk1-f198.google.com with SMTP id v74so49180372qkb.21 for ; Mon, 19 Nov 2018 10:57:50 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:in-reply-to:references; bh=SI7tz9eZrMp1hrTBYCrMNckVSLrQLCvVme6CnCUGkhE=; b=FLdhm+lnwf2d6W0hboCGBi5Fp+Hvtn8D6rJNrTuCkJI9w28zdzQlp5Eb0ygoQ+o0Pf Jxjk3k5n2Zs7yY/DmahmTCs+72KjB7XYADQ6JZY2CO0kJPgqn7It78qK1ZxEb8StShR7 Bzqc4ojPJkDYZ1xKRkv8iO6kYK22QnOdsACVDvcjDhGwdFvyXiBvsdMix7Le84RwEcwb vB3O96meUplPKgqdhU5DOfkLmG1EvAIMF6775oowvF0NCYw+9FQhD3bcLynoP+tlwDt/ tHWENXjyTgmHQQUENa/RRGIQ6vOh5qVwsy/urHIpAC44GZN2YAcv4zQKpYPBkSNPU5ap Huag== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of longman@redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=longman@redhat.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com X-Gm-Message-State: AGRZ1gK0RN2sLj7rh7/JhjOMaAGhZtkkEEKZjkg8IoHrHJyFo3uJamPv U+PGMwjaipN1c2OXY1SCnFWzXilGVnMNUDiTAQ+12UmLtmS4usoEBlyloqAOSWrcefgW8St6r7T /0X7890vXO6ZCupy+Ajx0vNflGPDlYLfnId9MOlFiriFil5FC65wFcVsl449LTdQgQQ== X-Received: by 2002:ac8:7950:: with SMTP id r16mr22367111qtt.12.1542653870116; Mon, 19 Nov 2018 10:57:50 -0800 (PST) X-Google-Smtp-Source: AJdET5d3Qb/kji8ahTzGLEtQ5T46+oFz3bDEQYHfQZyoNYeBwzX2s8couKEKEq6obxGZQa94hPkr X-Received: by 2002:ac8:7950:: with SMTP id r16mr22367077qtt.12.1542653869404; Mon, 19 Nov 2018 10:57:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542653869; cv=none; d=google.com; s=arc-20160816; b=yO9UB/TR/a8+7O+3Rfun9J/I+km8iJyJIcdV/1BK6P0JHsfho955PNe1yPhg47bc3N 1jAFcwrqzJUI1eMpzxG//T5djHgy4A+4KJj0yMCxPP+sWrgPD0qNmhGUIUfidNkpsPD2 wgLMVKDdt59sNMZNkqRk+4+Yu+fkw61IDc+tDWV8pli3mH526VYxqJ8TiNa+frZDDo5X y8lwmQIeCfqzvIqdMCz5fKaRfL1+6xt0Ez/Zmxeu8ZbPirugQWgpR+NdjsjATBeuI6Cb 7ebW1TjrFohgZs37nDsJC5CdZ4nbCDx71uOF1CFYrtfVNmPEgbTt4Rj6L3dpgJbnYcLH J0bA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from; bh=SI7tz9eZrMp1hrTBYCrMNckVSLrQLCvVme6CnCUGkhE=; b=EV/fStv2QKHp/ttn1ni0S3t65Ait6awNbJhxlrGe75tt+Orl2MyLQvdb+L+Jw+63vZ qtlBYZiaJUJfbm3HzRe8cUuHrJR/L+cHiCh4MEO0Ct7iAHooz9iZkX1ywW1SxdDjT6K7 WHZfsFwcSYSZA86FOUBeZUQyuLe4Kz7u4xm5hngnrM9dowS2LmGKEFzpEHD0+bUwB0/B BM/W0/mlKt1tcw7Kp50J4UH+4p4lURpw7i8sedS0t0hLvho8d/GTte0VVixm9Wmq6sLF QUSMTT7maQu4xJ3Sn5AQzXkD25nfp0lEhk717LzXcv/bB9Mx5PmxJXqo59gp/Mmmgkuk davQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of longman@redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=longman@redhat.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from mx1.redhat.com (mx1.redhat.com. [209.132.183.28]) by mx.google.com with ESMTPS id v30si2955799qtd.97.2018.11.19.10.57.49 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 19 Nov 2018 10:57:49 -0800 (PST) Received-SPF: pass (google.com: domain of longman@redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; Authentication-Results: mx.google.com; spf=pass (google.com: domain of longman@redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=longman@redhat.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6DF963082E4C; Mon, 19 Nov 2018 18:57:48 +0000 (UTC) Received: from llong.com (dhcp-17-55.bos.redhat.com [10.18.17.55]) by smtp.corp.redhat.com (Postfix) with ESMTP id F1BB5608E7; Mon, 19 Nov 2018 18:57:46 +0000 (UTC) From: Waiman Long To: Peter Zijlstra , Ingo Molnar , Will Deacon , Thomas Gleixner Cc: linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com, linux-mm@kvack.org, iommu@lists.linux-foundation.org, Petr Mladek , Sergey Senozhatsky , Andrey Ryabinin , Tejun Heo , Andrew Morton , Waiman Long Subject: [PATCH v2 17/17] locking/lockdep: Check raw/non-raw locking conflicts Date: Mon, 19 Nov 2018 13:55:26 -0500 Message-Id: <1542653726-5655-18-git-send-email-longman@redhat.com> In-Reply-To: <1542653726-5655-1-git-send-email-longman@redhat.com> References: <1542653726-5655-1-git-send-email-longman@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Mon, 19 Nov 2018 18:57:48 +0000 (UTC) X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP A task holding a raw spinlock should not acquire a non-raw lock as that will break PREEMPT_RT kernel. Checking is now added and a lockdep warning will be printed if that happens. Signed-off-by: Waiman Long --- include/linux/lockdep.h | 6 ++++++ include/linux/spinlock_types.h | 4 ++-- kernel/locking/lockdep.c | 15 +++++++++++++-- kernel/locking/spinlock_debug.c | 1 + 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index b9435fb..9a6fe0e 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -150,12 +150,15 @@ struct lock_class_stats { * another lock within its critical section is not allowed. * 3) LOCKDEP_FLAG_TERMINAL_NESTABLE: This is a terminal lock that can * allow one more regular terminal lock to be nested underneath it. + * 4) LOCKDEP_FLAG_RAW: This is a raw spinlock. A task holding a raw + * spinlock should not acquire a non-raw lock. * * Only the least significant 4 bits of the flags will be copied to the * held_lock structure. */ #define LOCKDEP_FLAG_TERMINAL (1 << 0) #define LOCKDEP_FLAG_TERMINAL_NESTABLE (1 << 1) +#define LOCKDEP_FLAG_RAW (1 << 2) #define LOCKDEP_FLAG_NOVALIDATE (1 << 4) #define LOCKDEP_HLOCK_FLAGS_MASK 0x0f @@ -333,6 +336,8 @@ extern void lockdep_init_map(struct lockdep_map *lock, const char *name, do { (lock)->dep_map.flags |= LOCKDEP_FLAG_TERMINAL; } while (0) #define lockdep_set_terminal_nestable_class(lock) \ do { (lock)->dep_map.flags |= LOCKDEP_FLAG_TERMINAL_NESTABLE; } while (0) +#define lockdep_set_raw_class(lock) \ + do { (lock)->dep_map.flags |= LOCKDEP_FLAG_RAW; } while (0) /* * Compare locking classes @@ -448,6 +453,7 @@ static inline void lockdep_on(void) do { (void)(key); } while (0) #define lockdep_set_subclass(lock, sub) do { } while (0) +#define lockdep_set_raw_class(lock) do { } while (0) #define lockdep_set_novalidate_class(lock) do { } while (0) #define lockdep_set_terminal_class(lock) do { } while (0) #define lockdep_set_terminal_nestable_class(lock) do { } while (0) diff --git a/include/linux/spinlock_types.h b/include/linux/spinlock_types.h index 6a8086e..1d2114b 100644 --- a/include/linux/spinlock_types.h +++ b/include/linux/spinlock_types.h @@ -55,11 +55,11 @@ SPIN_DEP_MAP_INIT(lockname, f) } #define __RAW_SPIN_LOCK_UNLOCKED(lockname) \ - (raw_spinlock_t) __RAW_SPIN_LOCK_INITIALIZER(lockname, 0) + (raw_spinlock_t) __RAW_SPIN_LOCK_INITIALIZER(lockname, LOCKDEP_FLAG_RAW) #define __RAW_TERMINAL_SPIN_LOCK_UNLOCKED(lockname) \ (raw_spinlock_t) __RAW_SPIN_LOCK_INITIALIZER(lockname, \ - LOCKDEP_FLAG_TERMINAL) + LOCKDEP_FLAG_TERMINAL|LOCKDEP_FLAG_RAW) #define DEFINE_RAW_SPINLOCK(x) raw_spinlock_t x = __RAW_SPIN_LOCK_UNLOCKED(x) #define DEFINE_RAW_TERMINAL_SPINLOCK(x) \ diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 5a853a6..efafd2d 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -3273,8 +3273,8 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, * one isn't a regular terminal lock. */ prev_type = hlock_is_terminal(hlock); - if (DEBUG_LOCKS_WARN_ON((prev_type == LOCKDEP_FLAG_TERMINAL) || - ((prev_type == LOCKDEP_FLAG_TERMINAL_NESTABLE) && + if (DEBUG_LOCKS_WARN_ON((prev_type & LOCKDEP_FLAG_TERMINAL) || + ((prev_type & LOCKDEP_FLAG_TERMINAL_NESTABLE) && (flags_is_terminal(class->flags) != LOCKDEP_FLAG_TERMINAL)))) { pr_warn("Terminal lock error: prev lock = %s, curr lock = %s\n", @@ -3282,6 +3282,17 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, return 0; } + /* + * A task holding a raw spinlock should not acquire another + * non-raw lock. + */ + if (DEBUG_LOCKS_WARN_ON((prev_type & LOCKDEP_FLAG_RAW) && + !(class->flags & LOCKDEP_FLAG_RAW))) { + pr_warn("Raw lock error: prev lock = %s, curr lock = %s\n", + hlock->instance->name, class->name); + return 0; + } + if (hlock->class_idx == class_idx && nest_lock) { if (hlock->references) { /* diff --git a/kernel/locking/spinlock_debug.c b/kernel/locking/spinlock_debug.c index 9aa0fcc..1794d47 100644 --- a/kernel/locking/spinlock_debug.c +++ b/kernel/locking/spinlock_debug.c @@ -22,6 +22,7 @@ void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name, */ debug_check_no_locks_freed((void *)lock, sizeof(*lock)); lockdep_init_map(&lock->dep_map, name, key, 0); + lockdep_set_raw_class(lock); #endif lock->raw_lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; lock->magic = SPINLOCK_MAGIC;