Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751782AbdGEObt (ORCPT ); Wed, 5 Jul 2017 10:31:49 -0400 Received: from terminus.zytor.com ([65.50.211.136]:47267 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751509AbdGEObr (ORCPT ); Wed, 5 Jul 2017 10:31:47 -0400 Date: Wed, 5 Jul 2017 07:27:58 -0700 From: tip-bot for Kirill Tkhai Message-ID: Cc: ktkhai@virtuozzo.com, a.p.zijlstra@chello.nl, niklas.cassel@axis.com, hpa@zytor.com, mingo@kernel.org, peterz@infradead.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, torvalds@linux-foundation.org, tglx@linutronix.de Reply-To: stable@vger.kernel.org, torvalds@linux-foundation.org, tglx@linutronix.de, a.p.zijlstra@chello.nl, ktkhai@virtuozzo.com, niklas.cassel@axis.com, hpa@zytor.com, linux-kernel@vger.kernel.org, peterz@infradead.org, mingo@kernel.org In-Reply-To: <149762063282.19811.9129615532201147826.stgit@localhost.localdomain> References: <149762063282.19811.9129615532201147826.stgit@localhost.localdomain> To: linux-tip-commits@vger.kernel.org Subject: [tip:locking/urgent] locking/rwsem-spinlock: Fix EINTR branch in __down_write_common() Git-Commit-ID: a0c4acd2c220376b4e9690e75782d0c0afdaab9f 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 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2253 Lines: 61 Commit-ID: a0c4acd2c220376b4e9690e75782d0c0afdaab9f Gitweb: http://git.kernel.org/tip/a0c4acd2c220376b4e9690e75782d0c0afdaab9f Author: Kirill Tkhai AuthorDate: Fri, 16 Jun 2017 16:44:34 +0300 Committer: Ingo Molnar CommitDate: Wed, 5 Jul 2017 12:26:29 +0200 locking/rwsem-spinlock: Fix EINTR branch in __down_write_common() If a writer could been woken up, the above branch if (sem->count == 0) break; would have moved us to taking the sem. So, it's not the time to wake a writer now, and only readers are allowed now. Thus, 0 must be passed to __rwsem_do_wake(). Next, __rwsem_do_wake() wakes readers unconditionally. But we mustn't do that if the sem is owned by writer in the moment. Otherwise, writer and reader own the sem the same time, which leads to memory corruption in callers. rwsem-xadd.c does not need that, as: 1) the similar check is made lockless there, 2) in __rwsem_mark_wake::try_reader_grant we test, that sem is not owned by writer. Signed-off-by: Kirill Tkhai Acked-by: Peter Zijlstra Cc: Cc: Linus Torvalds Cc: Niklas Cassel Cc: Peter Zijlstra (Intel) Cc: Peter Zijlstra Cc: Thomas Gleixner Fixes: 17fcbd590d0c "locking/rwsem: Fix down_write_killable() for CONFIG_RWSEM_GENERIC_SPINLOCK=y" Link: http://lkml.kernel.org/r/149762063282.19811.9129615532201147826.stgit@localhost.localdomain Signed-off-by: Ingo Molnar --- kernel/locking/rwsem-spinlock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/locking/rwsem-spinlock.c b/kernel/locking/rwsem-spinlock.c index c65f798..20819df 100644 --- a/kernel/locking/rwsem-spinlock.c +++ b/kernel/locking/rwsem-spinlock.c @@ -231,8 +231,8 @@ int __sched __down_write_common(struct rw_semaphore *sem, int state) out_nolock: list_del(&waiter.list); - if (!list_empty(&sem->wait_list)) - __rwsem_do_wake(sem, 1); + if (!list_empty(&sem->wait_list) && sem->count >= 0) + __rwsem_do_wake(sem, 0); raw_spin_unlock_irqrestore(&sem->wait_lock, flags); return -EINTR;