aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/multicalls.c
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>2010-12-17 20:32:28 -0500
committerJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>2011-07-18 18:43:45 -0400
commiteac303bf2ef63e7f7b6971badea0ff7bf08a2b22 (patch)
treefe992cb61954a55733208f60a2e6b393cc5698aa /arch/x86/xen/multicalls.c
parent4a7b005dbfa554e7cc7fbc08e0299a9b7a91ef3b (diff)
xen/multicall: special-case singleton hypercalls
Singleton calls seem to end up being pretty common, so just directly call the hypercall rather than going via multicall. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Diffstat (limited to 'arch/x86/xen/multicalls.c')
-rw-r--r--arch/x86/xen/multicalls.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/arch/x86/xen/multicalls.c b/arch/x86/xen/multicalls.c
index cc71f7cf1adc..2474553d1f26 100644
--- a/arch/x86/xen/multicalls.c
+++ b/arch/x86/xen/multicalls.c
@@ -55,6 +55,7 @@ DEFINE_PER_CPU(unsigned long, xen_mc_irq_flags);
55void xen_mc_flush(void) 55void xen_mc_flush(void)
56{ 56{
57 struct mc_buffer *b = &__get_cpu_var(mc_buffer); 57 struct mc_buffer *b = &__get_cpu_var(mc_buffer);
58 struct multicall_entry *mc;
58 int ret = 0; 59 int ret = 0;
59 unsigned long flags; 60 unsigned long flags;
60 int i; 61 int i;
@@ -67,7 +68,24 @@ void xen_mc_flush(void)
67 68
68 trace_xen_mc_flush(b->mcidx, b->argidx, b->cbidx); 69 trace_xen_mc_flush(b->mcidx, b->argidx, b->cbidx);
69 70
70 if (b->mcidx) { 71 switch (b->mcidx) {
72 case 0:
73 /* no-op */
74 BUG_ON(b->argidx != 0);
75 break;
76
77 case 1:
78 /* Singleton multicall - bypass multicall machinery
79 and just do the call directly. */
80 mc = &b->entries[0];
81
82 mc->result = privcmd_call(mc->op,
83 mc->args[0], mc->args[1], mc->args[2],
84 mc->args[3], mc->args[4]);
85 ret = mc->result < 0;
86 break;
87
88 default:
71#if MC_DEBUG 89#if MC_DEBUG
72 memcpy(b->debug, b->entries, 90 memcpy(b->debug, b->entries,
73 b->mcidx * sizeof(struct multicall_entry)); 91 b->mcidx * sizeof(struct multicall_entry));
@@ -94,11 +112,10 @@ void xen_mc_flush(void)
94 } 112 }
95 } 113 }
96#endif 114#endif
115 }
97 116
98 b->mcidx = 0; 117 b->mcidx = 0;
99 b->argidx = 0; 118 b->argidx = 0;
100 } else
101 BUG_ON(b->argidx != 0);
102 119
103 for (i = 0; i < b->cbidx; i++) { 120 for (i = 0; i < b->cbidx; i++) {
104 struct callback *cb = &b->callbacks[i]; 121 struct callback *cb = &b->callbacks[i];