mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-26 06:33:19 -04:00
Merge branch 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull locking fixes from Thomas Gleixner:
"The locking department delivers:
- A rather large and intrusive bundle of fixes to address serious
performance regressions introduced by the new rwsem / mcs
technology. Simpler solutions have been discussed, but they would
have been ugly bandaids with more risk than doing the right thing.
- Make the rwsem spin on owner technology opt-in for architectures
and enable it only on the known to work ones.
- A few fixes to the lockdep userspace library"
* 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
locking/rwsem: Add CONFIG_RWSEM_SPIN_ON_OWNER
locking/mutex: Disable optimistic spinning on some architectures
locking/rwsem: Reduce the size of struct rw_semaphore
locking/rwsem: Rename 'activity' to 'count'
locking/spinlocks/mcs: Micro-optimize osq_unlock()
locking/spinlocks/mcs: Introduce and use init macro and function for osq locks
locking/spinlocks/mcs: Convert osq lock to atomic_t to reduce overhead
locking/spinlocks/mcs: Rename optimistic_spin_queue() to optimistic_spin_node()
locking/rwsem: Allow conservative optimistic spinning when readers have lock
tools/liblockdep: Account for bitfield changes in lockdeps lock_acquire
tools/liblockdep: Remove debug print left over from development
tools/liblockdep: Fix comparison of a boolean value with a value of 2
This commit is contained in:
commit
d057190925
19 changed files with 154 additions and 86 deletions
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/lockdep.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <asm/processor.h>
|
||||
#include <linux/osq_lock.h>
|
||||
|
||||
/*
|
||||
* Simple, straightforward mutexes with strict semantics:
|
||||
|
|
@ -46,7 +47,6 @@
|
|||
* - detects multi-task circular deadlocks and prints out all affected
|
||||
* locks and tasks (and only those tasks)
|
||||
*/
|
||||
struct optimistic_spin_queue;
|
||||
struct mutex {
|
||||
/* 1: unlocked, 0: locked, negative: locked, possible waiters */
|
||||
atomic_t count;
|
||||
|
|
@ -56,7 +56,7 @@ struct mutex {
|
|||
struct task_struct *owner;
|
||||
#endif
|
||||
#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
|
||||
struct optimistic_spin_queue *osq; /* Spinner MCS lock */
|
||||
struct optimistic_spin_queue osq; /* Spinner MCS lock */
|
||||
#endif
|
||||
#ifdef CONFIG_DEBUG_MUTEXES
|
||||
const char *name;
|
||||
|
|
|
|||
27
include/linux/osq_lock.h
Normal file
27
include/linux/osq_lock.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef __LINUX_OSQ_LOCK_H
|
||||
#define __LINUX_OSQ_LOCK_H
|
||||
|
||||
/*
|
||||
* An MCS like lock especially tailored for optimistic spinning for sleeping
|
||||
* lock implementations (mutex, rwsem, etc).
|
||||
*/
|
||||
|
||||
#define OSQ_UNLOCKED_VAL (0)
|
||||
|
||||
struct optimistic_spin_queue {
|
||||
/*
|
||||
* Stores an encoded value of the CPU # of the tail node in the queue.
|
||||
* If the queue is empty, then it's set to OSQ_UNLOCKED_VAL.
|
||||
*/
|
||||
atomic_t tail;
|
||||
};
|
||||
|
||||
/* Init macro and function. */
|
||||
#define OSQ_LOCK_UNLOCKED { ATOMIC_INIT(OSQ_UNLOCKED_VAL) }
|
||||
|
||||
static inline void osq_lock_init(struct optimistic_spin_queue *lock)
|
||||
{
|
||||
atomic_set(&lock->tail, OSQ_UNLOCKED_VAL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -15,13 +15,13 @@
|
|||
#ifdef __KERNEL__
|
||||
/*
|
||||
* the rw-semaphore definition
|
||||
* - if activity is 0 then there are no active readers or writers
|
||||
* - if activity is +ve then that is the number of active readers
|
||||
* - if activity is -1 then there is one active writer
|
||||
* - if count is 0 then there are no active readers or writers
|
||||
* - if count is +ve then that is the number of active readers
|
||||
* - if count is -1 then there is one active writer
|
||||
* - if wait_list is not empty, then there are processes waiting for the semaphore
|
||||
*/
|
||||
struct rw_semaphore {
|
||||
__s32 activity;
|
||||
__s32 count;
|
||||
raw_spinlock_t wait_lock;
|
||||
struct list_head wait_list;
|
||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||
|
|
|
|||
|
|
@ -13,10 +13,11 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
|
||||
#include <linux/osq_lock.h>
|
||||
#endif
|
||||
|
||||
struct optimistic_spin_queue;
|
||||
struct rw_semaphore;
|
||||
|
||||
#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK
|
||||
|
|
@ -25,15 +26,15 @@ struct rw_semaphore;
|
|||
/* All arch specific implementations share the same struct */
|
||||
struct rw_semaphore {
|
||||
long count;
|
||||
raw_spinlock_t wait_lock;
|
||||
struct list_head wait_list;
|
||||
#ifdef CONFIG_SMP
|
||||
raw_spinlock_t wait_lock;
|
||||
#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
|
||||
struct optimistic_spin_queue osq; /* spinner MCS lock */
|
||||
/*
|
||||
* Write owner. Used as a speculative check to see
|
||||
* if the owner is running on the cpu.
|
||||
*/
|
||||
struct task_struct *owner;
|
||||
struct optimistic_spin_queue *osq; /* spinner MCS lock */
|
||||
#endif
|
||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||
struct lockdep_map dep_map;
|
||||
|
|
@ -64,22 +65,19 @@ static inline int rwsem_is_locked(struct rw_semaphore *sem)
|
|||
# define __RWSEM_DEP_MAP_INIT(lockname)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SMP) && !defined(CONFIG_RWSEM_GENERIC_SPINLOCK)
|
||||
#define __RWSEM_INITIALIZER(name) \
|
||||
{ RWSEM_UNLOCKED_VALUE, \
|
||||
__RAW_SPIN_LOCK_UNLOCKED(name.wait_lock), \
|
||||
LIST_HEAD_INIT((name).wait_list), \
|
||||
NULL, /* owner */ \
|
||||
NULL /* mcs lock */ \
|
||||
__RWSEM_DEP_MAP_INIT(name) }
|
||||
#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
|
||||
#define __RWSEM_OPT_INIT(lockname) , .osq = OSQ_LOCK_UNLOCKED, .owner = NULL
|
||||
#else
|
||||
#define __RWSEM_INITIALIZER(name) \
|
||||
{ RWSEM_UNLOCKED_VALUE, \
|
||||
__RAW_SPIN_LOCK_UNLOCKED(name.wait_lock), \
|
||||
LIST_HEAD_INIT((name).wait_list) \
|
||||
__RWSEM_DEP_MAP_INIT(name) }
|
||||
#define __RWSEM_OPT_INIT(lockname)
|
||||
#endif
|
||||
|
||||
#define __RWSEM_INITIALIZER(name) \
|
||||
{ .count = RWSEM_UNLOCKED_VALUE, \
|
||||
.wait_list = LIST_HEAD_INIT((name).wait_list), \
|
||||
.wait_lock = __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock) \
|
||||
__RWSEM_OPT_INIT(name) \
|
||||
__RWSEM_DEP_MAP_INIT(name) }
|
||||
|
||||
#define DECLARE_RWSEM(name) \
|
||||
struct rw_semaphore name = __RWSEM_INITIALIZER(name)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue