diff options
author | Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> | 2010-12-17 20:32:28 -0500 |
---|---|---|
committer | Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> | 2011-07-18 18:43:45 -0400 |
commit | eac303bf2ef63e7f7b6971badea0ff7bf08a2b22 (patch) | |
tree | fe992cb61954a55733208f60a2e6b393cc5698aa /arch/x86/xen/multicalls.c | |
parent | 4a7b005dbfa554e7cc7fbc08e0299a9b7a91ef3b (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.c | 27 |
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); | |||
55 | void xen_mc_flush(void) | 55 | void 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]; |