--- zzzz-none-000/linux-3.10.107/include/linux/rwsem.h 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/include/linux/rwsem.h 2021-02-04 17:41:59.000000000 +0000 @@ -13,8 +13,10 @@ #include #include #include - #include +#ifdef CONFIG_RWSEM_SPIN_ON_OWNER +#include +#endif struct rw_semaphore; @@ -23,9 +25,17 @@ #else /* All arch specific implementations share the same struct */ struct rw_semaphore { - long count; - raw_spinlock_t wait_lock; - struct list_head wait_list; + long count; + struct list_head wait_list; + 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; +#endif #ifdef CONFIG_DEBUG_LOCK_ALLOC struct lockdep_map dep_map; #endif @@ -55,10 +65,17 @@ # define __RWSEM_DEP_MAP_INIT(lockname) #endif -#define __RWSEM_INITIALIZER(name) \ - { RWSEM_UNLOCKED_VALUE, \ - __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock), \ - LIST_HEAD_INIT((name).wait_list) \ +#ifdef CONFIG_RWSEM_SPIN_ON_OWNER +#define __RWSEM_OPT_INIT(lockname) , .osq = OSQ_LOCK_UNLOCKED, .owner = NULL +#else +#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) \ @@ -75,6 +92,17 @@ } while (0) /* + * This is the same regardless of which rwsem implementation that is being used. + * It is just a heuristic meant to be called by somebody alreadying holding the + * rwsem to see if somebody from an incompatible type is wanting access to the + * lock. + */ +static inline int rwsem_is_contended(struct rw_semaphore *sem) +{ + return !list_empty(&sem->wait_list); +} + +/* * lock for reading */ extern void down_read(struct rw_semaphore *sem); @@ -121,7 +149,7 @@ * static then another method for expressing nested locking is * the explicit definition of lock class keys and the use of * lockdep_set_class() at lock initialization time. - * See Documentation/lockdep-design.txt for more details.) + * See Documentation/locking/lockdep-design.txt for more details.) */ extern void down_read_nested(struct rw_semaphore *sem, int subclass); extern void down_write_nested(struct rw_semaphore *sem, int subclass);