Skip to content

Commit 1f8083c

Browse files
committed
Merge branch 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull locking fixes from Ingo Molnar: "Misc fixes: lockstat fix, futex fix on !MMU systems, big endian fix for qrwlocks and a race fix for pvqspinlocks" * 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: locking/pvqspinlock: Fix a bug in qstat_read() locking/pvqspinlock: Fix double hash race locking/qrwlock: Fix write unlock bug on big endian systems futex: Assume all mappings are private on !MMU systems
2 parents 25db691 + c2ace36 commit 1f8083c

File tree

4 files changed

+48
-5
lines changed

4 files changed

+48
-5
lines changed

include/asm-generic/qrwlock.h

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,20 @@
2525
#include <asm-generic/qrwlock_types.h>
2626

2727
/*
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+
* +----+----+----+----+
2942
*/
3043
#define _QW_WAITING 1 /* A writer is waiting */
3144
#define _QW_LOCKED 0xff /* A writer holds the lock */
@@ -133,13 +146,23 @@ static inline void queued_read_unlock(struct qrwlock *lock)
133146
(void)atomic_sub_return_release(_QR_BIAS, &lock->cnts);
134147
}
135148

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+
136159
/**
137160
* queued_write_unlock - release write lock of a queue rwlock
138161
* @lock : Pointer to queue rwlock structure
139162
*/
140163
static inline void queued_write_unlock(struct qrwlock *lock)
141164
{
142-
smp_store_release((u8 *)&lock->cnts, 0);
165+
smp_store_release(__qrwlock_write_byte(lock), 0);
143166
}
144167

145168
/*

kernel/futex.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,15 @@ int __read_mostly futex_cmpxchg_enabled;
179179
* Futex flags used to encode options to functions and preserve them across
180180
* restarts.
181181
*/
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
183191
#define FLAGS_CLOCKRT 0x02
184192
#define FLAGS_HAS_TIMEOUT 0x04
185193

@@ -405,6 +413,16 @@ static void get_futex_key_refs(union futex_key *key)
405413
if (!key->both.ptr)
406414
return;
407415

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+
408426
switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) {
409427
case FUT_OFF_INODE:
410428
ihold(key->shared.inode); /* implies smp_mb(); (B) */
@@ -436,6 +454,9 @@ static void drop_futex_key_refs(union futex_key *key)
436454
return;
437455
}
438456

457+
if (!IS_ENABLED(CONFIG_MMU))
458+
return;
459+
439460
switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) {
440461
case FUT_OFF_INODE:
441462
iput(key->shared.inode);

kernel/locking/qspinlock_paravirt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ pv_wait_head_or_lock(struct qspinlock *lock, struct mcs_spinlock *node)
450450
goto gotlock;
451451
}
452452
}
453-
WRITE_ONCE(pn->state, vcpu_halted);
453+
WRITE_ONCE(pn->state, vcpu_hashed);
454454
qstat_inc(qstat_pv_wait_head, true);
455455
qstat_inc(qstat_pv_wait_again, waitcnt);
456456
pv_wait(&l->locked, _Q_SLOW_VAL);

kernel/locking/qspinlock_stat.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ static ssize_t qstat_read(struct file *file, char __user *user_buf,
153153
*/
154154
if ((counter == qstat_pv_latency_kick) ||
155155
(counter == qstat_pv_latency_wake)) {
156-
stat = 0;
157156
if (kicks)
158157
stat = DIV_ROUND_CLOSEST_ULL(stat, kicks);
159158
}

0 commit comments

Comments
 (0)