linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Michael Neuling <mikey@neuling.org>
To: Paul Mackerras <paulus@samba.org>, Andrew Morton <akpm@osdl.org>,
	<linuxppc-dev@ozlabs.org>, <linux-kernel@vger.kernel.org>
Cc: Michael Neuling <mikey@neuling.org>,
	Balbir Singh <balbir@linux.vnet.ibm.com>
Subject: [PATCH 2/2] [POWERPC] Add scaled time accounting
Date: Thu, 16 Aug 2007 17:09:22 +1000	[thread overview]
Message-ID: <20070816070922.6642E70073@localhost.localdomain> (raw)

This adds POWERPC specific hooks for scaled time accounting.

POWER6 includes a SPURR register.  The SPURR is based off the PURR
register but is scaled based on CPU frequency and issue rates.  This
gives a more accurate account of the instructions used per task.  The
PURR and timebase will be constant relative to the wall clock,
irrespective of the CPU frequency.  

This implementation reads the SPURR register in account_system_vtime
which is only call called on context witch and hard and soft irq entry
and exit.  The percentage of user and system time is then estimated
using the ratio of these accounted by the PURR.  If the SPURR is not
present, the PURR read.

An earlier implementation of this patch read the SPURR whenever the
PURR was read, which included the system call entry and exit path.
Unfortunately this showed a performance regression on lmbench runs, so
was re-implemented.

I've included the lmbench results here when run bare metal on POWER6.
1st column is the unpatch results.  2nd column is the results using the
below patch and the 3rd is the % diff of these results from the base.
4th and 5th columns are the results and % differnce from the base
using the older patch (SPURR read in syscall entry/exit path).

                              Base        Scaled-Acct     SPURR-in-syscall 
                             Result      Result  % diff    Result % diff  
Simple syscall:              0.3086      0.3086  0.0000    0.3452 11.8600 
Simple read:                 0.4591      0.4671  1.7425    0.5044 9.86713 
Simple write:                0.4364      0.4366  0.0458    0.4731 8.40971 
Simple stat:                 2.0055      2.0295  1.1967    2.0669 3.06158 
Simple fstat:                0.5962      0.5876  -1.442    0.6368 6.80979 
Simple open/close:           3.1283      3.1009  -0.875    3.2088 2.57328 
Select on 10 fd's:           0.8554      0.8457  -1.133    0.8667 1.32101 
Select on 100 fd's:          3.5292      3.6329  2.9383    3.6664 3.88756 
Select on 250 fd's:          7.9097      8.1881  3.5197    8.2242 3.97613 
Select on 500 fd's:          15.2659     15.836  3.7357    15.873 3.97814 
Select on 10 tcp fd's:       0.9576      0.9416  -1.670    0.9752 1.83792 
Select on 100 tcp fd's:      7.248       7.2254  -0.311    7.2685 0.28283 
Select on 250 tcp fd's:      17.7742     17.707  -0.375    17.749 -0.1406 
Select on 500 tcp fd's:      35.4258     35.25   -0.496    35.286 -0.3929 
Signal handler installation: 0.6131      0.6075  -0.913    0.647  5.52927 
Signal handler overhead:     2.0919      2.1078  0.7600    2.1831 4.35967 
Protection fault:            0.7345      0.7478  1.8107    0.8031 9.33968 
Pipe latency:                33.006      16.398  -50.31    33.475 1.42368 
AF_UNIX sock stream latency: 14.5093     30.910  113.03    30.715 111.692 
Process fork+exit:           219.8       222.8   1.3648    229.37 4.35623 
Process fork+execve:         876.14      873.28  -0.32     868.66 -0.8533 
Process fork+/bin/sh -c:     2830        2876.5  1.6431    2958   4.52296 
File /var/tmp/XXX write bw:  1193497     1195536 0.1708    118657 -0.5799 
Pagefaults on /var/tmp/XXX:  3.1272      3.2117  2.7020    3.2521 3.99398 

Also, kernel compile times show no difference with this patch applied.

Signed-off-by: Michael Neuling <mikey@neuling.org>

---

 arch/powerpc/kernel/asm-offsets.c |    1 +
 arch/powerpc/kernel/time.c        |   32 ++++++++++++++++++++++++++++++--
 include/asm-powerpc/paca.h        |    3 +++
 3 files changed, 34 insertions(+), 2 deletions(-)

