提交 a7b40310 编写于 作者: J Juergen Gross

xen/x86: add diagnostic printout to xen_mc_flush() in case of error

Failure of an element of a Xen multicall is signalled via a WARN()
only if the kernel is compiled with MC_DEBUG. It is impossible to
know which element failed and why it did so.

Change that by printing the related information even without MC_DEBUG,
even if maybe in some limited form (e.g. without information which
caller produced the failing element).

Move the printing out of the switch statement in order to have the
same information for a single call.
Signed-off-by: NJuergen Gross <jgross@suse.com>
Reviewed-by: NBoris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: NJuergen Gross <jgross@suse.com>
上级 f2a5fef1
...@@ -69,6 +69,11 @@ void xen_mc_flush(void) ...@@ -69,6 +69,11 @@ void xen_mc_flush(void)
trace_xen_mc_flush(b->mcidx, b->argidx, b->cbidx); trace_xen_mc_flush(b->mcidx, b->argidx, b->cbidx);
#if MC_DEBUG
memcpy(b->debug, b->entries,
b->mcidx * sizeof(struct multicall_entry));
#endif
switch (b->mcidx) { switch (b->mcidx) {
case 0: case 0:
/* no-op */ /* no-op */
...@@ -87,32 +92,34 @@ void xen_mc_flush(void) ...@@ -87,32 +92,34 @@ void xen_mc_flush(void)
break; break;
default: default:
#if MC_DEBUG
memcpy(b->debug, b->entries,
b->mcidx * sizeof(struct multicall_entry));
#endif
if (HYPERVISOR_multicall(b->entries, b->mcidx) != 0) if (HYPERVISOR_multicall(b->entries, b->mcidx) != 0)
BUG(); BUG();
for (i = 0; i < b->mcidx; i++) for (i = 0; i < b->mcidx; i++)
if (b->entries[i].result < 0) if (b->entries[i].result < 0)
ret++; ret++;
}
if (WARN_ON(ret)) {
pr_err("%d of %d multicall(s) failed: cpu %d\n",
ret, b->mcidx, smp_processor_id());
for (i = 0; i < b->mcidx; i++) {
if (b->entries[i].result < 0) {
#if MC_DEBUG #if MC_DEBUG
if (ret) { pr_err(" call %2d: op=%lu arg=[%lx] result=%ld\t%pF\n",
printk(KERN_ERR "%d multicall(s) failed: cpu %d\n", i + 1,
ret, smp_processor_id());
dump_stack();
for (i = 0; i < b->mcidx; i++) {
printk(KERN_DEBUG " call %2d/%d: op=%lu arg=[%lx] result=%ld\t%pF\n",
i+1, b->mcidx,
b->debug[i].op, b->debug[i].op,
b->debug[i].args[0], b->debug[i].args[0],
b->entries[i].result, b->entries[i].result,
b->caller[i]); b->caller[i]);
#else
pr_err(" call %2d: op=%lu arg=[%lx] result=%ld\n",
i + 1,
b->entries[i].op,
b->entries[i].args[0],
b->entries[i].result);
#endif
} }
} }
#endif
} }
b->mcidx = 0; b->mcidx = 0;
...@@ -126,8 +133,6 @@ void xen_mc_flush(void) ...@@ -126,8 +133,6 @@ void xen_mc_flush(void)
b->cbidx = 0; b->cbidx = 0;
local_irq_restore(flags); local_irq_restore(flags);
WARN_ON(ret);
} }
struct multicall_space __xen_mc_entry(size_t args) struct multicall_space __xen_mc_entry(size_t args)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册