1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
From: Mike Galbraith <efault@gmx.de>
Date: Fri, 18 Aug 2017 10:56:14 +0200
Subject: [PATCH] locking, rwlock-rt: do not save state multiple times in
__write_rt_lock()
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 <efault@gmx.de>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
kernel/locking/rwlock-rt.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
--- a/kernel/locking/rwlock-rt.c
+++ b/kernel/locking/rwlock-rt.c
@@ -190,14 +190,14 @@ 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_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(&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);
@@ -213,6 +213,12 @@ void __sched __write_rt_lock(struct rt_r
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);
}
}
|