Skip to content

Commit

Permalink
locking/qrwlock: Use 'struct qrwlock' instead of 'struct __qrwlock'
Browse files Browse the repository at this point in the history
There's no good reason to keep the internal structure of struct qrwlock
hidden from qrwlock.h, particularly as it's actually needed for unlock
and ends up being abstracted independently behind the __qrwlock_write_byte()
function.

Stop pretending we can hide this stuff, and move the __qrwlock definition
into qrwlock, removing the __qrwlock_write_byte() nastiness and using the
same struct definition everywhere instead.

Signed-off-by: Will Deacon <[email protected]>
Acked-by: Peter Zijlstra <[email protected]>
Cc: Boqun Feng <[email protected]>
Cc: [email protected]
Cc: Linus Torvalds <[email protected]>
Cc: Paul E. McKenney <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Waiman Long <[email protected]>
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
  • Loading branch information
wildea01 authored and Ingo Molnar committed Oct 25, 2017
1 parent 5a8897c commit e0d0228
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 37 deletions.
12 changes: 1 addition & 11 deletions include/asm-generic/qrwlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,23 +128,13 @@ static inline void queued_read_unlock(struct qrwlock *lock)
(void)atomic_sub_return_release(_QR_BIAS, &lock->cnts);
}

/**
* __qrwlock_write_byte - retrieve the write byte address of a queue rwlock
* @lock : Pointer to queue rwlock structure
* Return: the write byte address of a queue rwlock
*/
static inline u8 *__qrwlock_write_byte(struct qrwlock *lock)
{
return (u8 *)lock + 3 * IS_BUILTIN(CONFIG_CPU_BIG_ENDIAN);
}

/**
* queued_write_unlock - release write lock of a queue rwlock
* @lock : Pointer to queue rwlock structure
*/
static inline void queued_write_unlock(struct qrwlock *lock)
{
smp_store_release(__qrwlock_write_byte(lock), 0);
smp_store_release(&lock->wmode, 0);
}

/*
Expand Down
15 changes: 13 additions & 2 deletions include/asm-generic/qrwlock_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,23 @@
*/

typedef struct qrwlock {
atomic_t cnts;
union {
atomic_t cnts;
struct {
#ifdef __LITTLE_ENDIAN
u8 wmode; /* Writer mode */
u8 rcnts[3]; /* Reader counts */
#else
u8 rcnts[3]; /* Reader counts */
u8 wmode; /* Writer mode */
#endif
};
};
arch_spinlock_t wait_lock;
} arch_rwlock_t;

#define __ARCH_RW_LOCK_UNLOCKED { \
.cnts = ATOMIC_INIT(0), \
{ .cnts = ATOMIC_INIT(0), }, \
.wait_lock = __ARCH_SPIN_LOCK_UNLOCKED, \
}

Expand Down
26 changes: 2 additions & 24 deletions kernel/locking/qrwlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,6 @@
#include <linux/spinlock.h>
#include <asm/qrwlock.h>

/*
* This internal data structure is used for optimizing access to some of
* the subfields within the atomic_t cnts.
*/
struct __qrwlock {
union {
atomic_t cnts;
struct {
#ifdef __LITTLE_ENDIAN
u8 wmode; /* Writer mode */
u8 rcnts[3]; /* Reader counts */
#else
u8 rcnts[3]; /* Reader counts */
u8 wmode; /* Writer mode */
#endif
};
};
arch_spinlock_t lock;
};

/**
* rspin_until_writer_unlock - inc reader count & spin until writer is gone
* @lock : Pointer to queue rwlock structure
Expand Down Expand Up @@ -125,10 +105,8 @@ void queued_write_lock_slowpath(struct qrwlock *lock)
* or wait for a previous writer to go away.
*/
for (;;) {
struct __qrwlock *l = (struct __qrwlock *)lock;

if (!READ_ONCE(l->wmode) &&
(cmpxchg_relaxed(&l->wmode, 0, _QW_WAITING) == 0))
if (!READ_ONCE(lock->wmode) &&
(cmpxchg_relaxed(&lock->wmode, 0, _QW_WAITING) == 0))
break;

cpu_relax();
Expand Down

0 comments on commit e0d0228

Please sign in to comment.