Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp2906235rwb; Thu, 17 Nov 2022 18:42:19 -0800 (PST) X-Google-Smtp-Source: AA0mqf7mnZfE/urYPAFGauH+I26T89fmaYzMRaO8zBt91LLInOt9tvsjk2TlKjSkWCVmo7vmdxLJ X-Received: by 2002:a17:907:d092:b0:7ad:7e85:8056 with SMTP id vc18-20020a170907d09200b007ad7e858056mr4294496ejc.40.1668739339557; Thu, 17 Nov 2022 18:42:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668739339; cv=none; d=google.com; s=arc-20160816; b=mXiqe4VlJoFWDUSpXHvkOoNUKMzdRz5d3x3MQhH//4e4iiwW3eW/x+asaZG3KEA7rA xA1Si4T6mn4GTMxG2DzRbzdMuG8aIW9yghUa2owwe4SruhTwWPdEMRTm4q0B8jS/J/Id AOeM0LYgYTv4PXoKfZXa2zkXfxtUpb3WNeYXgd07Xv1Qop1/OlUatnZ2ARCRGt+VJYaf Qokd3LLTuITGIUEi/g70XvsOOq6Kr825FalFzKBiGE/0yGgSkkbne71g+8hysIEzu93+ Up68XtD7iqExz35bRKAkAWe6f8Sml/GUIOayt7r99IM+2I+l/5LwMHkzvbhG18VTLlAV g4fg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=lVJQ6hSeE7yu8R15/R64CIrCsSyaWJogCMScfV2fhQc=; b=BiZqCv7YP/1tGQReVI/Au+bULOfhpSVGgVpGYCtSIWp76ffcJv/pD31mGFE+vr6FTo Rok0bsgMNYrwd/zqbGxizk/KHNveaKipEqsV9xLhaFRo6dD6ShaPJj4yRcEfcFf6Jjnp Po0mQFScLNDQko0w9AGnilcvjWQmADQeW4JDUV+mqaqeMD/RZY/B5FL6D2tfrpX1MyWB V1e8g9mnFkGSmMNmQhWO+NcQrX2hS9xw1jLdrFx2ZoA6FEk2Ku6nJvzItJPcFXcFbiki EpA7XdkPFtINbOT4S/2V66wDRvuep2CO7apZvyIG2MQKuFRTMViFjwrDnSxwskgx8w9T /MKg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=hWRqhY9m; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id y13-20020a056402270d00b0046769e40ee5si2550269edd.321.2022.11.17.18.41.57; Thu, 17 Nov 2022 18:42:19 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=hWRqhY9m; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240796AbiKRCVX (ORCPT + 91 others); Thu, 17 Nov 2022 21:21:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45562 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240125AbiKRCVW (ORCPT ); Thu, 17 Nov 2022 21:21:22 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7D77273BBA for ; Thu, 17 Nov 2022 18:20:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1668738027; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lVJQ6hSeE7yu8R15/R64CIrCsSyaWJogCMScfV2fhQc=; b=hWRqhY9mtL6gzfXSgEyX4TlDJyP50BSjbWoGLijTkBylHvgkLJLtl6+UoOovjKiVLyUzFk 1+cUCCfSnrKyBvsfymLXAvxamuA+/2pZE7EQ4ucnWipQmIoQGYuNPnBjwbDNWbxCrqH5Oc a3dlEklbXhwletp0iEOJW5/2J7Ks41E= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-604-yat0ZngWP7yFMYR3tIRVEg-1; Thu, 17 Nov 2022 21:20:24 -0500 X-MC-Unique: yat0ZngWP7yFMYR3tIRVEg-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 1C7F7811E7A; Fri, 18 Nov 2022 02:20:24 +0000 (UTC) Received: from llong.com (unknown [10.22.16.250]) by smtp.corp.redhat.com (Postfix) with ESMTP id AE15749BB60; Fri, 18 Nov 2022 02:20:23 +0000 (UTC) From: Waiman Long To: Peter Zijlstra , Ingo Molnar , Will Deacon , Boqun Feng Cc: linux-kernel@vger.kernel.org, john.p.donnelly@oracle.com, Hillf Danton , Mukesh Ojha , =?UTF-8?q?Ting11=20Wang=20=E7=8E=8B=E5=A9=B7?= , Waiman Long Subject: [PATCH v6 2/6] locking/rwsem: Disable preemption at all down_read*() and up_read() code paths Date: Thu, 17 Nov 2022 21:20:12 -0500 Message-Id: <20221118022016.462070-3-longman@redhat.com> In-Reply-To: <20221118022016.462070-1-longman@redhat.com> References: <20221118022016.462070-1-longman@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 3.1 on 10.11.54.9 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit 91d2a812dfb9 ("locking/rwsem: Make handoff writer optimistically spin on owner") assumes that when the owner field is changed to NULL, the lock will become free soon. Commit 48dfb5d2560d ("locking/rwsem: Disable preemption while trying for rwsem lock") disables preemption when acquiring rwsem for write. However, preemption has not yet been disabled when acquiring a read lock on a rwsem. So a reader can add a RWSEM_READER_BIAS to count without setting owner to signal a reader, got preempted out by a RT task which then spins in the writer slowpath as owner remains NULL leading to live lock. One easy way to fix this problem is to disable preemption at all the down_read*() and up_read() code paths as implemented in this patch. Fixes: 91d2a812dfb9 ("locking/rwsem: Make handoff writer optimistically spin on owner") Reported-by: Mukesh Ojha Suggested-by: Peter Zijlstra Signed-off-by: Waiman Long --- kernel/locking/rwsem.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index be2df9ea7c30..ebaff8a87e1d 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -1091,7 +1091,7 @@ rwsem_down_read_slowpath(struct rw_semaphore *sem, long count, unsigned int stat /* Ordered by sem->wait_lock against rwsem_mark_wake(). */ break; } - schedule(); + schedule_preempt_disabled(); lockevent_inc(rwsem_sleep_reader); } @@ -1253,14 +1253,20 @@ static struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem) */ static inline int __down_read_common(struct rw_semaphore *sem, int state) { + int ret = 0; long count; + preempt_disable(); if (!rwsem_read_trylock(sem, &count)) { - if (IS_ERR(rwsem_down_read_slowpath(sem, count, state))) - return -EINTR; + if (IS_ERR(rwsem_down_read_slowpath(sem, count, state))) { + ret = -EINTR; + goto out; + } DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem); } - return 0; +out: + preempt_enable(); + return ret; } static inline void __down_read(struct rw_semaphore *sem) @@ -1280,19 +1286,23 @@ static inline int __down_read_killable(struct rw_semaphore *sem) static inline int __down_read_trylock(struct rw_semaphore *sem) { + int ret = 0; long tmp; DEBUG_RWSEMS_WARN_ON(sem->magic != sem, sem); + preempt_disable(); tmp = atomic_long_read(&sem->count); while (!(tmp & RWSEM_READ_FAILED_MASK)) { if (atomic_long_try_cmpxchg_acquire(&sem->count, &tmp, tmp + RWSEM_READER_BIAS)) { rwsem_set_reader_owned(sem); - return 1; + ret = 1; + break; } } - return 0; + preempt_enable(); + return ret; } /* @@ -1334,6 +1344,7 @@ static inline void __up_read(struct rw_semaphore *sem) DEBUG_RWSEMS_WARN_ON(sem->magic != sem, sem); DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem); + preempt_disable(); rwsem_clear_reader_owned(sem); tmp = atomic_long_add_return_release(-RWSEM_READER_BIAS, &sem->count); DEBUG_RWSEMS_WARN_ON(tmp < 0, sem); @@ -1342,6 +1353,7 @@ static inline void __up_read(struct rw_semaphore *sem) clear_nonspinnable(sem); rwsem_wake(sem); } + preempt_enable(); } /* -- 2.31.1