Module: xenomai-3 Branch: stable-3.0.x Commit: 5036abbe902454f4402a1bc11e7687f4ed39116b URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=5036abbe902454f4402a1bc11e7687f4ed39116b
Author: Jan Kiszka <jan.kis...@siemens.com> Date: Thu Oct 12 09:46:41 2017 +0200 cobalt/debug: Fix locking None of these functions are called over interrupt context. Leaving the critical sections interruptible can cause premature/double-unlock scenarios and bug reports such as [Xenomai] lock ffffffff81c56000 already unlocked on CPU #1 last owner = kernel/xenomai/debug.c:74 (hash_symbol(), CPU #1) 000000000000002f ffff88007dc8bb10 ffffffff8118ae8f ffffffff00000001 0000000000000021 ffff88007f897fde ffff88007dc8bb50 ffffffff8118b266 00000000000000f1 ffff88007dc8bd68 0000000000000006 ffff88007dc8bd40 Call Trace: [<ffffffff8118ae8f>] xnlock_dbg_release+0xdf/0xf0 [<ffffffff8118b266>] hash_symbol+0x236/0x2d0 [<ffffffff8118b668>] xndebug_trace_relax+0x118/0x450 [<ffffffff811b8d50>] ? CoBaLt32emu_mmap+0xf0/0xf0 [<ffffffff811b8dd7>] CoBaLt32emu_backtrace+0x87/0xb0 [<ffffffff8100def6>] ? fpu__clear+0xd6/0x160 [<ffffffff817b3691>] ? _raw_spin_unlock_irq+0x11/0x30 [<ffffffff811ab1cc>] ipipe_syscall_hook+0x11c/0x3a0 [<ffffffff8113d9bf>] __ipipe_notify_syscall+0xbf/0x180 [<ffffffff810cd019>] ? __set_current_blocked+0x49/0x50 [<ffffffff8113daab>] ipipe_handle_syscall+0x2b/0xb0 [<ffffffff81001c9d>] do_fast_syscall_32+0xbd/0x220 [<ffffffff817b64e2>] sysenter_flags_fixed+0x8/0x12 Signed-off-by: Jan Kiszka <jan.kis...@siemens.com> --- kernel/cobalt/debug.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/kernel/cobalt/debug.c b/kernel/cobalt/debug.c index 312f43a..2c5dee1 100644 --- a/kernel/cobalt/debug.c +++ b/kernel/cobalt/debug.c @@ -64,14 +64,15 @@ DEFINE_PRIVATE_XNLOCK(symbol_lock); static const char *hash_symbol(const char *symbol) { struct hashed_symbol *p, **h; - const char *s; + const char *str; size_t len; u32 hash; + spl_t s; len = strlen(symbol); hash = jhash(symbol, len, 0); - xnlock_get(&symbol_lock); + xnlock_get_irqsave(&symbol_lock, s); h = &symbol_jhash[hash & (SYMBOL_HSLOTS - 1)]; p = *h; @@ -85,7 +86,7 @@ static const char *hash_symbol(const char *symbol) p = xnheap_alloc(&memory_pool, sizeof(*p) + len + 1); if (p == NULL) { - s = NULL; + str = NULL; goto out; } @@ -93,11 +94,11 @@ static const char *hash_symbol(const char *symbol) p->next = *h; *h = p; done: - s = p->symbol; + str = p->symbol; out: - xnlock_put(&symbol_lock); + xnlock_put_irqrestore(&symbol_lock, s); - return s; + return str; } /* @@ -214,6 +215,7 @@ void xndebug_trace_relax(int nr, unsigned long *backtrace, int n, depth; char *tmp; u32 hash; + spl_t s; thread = xnthread_current(); if (thread == NULL) @@ -285,7 +287,7 @@ void xndebug_trace_relax(int nr, unsigned long *backtrace, strcpy(spot.thread, thread->name); hash = jhash2((u32 *)&spot, sizeof(spot) / sizeof(u32), 0); - xnlock_get(&relax_lock); + xnlock_get_irqsave(&relax_lock, s); h = &relax_jhash[hash & (RELAX_HSLOTS - 1)]; p = *h; @@ -326,7 +328,7 @@ void xndebug_trace_relax(int nr, unsigned long *backtrace, out: relax_overall++; - xnlock_put(&relax_lock); + xnlock_put_irqrestore(&relax_lock, s); } static DEFINE_VFILE_HOSTLOCK(relax_mutex); @@ -343,6 +345,7 @@ static void *relax_vfile_begin(struct xnvfile_regular_iterator *it) { struct relax_vfile_priv *priv = xnvfile_iterator_priv(it); struct relax_record *p; + spl_t s; int n; /* @@ -352,7 +355,7 @@ static void *relax_vfile_begin(struct xnvfile_regular_iterator *it) * holds the relax_mutex lock for us, so that we can't race * with ->store(). */ - xnlock_get(&relax_lock); + xnlock_get_irqsave(&relax_lock, s); if (relax_queued == 0 || it->pos > relax_queued) { xnlock_put(&relax_lock); @@ -362,7 +365,7 @@ static void *relax_vfile_begin(struct xnvfile_regular_iterator *it) priv->queued = relax_queued; priv->head = relax_record_list; - xnlock_put(&relax_lock); + xnlock_put_irqrestore(&relax_lock, s); if (it->pos == 0) { priv->curr = NULL; @@ -447,19 +450,20 @@ static int relax_vfile_show(struct xnvfile_regular_iterator *it, void *data) static ssize_t relax_vfile_store(struct xnvfile_input *input) { struct relax_record *p, *np; + spl_t s; /* * Flush out all records. Races with ->show() are prevented * using the relax_mutex lock. The vfile layer takes care of * this internally. */ - xnlock_get(&relax_lock); + xnlock_get_irqsave(&relax_lock, s); p = relax_record_list; relax_record_list = NULL; relax_overall = 0; relax_queued = 0; memset(relax_jhash, 0, sizeof(relax_jhash)); - xnlock_put(&relax_lock); + xnlock_put_irqrestore(&relax_lock, s); while (p) { np = p->r_next; _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git