diff options
Diffstat (limited to 'arch/powerpc/platforms/pseries/setup.c')
| -rw-r--r-- | arch/powerpc/platforms/pseries/setup.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index a6d19e3a505..d345bfd56bb 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
| @@ -273,6 +273,58 @@ static struct notifier_block pci_dn_reconfig_nb = { | |||
| 273 | .notifier_call = pci_dn_reconfig_notifier, | 273 | .notifier_call = pci_dn_reconfig_notifier, |
| 274 | }; | 274 | }; |
| 275 | 275 | ||
| 276 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | ||
| 277 | /* | ||
| 278 | * Allocate space for the dispatch trace log for all possible cpus | ||
| 279 | * and register the buffers with the hypervisor. This is used for | ||
| 280 | * computing time stolen by the hypervisor. | ||
| 281 | */ | ||
| 282 | static int alloc_dispatch_logs(void) | ||
| 283 | { | ||
| 284 | int cpu, ret; | ||
| 285 | struct paca_struct *pp; | ||
| 286 | struct dtl_entry *dtl; | ||
| 287 | |||
| 288 | if (!firmware_has_feature(FW_FEATURE_SPLPAR)) | ||
| 289 | return 0; | ||
| 290 | |||
| 291 | for_each_possible_cpu(cpu) { | ||
| 292 | pp = &paca[cpu]; | ||
| 293 | dtl = kmalloc_node(DISPATCH_LOG_BYTES, GFP_KERNEL, | ||
| 294 | cpu_to_node(cpu)); | ||
| 295 | if (!dtl) { | ||
| 296 | pr_warn("Failed to allocate dispatch trace log for cpu %d\n", | ||
| 297 | cpu); | ||
| 298 | pr_warn("Stolen time statistics will be unreliable\n"); | ||
| 299 | break; | ||
| 300 | } | ||
| 301 | |||
| 302 | pp->dtl_ridx = 0; | ||
| 303 | pp->dispatch_log = dtl; | ||
| 304 | pp->dispatch_log_end = dtl + N_DISPATCH_LOG; | ||
| 305 | pp->dtl_curr = dtl; | ||
| 306 | } | ||
| 307 | |||
| 308 | /* Register the DTL for the current (boot) cpu */ | ||
| 309 | dtl = get_paca()->dispatch_log; | ||
| 310 | get_paca()->dtl_ridx = 0; | ||
| 311 | get_paca()->dtl_curr = dtl; | ||
| 312 | get_paca()->lppaca_ptr->dtl_idx = 0; | ||
| 313 | |||
| 314 | /* hypervisor reads buffer length from this field */ | ||
| 315 | dtl->enqueue_to_dispatch_time = DISPATCH_LOG_BYTES; | ||
| 316 | ret = register_dtl(hard_smp_processor_id(), __pa(dtl)); | ||
| 317 | if (ret) | ||
| 318 | pr_warn("DTL registration failed for boot cpu %d (%d)\n", | ||
| 319 | smp_processor_id(), ret); | ||
| 320 | get_paca()->lppaca_ptr->dtl_enable_mask = 2; | ||
| 321 | |||
| 322 | return 0; | ||
| 323 | } | ||
| 324 | |||
| 325 | early_initcall(alloc_dispatch_logs); | ||
| 326 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING */ | ||
| 327 | |||
| 276 | static void __init pSeries_setup_arch(void) | 328 | static void __init pSeries_setup_arch(void) |
| 277 | { | 329 | { |
| 278 | /* Discover PIC type and setup ppc_md accordingly */ | 330 | /* Discover PIC type and setup ppc_md accordingly */ |
