From: Peter Zijlstra <peterz@infradead.org>
To: mingo@kernel.org, linux-kernel@vger.kernel.org
Cc: peterz@infradead.org, torvalds@linux-foundation.org,
tglx@linutronix.de, bigeasy@linutronix.de, oleg@redhat.com,
paulmck@linux.vnet.ibm.com, pbonzini@redhat.com
Subject: [PATCH 2/3] sched/swait: Switch to full exclusive mode
Date: Tue, 12 Jun 2018 10:34:51 +0200 [thread overview]
Message-ID: <20180612083909.209762413@infradead.org> (raw)
In-Reply-To: 20180612083449.100099222@infradead.org
[-- Attachment #1: peterz-swait-1.patch --]
[-- Type: text/plain, Size: 3397 bytes --]
Linus noted that swait basically implements exclusive mode -- because
swake_up() only wakes a single waiter. And because of that it should
take care to properly deal with the interruptible case.
In short, the problem is that swake_up() can race with a signal. In
this this case it is possible the swake_up() 'wakes' the waiter that
is already on the way out because it just got a signal and the wakeup
gets lost.
The normal wait code is very careful and avoids this situation, make
sure we do too.
Copy the exact exclusive semantics from wait.
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
include/linux/swait.h | 11 ++++++-----
kernel/sched/swait.c | 22 +++++++++++++++++-----
2 files changed, 23 insertions(+), 10 deletions(-)
--- a/include/linux/swait.h
+++ b/include/linux/swait.h
@@ -38,8 +38,8 @@
* all wakeups are TASK_NORMAL in order to avoid O(n) lookups for the right
* sleeper state.
*
- * - the exclusive mode; because this requires preserving the list order
- * and this is hard.
+ * - the !exclusive mode; because that leads to O(n) wakeups, everything is
+ * exclusive.
*
* - custom wake callback functions; because you cannot give any guarantees
* about random code. This also allows swait to be used in RT, such that
@@ -167,9 +167,10 @@ extern long prepare_to_swait_event(struc
extern void __finish_swait(struct swait_queue_head *q, struct swait_queue *wait);
extern void finish_swait(struct swait_queue_head *q, struct swait_queue *wait);
-/* as per ___wait_event() but for swait, therefore "exclusive == 0" */
+/* as per ___wait_event() but for swait, therefore "exclusive == 1" */
#define ___swait_event(wq, condition, state, ret, cmd) \
({ \
+ __label__ __out; \
struct swait_queue __wait; \
long __ret = ret; \
\
@@ -182,13 +183,13 @@ extern void finish_swait(struct swait_qu
\
if (___wait_is_interruptible(state) && __int) { \
__ret = __int; \
- break; \
+ goto __out; \
} \
\
cmd; \
} \
finish_swait(&wq, &__wait); \
- __ret; \
+__out: __ret; \
})
#define __swait_event(wq, condition) \
--- a/kernel/sched/swait.c
+++ b/kernel/sched/swait.c
@@ -73,7 +73,7 @@ static void __prepare_to_swait(struct sw
{
wait->task = current;
if (list_empty(&wait->task_list))
- list_add(&wait->task_list, &q->task_list);
+ list_add_tail(&wait->task_list, &q->task_list);
}
void prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait, int state)
@@ -89,12 +89,24 @@ EXPORT_SYMBOL(prepare_to_swait);
long prepare_to_swait_event(struct swait_queue_head *q, struct swait_queue *wait, int state)
{
- if (signal_pending_state(state, current))
- return -ERESTARTSYS;
+ unsigned long flags;
+ long ret = 0;
- prepare_to_swait(q, wait, state);
+ raw_spin_lock_irqsave(&q->lock, flags);
+ if (unlikely(signal_pending_state(state, current))) {
+ /*
+ * See prepare_to_wait_event(). TL;DR, subsequent swake_up()
+ * must not see us.
+ */
+ list_del_init(&wait->task_list);
+ ret = -ERESTARTSYS;
+ } else {
+ __prepare_to_swait(q, wait);
+ set_current_state(state);
+ }
+ raw_spin_unlock_irqrestore(&q->lock, flags);
- return 0;
+ return ret;
}
EXPORT_SYMBOL(prepare_to_swait_event);
next prev parent reply other threads:[~2018-06-12 8:41 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-12 8:34 [PATCH 0/3] sched/swait: Convert to full exclusive mode Peter Zijlstra
2018-06-12 8:34 ` [PATCH 1/3] sched/swait: Remove __prepare_to_swait Peter Zijlstra
2018-06-20 9:39 ` [tip:sched/core] " tip-bot for Peter Zijlstra
2018-06-12 8:34 ` Peter Zijlstra [this message]
2018-06-20 9:40 ` [tip:sched/core] sched/swait: Switch to full exclusive mode tip-bot for Peter Zijlstra
2018-06-12 8:34 ` [PATCH 3/3] sched/swait: Rename to exclusive Peter Zijlstra
2018-06-20 9:40 ` [tip:sched/core] " tip-bot for Peter Zijlstra
2018-06-12 16:47 ` [PATCH 0/3] sched/swait: Convert to full exclusive mode Linus Torvalds
2018-06-12 17:14 ` Quilt vs gmail (Was: [PATCH 0/3] sched/swait: Convert to full exclusive mode) Peter Zijlstra
2018-06-13 12:32 ` Jean Delvare
2018-06-13 13:27 ` Andreas Grünbacher
2018-06-13 13:48 ` Linus Torvalds
2018-06-13 14:40 ` Jean Delvare
2018-06-12 18:52 ` [PATCH 0/3] sched/swait: Convert to full exclusive mode Andreas Grünbacher
[not found] ` <CA+55aFx81igOjFZcvO03mvDFd3=pxsq2QuNrWrPW+4pvJy780A@mail.gmail.com>
2018-06-12 19:43 ` Thomas Gleixner
2018-06-12 21:54 ` Sebastian Andrzej Siewior
2018-06-12 22:03 ` Linus Torvalds
2018-06-12 22:55 ` Randy Dunlap
2018-06-13 13:00 ` [Quilt-dev] Quilt vs gmail Jean Delvare
2018-06-13 13:35 ` Greg KH
2018-06-14 1:27 ` [PATCH 0/3] sched/swait: Convert to full exclusive mode Paul E. McKenney
2018-06-19 14:49 ` Paul E. McKenney
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=20180612083909.209762413@infradead.org \
--to=peterz@infradead.org \
--cc=bigeasy@linutronix.de \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=oleg@redhat.com \
--cc=paulmck@linux.vnet.ibm.com \
--cc=pbonzini@redhat.com \
--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).