Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp2604308ybi; Mon, 17 Jun 2019 07:34:47 -0700 (PDT) X-Google-Smtp-Source: APXvYqwEncxbMfPcN7zoE0Ra1RvDL/XOIuuwXiW/97k/JAZhzn72s4nc96PAx4Hbq95cWowijN6H X-Received: by 2002:a63:a41:: with SMTP id z1mr771522pgk.290.1560782087457; Mon, 17 Jun 2019 07:34:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1560782087; cv=none; d=google.com; s=arc-20160816; b=oGba9mFWeIpnYAfRHSP3zOdghDvcBjJnnH2ZKv/J0H0pitfehhtu2YJnJlqVTt0v3B 3mQMuBrAQTJQkudU37jKBBwy84LYplto+2xcBSy7LN4aPC2cu2y1JWO5XozH6UkyjA0n R8ikyW+S1r7ig1I75ubAyOW4wGgpGrnrXO42Q1D+3RwyM19D+4AGOOUAl7tNHYQYYTeh oy3W4jb41xM3vQ+ooTFqtzyLhA/twiSwLKnCl8ScmpItCKKf3h+3oRziOxlnA2PN7Y2W v5kgEDxfZi48ItzYWnQswRHPvG6wR+d7OWs5lBjHi0iX06QTMd1qBlwYxCfQ5Qv5GZcc 0vlA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-disposition :content-transfer-encoding:mime-version:robot-unsubscribe:robot-id :git-commit-id:subject:to:references:in-reply-to:reply-to:cc :message-id:from:date:dkim-signature:dkim-filter; bh=a9S2CuzLd4kYKu7CFHR/CjGCiqejAErFwevCNYz/wo8=; b=QMFtpkgmudMcgXZ/+8+iGXb3VKYlJdwN1jmHltdn7tXfhyeortFm5n5V8VahAELiIV 5LJDIfcYHV4C2a+JM72QhsLtbdSpuxrlvPqY2UaaVR4YlUQGkn/zu6zBmwnp5j1hLt+2 xlkaWaEQMD2FWoH9WGJw2+JMLCXDU7wgQ6ZrgA9XRwJcaSVesBz/hGUaFmXtVhwjlVA7 WzBToixFY7ROgjXIj2Yt5J2d8zSuRgyTufsGpOHWvzDQaY5B/tkRSSB2MPlM9kqziOKU DsP55/wb6eWlBiDQNUbYv+bzYxZjEHFecTTUIrQr8agGbHByq5OCKTQcyWlcYa8b2mUx cz8g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@zytor.com header.s=2019051801 header.b=AMDNfnxL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=zytor.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id gn3si9980712plb.321.2019.06.17.07.34.31; Mon, 17 Jun 2019 07:34:47 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@zytor.com header.s=2019051801 header.b=AMDNfnxL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=zytor.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728121AbfFQOdN (ORCPT + 99 others); Mon, 17 Jun 2019 10:33:13 -0400 Received: from terminus.zytor.com ([198.137.202.136]:40373 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726065AbfFQOdN (ORCPT ); Mon, 17 Jun 2019 10:33:13 -0400 Received: from terminus.zytor.com (localhost [127.0.0.1]) by terminus.zytor.com (8.15.2/8.15.2) with ESMTPS id x5HEUaAE3457199 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Mon, 17 Jun 2019 07:30:36 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 terminus.zytor.com x5HEUaAE3457199 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2019051801; t=1560781837; bh=a9S2CuzLd4kYKu7CFHR/CjGCiqejAErFwevCNYz/wo8=; h=Date:From:Cc:Reply-To:In-Reply-To:References:To:Subject:From; b=AMDNfnxL1U//1YRMAtMTtPAeDlT3jJJ3ewrf3Vn5Lm2azvwtsgDmvB9otdShvY1Rm j2KFeT+/oCThvuSokG7npNEBh65BJno07+Ri2isX2VjLz0EjM0vvLDEsJoJSa69e5X 3Tw9Cxrp3lmN0npb5175125FCN/e6kFQG8zUJj6i49XmW26RptuJN0ptSa66dJhpvV BKlqtEs7uG+2Cadm0J+Ed+D+EaBb/mIdlIex0VeTH209LobkbQZA5KTH8sHMcfYwVn lw4N2ipSZ5qaFrBEC7Sav/r9+hR646E/8XXC84h3WQTmyhLQMFWsJenGtO3TIx/6NT k+IghpejThvbA== Received: (from tipbot@localhost) by terminus.zytor.com (8.15.2/8.15.2/Submit) id x5HEUatR3457196; Mon, 17 Jun 2019 07:30:36 -0700 Date: Mon, 17 Jun 2019 07:30:36 -0700 X-Authentication-Warning: terminus.zytor.com: tipbot set sender to tipbot@zytor.com using -f From: tip-bot for Waiman Long Message-ID: Cc: torvalds@linux-foundation.org, mingo@kernel.org, bp@alien8.de, huang.ying.caritas@gmail.com, will.deacon@arm.com, tglx@linutronix.de, peterz@infradead.org, hpa@zytor.com, tim.c.chen@linux.intel.com, linux-kernel@vger.kernel.org, longman@redhat.com, dave@stgolabs.net Reply-To: peterz@infradead.org, tglx@linutronix.de, will.deacon@arm.com, huang.ying.caritas@gmail.com, mingo@kernel.org, bp@alien8.de, torvalds@linux-foundation.org, dave@stgolabs.net, longman@redhat.com, linux-kernel@vger.kernel.org, hpa@zytor.com, tim.c.chen@linux.intel.com In-Reply-To: <20190520205918.22251-12-longman@redhat.com> References: <20190520205918.22251-12-longman@redhat.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:locking/core] locking/rwsem: Clarify usage of owner's nonspinaable bit Git-Commit-ID: 02f1082b003a0cd48f48f12533d969cdbf1c2b63 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline X-Spam-Status: No, score=0.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, DATE_IN_FUTURE_06_12,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU, DKIM_VALID_EF,FREEMAIL_FORGED_REPLYTO autolearn=no autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on terminus.zytor.com Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 02f1082b003a0cd48f48f12533d969cdbf1c2b63 Gitweb: https://git.kernel.org/tip/02f1082b003a0cd48f48f12533d969cdbf1c2b63 Author: Waiman Long AuthorDate: Mon, 20 May 2019 16:59:10 -0400 Committer: Ingo Molnar CommitDate: Mon, 17 Jun 2019 12:28:03 +0200 locking/rwsem: Clarify usage of owner's nonspinaable bit Bit 1 of sem->owner (RWSEM_ANONYMOUSLY_OWNED) is used to designate an anonymous owner - readers or an anonymous writer. The setting of this anonymous bit is used as an indicator that optimistic spinning cannot be done on this rwsem. With the upcoming reader optimistic spinning patches, a reader-owned rwsem can be spinned on for a limit period of time. We still need this bit to indicate a rwsem is nonspinnable, but not setting this bit loses its meaning that the owner is known. So rename the bit to RWSEM_NONSPINNABLE to clarify its meaning. This patch also fixes a DEBUG_RWSEMS_WARN_ON() bug in __up_write(). Signed-off-by: Waiman Long Signed-off-by: Peter Zijlstra (Intel) Cc: Borislav Petkov Cc: Davidlohr Bueso Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Tim Chen Cc: Will Deacon Cc: huang ying Link: https://lkml.kernel.org/r/20190520205918.22251-12-longman@redhat.com Signed-off-by: Ingo Molnar --- include/linux/rwsem.h | 2 +- kernel/locking/rwsem.c | 43 +++++++++++++++++++++---------------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h index 148983e21d47..bb76e82398b2 100644 --- a/include/linux/rwsem.h +++ b/include/linux/rwsem.h @@ -50,7 +50,7 @@ struct rw_semaphore { }; /* - * Setting bit 1 of the owner field but not bit 0 will indicate + * Setting all bits of the owner field except bit 0 will indicate * that the rwsem is writer-owned with an unknown owner. */ #define RWSEM_OWNER_UNKNOWN ((struct task_struct *)-2L) diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index ded96023f4dc..180455b6b0d4 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -33,17 +33,18 @@ /* * The least significant 2 bits of the owner value has the following * meanings when set. - * - RWSEM_READER_OWNED (bit 0): The rwsem is owned by readers - * - RWSEM_ANONYMOUSLY_OWNED (bit 1): The rwsem is anonymously owned, - * i.e. the owner(s) cannot be readily determined. It can be reader - * owned or the owning writer is indeterminate. + * - Bit 0: RWSEM_READER_OWNED - The rwsem is owned by readers + * - Bit 1: RWSEM_NONSPINNABLE - Waiters cannot spin on the rwsem + * The rwsem is anonymously owned, i.e. the owner(s) cannot be + * readily determined. It can be reader owned or the owning writer + * is indeterminate. * * When a writer acquires a rwsem, it puts its task_struct pointer * into the owner field. It is cleared after an unlock. * * When a reader acquires a rwsem, it will also puts its task_struct * pointer into the owner field with both the RWSEM_READER_OWNED and - * RWSEM_ANONYMOUSLY_OWNED bits set. On unlock, the owner field will + * RWSEM_NONSPINNABLE bits set. On unlock, the owner field will * largely be left untouched. So for a free or reader-owned rwsem, * the owner value may contain information about the last reader that * acquires the rwsem. The anonymous bit is set because that particular @@ -55,7 +56,8 @@ * a rwsem, but the overhead is simply too big. */ #define RWSEM_READER_OWNED (1UL << 0) -#define RWSEM_ANONYMOUSLY_OWNED (1UL << 1) +#define RWSEM_NONSPINNABLE (1UL << 1) +#define RWSEM_OWNER_FLAGS_MASK (RWSEM_READER_OWNED | RWSEM_NONSPINNABLE) #ifdef CONFIG_DEBUG_RWSEMS # define DEBUG_RWSEMS_WARN_ON(c, sem) do { \ @@ -132,7 +134,7 @@ static inline void __rwsem_set_reader_owned(struct rw_semaphore *sem, struct task_struct *owner) { unsigned long val = (unsigned long)owner | RWSEM_READER_OWNED - | RWSEM_ANONYMOUSLY_OWNED; + | RWSEM_NONSPINNABLE; WRITE_ONCE(sem->owner, (struct task_struct *)val); } @@ -144,20 +146,12 @@ static inline void rwsem_set_reader_owned(struct rw_semaphore *sem) /* * Return true if the a rwsem waiter can spin on the rwsem's owner - * and steal the lock, i.e. the lock is not anonymously owned. + * and steal the lock. * N.B. !owner is considered spinnable. */ static inline bool is_rwsem_owner_spinnable(struct task_struct *owner) { - return !((unsigned long)owner & RWSEM_ANONYMOUSLY_OWNED); -} - -/* - * Return true if rwsem is owned by an anonymous writer or readers. - */ -static inline bool rwsem_has_anonymous_owner(struct task_struct *owner) -{ - return (unsigned long)owner & RWSEM_ANONYMOUSLY_OWNED; + return !((unsigned long)owner & RWSEM_NONSPINNABLE); } #ifdef CONFIG_DEBUG_RWSEMS @@ -170,10 +164,10 @@ static inline bool rwsem_has_anonymous_owner(struct task_struct *owner) static inline void rwsem_clear_reader_owned(struct rw_semaphore *sem) { unsigned long val = (unsigned long)current | RWSEM_READER_OWNED - | RWSEM_ANONYMOUSLY_OWNED; + | RWSEM_NONSPINNABLE; if (READ_ONCE(sem->owner) == (struct task_struct *)val) cmpxchg_relaxed((unsigned long *)&sem->owner, val, - RWSEM_READER_OWNED | RWSEM_ANONYMOUSLY_OWNED); + RWSEM_READER_OWNED | RWSEM_NONSPINNABLE); } #else static inline void rwsem_clear_reader_owned(struct rw_semaphore *sem) @@ -495,7 +489,7 @@ static inline bool rwsem_can_spin_on_owner(struct rw_semaphore *sem) struct task_struct *owner; bool ret = true; - BUILD_BUG_ON(!rwsem_has_anonymous_owner(RWSEM_OWNER_UNKNOWN)); + BUILD_BUG_ON(is_rwsem_owner_spinnable(RWSEM_OWNER_UNKNOWN)); if (need_resched()) return false; @@ -534,7 +528,7 @@ static inline enum owner_state rwsem_owner_state(unsigned long owner) if (!owner) return OWNER_NULL; - if (owner & RWSEM_ANONYMOUSLY_OWNED) + if (owner & RWSEM_NONSPINNABLE) return OWNER_NONSPINNABLE; if (owner & RWSEM_READER_OWNED) @@ -1043,7 +1037,12 @@ static inline void __up_write(struct rw_semaphore *sem) { long tmp; - DEBUG_RWSEMS_WARN_ON(sem->owner != current, sem); + /* + * sem->owner may differ from current if the ownership is transferred + * to an anonymous writer by setting the RWSEM_NONSPINNABLE bits. + */ + DEBUG_RWSEMS_WARN_ON((sem->owner != current) && + !((long)sem->owner & RWSEM_NONSPINNABLE), sem); rwsem_clear_owner(sem); tmp = atomic_long_fetch_add_release(-RWSEM_WRITER_LOCKED, &sem->count); if (unlikely(tmp & RWSEM_FLAG_WAITERS))