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

Reply via email to