Module: xenomai-forge Branch: master Commit: f513f3052423c0848fd1714f2500c1fabe428b1f URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=f513f3052423c0848fd1714f2500c1fabe428b1f
Author: Philippe Gerum <r...@xenomai.org> Date: Fri Jan 4 16:55:54 2013 +0100 nucleus/lock: track location of last valid unlock When a spurious unlock operation is detected in debug mode, knowing about the last valid call to xnlock_put*() brings more value than knowing about who locked the mis-operated lock last. --- include/cobalt/nucleus/lock.h | 16 +++++++++++----- kernel/cobalt/nucleus/debug.c | 21 ++++++++++++++++----- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/include/cobalt/nucleus/lock.h b/include/cobalt/nucleus/lock.h index aa6249e..b142e84 100644 --- a/include/cobalt/nucleus/lock.h +++ b/include/cobalt/nucleus/lock.h @@ -101,7 +101,9 @@ void xnlock_dbg_acquired(struct xnlock *lock, int cpu, unsigned long long *start, const char *file, int line, const char *function); -int xnlock_dbg_release(struct xnlock *lock); +int xnlock_dbg_release(struct xnlock *lock, + const char *file, int line, + const char *function); #else /* !XENO_DEBUG(XNLOCK) */ @@ -146,8 +148,11 @@ static inline int xnlock_dbg_release(struct xnlock *lock) #if defined(CONFIG_SMP) || XENO_DEBUG(XNLOCK) #define xnlock_get(lock) __xnlock_get(lock XNLOCK_DBG_CONTEXT) +#define xnlock_put(lock) __xnlock_put(lock XNLOCK_DBG_CONTEXT) #define xnlock_get_irqsave(lock,x) \ ((x) = __xnlock_get_irqsave(lock XNLOCK_DBG_CONTEXT)) +#define xnlock_put_irqrestore(lock,x) \ + __xnlock_put_irqrestore(lock,x XNLOCK_DBG_CONTEXT) #define xnlock_clear_irqoff(lock) xnlock_put_irqrestore(lock, 1) #define xnlock_clear_irqon(lock) xnlock_put_irqrestore(lock, 0) @@ -181,9 +186,9 @@ static inline int __xnlock_get(struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARG return 0; } -static inline void xnlock_put(struct xnlock *lock) +static inline void __xnlock_put(struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS) { - if (xnlock_dbg_release(lock)) + if (xnlock_dbg_release(lock /*, */ XNLOCK_DBG_PASS_CONTEXT)) return; /* @@ -207,11 +212,12 @@ __xnlock_get_irqsave(struct xnlock *lock /*, */ XNLOCK_DBG_CONTEXT_ARGS) return flags; } -static inline void xnlock_put_irqrestore(struct xnlock *lock, spl_t flags) +static inline void __xnlock_put_irqrestore(struct xnlock *lock, spl_t flags + /*, */ XNLOCK_DBG_CONTEXT_ARGS) { /* Only release the lock if we didn't take it recursively. */ if (!(flags & 2)) - xnlock_put(lock); + __xnlock_put(lock /*, */ XNLOCK_DBG_PASS_CONTEXT); splexit(flags & 1); } diff --git a/kernel/cobalt/nucleus/debug.c b/kernel/cobalt/nucleus/debug.c index f9bd4d6..11d5464 100644 --- a/kernel/cobalt/nucleus/debug.c +++ b/kernel/cobalt/nucleus/debug.c @@ -551,7 +551,7 @@ void xnlock_dbg_spinning(struct xnlock *lock, int cpu, { if (--*spin_limit == 0) { ipipe_prepare_panic(); - printk(KERN_ERR "Xenomai: stuck on nucleus lock %p\n" + printk(KERN_ERR "Xenomai: stuck on lock %p\n" " waiter = %s:%u (%s(), CPU #%d)\n" " owner = %s:%u (%s(), CPU #%d)\n", lock, file, line, function, cpu, @@ -576,7 +576,8 @@ void xnlock_dbg_acquired(struct xnlock *lock, int cpu, unsigned long long *start } EXPORT_SYMBOL_GPL(xnlock_dbg_acquired); -int xnlock_dbg_release(struct xnlock *lock) +int xnlock_dbg_release(struct xnlock *lock, + const char *file, int line, const char *function) { unsigned long long lock_time; struct xnlockinfo *stats; @@ -586,18 +587,28 @@ int xnlock_dbg_release(struct xnlock *lock) cpu = ipipe_processor_id(); stats = &xnlock_stats[cpu]; + if (lock->file == NULL) { + lock->file = "??"; + lock->line = 0; + lock->function = "invalid"; + } + if (unlikely(atomic_read(&lock->owner) != cpu)) { ipipe_prepare_panic(); - printk(KERN_ERR "Xenomai: unlocking unlocked nucleus lock %p" + printk(KERN_ERR "Xenomai: lock %p already unlocked" " on CPU #%d\n" - " owner = %s:%u (%s(), CPU #%d)\n", + " last owner = %s:%u (%s(), CPU #%d)\n", lock, cpu, lock->file, lock->line, lock->function, lock->cpu); show_stack(NULL,NULL); return 1; } - lock->cpu = -lock->cpu; /* File that we released it. */ + /* File that we released it. */ + lock->cpu = -lock->cpu; + lock->file = file; + lock->line = line; + lock->function = function; if (lock_time > stats->lock_time) { stats->lock_time = lock_time; _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git