Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/pseries: Fix CONFIG_DTL=n build

The recently moved dtl code must be compiled-in if
CONFIG_VIRT_CPU_ACCOUNTING_NATIVE=y even if CONFIG_DTL=n.

Fixes: 6ba5aa541aaa0 ("powerpc/pseries: Move dtl scanning and steal time accounting to pseries platform")
Reported-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20221013073131.1485742-1-npiggin@gmail.com

authored by

Nicholas Piggin and committed by
Michael Ellerman
90d5ce82 a4cb3651

+80 -74
+1 -2
arch/powerpc/platforms/pseries/Makefile
··· 7 7 setup.o iommu.o event_sources.o ras.o \ 8 8 firmware.o power.o dlpar.o mobility.o rng.o \ 9 9 pci.o pci_dlpar.o eeh_pseries.o msi.o \ 10 - papr_platform_attributes.o 10 + papr_platform_attributes.o dtl.o 11 11 obj-$(CONFIG_SMP) += smp.o 12 12 obj-$(CONFIG_KEXEC_CORE) += kexec.o 13 13 obj-$(CONFIG_PSERIES_ENERGY) += pseries_energy.o ··· 19 19 obj-$(CONFIG_HVCS) += hvcserver.o 20 20 obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o 21 21 obj-$(CONFIG_CMM) += cmm.o 22 - obj-$(CONFIG_DTL) += dtl.o 23 22 obj-$(CONFIG_IO_EVENT_IRQ) += io_event_irq.o 24 23 obj-$(CONFIG_LPARCFG) += lparcfg.o 25 24 obj-$(CONFIG_IBMVIO) += vio.o
+79 -72
arch/powerpc/platforms/pseries/dtl.c
··· 18 18 #include <asm/plpar_wrappers.h> 19 19 #include <asm/machdep.h> 20 20 21 + #ifdef CONFIG_DTL 21 22 struct dtl { 22 23 struct dtl_entry *buf; 23 24 int cpu; ··· 57 56 static DEFINE_PER_CPU(struct dtl_ring, dtl_rings); 58 57 59 58 static atomic_t dtl_count; 60 - 61 - /* 62 - * Scan the dispatch trace log and count up the stolen time. 63 - * Should be called with interrupts disabled. 64 - */ 65 - static notrace u64 scan_dispatch_log(u64 stop_tb) 66 - { 67 - u64 i = local_paca->dtl_ridx; 68 - struct dtl_entry *dtl = local_paca->dtl_curr; 69 - struct dtl_entry *dtl_end = local_paca->dispatch_log_end; 70 - struct lppaca *vpa = local_paca->lppaca_ptr; 71 - u64 tb_delta; 72 - u64 stolen = 0; 73 - u64 dtb; 74 - 75 - if (!dtl) 76 - return 0; 77 - 78 - if (i == be64_to_cpu(vpa->dtl_idx)) 79 - return 0; 80 - while (i < be64_to_cpu(vpa->dtl_idx)) { 81 - dtb = be64_to_cpu(dtl->timebase); 82 - tb_delta = be32_to_cpu(dtl->enqueue_to_dispatch_time) + 83 - be32_to_cpu(dtl->ready_to_enqueue_time); 84 - barrier(); 85 - if (i + N_DISPATCH_LOG < be64_to_cpu(vpa->dtl_idx)) { 86 - /* buffer has overflowed */ 87 - i = be64_to_cpu(vpa->dtl_idx) - N_DISPATCH_LOG; 88 - dtl = local_paca->dispatch_log + (i % N_DISPATCH_LOG); 89 - continue; 90 - } 91 - if (dtb > stop_tb) 92 - break; 93 - if (dtl_consumer) 94 - dtl_consumer(dtl, i); 95 - stolen += tb_delta; 96 - ++i; 97 - ++dtl; 98 - if (dtl == dtl_end) 99 - dtl = local_paca->dispatch_log; 100 - } 101 - local_paca->dtl_ridx = i; 102 - local_paca->dtl_curr = dtl; 103 - return stolen; 104 - } 105 - 106 - /* 107 - * Accumulate stolen time by scanning the dispatch trace log. 108 - * Called on entry from user mode. 109 - */ 110 - void notrace pseries_accumulate_stolen_time(void) 111 - { 112 - u64 sst, ust; 113 - struct cpu_accounting_data *acct = &local_paca->accounting; 114 - 115 - sst = scan_dispatch_log(acct->starttime_user); 116 - ust = scan_dispatch_log(acct->starttime); 117 - acct->stime -= sst; 118 - acct->utime -= ust; 119 - acct->steal_time += ust + sst; 120 - } 121 - 122 - u64 pseries_calculate_stolen_time(u64 stop_tb) 123 - { 124 - if (!firmware_has_feature(FW_FEATURE_SPLPAR)) 125 - return 0; 126 - 127 - if (get_paca()->dtl_ridx != be64_to_cpu(get_lppaca()->dtl_idx)) 128 - return scan_dispatch_log(stop_tb); 129 - 130 - return 0; 131 - } 132 59 133 60 /* 134 61 * The cpu accounting code controls the DTL ring buffer, and we get ··· 365 436 return 0; 366 437 } 367 438 machine_arch_initcall(pseries, dtl_init); 439 + #endif /* CONFIG_DTL */ 440 + 441 + #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE 442 + /* 443 + * Scan the dispatch trace log and count up the stolen time. 444 + * Should be called with interrupts disabled. 445 + */ 446 + static notrace u64 scan_dispatch_log(u64 stop_tb) 447 + { 448 + u64 i = local_paca->dtl_ridx; 449 + struct dtl_entry *dtl = local_paca->dtl_curr; 450 + struct dtl_entry *dtl_end = local_paca->dispatch_log_end; 451 + struct lppaca *vpa = local_paca->lppaca_ptr; 452 + u64 tb_delta; 453 + u64 stolen = 0; 454 + u64 dtb; 455 + 456 + if (!dtl) 457 + return 0; 458 + 459 + if (i == be64_to_cpu(vpa->dtl_idx)) 460 + return 0; 461 + while (i < be64_to_cpu(vpa->dtl_idx)) { 462 + dtb = be64_to_cpu(dtl->timebase); 463 + tb_delta = be32_to_cpu(dtl->enqueue_to_dispatch_time) + 464 + be32_to_cpu(dtl->ready_to_enqueue_time); 465 + barrier(); 466 + if (i + N_DISPATCH_LOG < be64_to_cpu(vpa->dtl_idx)) { 467 + /* buffer has overflowed */ 468 + i = be64_to_cpu(vpa->dtl_idx) - N_DISPATCH_LOG; 469 + dtl = local_paca->dispatch_log + (i % N_DISPATCH_LOG); 470 + continue; 471 + } 472 + if (dtb > stop_tb) 473 + break; 474 + #ifdef CONFIG_DTL 475 + if (dtl_consumer) 476 + dtl_consumer(dtl, i); 477 + #endif 478 + stolen += tb_delta; 479 + ++i; 480 + ++dtl; 481 + if (dtl == dtl_end) 482 + dtl = local_paca->dispatch_log; 483 + } 484 + local_paca->dtl_ridx = i; 485 + local_paca->dtl_curr = dtl; 486 + return stolen; 487 + } 488 + 489 + /* 490 + * Accumulate stolen time by scanning the dispatch trace log. 491 + * Called on entry from user mode. 492 + */ 493 + void notrace pseries_accumulate_stolen_time(void) 494 + { 495 + u64 sst, ust; 496 + struct cpu_accounting_data *acct = &local_paca->accounting; 497 + 498 + sst = scan_dispatch_log(acct->starttime_user); 499 + ust = scan_dispatch_log(acct->starttime); 500 + acct->stime -= sst; 501 + acct->utime -= ust; 502 + acct->steal_time += ust + sst; 503 + } 504 + 505 + u64 pseries_calculate_stolen_time(u64 stop_tb) 506 + { 507 + if (!firmware_has_feature(FW_FEATURE_SPLPAR)) 508 + return 0; 509 + 510 + if (get_paca()->dtl_ridx != be64_to_cpu(get_lppaca()->dtl_idx)) 511 + return scan_dispatch_log(stop_tb); 512 + 513 + return 0; 514 + } 515 + 516 + #endif