Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp884693imm; Wed, 6 Jun 2018 07:22:40 -0700 (PDT) X-Google-Smtp-Source: ADUXVKLPQGYe/+YtrOIECCVQ70ysQ7ao1ryLbvVnPAXkPWwkqyp0MkT3F/g+JSgbiEH+EbrCWbKU X-Received: by 2002:a65:611a:: with SMTP id z26-v6mr2752614pgu.61.1528294960355; Wed, 06 Jun 2018 07:22:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528294960; cv=none; d=google.com; s=arc-20160816; b=EyjlrzjHNy3swYa7huWaXFcG6VCVnujd4ih8zejOa892LhcGp3dxPsDOVzYPSFoN8U QA2D2iQsl7gI7p/iqbmC4nlCaxC/LsYtnTKoRj+U7Fh5I5Xeo7BbhMolejV4a5tZLGuZ epClgbQFYzmWdXmv+AjdzuYWCQyb9yHPSU9RuJ66/QDNRacsiboUyEssNvyofYsWpptm GdTh1YTGnwmzQZpN24i0Hw75ZkgcDhuVCf5GCoKWtUt3BeZwNTkp5zyVnctpTUNkupYL uxE3Y6mbLpcDgrLCLu+D1xjn98txlCYRgCg6E3oIfqnr0nHedTLQKBRHcPa9kxQ+uABm YLJA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:date:cc:to:subject:from:message-id :arc-authentication-results; bh=AsR5iGPyc0RRgrZYZkBX73uqzEZ+RKVr/uSVEdR4Vao=; b=Aq1samxW27icF5CTvz/SAjDAaoMqtiwI4uARd65boi08LcpTaG0nMNWpzIgDakNFMg R/D5yzOxcgPoFpAGwhD5XxFqb16kT4FcrfrpC1UN9psgDqUsoUi+eQ7Y/MvVMEGsAyLC ciqFejDqPhP2nEUn3jdR8iL8SmfxpDinTfzQlHVy709Py6DJ6JNphDRkqrSqycyozrPD Svw7yvChzvgc2n8xxx84qaaDM/VmXi4OlNAu/WeDy+mZm5q+CwITxcSK5VPH7ChQL/BI 9FWmNdUCdu6t2IU4KPAutw+3zWdePwWzF91x7RLQiAnm3/gj3prCjljBdY4Zjy7ZVNGi s4ig== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n8-v6si12277721pgr.437.2018.06.06.07.22.25; Wed, 06 Jun 2018 07:22:40 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752132AbeFFOVM (ORCPT + 99 others); Wed, 6 Jun 2018 10:21:12 -0400 Received: from pegase1.c-s.fr ([93.17.236.30]:5208 "EHLO pegase1.c-s.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751546AbeFFOVL (ORCPT ); Wed, 6 Jun 2018 10:21:11 -0400 Received: from localhost (mailhub1-int [192.168.12.234]) by localhost (Postfix) with ESMTP id 4119nx1RVpz9ttkx; Wed, 6 Jun 2018 16:21:09 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [192.168.12.234]) (amavisd-new, port 10024) with ESMTP id EeKn4NX4LhCX; Wed, 6 Jun 2018 16:21:09 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4119nx0x7Kz9ttCS; Wed, 6 Jun 2018 16:21:09 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id E6A1F8B937; Wed, 6 Jun 2018 16:21:08 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id 2VeNZHRw3J5G; Wed, 6 Jun 2018 16:21:08 +0200 (CEST) Received: from po14934vm.idsi0.si.c-s.fr (po15451.idsi0.si.c-s.fr [172.25.231.2]) by messagerie.si.c-s.fr (Postfix) with ESMTP id BF77E8B935; Wed, 6 Jun 2018 16:21:08 +0200 (CEST) Received: by po14934vm.idsi0.si.c-s.fr (Postfix, from userid 0) id 0CC976F822; Wed, 6 Jun 2018 14:21:08 +0000 (UTC) Message-Id: From: Christophe Leroy Subject: [PATCH v4 1/2] powerpc/time: Only set CONFIG_ARCH_HAS_SCALED_CPUTIME on PPC64 To: Benjamin Herrenschmidt , Paul Mackerras , Michael Ellerman , Frederic Weisbecker , Nicholas Piggin Cc: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Date: Wed, 6 Jun 2018 14:21:08 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org scaled cputime is only meaningfull when the processor has SPURR and/or PURR, which means only on PPC64. Removing it on PPC32 significantly reduces the size of vtime_account_system() and vtime_account_idle() on an 8xx: Before: 00000000 l F .text 000000a8 vtime_delta 00000280 g F .text 0000010c vtime_account_system 0000038c g F .text 00000048 vtime_account_idle After: (vtime_delta gets inlined in the two functions) 000001d8 g F .text 000000a0 vtime_account_system 00000278 g F .text 00000038 vtime_account_idle In terms of performance, we also get approximatly 5% improvement on task switch: The following small benchmark app is run with perf stat: void *thread(void *arg) { int i; for (i = 0; i < atoi((char*)arg); i++) pthread_yield(); } int main(int argc, char **argv) { pthread_t th1, th2; pthread_create(&th1, NULL, thread, argv[1]); pthread_create(&th2, NULL, thread, argv[1]); pthread_join(th1, NULL); pthread_join(th2, NULL); return 0; } Before the patch: ~# perf stat chrt -f 98 ./sched 100000 Performance counter stats for 'chrt -f 98 ./sched 100000': 8622.166272 task-clock (msec) # 0.955 CPUs utilized 200027 context-switches # 0.023 M/sec After the patch: ~# perf stat chrt -f 98 ./sched 100000 Performance counter stats for 'chrt -f 98 ./sched 100000': 8207.090048 task-clock (msec) # 0.958 CPUs utilized 200025 context-switches # 0.024 M/sec Signed-off-by: Christophe Leroy --- v4: - Using the correct symbol CONFIG_ARCH_HAS_SCALED_CPUTIME instead of ARCH_HAS_SCALED_CPUTIME - Grouped CONFIG_ARCH_HAS_SCALED_CPUTIME related code in dedicated functions to reduce the number of #ifdefs - Integrated read_spurr() directly into the related function. v3: Rebased following modifications in xmon.c v2: added ifdefs in xmon to fix compilation error arch/powerpc/Kconfig | 2 +- arch/powerpc/include/asm/accounting.h | 4 ++ arch/powerpc/include/asm/cputime.h | 1 - arch/powerpc/kernel/time.c | 111 +++++++++++++++++++++------------- arch/powerpc/xmon/xmon.c | 4 ++ 5 files changed, 77 insertions(+), 45 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index b62a16e2c7cc..735398fd390d 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -142,7 +142,7 @@ config PPC select ARCH_HAS_PHYS_TO_DMA select ARCH_HAS_PMEM_API if PPC64 select ARCH_HAS_MEMBARRIER_CALLBACKS - select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE + select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE && PPC64 select ARCH_HAS_SG_CHAIN select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION) select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST diff --git a/arch/powerpc/include/asm/accounting.h b/arch/powerpc/include/asm/accounting.h index 3abcf98ed2e0..c607c5d835cc 100644 --- a/arch/powerpc/include/asm/accounting.h +++ b/arch/powerpc/include/asm/accounting.h @@ -15,8 +15,10 @@ struct cpu_accounting_data { /* Accumulated cputime values to flush on ticks*/ unsigned long utime; unsigned long stime; +#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME unsigned long utime_scaled; unsigned long stime_scaled; +#endif unsigned long gtime; unsigned long hardirq_time; unsigned long softirq_time; @@ -25,8 +27,10 @@ struct cpu_accounting_data { /* Internal counters */ unsigned long starttime; /* TB value snapshot */ unsigned long starttime_user; /* TB value on exit to usermode */ +#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME unsigned long startspurr; /* SPURR value snapshot */ unsigned long utime_sspurr; /* ->user_time when ->startspurr set */ +#endif }; #endif diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h index bc4903badb3f..a48c7b5e5cf9 100644 --- a/arch/powerpc/include/asm/cputime.h +++ b/arch/powerpc/include/asm/cputime.h @@ -62,7 +62,6 @@ static inline void arch_vtime_task_switch(struct task_struct *prev) struct cpu_accounting_data *acct0 = get_accounting(prev); acct->starttime = acct0->starttime; - acct->startspurr = acct0->startspurr; } #endif diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 70f145e02487..7a9f4e2f22c8 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -171,19 +171,6 @@ static void calc_cputime_factors(void) __cputime_usec_factor = res.result_low; } -/* - * Read the SPURR on systems that have it, otherwise the PURR, - * or if that doesn't exist return the timebase value passed in. - */ -static unsigned long read_spurr(unsigned long tb) -{ - if (cpu_has_feature(CPU_FTR_SPURR)) - return mfspr(SPRN_SPURR); - if (cpu_has_feature(CPU_FTR_PURR)) - return mfspr(SPRN_PURR); - return tb; -} - #ifdef CONFIG_PPC_SPLPAR /* @@ -277,30 +264,27 @@ static inline u64 calculate_stolen_time(u64 stop_tb) #endif /* CONFIG_PPC_SPLPAR */ -/* - * Account time for a transition between system, hard irq - * or soft irq state. - */ -static unsigned long vtime_delta(struct task_struct *tsk, - unsigned long *stime_scaled, - unsigned long *steal_time) +static unsigned long vtime_delta_scaled(struct cpu_accounting_data *acct, + unsigned long now, unsigned long stime) { - unsigned long now, nowscaled, deltascaled; - unsigned long stime; +#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME + unsigned long nowscaled, deltascaled; unsigned long utime, utime_scaled; - struct cpu_accounting_data *acct = get_accounting(tsk); + unsigned long stime_scaled; - WARN_ON_ONCE(!irqs_disabled()); + /* + * Read the SPURR on systems that have it, otherwise the PURR, + * or if that doesn't exist user the timebase value passed in. + */ + if (cpu_has_feature(CPU_FTR_SPURR)) + nowscaled = mfspr(SPRN_SPURR); + else if (cpu_has_feature(CPU_FTR_PURR)) + nowscaled = mfspr(SPRN_PURR); + else + nowscaled = now; - now = mftb(); - nowscaled = read_spurr(now); - stime = now - acct->starttime; - acct->starttime = now; deltascaled = nowscaled - acct->startspurr; acct->startspurr = nowscaled; - - *steal_time = calculate_stolen_time(now); - utime = acct->utime - acct->utime_sspurr; acct->utime_sspurr = acct->utime; @@ -314,18 +298,46 @@ static unsigned long vtime_delta(struct task_struct *tsk, * the user ticks get saved up in paca->user_time_scaled to be * used by account_process_tick. */ - *stime_scaled = stime; + stime_scaled = stime; utime_scaled = utime; if (deltascaled != stime + utime) { if (utime) { - *stime_scaled = deltascaled * stime / (stime + utime); - utime_scaled = deltascaled - *stime_scaled; + stime_scaled = deltascaled * stime / (stime + utime); + utime_scaled = deltascaled - stime_scaled; } else { - *stime_scaled = deltascaled; + stime_scaled = deltascaled; } } acct->utime_scaled += utime_scaled; + return stime_scaled; +#else + return 0; +#endif +} + +/* + * Account time for a transition between system, hard irq + * or soft irq state. + */ +static unsigned long vtime_delta(struct task_struct *tsk, + unsigned long *stime_scaled, + unsigned long *steal_time) +{ + unsigned long now; + unsigned long stime; + struct cpu_accounting_data *acct = get_accounting(tsk); + + WARN_ON_ONCE(!irqs_disabled()); + + now = mftb(); + stime = now - acct->starttime; + acct->starttime = now; + + *stime_scaled = vtime_delta_scaled(acct, now, stime); + + *steal_time = calculate_stolen_time(now); + return stime; } @@ -341,7 +353,9 @@ void vtime_account_system(struct task_struct *tsk) if ((tsk->flags & PF_VCPU) && !irq_count()) { acct->gtime += stime; +#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME acct->utime_scaled += stime_scaled; +#endif } else { if (hardirq_count()) acct->hardirq_time += stime; @@ -350,7 +364,9 @@ void vtime_account_system(struct task_struct *tsk) else acct->stime += stime; +#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME acct->stime_scaled += stime_scaled; +#endif } } EXPORT_SYMBOL_GPL(vtime_account_system); @@ -364,6 +380,21 @@ void vtime_account_idle(struct task_struct *tsk) acct->idle_time += stime + steal_time; } +static void vtime_flush_scaled(struct task_struct *tsk, + struct cpu_accounting_data *acct) +{ +#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME + if (acct->utime_scaled) + tsk->utimescaled += cputime_to_nsecs(acct->utime_scaled); + if (acct->stime_scaled) + tsk->stimescaled += cputime_to_nsecs(acct->stime_scaled); + + acct->utime_scaled = 0; + acct->utime_sspurr = 0; + acct->stime_scaled = 0; +#endif +} + /* * Account the whole cputime accumulated in the paca * Must be called with interrupts disabled. @@ -378,9 +409,6 @@ void vtime_flush(struct task_struct *tsk) if (acct->utime) account_user_time(tsk, cputime_to_nsecs(acct->utime)); - if (acct->utime_scaled) - tsk->utimescaled += cputime_to_nsecs(acct->utime_scaled); - if (acct->gtime) account_guest_time(tsk, cputime_to_nsecs(acct->gtime)); @@ -393,8 +421,6 @@ void vtime_flush(struct task_struct *tsk) if (acct->stime) account_system_index_time(tsk, cputime_to_nsecs(acct->stime), CPUTIME_SYSTEM); - if (acct->stime_scaled) - tsk->stimescaled += cputime_to_nsecs(acct->stime_scaled); if (acct->hardirq_time) account_system_index_time(tsk, cputime_to_nsecs(acct->hardirq_time), @@ -404,15 +430,14 @@ void vtime_flush(struct task_struct *tsk) CPUTIME_SOFTIRQ); acct->utime = 0; - acct->utime_scaled = 0; - acct->utime_sspurr = 0; acct->gtime = 0; acct->steal_time = 0; acct->idle_time = 0; acct->stime = 0; - acct->stime_scaled = 0; acct->hardirq_time = 0; acct->softirq_time = 0; + + vtime_flush_scaled(tsk, acct); } #else /* ! CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 47166ad2a669..b1e551d40ee1 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -2443,11 +2443,15 @@ static void dump_one_paca(int cpu) DUMP(p, accounting.utime, "%#-*lx"); DUMP(p, accounting.stime, "%#-*lx"); +#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME DUMP(p, accounting.utime_scaled, "%#-*lx"); +#endif DUMP(p, accounting.starttime, "%#-*lx"); DUMP(p, accounting.starttime_user, "%#-*lx"); +#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME DUMP(p, accounting.startspurr, "%#-*lx"); DUMP(p, accounting.utime_sspurr, "%#-*lx"); +#endif DUMP(p, accounting.steal_time, "%#-*lx"); #undef DUMP -- 2.13.3