[PATCH] powerpc/pseries: Fix CONFIG_DTL=n build
Guenter Roeck
linux at roeck-us.net
Sat Oct 15 04:03:35 AEDT 2022
On Thu, Oct 13, 2022 at 05:31:31PM +1000, Nicholas Piggin wrote:
> The recently moved dtl code must be compiled-in if
> CONFIG_VIRT_CPU_ACCOUNTING_NATIVE=y even if CONFIG_DTL=n.
>
> Reported-by: Guenter Roeck <linux at roeck-us.net>
> Fixes: 6ba5aa541aaa0 ("powerpc/pseries: Move dtl scanning and steal time accounting to pseries platform")
> Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
Tested-by: Guenter Roeck <linux at roeck-us.net>
> ---
> arch/powerpc/platforms/pseries/Makefile | 3 +-
> arch/powerpc/platforms/pseries/dtl.c | 151 +++++++++++++-----------
> 2 files changed, 80 insertions(+), 74 deletions(-)
>
> diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
> index 14e143b946a3..92310202bdd7 100644
> --- a/arch/powerpc/platforms/pseries/Makefile
> +++ b/arch/powerpc/platforms/pseries/Makefile
> @@ -7,7 +7,7 @@ obj-y := lpar.o hvCall.o nvram.o reconfig.o \
> setup.o iommu.o event_sources.o ras.o \
> firmware.o power.o dlpar.o mobility.o rng.o \
> pci.o pci_dlpar.o eeh_pseries.o msi.o \
> - papr_platform_attributes.o
> + papr_platform_attributes.o dtl.o
> obj-$(CONFIG_SMP) += smp.o
> obj-$(CONFIG_KEXEC_CORE) += kexec.o
> obj-$(CONFIG_PSERIES_ENERGY) += pseries_energy.o
> @@ -19,7 +19,6 @@ obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
> obj-$(CONFIG_HVCS) += hvcserver.o
> obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o
> obj-$(CONFIG_CMM) += cmm.o
> -obj-$(CONFIG_DTL) += dtl.o
> obj-$(CONFIG_IO_EVENT_IRQ) += io_event_irq.o
> obj-$(CONFIG_LPARCFG) += lparcfg.o
> obj-$(CONFIG_IBMVIO) += vio.o
> diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c
> index 1b1977bc78e7..3f1cdccebc9c 100644
> --- a/arch/powerpc/platforms/pseries/dtl.c
> +++ b/arch/powerpc/platforms/pseries/dtl.c
> @@ -18,6 +18,7 @@
> #include <asm/plpar_wrappers.h>
> #include <asm/machdep.h>
>
> +#ifdef CONFIG_DTL
> struct dtl {
> struct dtl_entry *buf;
> int cpu;
> @@ -57,78 +58,6 @@ static DEFINE_PER_CPU(struct dtl_ring, dtl_rings);
>
> static atomic_t dtl_count;
>
> -/*
> - * Scan the dispatch trace log and count up the stolen time.
> - * Should be called with interrupts disabled.
> - */
> -static notrace u64 scan_dispatch_log(u64 stop_tb)
> -{
> - u64 i = local_paca->dtl_ridx;
> - struct dtl_entry *dtl = local_paca->dtl_curr;
> - struct dtl_entry *dtl_end = local_paca->dispatch_log_end;
> - struct lppaca *vpa = local_paca->lppaca_ptr;
> - u64 tb_delta;
> - u64 stolen = 0;
> - u64 dtb;
> -
> - if (!dtl)
> - return 0;
> -
> - if (i == be64_to_cpu(vpa->dtl_idx))
> - return 0;
> - while (i < be64_to_cpu(vpa->dtl_idx)) {
> - dtb = be64_to_cpu(dtl->timebase);
> - tb_delta = be32_to_cpu(dtl->enqueue_to_dispatch_time) +
> - be32_to_cpu(dtl->ready_to_enqueue_time);
> - barrier();
> - if (i + N_DISPATCH_LOG < be64_to_cpu(vpa->dtl_idx)) {
> - /* buffer has overflowed */
> - i = be64_to_cpu(vpa->dtl_idx) - N_DISPATCH_LOG;
> - dtl = local_paca->dispatch_log + (i % N_DISPATCH_LOG);
> - continue;
> - }
> - if (dtb > stop_tb)
> - break;
> - if (dtl_consumer)
> - dtl_consumer(dtl, i);
> - stolen += tb_delta;
> - ++i;
> - ++dtl;
> - if (dtl == dtl_end)
> - dtl = local_paca->dispatch_log;
> - }
> - local_paca->dtl_ridx = i;
> - local_paca->dtl_curr = dtl;
> - return stolen;
> -}
> -
> -/*
> - * Accumulate stolen time by scanning the dispatch trace log.
> - * Called on entry from user mode.
> - */
> -void notrace pseries_accumulate_stolen_time(void)
> -{
> - u64 sst, ust;
> - struct cpu_accounting_data *acct = &local_paca->accounting;
> -
> - sst = scan_dispatch_log(acct->starttime_user);
> - ust = scan_dispatch_log(acct->starttime);
> - acct->stime -= sst;
> - acct->utime -= ust;
> - acct->steal_time += ust + sst;
> -}
> -
> -u64 pseries_calculate_stolen_time(u64 stop_tb)
> -{
> - if (!firmware_has_feature(FW_FEATURE_SPLPAR))
> - return 0;
> -
> - if (get_paca()->dtl_ridx != be64_to_cpu(get_lppaca()->dtl_idx))
> - return scan_dispatch_log(stop_tb);
> -
> - return 0;
> -}
> -
> /*
> * The cpu accounting code controls the DTL ring buffer, and we get
> * given entries as they are processed.
> @@ -436,3 +365,81 @@ static int dtl_init(void)
> return 0;
> }
> machine_arch_initcall(pseries, dtl_init);
> +#endif /* CONFIG_DTL */
> +
> +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
> +/*
> + * Scan the dispatch trace log and count up the stolen time.
> + * Should be called with interrupts disabled.
> + */
> +static notrace u64 scan_dispatch_log(u64 stop_tb)
> +{
> + u64 i = local_paca->dtl_ridx;
> + struct dtl_entry *dtl = local_paca->dtl_curr;
> + struct dtl_entry *dtl_end = local_paca->dispatch_log_end;
> + struct lppaca *vpa = local_paca->lppaca_ptr;
> + u64 tb_delta;
> + u64 stolen = 0;
> + u64 dtb;
> +
> + if (!dtl)
> + return 0;
> +
> + if (i == be64_to_cpu(vpa->dtl_idx))
> + return 0;
> + while (i < be64_to_cpu(vpa->dtl_idx)) {
> + dtb = be64_to_cpu(dtl->timebase);
> + tb_delta = be32_to_cpu(dtl->enqueue_to_dispatch_time) +
> + be32_to_cpu(dtl->ready_to_enqueue_time);
> + barrier();
> + if (i + N_DISPATCH_LOG < be64_to_cpu(vpa->dtl_idx)) {
> + /* buffer has overflowed */
> + i = be64_to_cpu(vpa->dtl_idx) - N_DISPATCH_LOG;
> + dtl = local_paca->dispatch_log + (i % N_DISPATCH_LOG);
> + continue;
> + }
> + if (dtb > stop_tb)
> + break;
> +#ifdef CONFIG_DTL
> + if (dtl_consumer)
> + dtl_consumer(dtl, i);
> +#endif
> + stolen += tb_delta;
> + ++i;
> + ++dtl;
> + if (dtl == dtl_end)
> + dtl = local_paca->dispatch_log;
> + }
> + local_paca->dtl_ridx = i;
> + local_paca->dtl_curr = dtl;
> + return stolen;
> +}
> +
> +/*
> + * Accumulate stolen time by scanning the dispatch trace log.
> + * Called on entry from user mode.
> + */
> +void notrace pseries_accumulate_stolen_time(void)
> +{
> + u64 sst, ust;
> + struct cpu_accounting_data *acct = &local_paca->accounting;
> +
> + sst = scan_dispatch_log(acct->starttime_user);
> + ust = scan_dispatch_log(acct->starttime);
> + acct->stime -= sst;
> + acct->utime -= ust;
> + acct->steal_time += ust + sst;
> +}
> +
> +u64 pseries_calculate_stolen_time(u64 stop_tb)
> +{
> + if (!firmware_has_feature(FW_FEATURE_SPLPAR))
> + return 0;
> +
> + if (get_paca()->dtl_ridx != be64_to_cpu(get_lppaca()->dtl_idx))
> + return scan_dispatch_log(stop_tb);
> +
> + return 0;
> +}
> +
> +#endif
More information about the Linuxppc-dev
mailing list