Index: linux-2.6-ozlabs/arch/powerpc/kernel/asm-offsets.c
===================================================================
--- linux-2.6-ozlabs.orig/arch/powerpc/kernel/asm-offsets.c
+++ linux-2.6-ozlabs/arch/powerpc/kernel/asm-offsets.c
@@ -141,6 +141,7 @@ int main(void)
 	DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr));
 	DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
 	DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
+	DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr));
 	DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
 	DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
 	DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr));
Index: linux-2.6-ozlabs/arch/powerpc/kernel/time.c
===================================================================
--- linux-2.6-ozlabs.orig/arch/powerpc/kernel/time.c
+++ linux-2.6-ozlabs/arch/powerpc/kernel/time.c
@@ -168,23 +168,44 @@ static u64 read_purr(void)
 }
 
 /*
+ * Read the SPURR on systems that have it, otherwise the purr
+ */
+static u64 read_spurr(void)
+{
+	if (cpu_has_feature(CPU_FTR_SPURR))
+		return mfspr(SPRN_SPURR);
+	return read_purr();
+}
+
+/*
  * Account time for a transition between system, hard irq
  * or soft irq state.
  */
 void account_system_vtime(struct task_struct *tsk)
 {
-	u64 now, delta;
+	u64 now, nowscaled, delta, deltascaled;
 	unsigned long flags;
 
 	local_irq_save(flags);
 	now = read_purr();
 	delta = now - get_paca()->startpurr;
 	get_paca()->startpurr = now;
+	nowscaled = read_spurr();
+	deltascaled = nowscaled - get_paca()->startspurr;
+	get_paca()->startspurr = nowscaled;
 	if (!in_interrupt()) {
+		/* deltascaled includes both user and system time.
+		 * Hence scale it based on the purr ratio to estimate
+		 * the system time */
+		deltascaled = deltascaled * get_paca()->system_time /
+			(get_paca()->system_time + get_paca()->user_time);
 		delta += get_paca()->system_time;
 		get_paca()->system_time = 0;
 	}
 	account_system_time(tsk, 0, delta);
+	get_paca()->purrdelta = delta;
+	account_system_time_scaled(tsk, deltascaled);
+	get_paca()->spurrdelta = deltascaled;
 	local_irq_restore(flags);
 }
 
@@ -196,11 +217,17 @@ void account_system_vtime(struct task_st
  */
 void account_process_vtime(struct task_struct *tsk)
 {
-	cputime_t utime;
+	cputime_t utime, utimescaled;
 
 	utime = get_paca()->user_time;
 	get_paca()->user_time = 0;
 	account_user_time(tsk, utime);
+
+	/* Estimate the scaled utime by scaling the real utime based
+	 * on the last spurr to purr ratio */
+	utimescaled = utime * get_paca()->spurrdelta / get_paca()->purrdelta;
+	get_paca()->spurrdelta = get_paca()->purrdelta = 0;
+	account_user_time_scaled(tsk, utimescaled);
 }
 
 static void account_process_time(struct pt_regs *regs)
@@ -222,6 +249,7 @@ struct cpu_purr_data {
 	int	initialized;			/* thread is running */
 	u64	tb;			/* last TB value read */
 	u64	purr;			/* last PURR value read */
+	u64	spurr;			/* last SPURR value read */
 };
 
 /*
Index: linux-2.6-ozlabs/include/asm-powerpc/paca.h
===================================================================
--- linux-2.6-ozlabs.orig/include/asm-powerpc/paca.h
+++ linux-2.6-ozlabs/include/asm-powerpc/paca.h
@@ -103,6 +103,9 @@ struct paca_struct {
 	u64 user_time;			/* accumulated usermode TB ticks */
 	u64 system_time;		/* accumulated system TB ticks */
 	u64 startpurr;			/* PURR/TB value snapshot */
+	u64 startspurr;			/* SPURR value snapshot */
+	u64 purrdelta;			/* FIXME: document */
+	u64 spurrdelta;			/* FIXME: document */
 };
 
 extern struct paca_struct paca[];

             reply	other threads:[~2007-08-16  7:09 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-08-16  7:09 Michael Neuling [this message]
2007-08-16  9:44 ` [PATCH 2/2] [POWERPC] Add scaled time accounting Balbir Singh
2007-08-16 23:48   ` Michael Neuling

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070816070922.6642E70073@localhost.localdomain \
    --to=mikey@neuling.org \
    --cc=akpm@osdl.org \
    --cc=balbir@linux.vnet.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=paulus@samba.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).