scheduler changes for v3.9
Subsystems (30)
Ingo Molnar
maintainerLinus,
Please pull the latest sched-core-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git sched-core-for-linus
HEAD: 77852fea6e2442a0e654a9292060489895de18c7 sched/rt: Add <linux/sched/rt.h> header to <linux/init_task.h>
Main changes:
* scheduler side full-dynticks (user-space execution is undisturbed and receives no timer IRQs) preparation changes that convert the cputime accounting code to be full-dynticks ready, from Frederic Weisbecker.
* Initial sched.h split-up changes, by Clark Williams
* select_idle_sibling() performance improvement by Mike Galbraith:
" 1 tbench pair (worst case) in a 10 core + SMT package:
pre 15.22 MB/sec 1 procs
post 252.01 MB/sec 1 procs " * sched_rr_get_interval() ABI fix/change. We think this detail is not used by apps (so it's not an ABI in practice), but lets keep it under observation.
* misc RT scheduling cleanups, optimizations
Thanks,
Ingo
------------------>
Clark Williams (3):
sched: Move sched.h sysctl bits into separate header sched/rt: Add a tuning knob to allow changing SCHED_RR timeslice sched/rt: Move rt specific bits into new header file
Dan Carpenter (1):
sched: Fix signedness bug in yield_to()
Frederic Weisbecker (9):
context_tracking: Export context state for generic vtime
cputime: Avoid multiplication overflow on utime scaling
cputime: Librarize per nsecs resolution cputime definitions
cputime: Move default nsecs_to_cputime() to jiffies based cputime file
cputime: Generic on-demand virtual cputime accounting
cputime: Allow dynamic switch between tick/virtual based cputime accounting
cputime: Use accessors to read task cputime stats
kvm: Prepare to add generic guest entry/exit callbacks
cputime: Safely read cputime of full dynticks CPUs
Ingo Molnar (2):
sched, powerpc: Fix sched.h split-up build failure sched/rt: Add <linux/sched/rt.h> header to <linux/init_task.h>
Kirill Tkhai (3):
sched/rt: Add reschedule check to switched_from_rt() sched/rt: Do not account zero delta_exec in update_curr_rt() sched/rt: Further simplify pick_rt_task()
Mike Galbraith (1):
sched: Fix select_idle_sibling() bouncing cow syndrome
Stephen Rothwell (1):
cputime: Restore CPU_ACCOUNTING config defaults for PPC64
Thomas Gleixner (1):
cputime: Remove irqsave from seqlock readers
Viresh Kumar (1):
sched/fair: Set se->vruntime directly in place_entity()
Ying Xue (1):
sched/rt: Avoid updating RT entry timeout twice within one tick period
Zhu Yanhai (1):
sched: Fix the broken sched_rr_get_interval()
arch/alpha/kernel/osf_sys.c | 6 +- arch/ia64/include/asm/cputime.h | 92 +------- arch/ia64/include/asm/thread_info.h | 4 +- arch/ia64/include/asm/xen/minstate.h | 2 +- arch/ia64/kernel/asm-offsets.c | 2 +- arch/ia64/kernel/entry.S | 16 +- arch/ia64/kernel/fsys.S | 4 +- arch/ia64/kernel/head.S | 4 +- arch/ia64/kernel/ivt.S | 8 +- arch/ia64/kernel/minstate.h | 2 +- arch/ia64/kernel/time.c | 5 +- arch/powerpc/configs/chroma_defconfig | 2 +- arch/powerpc/configs/corenet64_smp_defconfig | 2 +- arch/powerpc/configs/pasemi_defconfig | 2 +- arch/powerpc/include/asm/cputime.h | 6 +- arch/powerpc/include/asm/lppaca.h | 2 +- arch/powerpc/include/asm/ppc_asm.h | 4 +- arch/powerpc/kernel/entry_64.S | 4 +- arch/powerpc/kernel/time.c | 5 +- arch/powerpc/platforms/cell/spufs/sched.c | 1 + arch/powerpc/platforms/pseries/dtl.c | 6 +- arch/powerpc/platforms/pseries/setup.c | 6 +- arch/s390/kernel/vtime.c | 6 +- arch/x86/kernel/apm_32.c | 11 +- block/blk-exec.c | 1 + drivers/isdn/mISDN/stack.c | 7 +- drivers/spi/spi.c | 2 +- drivers/staging/csr/bh.c | 2 +- drivers/staging/csr/unifi_sme.c | 2 +- drivers/tty/sysrq.c | 1 + fs/binfmt_elf.c | 8 +- fs/binfmt_elf_fdpic.c | 7 +- fs/proc/array.c | 4 +- fs/select.c | 1 + include/asm-generic/cputime.h | 66 +----- include/asm-generic/cputime_jiffies.h | 72 ++++++ include/asm-generic/cputime_nsecs.h | 104 +++++++++ include/linux/context_tracking.h | 28 +++ include/linux/hardirq.h | 4 +- include/linux/init_task.h | 12 + include/linux/kernel_stat.h | 2 +- include/linux/kvm_host.h | 55 ++++- include/linux/sched.h | 185 ++++------------ include/linux/sched/rt.h | 58 +++++ include/linux/sched/sysctl.h | 110 ++++++++++ include/linux/tsacct_kern.h | 3 + include/linux/vtime.h | 59 +++-- init/Kconfig | 25 ++- init/init_task.c | 2 + kernel/acct.c | 6 +- kernel/context_tracking.c | 43 ++-- kernel/cpu.c | 4 +- kernel/delayacct.c | 7 +- kernel/exit.c | 10 +- kernel/fork.c | 6 + kernel/futex.c | 1 + kernel/hrtimer.c | 2 + kernel/irq/manage.c | 1 + kernel/mutex.c | 1 + kernel/posix-cpu-timers.c | 28 ++- kernel/rtmutex-debug.c | 1 + kernel/rtmutex-tester.c | 1 + kernel/rtmutex.c | 1 + kernel/sched/core.c | 22 +- kernel/sched/cpupri.c | 2 + kernel/sched/cputime.c | 314 +++++++++++++++++++++++---- kernel/sched/fair.c | 27 +-- kernel/sched/rt.c | 26 ++- kernel/sched/sched.h | 2 + kernel/signal.c | 12 +- kernel/softirq.c | 6 +- kernel/sysctl.c | 8 + kernel/time/tick-sched.c | 5 +- kernel/timer.c | 1 + kernel/trace/trace.c | 1 + kernel/trace/trace_sched_wakeup.c | 2 +- kernel/tsacct.c | 44 +++- kernel/watchdog.c | 1 + mm/mmap.c | 1 + mm/mremap.c | 1 + mm/nommu.c | 1 + mm/page-writeback.c | 1 + mm/page_alloc.c | 1 + 83 files changed, 1105 insertions(+), 507 deletions(-) create mode 100644 include/asm-generic/cputime_jiffies.h create mode 100644 include/asm-generic/cputime_nsecs.h create mode 100644 include/linux/sched/rt.h create mode 100644 include/linux/sched/sysctl.h
arch/alpha/kernel/osf_sys.c +4 -2
@@ -1139,6 +1139,7 @@ struct rusage32 { SYSCALL_DEFINE2(osf_getrusage, int, who, struct rusage32 __user *, ru) {struct rusage32 r; +cputime_t utime, stime;if (who !=RUSAGE_SELF && who !=RUSAGE_CHILDREN )return -EINVAL ;
@@ -1146,8 +1147,9 @@ SYSCALL_DEFINE2(osf_getrusage, int, who, struct rusage32 __user *, ru)memset (&r,0 ,sizeof (r));switch (who) {case RUSAGE_SELF : -jiffies_to_timeval32 (current->utime, &r.ru_utime); -jiffies_to_timeval32 (current->stime, &r.ru_stime); +task_cputime (current, &utime, &stime); +jiffies_to_timeval32 (utime, &r.ru_utime); +jiffies_to_timeval32 (stime, &r.ru_stime); r.ru_minflt = current->min_flt; r.ru_majflt = current->maj_flt;break ;
arch/ia64/include/asm/cputime.h +6 -86
105 lines not on this page · raw message
arch/ia64/include/asm/thread_info.h +2 -2
@@ -31,7 +31,7 @@ struct thread_info {mm_segment_t addr_limit;/* user-level address space limit */ int preempt_count;/* 0=premptable, <0=BUG; will also serve as bh-counter */ struct restart_block restart_block; -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE __u64 ac_stamp;__u64 ac_leave;__u64 ac_stime;
@@ -69,7 +69,7 @@ struct thread_info {#define task_stack_page (tsk) ((void *)(tsk))#define __HAVE_THREAD_FUNCTIONS -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE #define setup_thread_stack (p, org) \ *task_thread_info(p) = *task_thread_info(org); \ task_thread_info(p)->ac_stime = 0; \
arch/ia64/include/asm/xen/minstate.h +1 -1
@@ -1,5 +1,5 @@ -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE /* read ar.itc in advance, and use it before leaving bank 0 */ #define XEN_ACCOUNT_GET_STAMP \ MOV_FROM_ITC(pUStk, p6, r20, r2);
arch/ia64/kernel/asm-offsets.c +1 -1
@@ -41,7 +41,7 @@ void foo(void)DEFINE (TI_FLAGS , offsetof(struct thread_info , flags));DEFINE (TI_CPU , offsetof(struct thread_info , cpu));DEFINE (TI_PRE_COUNT , offsetof(struct thread_info , preempt_count)); -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE DEFINE (TI_AC_STAMP , offsetof(struct thread_info , ac_stamp));DEFINE (TI_AC_LEAVE , offsetof(struct thread_info , ac_leave));DEFINE (TI_AC_STIME , offsetof(struct thread_info , ac_stime));
arch/ia64/kernel/entry.S +8 -8
@@ -724,7 +724,7 @@ GLOBAL_ENTRY(__paravirt_leave_syscall) #endif .global __paravirt_work_processed_syscall; __paravirt_work_processed_syscall: -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE adds r2=PT(LOADRS)+16,r12 MOV_FROM_ITC(pUStk, p9, r22, r19) // fetch time at leave adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
@@ -762,7 +762,7 @@ __paravirt_work_processed_syscall: ld8 r29=[r2],16 // M0|1 load cr.ipsr ld8 r28=[r3],16 // M0|1 load cr.iip -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE (pUStk) add r14=TI_AC_LEAVE+IA64_TASK_SIZE,r13 ;; ld8 r30=[r2],16 // M0|1 load cr.ifs
@@ -793,7 +793,7 @@ __paravirt_work_processed_syscall: ld8.fill r1=[r3],16 // M0|1 load r1 (pUStk) mov r17=1 // A ;; -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE (pUStk) st1 [r15]=r17 // M2|3 #else (pUStk) st1 [r14]=r17 // M2|3
@@ -813,7 +813,7 @@ __paravirt_work_processed_syscall: shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition COVER // B add current frame into dirty partition & set cr.ifs ;; -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE mov r19=ar.bsp // M2 get new backing store pointer st8 [r14]=r22 // M save time at leave mov f10=f0 // F clear f10
@@ -948,7 +948,7 @@ GLOBAL_ENTRY(__paravirt_leave_kernel) adds r16=PT(CR_IPSR)+16,r12 adds r17=PT(CR_IIP)+16,r12 -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE .pred.rel.mutex pUStk,pKStk MOV_FROM_PSR(pKStk, r22, r29) // M2 read PSR now that interrupts are disabled MOV_FROM_ITC(pUStk, p9, r22, r29) // M fetch time at leave
@@ -981,7 +981,7 @@ GLOBAL_ENTRY(__paravirt_leave_kernel) ;; ld8.fill r12=[r16],16 ld8.fill r13=[r17],16 -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE (pUStk) adds r3=TI_AC_LEAVE+IA64_TASK_SIZE,r18 #else (pUStk) adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18
@@ -989,7 +989,7 @@ GLOBAL_ENTRY(__paravirt_leave_kernel) ;; ld8 r20=[r16],16 // ar.fpsr ld8.fill r15=[r17],16 -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE (pUStk) adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18 // deferred #endif ;;
@@ -997,7 +997,7 @@ GLOBAL_ENTRY(__paravirt_leave_kernel) ld8.fill r2=[r17] (pUStk) mov r17=1 ;; -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE // mmi_ : ld8 st1 shr;; mmi_ : st8 st1 shr;; // mib : mov add br -> mib : ld8 add br // bbb_ : br nop cover;; mbb_ : mov br cover;;
arch/ia64/kernel/fsys.S +2 -2
@@ -529,7 +529,7 @@ GLOBAL_ENTRY(paravirt_fsys_bubble_down) nop.i 0 ;; mov ar.rsc=0 // M2 set enforced lazy mode, pl 0, LE, loadrs=0 -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE MOV_FROM_ITC(p0, p6, r30, r23) // M get cycle for accounting #else nop.m 0
@@ -555,7 +555,7 @@ GLOBAL_ENTRY(paravirt_fsys_bubble_down) cmp.ne pKStk,pUStk=r0,r0 // A set pKStk <- 0, pUStk <- 1 br.call.sptk.many b7=ia64_syscall_setup // B ;; -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE // mov.m r30=ar.itc is called in advance add r16=TI_AC_STAMP+IA64_TASK_SIZE,r2 add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r2
arch/ia64/kernel/head.S +2 -2
@@ -1073,7 +1073,7 @@ END(ia64_native_sched_clock) sched_clock = ia64_native_sched_clock #endif -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE GLOBAL_ENTRY(cycle_to_cputime) alloc r16=ar.pfs,1,0,0,0 addl r8=THIS_CPU(ia64_cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0
@@ -1091,7 +1091,7 @@ GLOBAL_ENTRY(cycle_to_cputime) shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT br.ret.sptk.many rp END(cycle_to_cputime) -#endif /* CONFIG_VIRT_CPU_ACCOUNTING */ +#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ #ifdef CONFIG_IA64_BRL_EMU
arch/ia64/kernel/ivt.S +4 -4
@@ -784,7 +784,7 @@ ENTRY(break_fault) (p8) adds r28=16,r28 // A switch cr.iip to next bundle (p9) adds r8=1,r8 // A increment ei to next slot -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE ;; mov b6=r30 // I0 setup syscall handler branch reg early #else
@@ -801,7 +801,7 @@ ENTRY(break_fault) // /////////////////////////////////////////////////////////////////////// st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE MOV_FROM_ITC(p0, p14, r30, r18) // M get cycle for accounting #else mov b6=r30 // I0 setup syscall handler branch reg early
@@ -817,7 +817,7 @@ ENTRY(break_fault) cmp.eq p14,p0=r9,r0 // A are syscalls being traced/audited? br.call.sptk.many b7=ia64_syscall_setup // B 1: -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE // mov.m r30=ar.itc is called in advance, and r13 is current add r16=TI_AC_STAMP+IA64_TASK_SIZE,r13 // A add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r13 // A
@@ -1043,7 +1043,7 @@ END(ia64_syscall_setup) DBG_FAULT(16) FAULT(16) -#if defined(CONFIG_VIRT_CPU_ACCOUNTING) && defined(__IA64_ASM_PARAVIRTUALIZED_NATIVE) +#if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) && defined(__IA64_ASM_PARAVIRTUALIZED_NATIVE) /* * There is no particular reason for this code to be here, other than * that there happens to be space here that would go unused otherwise.
arch/ia64/kernel/minstate.h +1 -1
@@ -4,7 +4,7 @@#include "entry.h" #include "paravirt_inst.h" -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE /* read ar.itc in advance, and use it before leaving bank 0 */ #define ACCOUNT_GET_STAMP \ (pUStk) mov.m r20=ar.itc;
arch/ia64/kernel/time.c +3 -2
@@ -77,7 +77,7 @@ static struct clocksource clocksource_itc = { };static struct clocksource *itc_clocksource; -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE #include <linux/kernel_stat.h>
@@ -136,13 +136,14 @@ void vtime_account_system(struct task_struct *tsk) account_system_time(tsk, 0, delta, delta); } +EXPORT_SYMBOL_GPL (vtime_account_system);void vtime_account_idle (struct task_struct *tsk) {account_idle_time (vtime_delta (tsk)); } -#endif /* CONFIG_VIRT_CPU_ACCOUNTING */ +#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ static irqreturn_t timer_interrupt (int irq,void *dev_id)
arch/powerpc/configs/chroma_defconfig +1 -1
@@ -1,6 +1,6 @@ CONFIG_PPC64=y CONFIG_PPC_BOOK3E_64=y -# CONFIG_VIRT_CPU_ACCOUNTING is not set +# CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set CONFIG_SMP=y CONFIG_NR_CPUS=256 CONFIG_EXPERIMENTAL=y
arch/powerpc/configs/corenet64_smp_defconfig +1 -1
@@ -1,6 +1,6 @@ CONFIG_PPC64=y CONFIG_PPC_BOOK3E_64=y -# CONFIG_VIRT_CPU_ACCOUNTING is not set +# CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_EXPERIMENTAL=y
arch/powerpc/configs/pasemi_defconfig +1 -1
@@ -1,6 +1,6 @@ CONFIG_PPC64=y CONFIG_ALTIVEC=y -# CONFIG_VIRT_CPU_ACCOUNTING is not set +# CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_EXPERIMENTAL=y
arch/powerpc/include/asm/cputime.h +3 -3
@@ -8,7 +8,7 @@* as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * -* If we have CONFIG_VIRT_CPU_ACCOUNTING, we measure cpu time in +* If we have CONFIG_VIRT_CPU_ACCOUNTING_NATIVE, we measure cpu time in * the same units as the timebase. Otherwise we measure cpu time * in jiffies using the generic definitions. */
@@ -16,7 +16,7 @@#ifndef __POWERPC_CPUTIME_H#define __POWERPC_CPUTIME_H -#ifndef CONFIG_VIRT_CPU_ACCOUNTING +#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE #include <asm-generic/cputime.h> #ifdef __KERNEL__static inline void setup_cputime_one_jiffy (void ) { }
@@ -231,5 +231,5 @@ static inline cputime_t clock_t_to_cputime(const unsigned long clk)static inline void arch_vtime_task_switch (struct task_struct *tsk) { }#endif /* __KERNEL__ */ -#endif /* CONFIG_VIRT_CPU_ACCOUNTING */ +#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ #endif /* __POWERPC_CPUTIME_H */
arch/powerpc/include/asm/lppaca.h +1 -1
@@ -145,7 +145,7 @@ struct dtl_entry {extern struct kmem_cache *dtl_cache;/* -* When CONFIG_VIRT_CPU_ACCOUNTING = y, the cpu accounting code controls +* When CONFIG_VIRT_CPU_ACCOUNTING_NATIVE = y, the cpu accounting code controls * reading from the dispatch trace log. If other code wants to consume * DTL entries, it can set this pointer to a function that will get * called once for each DTL entry that gets processed.
arch/powerpc/include/asm/ppc_asm.h +2 -2
@@ -24,7 +24,7 @@* user_time and system_time fields in the paca. */ -#ifndef CONFIG_VIRT_CPU_ACCOUNTING +#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE #define ACCOUNT_CPU_USER_ENTRY (ra, rb)#define ACCOUNT_CPU_USER_EXIT (ra, rb)#define ACCOUNT_STOLEN_TIME
@@ -70,7 +70,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)#endif /* CONFIG_PPC_SPLPAR */ -#endif /* CONFIG_VIRT_CPU_ACCOUNTING */ +#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ /* * Macros for storing registers into and loading registers from
arch/powerpc/kernel/entry_64.S +2 -2
@@ -94,7 +94,7 @@ system_call_common: addi r9,r1,STACK_FRAME_OVERHEAD ld r11,exception_marker@toc(r2) std r11,-16(r9) /* "regshere" marker */ -#if defined(CONFIG_VIRT_CPU_ACCOUNTING) && defined(CONFIG_PPC_SPLPAR) +#if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) && defined(CONFIG_PPC_SPLPAR) BEGIN_FW_FTR_SECTION beq 33f /* if from user, see if there are any DTL entries to process */
@@ -110,7 +110,7 @@ BEGIN_FW_FTR_SECTION addi r9,r1,STACK_FRAME_OVERHEAD 33: END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) -#endif /* CONFIG_VIRT_CPU_ACCOUNTING && CONFIG_PPC_SPLPAR */ +#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE && CONFIG_PPC_SPLPAR */ /* * A syscall should always be called with interrupts enabled
arch/powerpc/kernel/time.c +3 -2
@@ -143,7 +143,7 @@ EXPORT_SYMBOL_GPL(ppc_proc_freq);unsigned long ppc_tb_freq;EXPORT_SYMBOL_GPL (ppc_tb_freq); -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE /* * Factors for converting from cputime_t (timebase ticks) to * jiffies, microseconds, seconds, and clock_t (1/USER_HZ seconds).
@@ -347,6 +347,7 @@ void vtime_account_system(struct task_struct *tsk)if (stolen)account_steal_time (stolen); } +EXPORT_SYMBOL_GPL (vtime_account_system);void vtime_account_idle (struct task_struct *tsk) {
@@ -377,7 +378,7 @@ void vtime_account_user(struct task_struct *tsk) account_user_time(tsk, utime, utimescaled); } -#else /* ! CONFIG_VIRT_CPU_ACCOUNTING */ +#else /* ! CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ #define calc_cputime_factors ()#endif
arch/powerpc/platforms/cell/spufs/sched.c +1 -0
@@ -24,6 +24,7 @@#include <linux/errno.h> #include <linux/sched.h> +#include <linux/sched/rt.h> #include <linux/kernel.h> #include <linux/mm.h> #include <linux/slab.h>
arch/powerpc/platforms/pseries/dtl.c +3 -3
@@ -57,7 +57,7 @@ static u8 dtl_event_mask = 0x7;*/ static int dtl_buf_entries =N_DISPATCH_LOG ; -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE struct dtl_ring { u64 write_index; struct dtl_entry *write_ptr;
@@ -142,7 +142,7 @@ static u64 dtl_current_index(struct dtl *dtl) return per_cpu(dtl_rings, dtl->cpu).write_index; } -#else /* CONFIG_VIRT_CPU_ACCOUNTING */ +#else /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ static int dtl_start (struct dtl *dtl) {
@@ -188,7 +188,7 @@ static u64 dtl_current_index(struct dtl *dtl) {return lppaca_of (dtl->cpu).dtl_idx; } -#endif /* CONFIG_VIRT_CPU_ACCOUNTING */ +#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ static int dtl_enable (struct dtl *dtl) {
arch/powerpc/platforms/pseries/setup.c +3 -3
@@ -281,7 +281,7 @@ static struct notifier_block pci_dn_reconfig_nb = {struct kmem_cache *dtl_cache; -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE /* * Allocate space for the dispatch trace log for all possible cpus * and register the buffers with the hypervisor. This is used for
@@ -332,12 +332,12 @@ static int alloc_dispatch_logs(void) return 0; } -#else /* !CONFIG_VIRT_CPU_ACCOUNTING */ +#else /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ static inline int alloc_dispatch_logs (void ) {return 0 ; } -#endif /* CONFIG_VIRT_CPU_ACCOUNTING */ +#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ static int alloc_dispatch_log_kmem_cache (void ) {
arch/s390/kernel/vtime.c +3 -3
@@ -127,7 +127,7 @@ void vtime_account_user(struct task_struct *tsk)* Update process times based on virtual cpu times stored by entry.S * to the lowcore fields user_timer, system_timer & steal_clock. */ -void vtime_account (struct task_struct *tsk) +void vtime_account_irq_enter (struct task_struct *tsk) {struct thread_info *ti =task_thread_info (tsk);u64 timer, system;
@@ -145,10 +145,10 @@ void vtime_account(struct task_struct *tsk)virt_timer_forward (system); } -EXPORT_SYMBOL_GPL (vtime_account); +EXPORT_SYMBOL_GPL (vtime_account_irq_enter);void vtime_account_system (struct task_struct *tsk) -__attribute__((alias ("vtime_account" ))); +__attribute__((alias ("vtime_account_irq_enter" )));EXPORT_SYMBOL_GPL (vtime_account_system);void __kprobes vtime_stop_cpu (void )
arch/x86/kernel/apm_32.c +6 -5
@@ -899,6 +899,7 @@ static void apm_cpu_idle(void)static int use_apm_idle;/* = 0 */ static unsigned int last_jiffies;/* = 0 */ static unsigned int last_stime;/* = 0 */ +cputime_t stime;int apm_idle_done =0 ;unsigned int jiffies_since_last_check = jiffies - last_jiffies;
@@ -906,23 +907,23 @@ static void apm_cpu_idle(void)WARN_ONCE (1 ,"deprecated apm_cpu_idle will be deleted in 2012" ); recalc: +task_cputime (current,NULL , &stime);if (jiffies_since_last_check >IDLE_CALC_LIMIT ) { use_apm_idle =0 ; - last_jiffies = jiffies; - last_stime = current->stime; }else if (jiffies_since_last_check > idle_period) {unsigned int idle_percentage; - idle_percentage = current->stime - last_stime; + idle_percentage = stime - last_stime; idle_percentage *=100 ; idle_percentage /= jiffies_since_last_check; use_apm_idle = (idle_percentage > idle_threshold);if (apm_info.forbid_idle) use_apm_idle =0 ; - last_jiffies = jiffies; - last_stime = current->stime; } + last_jiffies = jiffies; + last_stime = stime; + bucket =IDLE_LEAKY_MAX ;while (!need_resched ()) {
block/blk-exec.c +1 -0
@@ -5,6 +5,7 @@#include <linux/module.h> #include <linux/bio.h> #include <linux/blkdev.h> +#include <linux/sched/sysctl.h> #include "blk.h"
drivers/isdn/mISDN/stack.c +6 -1
@@ -18,6 +18,7 @@#include <linux/slab.h> #include <linux/mISDNif.h> #include <linux/kthread.h> +#include <linux/sched.h> #include "core.h" static u_int *debug;
@@ -202,6 +203,9 @@ static int mISDNStackd(void *data) {struct mISDNstack *st = data; +#ifdef MISDN_MSG_STATS +cputime_t utime, stime; +#endif int err =0 ;sigfillset (¤t->blocked);
@@ -303,9 +307,10 @@ mISDNStackd(void *data)"msg %d sleep %d stopped\n" ,dev_name (&st->dev->dev), st->msg_cnt, st->sleep_cnt, st->stopped_cnt); +task_cputime (st->thread, &utime, &stime);printk (KERN_DEBUG "mISDNStackd daemon for %s utime(%ld) stime(%ld)\n" , -dev_name (&st->dev->dev), st->thread->utime, st->thread->stime); +dev_name (&st->dev->dev), utime, stime);printk (KERN_DEBUG "mISDNStackd daemon for %s nvcsw(%ld) nivcsw(%ld)\n" ,dev_name (&st->dev->dev), st->thread->nvcsw, st->thread->nivcsw);
drivers/spi/spi.c +1 -1
@@ -33,7 +33,7 @@#include <linux/of_gpio.h> #include <linux/pm_runtime.h> #include <linux/export.h> -#include <linux/sched.h> +#include <linux/sched/rt.h> #include <linux/delay.h> #include <linux/kthread.h> #include <linux/ioport.h>
drivers/staging/csr/bh.c +1 -1
@@ -15,7 +15,7 @@*/ #include "csr_wifi_hip_unifi.h" #include "unifi_priv.h" - +#include <linux/sched/rt.h> /* * ---------------------------------------------------------------------------
drivers/staging/csr/unifi_sme.c +1 -1
@@ -15,7 +15,7 @@#include "unifi_priv.h" #include "csr_wifi_hip_unifi.h" #include "csr_wifi_hip_conversions.h" - +#include <linux/sched/rt.h>
drivers/tty/sysrq.c +1 -0
@@ -15,6 +15,7 @@#define pr_fmt (fmt) KBUILD_MODNAME ": " fmt#include <linux/sched.h> +#include <linux/sched/rt.h> #include <linux/interrupt.h> #include <linux/mm.h> #include <linux/fs.h>
fs/binfmt_elf.c +6 -2
@@ -33,6 +33,7 @@#include <linux/elf.h> #include <linux/utsname.h> #include <linux/coredump.h> +#include <linux/sched.h> #include <asm/uaccess.h> #include <asm/param.h> #include <asm/page.h>
@@ -1320,8 +1321,11 @@ static void fill_prstatus(struct elf_prstatus *prstatus,cputime_to_timeval (cputime.utime, &prstatus->pr_utime);cputime_to_timeval (cputime.stime, &prstatus->pr_stime); }else { -cputime_to_timeval (p->utime, &prstatus->pr_utime); -cputime_to_timeval (p->stime, &prstatus->pr_stime); +cputime_t utime, stime; + +task_cputime (p, &utime, &stime); +cputime_to_timeval (utime, &prstatus->pr_utime); +cputime_to_timeval (stime, &prstatus->pr_stime); }cputime_to_timeval (p->signal->cutime, &prstatus->pr_cutime);cputime_to_timeval (p->signal->cstime, &prstatus->pr_cstime);
fs/binfmt_elf_fdpic.c +5 -2
@@ -1375,8 +1375,11 @@ static void fill_prstatus(struct elf_prstatus *prstatus,cputime_to_timeval (cputime.utime, &prstatus->pr_utime);cputime_to_timeval (cputime.stime, &prstatus->pr_stime); }else { -cputime_to_timeval (p->utime, &prstatus->pr_utime); -cputime_to_timeval (p->stime, &prstatus->pr_stime); +cputime_t utime, stime; + +task_cputime (p, &utime, &stime); +cputime_to_timeval (utime, &prstatus->pr_utime); +cputime_to_timeval (stime, &prstatus->pr_stime); }cputime_to_timeval (p->signal->cutime, &prstatus->pr_cutime);cputime_to_timeval (p->signal->cstime, &prstatus->pr_cstime);
fs/proc/array.c +2 -2
@@ -449,7 +449,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,do { min_flt += t->min_flt; maj_flt += t->maj_flt; - gtime += t->gtime; + gtime +=task_gtime (t); t =next_thread (t); }while (t != task);
@@ -472,7 +472,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, min_flt = task->min_flt; maj_flt = task->maj_flt;task_cputime_adjusted (task, &utime, &stime); - gtime = task->gtime; + gtime =task_gtime (task); }/* scale priority and nice values from timeslices to -20..20 */
fs/select.c +1 -0
@@ -26,6 +26,7 @@#include <linux/fs.h> #include <linux/rcupdate.h> #include <linux/hrtimer.h> +#include <linux/sched/rt.h> #include <asm/uaccess.h>
include/asm-generic/cputime.h +6 -60
72 lines not on this page · raw message
include/asm-generic/cputime_jiffies.h new file +72 -0
72 lines not on this page · raw message
include/asm-generic/cputime_nsecs.h new file +104 -0
104 lines not on this page · raw message
include/linux/context_tracking.h +28 -0
@@ -3,12 +3,40 @@#ifdef CONFIG_CONTEXT_TRACKING #include <linux/sched.h> +#include <linux/percpu.h> + +struct context_tracking { +/* +* When active is false, probes are unset in order +* to minimize overhead: TIF flags are cleared +* and calls to user_enter/exit are ignored. This +* may be further optimized using static keys. +*/ +bool active; +enum { +IN_KERNEL =0 , +IN_USER , + } state; +}; + +DECLARE_PER_CPU(struct context_tracking, context_tracking); + +static inline bool context_tracking_in_user (void ) +{ +return __this_cpu_read (context_tracking.state) ==IN_USER ; +} + +static inline bool context_tracking_active (void ) +{ +return __this_cpu_read (context_tracking.active); +}extern void user_enter (void );extern void user_exit (void );extern void context_tracking_task_switch (struct task_struct *prev,struct task_struct *next);#else +static inline bool context_tracking_in_user (void ) {return false; }static inline void user_enter (void ) { }static inline void user_exit (void ) { } static inline void context_tracking_task_switch(struct task_struct *prev,
include/linux/hardirq.h +2 -2
@@ -153,7 +153,7 @@ extern void rcu_nmi_exit(void);*/ #define __irq_enter () \ do { \ - vtime_account_irq_enter(current); \ + account_irq_enter_time(current); \ add_preempt_count(HARDIRQ_OFFSET); \ trace_hardirq_enter(); \ } while (0)
@@ -169,7 +169,7 @@ extern void irq_enter(void);#define __irq_exit () \ do { \ trace_hardirq_exit(); \ - vtime_account_irq_exit(current); \ + account_irq_exit_time(current); \ sub_preempt_count(HARDIRQ_OFFSET); \ } while (0)
include/linux/init_task.h +12 -0
@@ -10,7 +10,9 @@#include <linux/pid_namespace.h> #include <linux/user_namespace.h> #include <linux/securebits.h> +#include <linux/seqlock.h> #include <net/net_namespace.h> +#include <linux/sched/rt.h> #ifdef CONFIG_SMP # define INIT_PUSHABLE_TASKS (tsk) \
@@ -141,6 +143,15 @@ extern struct task_group root_task_group;# define INIT_PERF_EVENTS (tsk)#endif +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN +# define INIT_VTIME (tsk) \ + .vtime_seqlock = __SEQLOCK_UNLOCKED(tsk.vtime_seqlock), \ + .vtime_snap = 0, \ + .vtime_snap_whence = VTIME_SYS, +#else +# define INIT_VTIME (tsk) +#endif +#define INIT_TASK_COMM "swapper"/*
@@ -210,6 +221,7 @@ extern struct task_group root_task_group; INIT_TRACE_RECURSION \ INIT_TASK_RCU_PREEMPT(tsk) \ INIT_CPUSET_SEQ \ + INIT_VTIME(tsk) \ }
include/linux/kernel_stat.h +1 -1
@@ -127,7 +127,7 @@ extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t)extern void account_steal_time (cputime_t );extern void account_idle_time (cputime_t ); -#ifdef CONFIG_VIRT_CPU_ACCOUNTING +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE static inline void account_process_tick (struct task_struct *tsk,int user) {vtime_account_user (tsk);
include/linux/kvm_host.h +46 -9
79 lines not on this page · raw message
include/linux/sched.h +42 -143
252 lines not on this page · raw message
include/linux/sched/rt.h new file +58 -0
58 lines not on this page · raw message
include/linux/sched/sysctl.h new file +110 -0
110 lines not on this page · raw message
include/linux/tsacct_kern.h +3 -0
@@ -23,12 +23,15 @@ static inline void bacct_add_tsk(struct user_namespace *user_ns,#ifdef CONFIG_TASK_XACCT extern void xacct_add_tsk (struct taskstats *stats,struct task_struct *p);extern void acct_update_integrals (struct task_struct *tsk); +extern void acct_account_cputime (struct task_struct *tsk);extern void acct_clear_integrals (struct task_struct *tsk);#else static inline void xacct_add_tsk (struct taskstats *stats,struct task_struct *p) {}static inline void acct_update_integrals (struct task_struct *tsk) {} +static inline void acct_account_cputime (struct task_struct *tsk) +{}static inline void acct_clear_integrals (struct task_struct *tsk) {}#endif /* CONFIG_TASK_XACCT */
include/linux/vtime.h +40 -19
80 lines not on this page · raw message
init/Kconfig +23 -2
@@ -326,10 +326,13 @@ source "kernel/time/Kconfig" menu "CPU/Task time and stats accounting" +config VIRT_CPU_ACCOUNTING + bool + choice prompt "Cputime accounting" default TICK_CPU_ACCOUNTING if !PPC64 - default VIRT_CPU_ACCOUNTING if PPC64 + default VIRT_CPU_ACCOUNTING_NATIVE if PPC64 # Kind of a stub config for the pure tick based cputime accounting config TICK_CPU_ACCOUNTING
@@ -342,9 +345,10 @@ config TICK_CPU_ACCOUNTING If unsure, say Y. -config VIRT_CPU_ACCOUNTING +config VIRT_CPU_ACCOUNTING_NATIVE bool "Deterministic task and CPU time accounting" depends on HAVE_VIRT_CPU_ACCOUNTING + select VIRT_CPU_ACCOUNTING help Select this option to enable more accurate task and CPU time accounting. This is done by reading a CPU counter on each
@@ -354,6 +358,23 @@ config VIRT_CPU_ACCOUNTING this also enables accounting of stolen time on logically-partitioned systems. +config VIRT_CPU_ACCOUNTING_GEN + bool "Full dynticks CPU time accounting" + depends on HAVE_CONTEXT_TRACKING && 64BIT + select VIRT_CPU_ACCOUNTING + select CONTEXT_TRACKING + help + Select this option to enable task and CPU time accounting on full + dynticks systems. This accounting is implemented by watching every + kernel-user boundaries using the context tracking subsystem. + The accounting is thus performed at the expense of some significant + overhead. + + For now this is only useful if you are working on the full + dynticks subsystem development. + + If unsure, say N. + config IRQ_TIME_ACCOUNTING bool "Fine granularity task level IRQ time accounting" depends on HAVE_IRQ_TIME_ACCOUNTING
init/init_task.c +2 -0
@@ -2,6 +2,8 @@#include <linux/export.h> #include <linux/mqueue.h> #include <linux/sched.h> +#include <linux/sched/sysctl.h> +#include <linux/sched/rt.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/mm.h>
kernel/acct.c +4 -2
@@ -566,6 +566,7 @@ out:void acct_collect (long exitcode,int group_dead) {struct pacct_struct *pacct = ¤t->signal->pacct; +cputime_t utime, stime;unsigned long vsize =0 ;if (group_dead && current->mm) {
@@ -593,8 +594,9 @@ void acct_collect(long exitcode, int group_dead) pacct->ac_flag |=ACORE ;if (current->flags &PF_SIGNALED ) pacct->ac_flag |=AXSIG ; - pacct->ac_utime += current->utime; - pacct->ac_stime += current->stime; +task_cputime (current, &utime, &stime); + pacct->ac_utime += utime; + pacct->ac_stime += stime; pacct->ac_minflt += current->min_flt; pacct->ac_majflt += current->maj_flt;spin_unlock_irq (¤t->sighand->siglock);
kernel/context_tracking.c +25 -18
69 lines not on this page · raw message
kernel/cpu.c +3 -1
@@ -224,11 +224,13 @@ void clear_tasks_mm_cpumask(int cpu)static inline void check_for_tasks (int cpu) {struct task_struct *p; +cputime_t utime, stime;write_lock_irq (&tasklist_lock);for_each_process (p) { +task_cputime (p, &utime, &stime);if (task_cpu (p) == cpu && p->state ==TASK_RUNNING && - (p->utime || p->stime)) + (utime || stime)) printk(KERN_WARNING "Task %s (pid = %d) is on cpu %d " "(state = %ld, flags = %x)\n", p->comm, task_pid_nr(p), cpu,
kernel/delayacct.c +5 -2
@@ -106,6 +106,7 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)unsigned long long t2, t3;unsigned long flags;struct timespec ts; +cputime_t utime, stime, stimescaled, utimescaled;/* Though tsk->delays accessed later, early exit avoids * unnecessary returning of other data
@@ -114,12 +115,14 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk) goto done; tmp = (s64 )d->cpu_run_real_total; -cputime_to_timespec (tsk->utime + tsk->stime, &ts); +task_cputime (tsk, &utime, &stime); +cputime_to_timespec (utime + stime, &ts); tmp +=timespec_to_ns (&ts); d->cpu_run_real_total = (tmp < (s64 )d->cpu_run_real_total) ?0 : tmp; tmp = (s64 )d->cpu_scaled_run_real_total; -cputime_to_timespec (tsk->utimescaled + tsk->stimescaled, &ts); +task_cputime_scaled (tsk, &utimescaled, &stimescaled); +cputime_to_timespec (utimescaled + stimescaled, &ts); tmp +=timespec_to_ns (&ts); d->cpu_scaled_run_real_total = (tmp < (s64 )d->cpu_scaled_run_real_total) ?0 : tmp;
kernel/exit.c +6 -4
@@ -85,6 +85,7 @@ static void __exit_signal(struct task_struct *tsk)bool group_dead =thread_group_leader (tsk);struct sighand_struct *sighand;struct tty_struct *uninitialized_var (tty ); +cputime_t utime, stime; sighand =rcu_dereference_check (tsk->sighand,lockdep_tasklist_lock_is_held ());
@@ -123,9 +124,10 @@ static void __exit_signal(struct task_struct *tsk)* We won't ever get here for the group leader, since it * will have been the last reference on the signal_struct. */ - sig->utime += tsk->utime; - sig->stime += tsk->stime; - sig->gtime += tsk->gtime; +task_cputime (tsk, &utime, &stime); + sig->utime += utime; + sig->stime += stime; + sig->gtime +=task_gtime (tsk); sig->min_flt += tsk->min_flt; sig->maj_flt += tsk->maj_flt; sig->nvcsw += tsk->nvcsw;
@@ -1092,7 +1094,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) sig = p->signal; psig->cutime += tgutime + sig->cutime; psig->cstime += tgstime + sig->cstime; - psig->cgtime += p->gtime + sig->gtime + sig->cgtime; + psig->cgtime +=task_gtime (p) + sig->gtime + sig->cgtime; psig->cmin_flt += p->min_flt + sig->min_flt + sig->cmin_flt; psig->cmaj_flt +=
kernel/fork.c +6 -0
@@ -1233,6 +1233,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,#ifndef CONFIG_VIRT_CPU_ACCOUNTING p->prev_cputime.utime = p->prev_cputime.stime =0 ;#endif +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN +seqlock_init (&p->vtime_seqlock); + p->vtime_snap =0 ; + p->vtime_snap_whence =VTIME_SLEEPING ; +#endif +#if defined(SPLIT_RSS_COUNTING )memset (&p->rss_stat,0 ,sizeof (p->rss_stat));#endif
kernel/futex.c +1 -0
@@ -60,6 +60,7 @@#include <linux/pid.h> #include <linux/nsproxy.h> #include <linux/ptrace.h> +#include <linux/sched/rt.h> #include <asm/futex.h>
kernel/hrtimer.c +2 -0
@@ -44,6 +44,8 @@#include <linux/err.h> #include <linux/debugobjects.h> #include <linux/sched.h> +#include <linux/sched/sysctl.h> +#include <linux/sched/rt.h> #include <linux/timer.h> #include <asm/uaccess.h>
kernel/irq/manage.c +1 -0
@@ -16,6 +16,7 @@#include <linux/interrupt.h> #include <linux/slab.h> #include <linux/sched.h> +#include <linux/sched/rt.h> #include <linux/task_work.h> #include "internals.h"
kernel/mutex.c +1 -0
@@ -19,6 +19,7 @@*/ #include <linux/mutex.h> #include <linux/sched.h> +#include <linux/sched/rt.h> #include <linux/export.h> #include <linux/spinlock.h> #include <linux/interrupt.h>
kernel/posix-cpu-timers.c +22 -6
@@ -155,11 +155,19 @@ static void bump_cpu_timer(struct k_itimer *timer,static inline cputime_t prof_ticks (struct task_struct *p) { -return p->utime + p->stime; +cputime_t utime, stime; + +task_cputime (p, &utime, &stime); + +return utime + stime; }static inline cputime_t virt_ticks (struct task_struct *p) { -return p->utime; +cputime_t utime; + +task_cputime (p, &utime,NULL ); + +return utime; } static int
@@ -471,18 +479,23 @@ static void cleanup_timers(struct list_head *head,*/ void posix_cpu_timers_exit (struct task_struct *tsk) { +cputime_t utime, stime; +add_device_randomness ((const void *) &tsk->se.sum_exec_runtime,sizeof (unsigned long long )); +task_cputime (tsk, &utime, &stime);cleanup_timers (tsk->cpu_timers, - tsk->utime, tsk->stime, tsk->se.sum_exec_runtime); + utime, stime, tsk->se.sum_exec_runtime); }void posix_cpu_timers_exit_group (struct task_struct *tsk) {struct signal_struct *const sig = tsk->signal; +cputime_t utime, stime; +task_cputime (tsk, &utime, &stime);cleanup_timers (tsk->signal->cpu_timers, - tsk->utime + sig->utime, tsk->stime + sig->stime, + utime + sig->utime, stime + sig->stime, tsk->se.sum_exec_runtime + sig->sum_sched_runtime); }
@@ -1226,11 +1239,14 @@ static inline int task_cputime_expired(const struct task_cputime *sample,static inline int fastpath_timer_check (struct task_struct *tsk) {struct signal_struct *sig; +cputime_t utime, stime; + +task_cputime (tsk, &utime, &stime);if (!task_cputime_zero (&tsk->cputime_expires)) {struct task_cputime task_sample = { - .utime = tsk->utime, - .stime = tsk->stime, + .utime = utime, + .stime = stime, .sum_exec_runtime = tsk->se.sum_exec_runtime };
kernel/rtmutex-debug.c +1 -0
@@ -17,6 +17,7 @@* See rt.c in preempt-rt for proper credits and further information */ #include <linux/sched.h> +#include <linux/sched/rt.h> #include <linux/delay.h> #include <linux/export.h> #include <linux/spinlock.h>
kernel/rtmutex-tester.c +1 -0
@@ -10,6 +10,7 @@#include <linux/kthread.h> #include <linux/export.h> #include <linux/sched.h> +#include <linux/sched/rt.h> #include <linux/spinlock.h> #include <linux/timer.h> #include <linux/freezer.h>
kernel/rtmutex.c +1 -0
@@ -13,6 +13,7 @@#include <linux/spinlock.h> #include <linux/export.h> #include <linux/sched.h> +#include <linux/sched/rt.h> #include <linux/timer.h> #include "rtmutex_common.h"
kernel/sched/core.c +21 -1
@@ -4371,7 +4371,7 @@ bool __sched yield_to(struct task_struct *p, bool preempt)struct task_struct *curr = current;struct rq *rq, *p_rq;unsigned long flags; -bool yielded =0 ; +int yielded =0 ;local_irq_save (flags); rq =this_rq ();
@@ -4667,6 +4667,7 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)*/ idle->sched_class = &idle_sched_class;ftrace_graph_init_idle_task (idle, cpu); +vtime_init_idle (idle);#if defined(CONFIG_SMP )sprintf (idle->comm,"%s/%d" ,INIT_TASK_COMM , cpu);#endif
@@ -7508,6 +7509,25 @@ static int sched_rt_global_constraints(void) }#endif /* CONFIG_RT_GROUP_SCHED */ +int sched_rr_handler (struct ctl_table *table,int write, +void __user *buffer,size_t *lenp, +loff_t *ppos) +{ +int ret; +static DEFINE_MUTEX (mutex); + +mutex_lock (&mutex); + ret =proc_dointvec (table, write, buffer, lenp, ppos); +/* make sure that internally we keep jiffies */ +/* also, writing zero resets timeslice to default */ +if (!ret && write) { + sched_rr_timeslice = sched_rr_timeslice <=0 ? +RR_TIMESLICE :msecs_to_jiffies (sched_rr_timeslice); + } +mutex_unlock (&mutex); +return ret; +} +int sched_rt_handler (struct ctl_table *table,int write,void __user *buffer,size_t *lenp,loff_t *ppos)
kernel/sched/cpupri.c +2 -0
@@ -28,6 +28,8 @@*/ #include <linux/gfp.h> +#include <linux/sched.h> +#include <linux/sched/rt.h> #include "cpupri.h" /* Convert between a 140 based task->prio, and our 102 based cpupri */
kernel/sched/cputime.c +271 -43
432 lines not on this page · raw message
kernel/sched/fair.c +9 -18
@@ -1680,9 +1680,7 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) }/* ensure we never gain time by being placed backwards. */ - vruntime =max_vruntime (se->vruntime, vruntime); - - se->vruntime = vruntime; + se->vruntime =max_vruntime (se->vruntime, vruntime); }static void check_enqueue_throttle (struct cfs_rq *cfs_rq);
@@ -3254,25 +3252,18 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)*/ static int select_idle_sibling (struct task_struct *p,int target) { -int cpu =smp_processor_id (); -int prev_cpu =task_cpu (p);struct sched_domain *sd;struct sched_group *sg; -int i; +int i =task_cpu (p); -/* -* If the task is going to be woken-up on this cpu and if it is -* already idle, then it is the right target. -*/ -if (target == cpu &&idle_cpu (cpu)) -return cpu; +if (idle_cpu (target)) +return target;/* -* If the task is going to be woken-up on the cpu where it previously -* ran and if it is currently idle, then it the right target. +* If the prevous cpu is cache affine and idle, don't be stupid. */ -if (target == prev_cpu &&idle_cpu (prev_cpu)) -return prev_cpu; +if (i != target &&cpus_share_cache (i, target) &&idle_cpu (i)) +return i;/* * Otherwise, iterate the domains and find an elegible idle cpu.
@@ -3286,7 +3277,7 @@ static int select_idle_sibling(struct task_struct *p, int target) goto next;for_each_cpu (i,sched_group_cpus (sg)) { -if (!idle_cpu (i)) +if (i == target || !idle_cpu (i)) goto next; }
@@ -6101,7 +6092,7 @@ static unsigned int get_rr_interval_fair(struct rq *rq, struct task_struct *task* idle runqueue: */ if (rq->cfs.load.weight) - rr_interval =NS_TO_JIFFIES (sched_slice (&rq->cfs, se)); + rr_interval =NS_TO_JIFFIES (sched_slice (cfs_rq_of (se), se));return rr_interval; }
kernel/sched/rt.c +17 -9
@@ -7,6 +7,8 @@#include <linux/slab.h> +int sched_rr_timeslice =RR_TIMESLICE ; +static int do_sched_rt_period_timer (struct rt_bandwidth *rt_b,int overrun);struct rt_bandwidth def_rt_bandwidth;
@@ -925,8 +927,8 @@ static void update_curr_rt(struct rq *rq)return ; delta_exec = rq->clock_task - curr->se.exec_start; -if (unlikely ((s64 )delta_exec <0 )) - delta_exec =0 ; +if (unlikely ((s64 )delta_exec <=0 )) +return ;schedstat_set (curr->se.statistics.exec_max,max (curr->se.statistics.exec_max, delta_exec));
@@ -1427,8 +1429,7 @@ static void put_prev_task_rt(struct rq *rq, struct task_struct *p)static int pick_rt_task (struct rq *rq,struct task_struct *p,int cpu) {if (!task_running (rq, p) && - (cpu <0 ||cpumask_test_cpu (cpu,tsk_cpus_allowed (p))) && - (p->nr_cpus_allowed >1 )) +cpumask_test_cpu (cpu,tsk_cpus_allowed (p)))return 1 ;return 0 ; }
@@ -1889,8 +1890,11 @@ static void switched_from_rt(struct rq *rq, struct task_struct *p)* we may need to handle the pulling of RT tasks * now. */ -if (p->on_rq && !rq->rt.rt_nr_running) -pull_rt_task (rq); +if (!p->on_rq || rq->rt.rt_nr_running) +return ; + +if (pull_rt_task (rq)) +resched_task (rq->curr); }void init_sched_rt_class (void )
@@ -1985,7 +1989,11 @@ static void watchdog(struct rq *rq, struct task_struct *p)if (soft !=RLIM_INFINITY ) {unsigned long next; - p->rt.timeout++; +if (p->rt.watchdog_stamp != jiffies) { + p->rt.timeout++; + p->rt.watchdog_stamp = jiffies; + } + next =DIV_ROUND_UP (min (soft, hard),USEC_PER_SEC /HZ );if (p->rt.timeout > next) p->cputime_expires.sched_exp = p->se.sum_exec_runtime;
@@ -2010,7 +2018,7 @@ static void task_tick_rt(struct rq *rq, struct task_struct *p, int queued)if (--p->rt.time_slice)return ; - p->rt.time_slice =RR_TIMESLICE ; + p->rt.time_slice = sched_rr_timeslice;/* * Requeue to the end of queue if we (and all of our ancestors) are the
@@ -2041,7 +2049,7 @@ static unsigned int get_rr_interval_rt(struct rq *rq, struct task_struct *task)* Time slice is 0 for SCHED_FIFO tasks */ if (task->policy ==SCHED_RR ) -return RR_TIMESLICE ; +return sched_rr_timeslice;else return 0 ; }
kernel/sched/sched.h +2 -0
@@ -1,5 +1,7 @@#include <linux/sched.h> +#include <linux/sched/sysctl.h> +#include <linux/sched/rt.h> #include <linux/mutex.h> #include <linux/spinlock.h> #include <linux/stop_machine.h>
kernel/signal.c +8 -4
@@ -1632,6 +1632,7 @@ bool do_notify_parent(struct task_struct *tsk, int sig)unsigned long flags;struct sighand_struct *psig;bool autoreap = false; +cputime_t utime, stime;BUG_ON (sig ==-1 );
@@ -1669,8 +1670,9 @@ bool do_notify_parent(struct task_struct *tsk, int sig) task_uid(tsk));rcu_read_unlock (); - info.si_utime =cputime_to_clock_t (tsk->utime + tsk->signal->utime); - info.si_stime =cputime_to_clock_t (tsk->stime + tsk->signal->stime); +task_cputime (tsk, &utime, &stime); + info.si_utime =cputime_to_clock_t (utime + tsk->signal->utime); + info.si_stime =cputime_to_clock_t (stime + tsk->signal->stime); info.si_status = tsk->exit_code &0x7f ;if (tsk->exit_code &0x80 )
@@ -1734,6 +1736,7 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,unsigned long flags;struct task_struct *parent;struct sighand_struct *sighand; +cputime_t utime, stime;if (for_ptracer) { parent = tsk->parent;
@@ -1752,8 +1755,9 @@ static void do_notify_parent_cldstop(struct task_struct *tsk, info.si_uid =from_kuid_munged (task_cred_xxx (parent, user_ns),task_uid (tsk));rcu_read_unlock (); - info.si_utime =cputime_to_clock_t (tsk->utime); - info.si_stime =cputime_to_clock_t (tsk->stime); +task_cputime (tsk, &utime, &stime); + info.si_utime =cputime_to_clock_t (utime); + info.si_stime =cputime_to_clock_t (stime); info.si_code = why;switch (why) {
kernel/softirq.c +3 -3
@@ -221,7 +221,7 @@ asmlinkage void __do_softirq(void) current->flags &= ~PF_MEMALLOC ; pending =local_softirq_pending (); -vtime_account_irq_enter (current); +account_irq_enter_time (current);__local_bh_disable ((unsigned long )__builtin_return_address (0 ),SOFTIRQ_OFFSET );
@@ -272,7 +272,7 @@ restart:lockdep_softirq_exit (); -vtime_account_irq_exit (current); +account_irq_exit_time (current);__local_bh_enable (SOFTIRQ_OFFSET );tsk_restore_flags (current, old_flags,PF_MEMALLOC ); }
@@ -341,7 +341,7 @@ static inline void invoke_softirq(void)*/ void irq_exit (void ) { -vtime_account_irq_exit (current); +account_irq_exit_time (current);trace_hardirq_exit ();sub_preempt_count (IRQ_EXIT_OFFSET );if (!in_interrupt () &&local_softirq_pending ())
kernel/sysctl.c +8 -0
@@ -61,6 +61,7 @@#include <linux/kmod.h> #include <linux/capability.h> #include <linux/binfmts.h> +#include <linux/sched/sysctl.h> #include <asm/uaccess.h> #include <asm/processor.h>
@@ -403,6 +404,13 @@ static struct ctl_table kern_table[] = { .mode = 0644, .proc_handler = sched_rt_handler, }, + { + .procname = "sched_rr_timeslice_ms", + .data = &sched_rr_timeslice, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = sched_rr_handler, + }, #ifdef CONFIG_SCHED_AUTOGROUP { .procname = "sched_autogroup_enabled",
kernel/time/tick-sched.c +4 -1
@@ -631,8 +631,11 @@ static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now)static void tick_nohz_account_idle_ticks (struct tick_sched *ts) { -#ifndef CONFIG_VIRT_CPU_ACCOUNTING +#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE unsigned long ticks; + +if (vtime_accounting_enabled ()) +return ;/* * We stopped the tick in idle. Update process times would miss the * time we slept as update_process_times does only a 1 tick
kernel/timer.c +1 -0
@@ -39,6 +39,7 @@#include <linux/kallsyms.h> #include <linux/irq_work.h> #include <linux/sched.h> +#include <linux/sched/sysctl.h> #include <linux/slab.h> #include <asm/uaccess.h>
kernel/trace/trace.c +1 -0
@@ -39,6 +39,7 @@#include <linux/poll.h> #include <linux/nmi.h> #include <linux/fs.h> +#include <linux/sched/rt.h> #include "trace.h" #include "trace_output.h"
kernel/trace/trace_sched_wakeup.c +1 -1
@@ -15,8 +15,8 @@#include <linux/kallsyms.h> #include <linux/uaccess.h> #include <linux/ftrace.h> +#include <linux/sched/rt.h> #include <trace/events/sched.h> -#include "trace.h" static struct trace_array *wakeup_trace;
kernel/tsacct.c +34 -10
74 lines not on this page · raw message
kernel/watchdog.c +1 -0
@@ -23,6 +23,7 @@#include <linux/module.h> #include <linux/sysctl.h> #include <linux/smpboot.h> +#include <linux/sched/rt.h> #include <asm/irq_regs.h> #include <linux/kvm_para.h>
mm/mmap.c +1 -0
@@ -32,6 +32,7 @@#include <linux/khugepaged.h> #include <linux/uprobes.h> #include <linux/rbtree_augmented.h> +#include <linux/sched/sysctl.h> #include <asm/uaccess.h> #include <asm/cacheflush.h>
mm/mremap.c +1 -0
@@ -19,6 +19,7 @@#include <linux/security.h> #include <linux/syscalls.h> #include <linux/mmu_notifier.h> +#include <linux/sched/sysctl.h> #include <asm/uaccess.h> #include <asm/cacheflush.h>
mm/nommu.c +1 -0
@@ -29,6 +29,7 @@#include <linux/security.h> #include <linux/syscalls.h> #include <linux/audit.h> +#include <linux/sched/sysctl.h> #include <asm/uaccess.h> #include <asm/tlb.h>
mm/page-writeback.c +1 -0
@@ -35,6 +35,7 @@#include <linux/buffer_head.h> /* __set_page_dirty_buffers */ #include <linux/pagevec.h> #include <linux/timer.h> +#include <linux/sched/rt.h> #include <trace/events/writeback.h> /*
mm/page_alloc.c +1 -0
@@ -58,6 +58,7 @@#include <linux/prefetch.h> #include <linux/migrate.h> #include <linux/page-debug-flags.h> +#include <linux/sched/rt.h> #include <asm/tlbflush.h> #include <asm/div64.h>