From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752799AbdHIMFF (ORCPT ); Wed, 9 Aug 2017 08:05:05 -0400 Received: from mout.gmx.net ([212.227.17.21]:63751 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752589AbdHIMFB (ORCPT ); Wed, 9 Aug 2017 08:05:01 -0400 Message-ID: <1502280288.6441.3.camel@gmx.de> Subject: [patch-rt] locking, rwlock-rt: do not save state multiple times in __write_rt_lock() From: Mike Galbraith To: Sebastian Andrzej Siewior Cc: Thomas Gleixner , LKML , linux-rt-users , Steven Rostedt Date: Wed, 09 Aug 2017 14:04:48 +0200 In-Reply-To: <1502095134.5568.27.camel@gmx.de> References: <20170804173823.lzuhnejlnxczr2lj@linutronix.de> <1501913583.7917.42.camel@gmx.de> <20170807075254.pdu7immtbakn7f7g@linutronix.de> <1502095134.5568.27.camel@gmx.de> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.20.5 Mime-Version: 1.0 Content-Transfer-Encoding: 7bit X-Provags-ID: V03:K0:J1jaQtZ8k1peU0x6ehZYB5P2HAC1iS0O1AUEKSD3AsY6vYYph7e 03tnd8IN7Pjsqh9EjTQYb1xxs2+IBw1mFa1zsMP5bE413QFbsQ4smZlzFc+l5DYEhcnLlkz C5mB2i4GqPoCI23D/Vmm2pv2sO6RbEaai+6u1NS4YZVeOcT9KnFmQ2H821j8Mauw2AWoSFn drvgGR6gPFDIzp2/jiSCw== X-UI-Out-Filterresults: notjunk:1;V01:K0:CGBwYNiEXRM=:kmnma+PIVO6ZNWCyiWhs98 Vy91gHS/ASo9bALk40Ts7+1nn78dJzZU4C4iqpEjgK3eSRPvSB32DgP2N1t68JkCfBC9PHvlW 0WKLoamzfQA8x4QKDuRKO0nwevJCzrkY2rKn/ZEPRKJ+7BKbt83/YkD2RSKkhDMxvgv1EbLB2 hcZ8iTxszKH+r79+uondOPF4MYKRNLo0a8dpohDTKtDlWSHfHX59VzuI4+3zg/FrWJlHHlR6L 2n2Scd+FNIysbg1XXBWuQrpc+6+b0+niy1DFi56/NOvd0y2GZUnyMXTN9NSQujnqpSrvimg4c 0CWyy/tn9kg7diKqdkJDdxQByu2b56oiHlPG7Q+7rTzodvxing9oAsucMhuP8FX3sxjSPeAjR eANEhNF9Zx9PJD8/Tvv0IhEptqpKCgsXAr5lWJmpMxcUvRNNfpRfdQ755g6XNIF7ThYoanZGJ XZOv9pEKnB2Bp80beJ8hGN/8Sgl+TAiuCAtWuw+OC/ssAqIdgnMmUC2aT6Y+eTFYePLhvBASV r3crjd+ElRRVqk/hGt6ToQ4p60iPnlIgqrynJ5o4tY7ThDj6lCCqO9MQLpwb0jm5MwMHAoda0 yyeaiwlXApiqWsxhBVa/rtnSNzZMxtKHIGFna2u4p1HyLC/rg0wd5Bt/IQR0YgC8FHOUX7gMz YODB6aoFzVqbvE53Qulbnei31NMP8iRmGqa94HbbhO28fK1lCLBO5fefMkknlm1GgTM/yHwwq WOQLdropLTZdPYwdE2iVR3CLaJpLsz3+D7WjMVgE9WAICV7Wf6Trr0it4KiuPzBiZ2o7SigGV XRQFaRsSHWEGLnwCnMD/bekJjv9E1JDM2N0txUjCgYKMDK+J7Y= Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Save state prior to entering the acquisition loop, otherwise we may initially see readers, but upon releasing ->wait_lock see none, loop back around, and having not slept, save TASK_UNINTERRUPTIBLE. Signed-off-by_ Mike Galbraith --- kernel/locking/rwlock-rt.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) --- a/kernel/locking/rwlock-rt.c +++ b/kernel/locking/rwlock-rt.c @@ -190,30 +190,33 @@ void __sched __write_rt_lock(struct rt_r /* Force readers into slow path */ atomic_sub(READER_BIAS, &lock->readers); - for (;;) { - raw_spin_lock_irqsave(&m->wait_lock, flags); - - raw_spin_lock(&self->pi_lock); - self->saved_state = self->state; - __set_current_state_no_track(TASK_UNINTERRUPTIBLE); - raw_spin_unlock(&self->pi_lock); + raw_spin_lock_irqsave(&m->wait_lock, flags); + raw_spin_lock(&self->pi_lock); + self->saved_state = self->state; + __set_current_state_no_track(TASK_UNINTERRUPTIBLE); + raw_spin_unlock(&self->pi_lock); + for (;;) { /* Have all readers left the critical region? */ - if (!atomic_read(&lock->readers)) { - atomic_set(&lock->readers, WRITER_BIAS); - raw_spin_lock(&self->pi_lock); - __set_current_state_no_track(self->saved_state); - self->saved_state = TASK_RUNNING; - raw_spin_unlock(&self->pi_lock); - raw_spin_unlock_irqrestore(&m->wait_lock, flags); - return; - } + if (!atomic_read(&lock->readers)) + break; raw_spin_unlock_irqrestore(&m->wait_lock, flags); - if (atomic_read(&lock->readers) != 0) schedule(); + raw_spin_lock_irqsave(&m->wait_lock, flags); + + raw_spin_lock(&self->pi_lock); + __set_current_state_no_track(TASK_UNINTERRUPTIBLE); + raw_spin_unlock(&self->pi_lock); } + + atomic_set(&lock->readers, WRITER_BIAS); + raw_spin_lock(&self->pi_lock); + __set_current_state_no_track(self->saved_state); + self->saved_state = TASK_RUNNING; + raw_spin_unlock(&self->pi_lock); + raw_spin_unlock_irqrestore(&m->wait_lock, flags); } int __write_rt_trylock(struct rt_rw_lock *lock)