From: Ingo Molnar <mingo@kernel.org>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: linux-kernel@vger.kernel.org,
Peter Zijlstra <a.p.zijlstra@chello.nl>,
Thomas Gleixner <tglx@linutronix.de>,
Andrew Morton <akpm@linux-foundation.org>
Subject: [GIT PULL] locking fix
Date: Thu, 16 May 2019 18:01:35 +0200 [thread overview]
Message-ID: <20190516160135.GA45760@gmail.com> (raw)
Linus,
Please pull the latest locking-urgent-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git locking-urgent-for-linus
# HEAD: a9e9bcb45b1525ba7aea26ed9441e8632aeeda58 locking/rwsem: Prevent decrement of reader count before increment
A single rwsem fix.
Thanks,
Ingo
------------------>
Waiman Long (1):
locking/rwsem: Prevent decrement of reader count before increment
kernel/locking/rwsem-xadd.c | 46 ++++++++++++++++++++++++++++++---------------
1 file changed, 31 insertions(+), 15 deletions(-)
diff --git a/kernel/locking/rwsem-xadd.c b/kernel/locking/rwsem-xadd.c
index 6b3ee9948bf1..0b1f77957240 100644
--- a/kernel/locking/rwsem-xadd.c
+++ b/kernel/locking/rwsem-xadd.c
@@ -130,6 +130,7 @@ static void __rwsem_mark_wake(struct rw_semaphore *sem,
{
struct rwsem_waiter *waiter, *tmp;
long oldcount, woken = 0, adjustment = 0;
+ struct list_head wlist;
/*
* Take a peek at the queue head waiter such that we can determine
@@ -188,18 +189,43 @@ static void __rwsem_mark_wake(struct rw_semaphore *sem,
* of the queue. We know that woken will be at least 1 as we accounted
* for above. Note we increment the 'active part' of the count by the
* number of readers before waking any processes up.
+ *
+ * We have to do wakeup in 2 passes to prevent the possibility that
+ * the reader count may be decremented before it is incremented. It
+ * is because the to-be-woken waiter may not have slept yet. So it
+ * may see waiter->task got cleared, finish its critical section and
+ * do an unlock before the reader count increment.
+ *
+ * 1) Collect the read-waiters in a separate list, count them and
+ * fully increment the reader count in rwsem.
+ * 2) For each waiters in the new list, clear waiter->task and
+ * put them into wake_q to be woken up later.
*/
- list_for_each_entry_safe(waiter, tmp, &sem->wait_list, list) {
- struct task_struct *tsk;
-
+ list_for_each_entry(waiter, &sem->wait_list, list) {
if (waiter->type == RWSEM_WAITING_FOR_WRITE)
break;
woken++;
- tsk = waiter->task;
+ }
+ list_cut_before(&wlist, &sem->wait_list, &waiter->list);
+
+ adjustment = woken * RWSEM_ACTIVE_READ_BIAS - adjustment;
+ lockevent_cond_inc(rwsem_wake_reader, woken);
+ if (list_empty(&sem->wait_list)) {
+ /* hit end of list above */
+ adjustment -= RWSEM_WAITING_BIAS;
+ }
+
+ if (adjustment)
+ atomic_long_add(adjustment, &sem->count);
+
+ /* 2nd pass */
+ list_for_each_entry_safe(waiter, tmp, &wlist, list) {
+ struct task_struct *tsk;
+ tsk = waiter->task;
get_task_struct(tsk);
- list_del(&waiter->list);
+
/*
* Ensure calling get_task_struct() before setting the reader
* waiter to nil such that rwsem_down_read_failed() cannot
@@ -213,16 +239,6 @@ static void __rwsem_mark_wake(struct rw_semaphore *sem,
*/
wake_q_add_safe(wake_q, tsk);
}
-
- adjustment = woken * RWSEM_ACTIVE_READ_BIAS - adjustment;
- lockevent_cond_inc(rwsem_wake_reader, woken);
- if (list_empty(&sem->wait_list)) {
- /* hit end of list above */
- adjustment -= RWSEM_WAITING_BIAS;
- }
-
- if (adjustment)
- atomic_long_add(adjustment, &sem->count);
}
/*
next reply other threads:[~2019-05-16 16:01 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-16 16:01 Ingo Molnar [this message]
2019-05-16 17:57 ` [GIT PULL] locking fix Linus Torvalds
2019-05-16 18:39 ` Greg KH
2019-05-16 18:42 ` Linus Torvalds
2019-05-16 23:55 ` Sasha Levin
2019-05-17 12:16 ` Greg KH
2019-05-16 18:20 ` pr-tracker-bot
-- strict thread matches above, loose matches on Subject: below --
2025-11-08 13:04 Ingo Molnar
2025-11-08 17:15 ` pr-tracker-bot
2025-09-07 10:16 Ingo Molnar
2025-09-07 15:32 ` pr-tracker-bot
2025-02-28 19:02 Ingo Molnar
2025-03-01 1:40 ` pr-tracker-bot
2025-02-08 9:08 Ingo Molnar
2025-02-08 20:07 ` pr-tracker-bot
2024-12-29 8:46 Ingo Molnar
2024-12-29 18:22 ` pr-tracker-bot
2024-06-08 7:35 Ingo Molnar
2024-06-08 16:50 ` pr-tracker-bot
2024-04-14 8:01 Ingo Molnar
2024-04-14 18:48 ` pr-tracker-bot
2023-11-26 9:39 Ingo Molnar
2023-11-26 17:16 ` pr-tracker-bot
2023-02-11 8:54 Ingo Molnar
2023-02-11 19:24 ` pr-tracker-bot
2021-03-28 10:28 Ingo Molnar
2021-03-28 19:22 ` pr-tracker-bot
2019-07-14 11:36 Ingo Molnar
2019-07-14 18:45 ` pr-tracker-bot
2019-04-12 11:53 Ingo Molnar
2019-04-13 4:05 ` pr-tracker-bot
2017-07-21 10:11 Ingo Molnar
2016-09-13 18:11 Ingo Molnar
2016-04-16 9:16 Ingo Molnar
2015-08-14 7:08 Ingo Molnar
2015-03-28 10:07 Ingo Molnar
2015-03-01 16:57 Ingo Molnar
2013-10-26 12:19 Ingo Molnar
2013-10-27 17:28 ` Linus Torvalds
2013-10-27 19:00 ` Maarten Lankhorst
2013-10-27 19:23 ` Linus Torvalds
2013-10-27 19:35 ` Linus Torvalds
2013-10-27 19:37 ` Maarten Lankhorst
2013-10-27 19:51 ` Linus Torvalds
2013-10-27 19:56 ` Maarten Lankhorst
2013-10-27 19:59 ` Linus Torvalds
2013-10-28 8:47 ` Ingo Molnar
2011-02-15 17:02 Ingo Molnar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190516160135.GA45760@gmail.com \
--to=mingo@kernel.org \
--cc=a.p.zijlstra@chello.nl \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).