mirror of
https://github.com/torvalds/linux.git
synced 2024-12-11 21:52:04 +00:00
6e2814745c
The mutex owner can get read and written to locklessly. Use WRITE_ONCE when setting and clearing the owner field in order to avoid optimizations such as store tearing. This avoids situations where the owner field gets written to with multiple stores and another thread could concurrently read and use a partially written owner value. Signed-off-by: Jason Low <jason.low2@hpe.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Davidlohr Bueso <dave@stgolabs.net> Acked-by: Waiman Long <Waiman.Long@hpe.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Scott J Norton <scott.norton@hpe.com> Cc: Terry Rudd <terry.rudd@hpe.com> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/1463782776.2479.9.camel@j-VirtualBox Signed-off-by: Ingo Molnar <mingo@kernel.org>
56 lines
1.7 KiB
C
56 lines
1.7 KiB
C
/*
|
|
* Mutexes: blocking mutual exclusion locks
|
|
*
|
|
* started by Ingo Molnar:
|
|
*
|
|
* Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
|
|
*
|
|
* This file contains mutex debugging related internal declarations,
|
|
* prototypes and inline functions, for the CONFIG_DEBUG_MUTEXES case.
|
|
* More details are in kernel/mutex-debug.c.
|
|
*/
|
|
|
|
/*
|
|
* This must be called with lock->wait_lock held.
|
|
*/
|
|
extern void debug_mutex_lock_common(struct mutex *lock,
|
|
struct mutex_waiter *waiter);
|
|
extern void debug_mutex_wake_waiter(struct mutex *lock,
|
|
struct mutex_waiter *waiter);
|
|
extern void debug_mutex_free_waiter(struct mutex_waiter *waiter);
|
|
extern void debug_mutex_add_waiter(struct mutex *lock,
|
|
struct mutex_waiter *waiter,
|
|
struct thread_info *ti);
|
|
extern void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,
|
|
struct thread_info *ti);
|
|
extern void debug_mutex_unlock(struct mutex *lock);
|
|
extern void debug_mutex_init(struct mutex *lock, const char *name,
|
|
struct lock_class_key *key);
|
|
|
|
static inline void mutex_set_owner(struct mutex *lock)
|
|
{
|
|
WRITE_ONCE(lock->owner, current);
|
|
}
|
|
|
|
static inline void mutex_clear_owner(struct mutex *lock)
|
|
{
|
|
WRITE_ONCE(lock->owner, NULL);
|
|
}
|
|
|
|
#define spin_lock_mutex(lock, flags) \
|
|
do { \
|
|
struct mutex *l = container_of(lock, struct mutex, wait_lock); \
|
|
\
|
|
DEBUG_LOCKS_WARN_ON(in_interrupt()); \
|
|
local_irq_save(flags); \
|
|
arch_spin_lock(&(lock)->rlock.raw_lock);\
|
|
DEBUG_LOCKS_WARN_ON(l->magic != l); \
|
|
} while (0)
|
|
|
|
#define spin_unlock_mutex(lock, flags) \
|
|
do { \
|
|
arch_spin_unlock(&(lock)->rlock.raw_lock); \
|
|
local_irq_restore(flags); \
|
|
preempt_check_resched(); \
|
|
} while (0)
|