read_lock migrate_disable pushdown to rt_read_lock
PATCH 2/2 read_lock migrate_disable pushdown to rt_read_lock
pushdown of migrate_disable/enable from read_*lock* to the rt_read_*lock* api level
general mapping to mutexes:
read_*lock*
`-> rt_read_*lock*
`-> __spin_lock (the sleeping spin locks)
`-> rt_mutex The real read_lock* mapping:
read_lock_irqsave -.read_lock_irq `-> rt_read_lock_irqsave()
`->read_lock ---------. \
read_lock_bh ------+ \
`--> rt_read_lock()
if (rt_mutex_owner(lock) != current){
`-> __rt_spin_lock()
rt_spin_lock_fastlock()
`->rt_mutex_cmpxchg()
migrate_disable()
}
rwlock->read_depth++;read_trylock mapping:
read_trylock
`-> rt_read_trylock
if (rt_mutex_owner(lock) != current){
`-> rt_mutex_trylock()
rt_mutex_fasttrylock()
rt_mutex_cmpxchg()
migrate_disable()
}
rwlock->read_depth++;read_unlock* mapping:
read_unlock_bh --------+read_unlock_irq -------+read_unlock_irqrestore +read_unlock -----------+
`-> rt_read_unlock()
if(--rwlock->read_depth==0){
`-> __rt_spin_unlock()
rt_spin_lock_fastunlock()
`-> rt_mutex_cmpxchg()
migrate_disable()
}So calls to migrate_disable/enable() are better placed at the rt_read_* level of lock/trylock/unlock as all of the read_*lock* API has this as a common path. In the rt_read* API of lock/trylock/unlock the nesting level is already being recorded in rwlock->read_depth, so we can push down the migrate disable/enable to that level and condition it on the read_depth going from 0 to 1 -> migrate_disable and 1 to 0 -> migrate_enable. This eliminates the recursive calls that were needed when migrate_disable/enable was done at the read_*lock* level.
The approach to read_*_bh also eliminates the concerns raised with the regards to api inbalances (read_lock_bh -> read_unlock+local_bh_enable)
this is on top of 3.12.6-rt9 with timers-do-not-raise-softirq-unconditionally.patch removed
No change of functional behavior
--- include/linux/rwlock_rt.h | 6 ------ kernel/rt.c | 9 +++++---- 2 files changed, 5 insertions(+), 10 deletions(-)
include/linux/rwlock_rt.h +0 -6
@@ -33,7 +33,6 @@ extern void __rt_rwlock_init(rwlock_t *rwlock, char *name, struct lock_class_key#define read_lock_irqsave (lock, flags) \ do { \ typecheck(unsigned long, flags); \ - migrate_disable(); \ flags = rt_read_lock_irqsave(lock); \ } while (0)
@@ -45,14 +44,12 @@ extern void __rt_rwlock_init(rwlock_t *rwlock, char *name, struct lock_class_key#define read_lock (lock) \ do { \ - migrate_disable(); \ rt_read_lock(lock); \ } while (0)#define read_lock_bh (lock) \ do { \ local_bh_disable(); \ - migrate_disable(); \ rt_read_lock(lock); \ } while (0)
@@ -74,13 +71,11 @@ extern void __rt_rwlock_init(rwlock_t *rwlock, char *name, struct lock_class_key#define read_unlock (lock) \ do { \ rt_read_unlock(lock); \ - migrate_enable(); \ } while (0)#define read_unlock_bh (lock) \ do { \ rt_read_unlock(lock); \ - migrate_enable(); \ local_bh_enable(); \ } while (0)
@@ -104,7 +99,6 @@ extern void __rt_rwlock_init(rwlock_t *rwlock, char *name, struct lock_class_key typecheck(unsigned long, flags); \ (void ) flags; \rt_read_unlock (lock); \ -migrate_enable (); \ }while (0 ) #define write_unlock_irqrestore(lock, flags) \
kernel/rt.c +5 -4
@@ -211,19 +211,18 @@ int __lockfunc rt_read_trylock(rwlock_t *rwlock)* but not when read_depth == 0 which means that the lock is * write locked. */ -migrate_disable ();if (rt_mutex_owner (lock) != current) { ret =rt_mutex_trylock (lock); -if (ret) +if (ret) {rwlock_acquire (&rwlock->dep_map,0 ,1 , _RET_IP_); +migrate_disable (); + } }else if (!rwlock->read_depth) { ret =0 ; }if (ret) rwlock->read_depth++; -else -migrate_enable ();return ret; }
@@ -247,6 +246,7 @@ void __lockfunc rt_read_lock(rwlock_t *rwlock)if (rt_mutex_owner (lock) != current) {rwlock_acquire (&rwlock->dep_map,0 ,0 , _RET_IP_);__rt_spin_lock (lock); +migrate_disable (); } rwlock->read_depth++; }
@@ -268,6 +268,7 @@ void __lockfunc rt_read_unlock(rwlock_t *rwlock)if (--rwlock->read_depth ==0 ) {rwlock_release (&rwlock->dep_map,1 , _RET_IP_);__rt_spin_unlock (&rwlock->lock); +migrate_enable (); } }EXPORT_SYMBOL (rt_read_unlock);
Signature · 1 line
1.7.2.5