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 <li...@roeck-us.net>
> Fixes: 6ba5aa541aaa0 ("powerpc/pseries: Move dtl scanning and steal time 
> accounting to pseries platform")
> Signed-off-by: Nicholas Piggin <npig...@gmail.com>

Tested-by: Guenter Roeck <li...@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

Reply via email to