Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 316618 Details for
Bug 460455
[FOCUS][24] R2:SAN:Hang triggered by filesystem testing on SAN
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
patch to catch misuses of rtmutexs
rtmutex-debug-magic.patch (text/plain), 13.08 KB, created by
Steven Rostedt
on 2008-09-12 19:56:42 UTC
(
hide
)
Description:
patch to catch misuses of rtmutexs
Filename:
MIME Type:
Creator:
Steven Rostedt
Created:
2008-09-12 19:56:42 UTC
Size:
13.08 KB
patch
obsolete
>From: Steven Rostedt <srostedt@redhat.com> >Subject: rtmutex: check integrity > >When PREEMPT_RT is configured on, a spinlock or semaphore can turn into >a rt_mutex. Since they also may stay the same in some cases (depending on >what type they were defined as) the API for them is determined by the >type. For example, if a spin lock is of type spinlock_t it will be converted >to an rt_mutex, and if it is defined as raw_spinlock_t it will stay the >same. > >If the locks are passed as pointers and typecasted to the wrong lock, >things can break. This patch adds a integrity check to make sure that >the rt_mutexs are indeed rt_mutexes when used. > >Signed-off-by: Steven Rostedt <srostedt@redhat.com> >--- > include/linux/rt_lock.h | 46 +++++++++++++++++++++++++++++++++++++++------- > include/linux/rtmutex.h | 25 ++++++++++++++++++++++++- > kernel/rt.c | 15 +++++++++++++-- > kernel/rtmutex.c | 27 +++++++++++++++++++++++++++ > lib/Kconfig.debug | 13 +++++++++++++ > 5 files changed, 116 insertions(+), 10 deletions(-) > >Index: linux-2.6.24.7.noarch/include/linux/rt_lock.h >=================================================================== >--- linux-2.6.24.7.noarch.orig/include/linux/rt_lock.h >+++ linux-2.6.24.7.noarch/include/linux/rt_lock.h >@@ -27,15 +27,47 @@ typedef struct { > #endif > } spinlock_t; > >+#ifdef CONFIG_RTMUTEX_CHECK >+#define RT_SPIN_CHECK_MAGIC 0x52545350 /* RTSP */ >+# define __RT_SPIN_CHECK_INIT , .magic = RT_SPIN_CHECK_MAGIC >+# define rt_spinlock_magic_check(mutex) \ >+ WARN_ON_ONCE((mutex)->lock.magic != RT_SPIN_CHECK_MAGIC) >+ >+# define rt_rwlock_magic_check(lock) \ >+ WARN_ON_ONCE((lock)->magic != RT_SPIN_CHECK_MAGIC); >+static inline void check_rt_spin_lock_init(spinlock_t *lock) >+{ >+ lock->lock.magic = RT_SPIN_CHECK_MAGIC; >+} >+static inline void check_rt_rwlock_init(struct rt_mutex *lock) >+{ >+ lock->magic = RT_SPIN_CHECK_MAGIC; >+} >+#else >+# define __RT_SPIN_CHECK_INIT >+static inline void rt_spinlock_magic_check(spinlock_t *lock) >+{ } >+static inline void rt_rwlock_magic_check(struct rt_mutex *lock) >+{ } >+static inline void check_rt_spin_lock_init(spinlock_t *lock) >+{ } >+static inline void check_rt_rwlock_init(struct rt_mutex *lock) >+{ } >+#endif >+ > #ifdef CONFIG_DEBUG_RT_MUTEXES >-# define __RT_SPIN_INITIALIZER(name) \ >- { .wait_lock = _RAW_SPIN_LOCK_UNLOCKED(name.wait_lock), \ >- .save_state = 1, \ >- .file = __FILE__, \ >- .line = __LINE__, } >+# define __RT_SPIN_INITIALIZER(name) \ >+ { .wait_lock = _RAW_SPIN_LOCK_UNLOCKED(name.wait_lock), \ >+ .save_state = 1, \ >+ .file = __FILE__, \ >+ .line = __LINE__ \ >+ __RT_SPIN_CHECK_INIT } >+ > #else >-# define __RT_SPIN_INITIALIZER(name) \ >- { .wait_lock = _RAW_SPIN_LOCK_UNLOCKED(name.wait_lock) } >+# define __RT_SPIN_INITIALIZER(name) \ >+ { \ >+ .wait_lock = _RAW_SPIN_LOCK_UNLOCKED(name.wait_lock) \ >+ __RT_SPIN_CHECK_INIT } > #endif > > #define __SPIN_LOCK_UNLOCKED(name) (spinlock_t) \ >Index: linux-2.6.24.7.noarch/include/linux/rtmutex.h >=================================================================== >--- linux-2.6.24.7.noarch.orig/include/linux/rtmutex.h >+++ linux-2.6.24.7.noarch/include/linux/rtmutex.h >@@ -31,7 +31,9 @@ struct rt_mutex { > int save_state; > const char *name, *file; > int line; >- void *magic; >+#endif >+#ifdef CONFIG_RTMUTEX_CHECK >+ unsigned long magic; > #endif > }; > >@@ -62,10 +64,31 @@ struct hrtimer_sleeper; > # define rt_mutex_debug_task_free(t) do { } while (0) > #endif > >+#ifdef CONFIG_RTMUTEX_CHECK >+#define RT_MUTEX_CHECK_MAGIC 0x52544d58 /* RTMX */ >+# define __RT_MUTEX_CHECK_INIT \ >+ , .magic = RT_MUTEX_CHECK_MAGIC >+# define rt_mutex_magic_check(lock) \ >+ WARN_ON_ONCE((lock)->magic != RT_MUTEX_CHECK_MAGIC); >+static inline void check_rt_mutex_init(struct rt_mutex *lock) >+{ >+ lock->magic = RT_MUTEX_CHECK_MAGIC; >+} >+#else >+# define __RT_MUTEX_CHECK_INIT >+static inline void rt_mutex_magic_check(struct rt_mutex *lock) >+{ >+} >+static inline void check_rt_mutex_init(struct rt_mutex *lock) >+{ >+} >+#endif >+ > #define __RT_MUTEX_INITIALIZER(mutexname) \ > { .wait_lock = RAW_SPIN_LOCK_UNLOCKED(mutexname) \ > , .wait_list = PLIST_HEAD_INIT(mutexname.wait_list, &mutexname.wait_lock) \ > , .owner = NULL \ >+ __RT_MUTEX_CHECK_INIT \ > __DEBUG_RT_MUTEX_INITIALIZER(mutexname)} > > #define DEFINE_RT_MUTEX(mutexname) \ >Index: linux-2.6.24.7.noarch/kernel/rt.c >=================================================================== >--- linux-2.6.24.7.noarch.orig/kernel/rt.c >+++ linux-2.6.24.7.noarch/kernel/rt.c >@@ -165,7 +165,10 @@ EXPORT_SYMBOL(_mutex_unlock); > */ > int __lockfunc rt_write_trylock(rwlock_t *rwlock) > { >- int ret = rt_mutex_down_write_trylock(&rwlock->owners); >+ int ret; >+ >+ rt_rwlock_magic_check(&rwlock->owners.mutex); >+ ret = rt_mutex_down_write_trylock(&rwlock->owners); > > if (ret) > rwlock_acquire(&rwlock->dep_map, 0, 1, _RET_IP_); >@@ -176,6 +179,7 @@ EXPORT_SYMBOL(rt_write_trylock); > > int __lockfunc rt_write_trylock_irqsave(rwlock_t *rwlock, unsigned long *flags) > { >+ rt_rwlock_magic_check(&rwlock->owners.mutex); > *flags = 0; > return rt_write_trylock(rwlock); > } >@@ -185,6 +189,7 @@ int __lockfunc rt_read_trylock(rwlock_t > { > int ret; > >+ rt_rwlock_magic_check(&rwlock->owners.mutex); > ret = rt_mutex_down_read_trylock(&rwlock->owners); > if (ret) > rwlock_acquire_read(&rwlock->dep_map, 0, 1, _RET_IP_); >@@ -249,6 +254,7 @@ void __rt_rwlock_init(rwlock_t *rwlock, > lockdep_init_map(&rwlock->dep_map, name, key, 0); > #endif > rt_mutex_rwsem_init(&rwlock->owners, name); >+ check_rt_rwlock_init(&rwlock->owners.mutex); > } > EXPORT_SYMBOL(__rt_rwlock_init); > >@@ -281,8 +287,10 @@ EXPORT_SYMBOL(rt_downgrade_write); > > int fastcall rt_down_write_trylock(struct rw_semaphore *rwsem) > { >- int ret = rt_mutex_down_write_trylock(&rwsem->owners); >+ int ret; > >+ rt_mutex_magic_check(&rwsem->owners.mutex); >+ ret = rt_mutex_down_write_trylock(&rwsem->owners); > if (ret) > rwsem_acquire(&rwsem->dep_map, 0, 1, _RET_IP_); > return ret; >@@ -311,6 +319,7 @@ int fastcall rt_down_read_trylock(struct > { > int ret; > >+ rt_mutex_magic_check(&rwsem->owners.mutex); > ret = rt_mutex_down_read_trylock(&rwsem->owners); > if (ret) > rwsem_acquire(&rwsem->dep_map, 0, 1, _RET_IP_); >@@ -403,6 +412,7 @@ int fastcall rt_down_trylock(struct sema > * embedded mutex internally. It would be quite complex to remove > * these transient failures so lets try it the simple way first: > */ >+ rt_mutex_magic_check(&sem->lock); > if (rt_mutex_trylock(&sem->lock)) { > __down_complete(sem); > return 0; >@@ -419,6 +429,7 @@ void fastcall rt_up(struct semaphore *se > * Disable preemption to make sure a highprio trylock-er cannot > * preempt us here and get into an infinite loop: > */ >+ rt_mutex_magic_check(&sem->lock); > preempt_disable(); > count = atomic_inc_return(&sem->count); > /* >Index: linux-2.6.24.7.noarch/kernel/rtmutex.c >=================================================================== >--- linux-2.6.24.7.noarch.orig/kernel/rtmutex.c >+++ linux-2.6.24.7.noarch/kernel/rtmutex.c >@@ -950,6 +950,7 @@ rt_spin_lock_slowunlock(struct rt_mutex > > void __lockfunc rt_spin_lock(spinlock_t *lock) > { >+ rt_spinlock_magic_check(lock); > spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); > LOCK_CONTENDED_RT(lock, rt_mutex_trylock, __rt_spin_lock); > } >@@ -965,6 +966,7 @@ EXPORT_SYMBOL(__rt_spin_lock); > > void __lockfunc rt_spin_lock_nested(spinlock_t *lock, int subclass) > { >+ rt_spinlock_magic_check(lock); > spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); > LOCK_CONTENDED_RT(lock, rt_mutex_trylock, __rt_spin_lock); > } >@@ -974,6 +976,7 @@ EXPORT_SYMBOL(rt_spin_lock_nested); > > void __lockfunc rt_spin_unlock(spinlock_t *lock) > { >+ rt_spinlock_magic_check(lock); > /* NOTE: we always pass in '1' for nested, for simplicity */ > spin_release(&lock->dep_map, 1, _RET_IP_); > rt_spin_lock_fastunlock(&lock->lock, rt_spin_lock_slowunlock); >@@ -1002,6 +1005,8 @@ int __lockfunc rt_spin_trylock(spinlock_ > { > int ret = rt_mutex_trylock(&lock->lock); > >+ rt_spinlock_magic_check(lock); >+ > if (ret) > spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); > >@@ -1013,6 +1018,8 @@ int __lockfunc rt_spin_trylock_irqsave(s > { > int ret; > >+ rt_spinlock_magic_check(lock); >+ > *flags = 0; > ret = rt_mutex_trylock(&lock->lock); > if (ret) >@@ -1024,6 +1031,8 @@ EXPORT_SYMBOL(rt_spin_trylock_irqsave); > > int _atomic_dec_and_spin_lock(spinlock_t *lock, atomic_t *atomic) > { >+ rt_spinlock_magic_check(lock); >+ > /* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */ > if (atomic_add_unless(atomic, -1, 1)) > return 0; >@@ -1046,6 +1055,7 @@ __rt_spin_lock_init(spinlock_t *lock, ch > lockdep_init_map(&lock->dep_map, name, key, 0); > #endif > __rt_mutex_init(&lock->lock, name); >+ check_rt_spin_lock_init(lock); > } > EXPORT_SYMBOL(__rt_spin_lock_init); > >@@ -1486,11 +1496,13 @@ rt_read_fastlock(struct rw_mutex *rwm, > > void fastcall rt_mutex_down_read(struct rw_mutex *rwm) > { >+ rt_mutex_magic_check(&rwm->mutex); > rt_read_fastlock(rwm, rt_read_slowlock, 1); > } > > void fastcall rt_rwlock_read_lock(struct rw_mutex *rwm) > { >+ rt_rwlock_magic_check(&rwm->mutex); > rt_read_fastlock(rwm, rt_read_slowlock, 0); > } > >@@ -1650,11 +1662,13 @@ rt_write_fastlock(struct rw_mutex *rwm, > > void fastcall rt_mutex_down_write(struct rw_mutex *rwm) > { >+ rt_mutex_magic_check(&rwm->mutex); > rt_write_fastlock(rwm, rt_write_slowlock, 1); > } > > void fastcall rt_rwlock_write_lock(struct rw_mutex *rwm) > { >+ rt_rwlock_magic_check(&rwm->mutex); > rt_write_fastlock(rwm, rt_write_slowlock, 0); > } > >@@ -1890,11 +1904,13 @@ rt_read_fastunlock(struct rw_mutex *rwm, > > void fastcall rt_mutex_up_read(struct rw_mutex *rwm) > { >+ rt_mutex_magic_check(&rwm->mutex); > rt_read_fastunlock(rwm, rt_read_slowunlock, 1); > } > > void fastcall rt_rwlock_read_unlock(struct rw_mutex *rwm) > { >+ rt_rwlock_magic_check(&rwm->mutex); > rt_read_fastunlock(rwm, rt_read_slowunlock, 0); > } > >@@ -2031,11 +2047,13 @@ rt_write_fastunlock(struct rw_mutex *rwm > > void fastcall rt_mutex_up_write(struct rw_mutex *rwm) > { >+ rt_mutex_magic_check(&rwm->mutex); > rt_write_fastunlock(rwm, rt_write_slowunlock, 1); > } > > void fastcall rt_rwlock_write_unlock(struct rw_mutex *rwm) > { >+ rt_rwlock_magic_check(&rwm->mutex); > rt_write_fastunlock(rwm, rt_write_slowunlock, 0); > } > >@@ -2052,6 +2070,7 @@ rt_mutex_downgrade_write(struct rw_mutex > unsigned long flags; > int reader_count; > >+ rt_mutex_magic_check(&rwm->mutex); > spin_lock_irqsave(&mutex->wait_lock, flags); > init_rw_lists(rwm); > >@@ -2523,6 +2542,7 @@ void __sched rt_mutex_lock(struct rt_mut > { > might_sleep(); > >+ rt_mutex_magic_check(lock); > rt_mutex_fastlock(lock, TASK_UNINTERRUPTIBLE, 0, rt_mutex_slowlock); > } > EXPORT_SYMBOL_GPL(rt_mutex_lock); >@@ -2543,6 +2563,7 @@ int __sched rt_mutex_lock_interruptible( > { > might_sleep(); > >+ rt_mutex_magic_check(lock); > return rt_mutex_fastlock(lock, TASK_INTERRUPTIBLE, > detect_deadlock, rt_mutex_slowlock); > } >@@ -2569,6 +2590,7 @@ rt_mutex_timed_lock(struct rt_mutex *loc > { > might_sleep(); > >+ rt_mutex_magic_check(lock); > return rt_mutex_timed_fastlock(lock, TASK_INTERRUPTIBLE, timeout, > detect_deadlock, rt_mutex_slowlock); > } >@@ -2594,6 +2616,7 @@ EXPORT_SYMBOL_GPL(rt_mutex_trylock); > */ > void __sched rt_mutex_unlock(struct rt_mutex *lock) > { >+ rt_mutex_magic_check(lock); > rt_mutex_fastunlock(lock, rt_mutex_slowunlock); > } > EXPORT_SYMBOL_GPL(rt_mutex_unlock); >@@ -2608,9 +2631,10 @@ EXPORT_SYMBOL_GPL(rt_mutex_unlock); > */ > void rt_mutex_destroy(struct rt_mutex *lock) > { >+ rt_mutex_magic_check(lock); > WARN_ON(rt_mutex_is_locked(lock)); >-#ifdef CONFIG_DEBUG_RT_MUTEXES >- lock->magic = NULL; >+#ifdef CONFIG_RTMUTEX_CHECK >+ lock->magic = 0; > #endif > } > >@@ -2632,6 +2656,7 @@ void __rt_mutex_init(struct rt_mutex *lo > plist_head_init(&lock->wait_list, &lock->wait_lock); > > debug_rt_mutex_init(lock, name); >+ check_rt_mutex_init(lock); > } > EXPORT_SYMBOL_GPL(__rt_mutex_init); > >@@ -2665,6 +2690,7 @@ void rt_mutex_init_proxy_locked(struct r > void rt_mutex_proxy_unlock(struct rt_mutex *lock, > struct task_struct *proxy_owner) > { >+ rt_mutex_magic_check(lock); > debug_rt_mutex_proxy_unlock(lock); > rt_mutex_set_owner(lock, NULL, 0); > rt_mutex_deadlock_account_unlock(proxy_owner); >@@ -2684,6 +2710,7 @@ void rt_mutex_proxy_unlock(struct rt_mut > */ > struct task_struct *rt_mutex_next_owner(struct rt_mutex *lock) > { >+ rt_mutex_magic_check(lock); > if (!rt_mutex_has_waiters(lock)) > return NULL; > >Index: linux-2.6.24.7.noarch/lib/Kconfig.debug >=================================================================== >--- linux-2.6.24.7.noarch.orig/lib/Kconfig.debug >+++ linux-2.6.24.7.noarch/lib/Kconfig.debug >@@ -192,6 +192,19 @@ config DEBUG_RT_MUTEXES > When realtime preemption is enabled this includes spinlocks, > rwlocks, mutexes and (rw)semaphores > >+config RTMUTEX_CHECK >+ bool "RT Mutex integrity checker" >+ depends on PREEMPT_RT >+ default y >+ help >+ When PREEMPT_RT is configured, most spinlocks and semaphores >+ are converted into mutexes. There still exists true spin locks >+ and old style semaphores. There are places in the kernel that >+ passes the lock via pointer and typecasts it back. This >+ can circumvent the compiler conversions. This option will add >+ a magic number to all converted locks and check to make sure >+ the lock is appropriate for the function being used. >+ > config DEBUG_PI_LIST > bool > default y
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 460455
:
315191
|
316488
| 316618