diff options
-rw-r--r-- | include/asm-generic/qrwlock.h | 27 | ||||
-rw-r--r-- | kernel/futex.c | 23 | ||||
-rw-r--r-- | kernel/locking/qspinlock_paravirt.h | 2 | ||||
-rw-r--r-- | kernel/locking/qspinlock_stat.h | 1 |
4 files changed, 48 insertions, 5 deletions
diff --git a/include/asm-generic/qrwlock.h b/include/asm-generic/qrwlock.h index 54a8e65e18b6..7d026bf27713 100644 --- a/include/asm-generic/qrwlock.h +++ b/include/asm-generic/qrwlock.h | |||
@@ -25,7 +25,20 @@ | |||
25 | #include <asm-generic/qrwlock_types.h> | 25 | #include <asm-generic/qrwlock_types.h> |
26 | 26 | ||
27 | /* | 27 | /* |
28 | * Writer states & reader shift and bias | 28 | * Writer states & reader shift and bias. |
29 | * | ||
30 | * | +0 | +1 | +2 | +3 | | ||
31 | * ----+----+----+----+----+ | ||
32 | * LE | 78 | 56 | 34 | 12 | 0x12345678 | ||
33 | * ----+----+----+----+----+ | ||
34 | * | wr | rd | | ||
35 | * +----+----+----+----+ | ||
36 | * | ||
37 | * ----+----+----+----+----+ | ||
38 | * BE | 12 | 34 | 56 | 78 | 0x12345678 | ||
39 | * ----+----+----+----+----+ | ||
40 | * | rd | wr | | ||
41 | * +----+----+----+----+ | ||
29 | */ | 42 | */ |
30 | #define _QW_WAITING 1 /* A writer is waiting */ | 43 | #define _QW_WAITING 1 /* A writer is waiting */ |
31 | #define _QW_LOCKED 0xff /* A writer holds the lock */ | 44 | #define _QW_LOCKED 0xff /* A writer holds the lock */ |
@@ -134,12 +147,22 @@ static inline void queued_read_unlock(struct qrwlock *lock) | |||
134 | } | 147 | } |
135 | 148 | ||
136 | /** | 149 | /** |
150 | * __qrwlock_write_byte - retrieve the write byte address of a queue rwlock | ||
151 | * @lock : Pointer to queue rwlock structure | ||
152 | * Return: the write byte address of a queue rwlock | ||
153 | */ | ||
154 | static inline u8 *__qrwlock_write_byte(struct qrwlock *lock) | ||
155 | { | ||
156 | return (u8 *)lock + 3 * IS_BUILTIN(CONFIG_CPU_BIG_ENDIAN); | ||
157 | } | ||
158 | |||
159 | /** | ||
137 | * queued_write_unlock - release write lock of a queue rwlock | 160 | * queued_write_unlock - release write lock of a queue rwlock |
138 | * @lock : Pointer to queue rwlock structure | 161 | * @lock : Pointer to queue rwlock structure |
139 | */ | 162 | */ |
140 | static inline void queued_write_unlock(struct qrwlock *lock) | 163 | static inline void queued_write_unlock(struct qrwlock *lock) |
141 | { | 164 | { |
142 | smp_store_release((u8 *)&lock->cnts, 0); | 165 | smp_store_release(__qrwlock_write_byte(lock), 0); |
143 | } | 166 | } |
144 | 167 | ||
145 | /* | 168 | /* |
diff --git a/kernel/futex.c b/kernel/futex.c index 33664f70e2d2..46cb3a301bc1 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -179,7 +179,15 @@ int __read_mostly futex_cmpxchg_enabled; | |||
179 | * Futex flags used to encode options to functions and preserve them across | 179 | * Futex flags used to encode options to functions and preserve them across |
180 | * restarts. | 180 | * restarts. |
181 | */ | 181 | */ |
182 | #define FLAGS_SHARED 0x01 | 182 | #ifdef CONFIG_MMU |
183 | # define FLAGS_SHARED 0x01 | ||
184 | #else | ||
185 | /* | ||
186 | * NOMMU does not have per process address space. Let the compiler optimize | ||
187 | * code away. | ||
188 | */ | ||
189 | # define FLAGS_SHARED 0x00 | ||
190 | #endif | ||
183 | #define FLAGS_CLOCKRT 0x02 | 191 | #define FLAGS_CLOCKRT 0x02 |
184 | #define FLAGS_HAS_TIMEOUT 0x04 | 192 | #define FLAGS_HAS_TIMEOUT 0x04 |
185 | 193 | ||
@@ -405,6 +413,16 @@ static void get_futex_key_refs(union futex_key *key) | |||
405 | if (!key->both.ptr) | 413 | if (!key->both.ptr) |
406 | return; | 414 | return; |
407 | 415 | ||
416 | /* | ||
417 | * On MMU less systems futexes are always "private" as there is no per | ||
418 | * process address space. We need the smp wmb nevertheless - yes, | ||
419 | * arch/blackfin has MMU less SMP ... | ||
420 | */ | ||
421 | if (!IS_ENABLED(CONFIG_MMU)) { | ||
422 | smp_mb(); /* explicit smp_mb(); (B) */ | ||
423 | return; | ||
424 | } | ||
425 | |||
408 | switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) { | 426 | switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) { |
409 | case FUT_OFF_INODE: | 427 | case FUT_OFF_INODE: |
410 | ihold(key->shared.inode); /* implies smp_mb(); (B) */ | 428 | ihold(key->shared.inode); /* implies smp_mb(); (B) */ |
@@ -436,6 +454,9 @@ static void drop_futex_key_refs(union futex_key *key) | |||
436 | return; | 454 | return; |
437 | } | 455 | } |
438 | 456 | ||
457 | if (!IS_ENABLED(CONFIG_MMU)) | ||
458 | return; | ||
459 | |||
439 | switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) { | 460 | switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) { |
440 | case FUT_OFF_INODE: | 461 | case FUT_OFF_INODE: |
441 | iput(key->shared.inode); | 462 | iput(key->shared.inode); |
diff --git a/kernel/locking/qspinlock_paravirt.h b/kernel/locking/qspinlock_paravirt.h index 37649e69056c..8a99abf58080 100644 --- a/kernel/locking/qspinlock_paravirt.h +++ b/kernel/locking/qspinlock_paravirt.h | |||
@@ -450,7 +450,7 @@ pv_wait_head_or_lock(struct qspinlock *lock, struct mcs_spinlock *node) | |||
450 | goto gotlock; | 450 | goto gotlock; |
451 | } | 451 | } |
452 | } | 452 | } |
453 | WRITE_ONCE(pn->state, vcpu_halted); | 453 | WRITE_ONCE(pn->state, vcpu_hashed); |
454 | qstat_inc(qstat_pv_wait_head, true); | 454 | qstat_inc(qstat_pv_wait_head, true); |
455 | qstat_inc(qstat_pv_wait_again, waitcnt); | 455 | qstat_inc(qstat_pv_wait_again, waitcnt); |
456 | pv_wait(&l->locked, _Q_SLOW_VAL); | 456 | pv_wait(&l->locked, _Q_SLOW_VAL); |
diff --git a/kernel/locking/qspinlock_stat.h b/kernel/locking/qspinlock_stat.h index 22e025309845..b9d031516254 100644 --- a/kernel/locking/qspinlock_stat.h +++ b/kernel/locking/qspinlock_stat.h | |||
@@ -153,7 +153,6 @@ static ssize_t qstat_read(struct file *file, char __user *user_buf, | |||
153 | */ | 153 | */ |
154 | if ((counter == qstat_pv_latency_kick) || | 154 | if ((counter == qstat_pv_latency_kick) || |
155 | (counter == qstat_pv_latency_wake)) { | 155 | (counter == qstat_pv_latency_wake)) { |
156 | stat = 0; | ||
157 | if (kicks) | 156 | if (kicks) |
158 | stat = DIV_ROUND_CLOSEST_ULL(stat, kicks); | 157 | stat = DIV_ROUND_CLOSEST_ULL(stat, kicks); |
159 | } | 158 | } |