diff options
| -rw-r--r-- | arch/x86/xen/multicalls.c | 109 | ||||
| -rw-r--r-- | arch/x86/xen/multicalls.h | 3 |
2 files changed, 4 insertions, 108 deletions
diff --git a/arch/x86/xen/multicalls.c b/arch/x86/xen/multicalls.c index 1b2b73ff0a6e..b9bf19884bc5 100644 --- a/arch/x86/xen/multicalls.c +++ b/arch/x86/xen/multicalls.c | |||
| @@ -52,76 +52,6 @@ struct mc_buffer { | |||
| 52 | static DEFINE_PER_CPU(struct mc_buffer, mc_buffer); | 52 | static DEFINE_PER_CPU(struct mc_buffer, mc_buffer); |
| 53 | DEFINE_PER_CPU(unsigned long, xen_mc_irq_flags); | 53 | DEFINE_PER_CPU(unsigned long, xen_mc_irq_flags); |
| 54 | 54 | ||
| 55 | /* flush reasons 0- slots, 1- args, 2- callbacks */ | ||
| 56 | enum flush_reasons | ||
| 57 | { | ||
| 58 | FL_SLOTS, | ||
| 59 | FL_ARGS, | ||
| 60 | FL_CALLBACKS, | ||
| 61 | |||
| 62 | FL_N_REASONS | ||
| 63 | }; | ||
| 64 | |||
| 65 | #ifdef CONFIG_XEN_DEBUG_FS | ||
| 66 | #define NHYPERCALLS 40 /* not really */ | ||
| 67 | |||
| 68 | static struct { | ||
| 69 | unsigned histo[MC_BATCH+1]; | ||
| 70 | |||
| 71 | unsigned issued; | ||
| 72 | unsigned arg_total; | ||
| 73 | unsigned hypercalls; | ||
| 74 | unsigned histo_hypercalls[NHYPERCALLS]; | ||
| 75 | |||
| 76 | unsigned flush[FL_N_REASONS]; | ||
| 77 | } mc_stats; | ||
| 78 | |||
| 79 | static u8 zero_stats; | ||
| 80 | |||
| 81 | static inline void check_zero(void) | ||
| 82 | { | ||
| 83 | if (unlikely(zero_stats)) { | ||
| 84 | memset(&mc_stats, 0, sizeof(mc_stats)); | ||
| 85 | zero_stats = 0; | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | static void mc_add_stats(const struct mc_buffer *mc) | ||
| 90 | { | ||
| 91 | int i; | ||
| 92 | |||
| 93 | check_zero(); | ||
| 94 | |||
| 95 | mc_stats.issued++; | ||
| 96 | mc_stats.hypercalls += mc->mcidx; | ||
| 97 | mc_stats.arg_total += mc->argidx; | ||
| 98 | |||
| 99 | mc_stats.histo[mc->mcidx]++; | ||
| 100 | for(i = 0; i < mc->mcidx; i++) { | ||
| 101 | unsigned op = mc->entries[i].op; | ||
| 102 | if (op < NHYPERCALLS) | ||
| 103 | mc_stats.histo_hypercalls[op]++; | ||
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | static void mc_stats_flush(enum flush_reasons idx) | ||
| 108 | { | ||
| 109 | check_zero(); | ||
| 110 | |||
| 111 | mc_stats.flush[idx]++; | ||
| 112 | } | ||
| 113 | |||
| 114 | #else /* !CONFIG_XEN_DEBUG_FS */ | ||
| 115 | |||
| 116 | static inline void mc_add_stats(const struct mc_buffer *mc) | ||
| 117 | { | ||
| 118 | } | ||
| 119 | |||
| 120 | static inline void mc_stats_flush(enum flush_reasons idx) | ||
| 121 | { | ||
| 122 | } | ||
| 123 | #endif /* CONFIG_XEN_DEBUG_FS */ | ||
| 124 | |||
| 125 | void xen_mc_flush(void) | 55 | void xen_mc_flush(void) |
| 126 | { | 56 | { |
| 127 | struct mc_buffer *b = &__get_cpu_var(mc_buffer); | 57 | struct mc_buffer *b = &__get_cpu_var(mc_buffer); |
| @@ -135,8 +65,6 @@ void xen_mc_flush(void) | |||
| 135 | something in the middle */ | 65 | something in the middle */ |
| 136 | local_irq_save(flags); | 66 | local_irq_save(flags); |
| 137 | 67 | ||
| 138 | mc_add_stats(b); | ||
| 139 | |||
| 140 | if (b->mcidx) { | 68 | if (b->mcidx) { |
| 141 | #if MC_DEBUG | 69 | #if MC_DEBUG |
| 142 | memcpy(b->debug, b->entries, | 70 | memcpy(b->debug, b->entries, |
| @@ -193,7 +121,6 @@ struct multicall_space __xen_mc_entry(size_t args) | |||
| 193 | 121 | ||
| 194 | if (b->mcidx == MC_BATCH || | 122 | if (b->mcidx == MC_BATCH || |
| 195 | (argidx + args) >= MC_ARGS) { | 123 | (argidx + args) >= MC_ARGS) { |
| 196 | mc_stats_flush(b->mcidx == MC_BATCH ? FL_SLOTS : FL_ARGS); | ||
| 197 | xen_mc_flush(); | 124 | xen_mc_flush(); |
| 198 | argidx = roundup(b->argidx, sizeof(u64)); | 125 | argidx = roundup(b->argidx, sizeof(u64)); |
| 199 | } | 126 | } |
| @@ -240,44 +167,10 @@ void xen_mc_callback(void (*fn)(void *), void *data) | |||
| 240 | struct mc_buffer *b = &__get_cpu_var(mc_buffer); | 167 | struct mc_buffer *b = &__get_cpu_var(mc_buffer); |
| 241 | struct callback *cb; | 168 | struct callback *cb; |
| 242 | 169 | ||
| 243 | if (b->cbidx == MC_BATCH) { | 170 | if (b->cbidx == MC_BATCH) |
| 244 | mc_stats_flush(FL_CALLBACKS); | ||
| 245 | xen_mc_flush(); | 171 | xen_mc_flush(); |
| 246 | } | ||
| 247 | 172 | ||
| 248 | cb = &b->callbacks[b->cbidx++]; | 173 | cb = &b->callbacks[b->cbidx++]; |
| 249 | cb->fn = fn; | 174 | cb->fn = fn; |
| 250 | cb->data = data; | 175 | cb->data = data; |
| 251 | } | 176 | } |
| 252 | |||
| 253 | #ifdef CONFIG_XEN_DEBUG_FS | ||
| 254 | |||
| 255 | static struct dentry *d_mc_debug; | ||
| 256 | |||
| 257 | static int __init xen_mc_debugfs(void) | ||
| 258 | { | ||
| 259 | struct dentry *d_xen = xen_init_debugfs(); | ||
| 260 | |||
| 261 | if (d_xen == NULL) | ||
| 262 | return -ENOMEM; | ||
| 263 | |||
| 264 | d_mc_debug = debugfs_create_dir("multicalls", d_xen); | ||
| 265 | |||
| 266 | debugfs_create_u8("zero_stats", 0644, d_mc_debug, &zero_stats); | ||
| 267 | |||
| 268 | debugfs_create_u32("batches", 0444, d_mc_debug, &mc_stats.issued); | ||
| 269 | debugfs_create_u32("hypercalls", 0444, d_mc_debug, &mc_stats.hypercalls); | ||
| 270 | debugfs_create_u32("arg_total", 0444, d_mc_debug, &mc_stats.arg_total); | ||
| 271 | |||
| 272 | xen_debugfs_create_u32_array("batch_histo", 0444, d_mc_debug, | ||
| 273 | mc_stats.histo, MC_BATCH); | ||
| 274 | xen_debugfs_create_u32_array("hypercall_histo", 0444, d_mc_debug, | ||
| 275 | mc_stats.histo_hypercalls, NHYPERCALLS); | ||
| 276 | xen_debugfs_create_u32_array("flush_reasons", 0444, d_mc_debug, | ||
| 277 | mc_stats.flush, FL_N_REASONS); | ||
| 278 | |||
| 279 | return 0; | ||
| 280 | } | ||
| 281 | fs_initcall(xen_mc_debugfs); | ||
| 282 | |||
| 283 | #endif /* CONFIG_XEN_DEBUG_FS */ | ||
diff --git a/arch/x86/xen/multicalls.h b/arch/x86/xen/multicalls.h index 4ec8035e3216..fa7b8af759ee 100644 --- a/arch/x86/xen/multicalls.h +++ b/arch/x86/xen/multicalls.h | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | #ifndef _XEN_MULTICALLS_H | 1 | #ifndef _XEN_MULTICALLS_H |
| 2 | #define _XEN_MULTICALLS_H | 2 | #define _XEN_MULTICALLS_H |
| 3 | 3 | ||
| 4 | #include <trace/events/xen.h> | ||
| 5 | |||
| 4 | #include "xen-ops.h" | 6 | #include "xen-ops.h" |
| 5 | 7 | ||
| 6 | /* Multicalls */ | 8 | /* Multicalls */ |
| @@ -20,6 +22,7 @@ DECLARE_PER_CPU(unsigned long, xen_mc_irq_flags); | |||
| 20 | static inline void xen_mc_batch(void) | 22 | static inline void xen_mc_batch(void) |
| 21 | { | 23 | { |
| 22 | unsigned long flags; | 24 | unsigned long flags; |
| 25 | |||
| 23 | /* need to disable interrupts until this entry is complete */ | 26 | /* need to disable interrupts until this entry is complete */ |
| 24 | local_irq_save(flags); | 27 | local_irq_save(flags); |
| 25 | __this_cpu_write(xen_mc_irq_flags, flags); | 28 | __this_cpu_write(xen_mc_irq_flags, flags); |
