forked from Minki/linux
4603ac180a
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. [pbadari@us.ibm.com: Avoid unnecessary PURR reading] Signed-off-by: Michael Neuling <mikey@neuling.org> Cc: Balbir Singh <balbir@in.ibm.com> Cc: Jay Lan <jlan@engr.sgi.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Badari Pulavarty <pbadari@us.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
128 lines
4.1 KiB
C
128 lines
4.1 KiB
C
/*
|
|
* include/asm-powerpc/paca.h
|
|
*
|
|
* This control block defines the PACA which defines the processor
|
|
* specific data for each logical processor on the system.
|
|
* There are some pointers defined that are utilized by PLIC.
|
|
*
|
|
* C 2001 PPC 64 Team, IBM Corp
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version
|
|
* 2 of the License, or (at your option) any later version.
|
|
*/
|
|
#ifndef _ASM_POWERPC_PACA_H
|
|
#define _ASM_POWERPC_PACA_H
|
|
#ifdef __KERNEL__
|
|
|
|
#include <asm/types.h>
|
|
#include <asm/lppaca.h>
|
|
#include <asm/mmu.h>
|
|
|
|
register struct paca_struct *local_paca asm("r13");
|
|
|
|
#if defined(CONFIG_DEBUG_PREEMPT) && defined(CONFIG_SMP)
|
|
extern unsigned int debug_smp_processor_id(void); /* from linux/smp.h */
|
|
/*
|
|
* Add standard checks that preemption cannot occur when using get_paca():
|
|
* otherwise the paca_struct it points to may be the wrong one just after.
|
|
*/
|
|
#define get_paca() ((void) debug_smp_processor_id(), local_paca)
|
|
#else
|
|
#define get_paca() local_paca
|
|
#endif
|
|
|
|
#define get_lppaca() (get_paca()->lppaca_ptr)
|
|
#define get_slb_shadow() (get_paca()->slb_shadow_ptr)
|
|
|
|
struct task_struct;
|
|
|
|
/*
|
|
* Defines the layout of the paca.
|
|
*
|
|
* This structure is not directly accessed by firmware or the service
|
|
* processor except for the first two pointers that point to the
|
|
* lppaca area and the ItLpRegSave area for this CPU. The lppaca
|
|
* object is currently contained within the PACA but it doesn't need
|
|
* to be.
|
|
*/
|
|
struct paca_struct {
|
|
/*
|
|
* Because hw_cpu_id, unlike other paca fields, is accessed
|
|
* routinely from other CPUs (from the IRQ code), we stick to
|
|
* read-only (after boot) fields in the first cacheline to
|
|
* avoid cacheline bouncing.
|
|
*/
|
|
|
|
/*
|
|
* MAGIC: These first two pointers can't be moved - they're
|
|
* accessed by the firmware
|
|
*/
|
|
struct lppaca *lppaca_ptr; /* Pointer to LpPaca for PLIC */
|
|
#ifdef CONFIG_PPC_ISERIES
|
|
void *reg_save_ptr; /* Pointer to LpRegSave for PLIC */
|
|
#endif /* CONFIG_PPC_ISERIES */
|
|
|
|
/*
|
|
* MAGIC: the spinlock functions in arch/powerpc/lib/locks.c
|
|
* load lock_token and paca_index with a single lwz
|
|
* instruction. They must travel together and be properly
|
|
* aligned.
|
|
*/
|
|
u16 lock_token; /* Constant 0x8000, used in locks */
|
|
u16 paca_index; /* Logical processor number */
|
|
|
|
u64 kernel_toc; /* Kernel TOC address */
|
|
u64 stab_real; /* Absolute address of segment table */
|
|
u64 stab_addr; /* Virtual address of segment table */
|
|
void *emergency_sp; /* pointer to emergency stack */
|
|
u64 data_offset; /* per cpu data offset */
|
|
s16 hw_cpu_id; /* Physical processor number */
|
|
u8 cpu_start; /* At startup, processor spins until */
|
|
/* this becomes non-zero. */
|
|
struct slb_shadow *slb_shadow_ptr;
|
|
|
|
/*
|
|
* Now, starting in cacheline 2, the exception save areas
|
|
*/
|
|
/* used for most interrupts/exceptions */
|
|
u64 exgen[10] __attribute__((aligned(0x80)));
|
|
u64 exmc[10]; /* used for machine checks */
|
|
u64 exslb[10]; /* used for SLB/segment table misses
|
|
* on the linear mapping */
|
|
|
|
mm_context_t context;
|
|
u16 vmalloc_sllp;
|
|
u16 slb_cache_ptr;
|
|
u16 slb_cache[SLB_CACHE_ENTRIES];
|
|
|
|
/*
|
|
* then miscellaneous read-write fields
|
|
*/
|
|
struct task_struct *__current; /* Pointer to current */
|
|
u64 kstack; /* Saved Kernel stack addr */
|
|
u64 stab_rr; /* stab/slb round-robin counter */
|
|
u64 saved_r1; /* r1 save for RTAS calls */
|
|
u64 saved_msr; /* MSR saved here by enter_rtas */
|
|
u16 trap_save; /* Used when bad stack is encountered */
|
|
u8 soft_enabled; /* irq soft-enable flag */
|
|
u8 hard_enabled; /* set if irqs are enabled in MSR */
|
|
u8 io_sync; /* writel() needs spin_unlock sync */
|
|
|
|
/* Stuff for accurate time accounting */
|
|
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[];
|
|
|
|
void setup_boot_paca(void);
|
|
|
|
#endif /* __KERNEL__ */
|
|
#endif /* _ASM_POWERPC_PACA_H */
|