Commit a7b40310 authored by Juergen Gross's avatar Juergen Gross
Browse files

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: default avatarJuergen Gross <jgross@suse.com>
Reviewed-by: default avatarBoris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
parent f2a5fef1
Loading
Loading
Loading
Loading
+20 −15
Original line number Diff line number Diff line
@@ -69,6 +69,11 @@ void xen_mc_flush(void)

	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) {
	case 0:
		/* no-op */
@@ -87,32 +92,34 @@ void xen_mc_flush(void)
		break;

	default:
#if MC_DEBUG
		memcpy(b->debug, b->entries,
		       b->mcidx * sizeof(struct multicall_entry));
#endif

		if (HYPERVISOR_multicall(b->entries, b->mcidx) != 0)
			BUG();
		for (i = 0; i < b->mcidx; i++)
			if (b->entries[i].result < 0)
				ret++;
	}

#if MC_DEBUG
		if (ret) {
			printk(KERN_ERR "%d multicall(s) failed: cpu %d\n",
			       ret, smp_processor_id());
			dump_stack();
	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++) {
				printk(KERN_DEBUG "  call %2d/%d: op=%lu arg=[%lx] result=%ld\t%pF\n",
				       i+1, b->mcidx,
			if (b->entries[i].result < 0) {
#if MC_DEBUG
				pr_err("  call %2d: op=%lu arg=[%lx] result=%ld\t%pF\n",
				       i + 1,
				       b->debug[i].op,
				       b->debug[i].args[0],
				       b->entries[i].result,
				       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;
@@ -126,8 +133,6 @@ void xen_mc_flush(void)
	b->cbidx = 0;

	local_irq_restore(flags);

	WARN_ON(ret);
}

struct multicall_space __xen_mc_entry(size_t args)