From patchwork Fri Nov 10 20:41:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Wilcox X-Patchwork-Id: 13452780 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 204CBC4332F for ; Fri, 10 Nov 2023 20:41:42 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id AD1ED8D00FA; Fri, 10 Nov 2023 15:41:41 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id A83568D0005; Fri, 10 Nov 2023 15:41:41 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 886B48D00FA; Fri, 10 Nov 2023 15:41:41 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id 786218D0005 for ; Fri, 10 Nov 2023 15:41:41 -0500 (EST) Received: from smtpin27.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id 4443B1A048E for ; Fri, 10 Nov 2023 20:41:41 +0000 (UTC) X-FDA: 81443215602.27.4107F7B Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) by imf03.hostedemail.com (Postfix) with ESMTP id 8092720005 for ; Fri, 10 Nov 2023 20:41:39 +0000 (UTC) Authentication-Results: imf03.hostedemail.com; dkim=pass header.d=infradead.org header.s=casper.20170209 header.b=vZbf4qLU; dmarc=none; spf=none (imf03.hostedemail.com: domain of willy@infradead.org has no SPF policy when checking 90.155.50.34) smtp.mailfrom=willy@infradead.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1699648899; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=Xki740aAoX9yBxyCdgA26lHDCnTzivKGn1Gv5eBSmHQ=; b=ejx5kKhmLB5rCpcmIW60/I3Y0fGINu1i1Yqf6biIVP17OOLX6RyWspSxgWg0PoDRqfhYv6 Bd7ht06BG2yfIYSS4Zr6yqExzdRED+EBY6WDYGFDIMhEgOeZPzlSkucp7twRUT+HxhTNoT 1KqragyA78aPShzWEbsnISs2zkuXfT8= ARC-Authentication-Results: i=1; imf03.hostedemail.com; dkim=pass header.d=infradead.org header.s=casper.20170209 header.b=vZbf4qLU; dmarc=none; spf=none (imf03.hostedemail.com: domain of willy@infradead.org has no SPF policy when checking 90.155.50.34) smtp.mailfrom=willy@infradead.org ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1699648899; a=rsa-sha256; cv=none; b=oHpqeKJH0Gk0JgWfM5e//OXqc2CUvA+3ep4TufWhG8Bvjle+E8vVJWIjldqoACibKUchdM F8UFFohi/4QG15bnXEB8LaLLMgbxqkdn8871Mu9ldJ4bjHsK/huwEF0NXUaGxvfbcIND56 bytrvEYGvzNujt/AoMHDngV6vOgLHtI= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=Xki740aAoX9yBxyCdgA26lHDCnTzivKGn1Gv5eBSmHQ=; b=vZbf4qLUD8BS9Dl7W1IRtLtjat xawi8qeBavSyl8iXANIozdeDZwFbgA/BRLWIdBz/nBloRyrsb6NH178+2p4YNsDS8Z3Hv5/bxkx1n s5fre0aG20Bfw5KLbwnVR2mgyIWjiVt+SWZ7Pqo1uCoo/3bcj6XCO+Y9UAKAMZGbS3QdtcWP3C4T+ vRiGf6JNzq2JDBCoZe2gydqfci30qTZptXtZQ99uKoKjsEiyRxjEjySoVVdYFUaA2VeKfD5riRcNF 3GagWA8b08j58LozOizxsJk6JKYtbKYBlAhkgqBXWrJh9FZDPGeon+ORMuksMkbUP7QUP/z7Unog7 fiqjjzRg==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1r1YJd-00FUT4-0t; Fri, 10 Nov 2023 20:41:21 +0000 From: "Matthew Wilcox (Oracle)" To: Peter Zijlstra , Ingo Molnar , Will Deacon , Waiman Long Cc: "Matthew Wilcox (Oracle)" , linux-kernel@vger.kernel.org, linux-mm@kvack.org, Chandan Babu R , "Darrick J . Wong" , linux-xfs@vger.kernel.org, Mateusz Guzik Subject: [PATCH v3 1/4] locking: Add rwsem_assert_held() and rwsem_assert_held_write() Date: Fri, 10 Nov 2023 20:41:16 +0000 Message-Id: <20231110204119.3692023-2-willy@infradead.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20231110204119.3692023-1-willy@infradead.org> References: <20231110204119.3692023-1-willy@infradead.org> MIME-Version: 1.0 X-Rspamd-Queue-Id: 8092720005 X-Rspam-User: X-Rspamd-Server: rspam02 X-Stat-Signature: nbkhrgwxj3dbgfy5xcgmwhe5y8ibcamn X-HE-Tag: 1699648899-73394 X-HE-Meta: U2FsdGVkX1/S8GCmuELVnLKb5K67WQRmN+JpIlkqjf8voQw35cjpwi3OwHGZ6MQKNm7ydqGEEuNJg4RsR4IDFumfXFgIz56bcXckBh2KZmuWkWqbb3l3bGyR02fPX3ssVq/zPHyQuKEprGb0PyMDy+/X+iccjDZ2OZWwvS7EuMfT4yRE8HgkFJSazzYQk8fwJ9TS70T+QKAsbhJa7xeN4/mppBSi7P6SsOo44laVZ3gao4Oaw/A6waKFyQ9tCm4KaChdrqZk0Q7plxi/I62q437Gsu4UwtFL47RU8nJPpzS7F5UboorCWTuyJCYpbCwOIv0GRVAKVAqOzNEzUBYZwAQe8t5S3UjYztjkRiHU1Ze+0g6L28Y7PGwoM1QK13ZB0hxSf5UKborDgoM6hKEr90lczaxcUt3zU6F8RN6sHWLnu75x3EYWaQXF+ZlJIsNxOKpzpseAUOxv8+zDnPq38fI0HVUiWZRjVGoUdPrfA0eD05Ipb8d/STc0t829UieBJSDsDstQwVMKihg9SQchZw0/+8K6lk9xn0dBpguC9oK1phy6W1j3fZQZaJ5RL9WRTdLJf3QYXsqNBajFSdwc/pmmhBS2V5wowSsXl7uBI+Z81TcFH7c3LC13y3bhfLVXVHeXJF5zxnsF7Ph2cbJdo3fuvFZvpu4XBQvKccBoVJ9r6A2MNpnY5DVjidBxY6M5gViB3W9jVsg/VvkJs4aI1d4vt86wmAC1wQ7Ms7nf5WALEgr9hluYd4PusXdYh4nBdltRjzbzH6Raa1f/sDlRxvOuB+7MGdbAxTJq7Jty61o+VFi+NLIZSJSRedYNNkxT0/2NJGm5L6eIlq9JJSHPc1QSdL09yMXgGCbb8MP4S/kVJk6ZaWJLCD1CaRCBVtRBo15E5F1qOVWJMKqJ1bTwKrRGNvY4xNZLX1cxqw5RRX/DCzm1RoiRGbMYEBR8MEs83HQ9R+zZ3q3u1PtSiD9 3L7pd+yA ZKMaqhYAcmW6hYBjdwG7YLAy0fxsf/hJohKl4w5IjW9BDA/YHyla+HnkA8s7HAvhWv/EuyUMitg9XbofZzmuiXSLaOkhu+vAROnN1cP6gKr9R8xf7bJseNY1SqKSbNcCHuVkybf52+MfWwMhXs0R+8pG1OGWF7JuRLpvxzHgpS9BC2n/ahVOTPNAl2nhx3PasyANqLe5FZv1O4+aEyrKps6OXSe2Gh99cvOemFx6BGK0XNh0= 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: List-Subscribe: List-Unsubscribe: Modelled after lockdep_assert_held() and lockdep_assert_held_write(), but are always active, even when lockdep is disabled. Of course, they don't test that _this_ thread is the owner, but it's sufficient to catch many bugs and doesn't incur the same performance penalty as lockdep. Signed-off-by: Matthew Wilcox (Oracle) --- include/linux/rwbase_rt.h | 9 ++++++-- include/linux/rwsem.h | 46 ++++++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/include/linux/rwbase_rt.h b/include/linux/rwbase_rt.h index 1d264dd08625..a04acd85705b 100644 --- a/include/linux/rwbase_rt.h +++ b/include/linux/rwbase_rt.h @@ -26,12 +26,17 @@ struct rwbase_rt { } while (0) -static __always_inline bool rw_base_is_locked(struct rwbase_rt *rwb) +static __always_inline bool rw_base_is_locked(const struct rwbase_rt *rwb) { return atomic_read(&rwb->readers) != READER_BIAS; } -static __always_inline bool rw_base_is_contended(struct rwbase_rt *rwb) +static inline void rw_base_assert_held_write(const struct rwbase_rt *rwb) +{ + BUG_ON(atomic_read(&rwb->readers) != WRITER_BIAS); +} + +static __always_inline bool rw_base_is_contended(const struct rwbase_rt *rwb) { return atomic_read(&rwb->readers) > 0; } diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h index 1dd530ce8b45..b5b34cca86f3 100644 --- a/include/linux/rwsem.h +++ b/include/linux/rwsem.h @@ -66,14 +66,24 @@ struct rw_semaphore { #endif }; -/* In all implementations count != 0 means locked */ +#define RWSEM_UNLOCKED_VALUE 0UL +#define RWSEM_WRITER_LOCKED (1UL << 0) +#define __RWSEM_COUNT_INIT(name) .count = ATOMIC_LONG_INIT(RWSEM_UNLOCKED_VALUE) + static inline int rwsem_is_locked(struct rw_semaphore *sem) { - return atomic_long_read(&sem->count) != 0; + return atomic_long_read(&sem->count) != RWSEM_UNLOCKED_VALUE; } -#define RWSEM_UNLOCKED_VALUE 0L -#define __RWSEM_COUNT_INIT(name) .count = ATOMIC_LONG_INIT(RWSEM_UNLOCKED_VALUE) +static inline void rwsem_assert_held_nolockdep(const struct rw_semaphore *sem) +{ + WARN_ON(atomic_long_read(&sem->count) == RWSEM_UNLOCKED_VALUE); +} + +static inline void rwsem_assert_held_write_nolockdep(const struct rw_semaphore *sem) +{ + WARN_ON(!(atomic_long_read(&sem->count) & RWSEM_WRITER_LOCKED)); +} /* Common initializer macros and functions */ @@ -152,11 +162,21 @@ do { \ __init_rwsem((sem), #sem, &__key); \ } while (0) -static __always_inline int rwsem_is_locked(struct rw_semaphore *sem) +static __always_inline int rwsem_is_locked(const struct rw_semaphore *sem) { return rw_base_is_locked(&sem->rwbase); } +static inline void rwsem_assert_held_nolockdep(const struct rw_semaphore *sem) +{ + BUG_ON(!rwsem_is_locked(sem)); +} + +static inline void rwsem_assert_held_write_nolockdep(const struct rw_semaphore *sem) +{ + rw_base_assert_held_write(sem); +} + static __always_inline int rwsem_is_contended(struct rw_semaphore *sem) { return rw_base_is_contended(&sem->rwbase); @@ -169,6 +189,22 @@ static __always_inline int rwsem_is_contended(struct rw_semaphore *sem) * the RT specific variant. */ +static inline void rwsem_assert_held(const struct rw_semaphore *sem) +{ + if (IS_ENABLED(CONFIG_LOCKDEP)) + lockdep_assert_held(sem); + else + rwsem_assert_held_nolockdep(sem); +} + +static inline void rwsem_assert_held_write(const struct rw_semaphore *sem) +{ + if (IS_ENABLED(CONFIG_LOCKDEP)) + lockdep_assert_held_write(sem); + else + rwsem_assert_held_write_nolockdep(sem); +} + /* * lock for reading */