scheduler changes for v3.14
Subsystems (21)
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: eaad45132c564ce377e6dce05e78e08e456d5315 sched: Fix __sched_setscheduler() nice test
The main changes:
- Add the initial implementation of SCHED_DEADLINE support: a real-time scheduling policy where tasks that meet their deadlines and periodically execute their instances in less than their runtime quota see real-time scheduling and won't miss any of their deadlines. Tasks that go over their quota get delayed. (Available to privileged users for now.)
- Clean up and fix preempt_enable_no_resched() abuse all around the tree.
- Do sched_clock() performance optimizations on x86 and elsewhere.
- Fix and improve auto-NUMA balancing.
- Fix and clean up the idle loop.
- Apply various cleanups and fixes.
Thanks,
Ingo
------------------>
Daniel Lezcano (8):
sched: Reduce trigger_load_balance() parameters
sched: Reduce nohz_kick_needed() parameters
sched: Pass 'struct rq' to on_null_domain()
sched: Remove unused parameter from find_new_ilb()
sched: Remove unused parameter from nohz_balancer_kick()
sched: Pass 'struct rq' to rebalance_domains()
sched: Pass 'struct rq' to nohz_idle_balance()
sched: Factor out the on_null_domain() checks in trigger_load_balance()
Dario Faggioli (7):
sched: Add sched_class->task_dead() method
sched: Add new scheduler syscalls to support an extended scheduling parameters ABI sched/deadline: Add SCHED_DEADLINE structures & implementation sched/deadline: Add SCHED_DEADLINE avg_update accounting sched/deadline: Add latency tracing for SCHED_DEADLINE tasks sched/deadline: Add SCHED_DEADLINE inheritance logic
sched/deadline: Add bandwidth management for SCHED_DEADLINE tasks
Fengguang Wu (1):
sched/deadline: Fix sparse static warnings
H. Peter Anvin (2):
x86, idle: Use static_cpu_has() for CLFLUSH workaround, add barriers x86, idle: Add memory barriers around clflush in mwait_play_dead()
Harald Gustafsson (1):
sched/deadline: Add period support for SCHED_DEADLINE tasks
Juri Lelli (4):
sched/deadline: Add SCHED_DEADLINE SMP-related data structures & logic sched/deadline: speed up SCHED_DEADLINE pushes with a push-heap sched/deadline: No need to check p if dl_se is valid sched/core: Fix htmldocs warnings
Kamalesh Babulal (1):
sched/fair: Clean up update_sg_lb_stats() a bit
Oleg Nesterov (3):
tasks/fork: Remove unnecessary child->exit_state tasks/exit: Remove unused task_is_dead() method
sched: Check TASK_DEAD rather than EXIT_DEAD in schedule_debug()
Peter Zijlstra (26):
x86, acpi, idle: Restructure the mwait idle routines
rtmutex: Turn the plist into an rb-tree
sched/deadline: Fix up the smp-affinity mask tests
sched/deadline: Remove the sysctl_sched_dl knobs
sched/deadline: Fix hotplug admission control
locking: Optimize lock_bh functions
sched/preempt: Take away preempt_enable_no_resched() from modules sched/clock, x86: Use mul_u64_u32_shr() for native_sched_clock() sched/clock, x86: Move some cyc2ns() code around
sched/clock, x86: Rewrite cyc2ns() to avoid the need to disable IRQs sched/clock: Remove local_irq_disable() from the clocks
sched/clock, x86: Use a static_key for sched_clock_stable sched/clock: Fix up clear_sched_clock_stable()
sched/clock, x86: Avoid a runtime condition in native_sched_clock() sched/preempt, locking: Rework local_bh_{dis,en}able()
sched/preempt: Fix up missed PREEMPT_NEED_RESCHED folding
sched, net: Clean up preempt_enable_no_resched() abuse
sched, net: Fixup busy_loop_us_clock()
sched, thermal: Clean up preempt_enable_no_resched() abuse
m68k: Fix build warning in mac_via.h
sched/deadline: Remove unused variables
sched: Preserve the nice level over sched_setscheduler() and sched_setparam() calls
sched: Fix up scheduler syscall LTP fails
sched: Fix up attr::sched_priority warning
sched: Move SCHED_RESET_ON_FORK into attr::sched_flags
sched: Fix __sched_setscheduler() nice test
Shigeru Yoshida (1):
sched: Fix a trivial syntax misuse
Vincent Guittot (1):
sched/fair: Move load idx selection in find_idlest_group
Wanpeng Li (5):
sched/numa: Drop idx field of task_numa_env struct
sched/numa: Drop sysctl_numa_balancing_settle_count sysctl sched/numa: Use wrapper function task_node to get node which task is on sched/numa: Use wrapper function task_faults_idx to calculate index in group_faults sched/numa: Fix period_slot recalculation
Documentation/sysctl/kernel.txt | 5 - arch/arm/include/asm/unistd.h | 2 +- arch/arm/include/uapi/asm/unistd.h | 2 + arch/arm/kernel/calls.S | 2 + arch/m68k/include/asm/mac_via.h | 2 + arch/x86/include/asm/mwait.h | 43 + arch/x86/include/asm/processor.h | 23 - arch/x86/include/asm/timer.h | 77 +- arch/x86/kernel/acpi/cstate.c | 23 - arch/x86/kernel/cpu/amd.c | 2 +- arch/x86/kernel/cpu/intel.c | 2 +- arch/x86/kernel/cpu/perf_event.c | 16 +- arch/x86/kernel/smpboot.c | 2 + arch/x86/kernel/tsc.c | 318 +++++-- arch/x86/platform/uv/tlb_uv.c | 66 +- arch/x86/syscalls/syscall_32.tbl | 2 + arch/x86/syscalls/syscall_64.tbl | 2 + drivers/acpi/acpi_pad.c | 5 +- drivers/acpi/processor_idle.c | 15 - drivers/idle/intel_idle.c | 11 +- drivers/thermal/intel_powerclamp.c | 6 +- include/linux/bottom_half.h | 32 +- include/linux/hardirq.h | 1 + include/linux/init_task.h | 10 + include/linux/preempt.h | 37 +- include/linux/preempt_mask.h | 16 +- include/linux/rtmutex.h | 18 +- include/linux/rwlock_api_smp.h | 12 +- include/linux/sched.h | 141 +++- include/linux/sched/deadline.h | 24 + include/linux/sched/rt.h | 5 + include/linux/sched/sysctl.h | 1 - include/linux/spinlock_api_smp.h | 12 +- include/linux/spinlock_api_up.h | 16 +- include/linux/syscalls.h | 6 + include/linux/uaccess.h | 5 +- include/net/busy_poll.h | 19 +- include/uapi/linux/sched.h | 6 + kernel/cpu/idle.c | 17 +- kernel/fork.c | 12 +- kernel/futex.c | 2 + kernel/hrtimer.c | 3 +- kernel/locking/rtmutex-debug.c | 8 +- kernel/locking/rtmutex.c | 166 +++- kernel/locking/rtmutex_common.h | 23 +- kernel/sched/Makefile | 5 +- kernel/sched/clock.c | 78 +- kernel/sched/core.c | 822 +++++++++++++++--- kernel/sched/cpudeadline.c | 216 +++++ kernel/sched/cpudeadline.h | 33 + kernel/sched/deadline.c | 1640 ++++++++++++++++++++++++++++++++++++ kernel/sched/debug.c | 4 +- kernel/sched/fair.c | 83 +- kernel/sched/rt.c | 2 +- kernel/sched/sched.h | 146 +++- kernel/sched/stop_task.c | 2 +- kernel/softirq.c | 39 +- kernel/sysctl.c | 7 - kernel/time/tick-sched.c | 2 +- kernel/trace/ring_buffer.c | 2 +- kernel/trace/trace_sched_wakeup.c | 65 +- kernel/trace/trace_selftest.c | 33 +- net/ipv4/tcp.c | 4 +- 63 files changed, 3775 insertions(+), 626 deletions(-) create mode 100644 include/linux/sched/deadline.h create mode 100644 kernel/sched/cpudeadline.c create mode 100644 kernel/sched/cpudeadline.h create mode 100644 kernel/sched/deadline.c
Documentation/sysctl/kernel.txt +0 -5
@@ -428,11 +428,6 @@ rate for each task. numa_balancing_scan_size_mb is how many megabytes worth of pages are scanned for a given scan. -numa_balancing_settle_count is how many scan periods must complete before -the schedule balancer stops pushing the task towards a preferred node. This -gives the scheduler a chance to place the task on an alternative node if the -preferred node is overloaded. - numa_balancing_migrate_deferred is how many page migrations get skipped unconditionally, after a page migration is skipped because a page is shared with other tasks. This reduces page migration overhead, and determines
arch/arm/include/asm/unistd.h +1 -1
@@ -15,7 +15,7 @@#include <uapi/asm/unistd.h> -#define __NR_syscalls (380) +#define __NR_syscalls (384)#define __ARM_NR_cmpxchg (__ARM_NR_BASE+0x00fff0)#define __ARCH_WANT_STAT64
arch/arm/include/uapi/asm/unistd.h +2 -0
@@ -406,6 +406,8 @@#define __NR_process_vm_writev (__NR_SYSCALL_BASE+377)#define __NR_kcmp (__NR_SYSCALL_BASE+378)#define __NR_finit_module (__NR_SYSCALL_BASE+379) +#define __NR_sched_setattr (__NR_SYSCALL_BASE+380) +#define __NR_sched_getattr (__NR_SYSCALL_BASE+381)/* * This may need to be greater than __NR_last_syscall+1 in order to
arch/arm/kernel/calls.S +2 -0
@@ -389,6 +389,8 @@ CALL(sys_process_vm_writev) CALL(sys_kcmp) CALL(sys_finit_module) +/* 380 */ CALL(sys_sched_setattr) + CALL(sys_sched_getattr) #ifndef syscalls_counted .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls #define syscalls_counted
arch/m68k/include/asm/mac_via.h +2 -0
@@ -254,6 +254,8 @@extern volatile __u8 *via1,*via2;extern int rbv_present,via_alt_mapping; +struct irq_desc ; +extern void via_register_interrupts (void );extern void via_irq_enable (int );extern void via_irq_disable (int );
arch/x86/include/asm/mwait.h +43 -0
53 lines not on this page · raw message
arch/x86/include/asm/processor.h +0 -23
@@ -700,29 +700,6 @@ static inline void sync_core(void)#endif } -static inline void __monitor (const void *eax,unsigned long ecx, -unsigned long edx) -{ -/* "monitor %eax, %ecx, %edx;" */ - asmvolatile (".byte 0x0f, 0x01, 0xc8;" - ::"a" (eax),"c" (ecx),"d" (edx)); -} - -static inline void __mwait (unsigned long eax,unsigned long ecx) -{ -/* "mwait %eax, %ecx;" */ - asmvolatile (".byte 0x0f, 0x01, 0xc9;" - ::"a" (eax),"c" (ecx)); -} - -static inline void __sti_mwait (unsigned long eax,unsigned long ecx) -{ -trace_hardirqs_on (); -/* "mwait %eax, %ecx;" */ - asmvolatile ("sti; .byte 0x0f, 0x01, 0xc9;" - ::"a" (eax),"c" (ecx)); -} -extern void select_idle_routine (const struct cpuinfo_x86 *c);extern void init_amd_e400_c1e_mask (void );
arch/x86/include/asm/timer.h +18 -59
92 lines not on this page · raw message
arch/x86/kernel/acpi/cstate.c +0 -23
@@ -150,29 +150,6 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu, }EXPORT_SYMBOL_GPL (acpi_processor_ffh_cstate_probe); -/* -* This uses new MONITOR/MWAIT instructions on P4 processors with PNI, -* which can obviate IPI to trigger checking of need_resched. -* We execute MONITOR against need_resched and enter optimized wait state -* through MWAIT. Whenever someone changes need_resched, we would be woken -* up from MWAIT (without an IPI). -* -* New with Core Duo processors, MWAIT can take some hints based on CPU -* capability. -*/ -void mwait_idle_with_hints (unsigned long ax,unsigned long cx) -{ -if (!need_resched ()) { -if (this_cpu_has (X86_FEATURE_CLFLUSH_MONITOR )) -clflush ((void *)¤t_thread_info ()->flags); - -__monitor ((void *)¤t_thread_info ()->flags,0 ,0 ); -smp_mb (); -if (!need_resched ()) -__mwait (ax, cx); - } -} -void acpi_processor_ffh_cstate_enter (struct acpi_processor_cx *cx) {unsigned int cpu =smp_processor_id ();
arch/x86/kernel/cpu/amd.c +1 -1
@@ -487,7 +487,7 @@ static void early_init_amd(struct cpuinfo_x86 *c)set_cpu_cap (c,X86_FEATURE_CONSTANT_TSC );set_cpu_cap (c,X86_FEATURE_NONSTOP_TSC );if (!check_tsc_unstable ()) - sched_clock_stable =1 ; +set_sched_clock_stable (); }#ifdef CONFIG_X86_64
arch/x86/kernel/cpu/intel.c +1 -1
@@ -93,7 +93,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)set_cpu_cap (c,X86_FEATURE_CONSTANT_TSC );set_cpu_cap (c,X86_FEATURE_NONSTOP_TSC );if (!check_tsc_unstable ()) - sched_clock_stable =1 ; +set_sched_clock_stable (); }/* Penwell and Cloverview have the TSC which doesn't sleep on S3 */
arch/x86/kernel/cpu/perf_event.c +11 -5
@@ -1883,21 +1883,27 @@ static struct pmu pmu = {void arch_perf_update_userpage (struct perf_event_mmap_page *userpg,u64 now) { +struct cyc2ns_data *data; + userpg->cap_user_time =0 ; userpg->cap_user_time_zero =0 ; userpg->cap_user_rdpmc = x86_pmu.attr_rdpmc; userpg->pmc_width = x86_pmu.cntval_bits; -if (!sched_clock_stable) +if (!sched_clock_stable ())return ; + data =cyc2ns_read_begin (); + userpg->cap_user_time =1 ; - userpg->time_mult =this_cpu_read (cyc2ns); - userpg->time_shift =CYC2NS_SCALE_FACTOR ; - userpg->time_offset =this_cpu_read (cyc2ns_offset) - now; + userpg->time_mult = data->cyc2ns_mul; + userpg->time_shift = data->cyc2ns_shift; + userpg->time_offset = data->cyc2ns_offset - now; userpg->cap_user_time_zero =1 ; - userpg->time_zero =this_cpu_read (cyc2ns_offset); + userpg->time_zero = data->cyc2ns_offset; + +cyc2ns_read_end (data); }/*
arch/x86/kernel/smpboot.c +2 -0
@@ -1417,7 +1417,9 @@ static inline void mwait_play_dead(void)* The WBINVD is insufficient due to the spurious-wakeup * case where we return around the loop. */ +mb ();clflush (mwait_ptr); +mb ();__monitor (mwait_ptr,0 ,0 );mb ();__mwait (eax,0 );
arch/x86/kernel/tsc.c +257 -61
390 lines not on this page · raw message
arch/x86/platform/uv/tlb_uv.c +40 -26
87 lines not on this page · raw message
arch/x86/syscalls/syscall_32.tbl +2 -0
@@ -357,3 +357,5 @@ 348 i386 process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev 349 i386 kcmp sys_kcmp 350 i386 finit_module sys_finit_module +351 i386 sched_setattr sys_sched_setattr +352 i386 sched_getattr sys_sched_getattr
arch/x86/syscalls/syscall_64.tbl +2 -0
@@ -320,6 +320,8 @@ 311 64 process_vm_writev sys_process_vm_writev 312 common kcmp sys_kcmp 313 common finit_module sys_finit_module +314 common sched_setattr sys_sched_setattr +315 common sched_getattr sys_sched_getattr # # x32-specific system call numbers start at 512 to avoid cache impact
drivers/acpi/acpi_pad.c +1 -4
@@ -193,10 +193,7 @@ static int power_saving_thread(void *data) CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);stop_critical_timings (); -__monitor ((void *)¤t_thread_info ()->flags,0 ,0 ); -smp_mb (); -if (!need_resched ()) -__mwait (power_saving_mwait_eax,1 ); +mwait_idle_with_hints (power_saving_mwait_eax,1 );start_critical_timings ();if (lapic_marked_unstable)
drivers/acpi/processor_idle.c +0 -15
@@ -727,11 +727,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,if (unlikely (!pr))return -EINVAL ; -if (cx->entry_method ==ACPI_CSTATE_FFH ) { -if (current_set_polling_and_test ()) -return -EINVAL ; - } -lapic_timer_state_broadcast (pr, cx,1 );acpi_idle_do_entry (cx);
@@ -785,11 +780,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,if (unlikely (!pr))return -EINVAL ; -if (cx->entry_method ==ACPI_CSTATE_FFH ) { -if (current_set_polling_and_test ()) -return -EINVAL ; - } -/* * Must be done before busmaster disable as we might need to * access HPET !
@@ -841,11 +831,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, } } -if (cx->entry_method ==ACPI_CSTATE_FFH ) { -if (current_set_polling_and_test ()) -return -EINVAL ; - } -acpi_unlazy_tlb (smp_processor_id ());/* Tell the scheduler that we are going deep-idle: */
drivers/idle/intel_idle.c +1 -10
@@ -377,16 +377,7 @@ static int intel_idle(struct cpuidle_device *dev,if (!(lapic_timer_reliable_states & (1 << (cstate))))clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_ENTER , &cpu); -if (!current_set_polling_and_test ()) { - -if (this_cpu_has (X86_FEATURE_CLFLUSH_MONITOR )) -clflush ((void *)¤t_thread_info ()->flags); - -__monitor ((void *)¤t_thread_info ()->flags,0 ,0 ); -smp_mb (); -if (!need_resched ()) -__mwait (eax, ecx); - } +mwait_idle_with_hints (eax, ecx);if (!(lapic_timer_reliable_states & (1 << (cstate))))clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_EXIT , &cpu);
drivers/thermal/intel_powerclamp.c +2 -4
@@ -438,14 +438,12 @@ static int clamp_thread(void *arg)*/ local_touch_nmi ();stop_critical_timings (); -__monitor ((void *)¤t_thread_info ()->flags,0 ,0 ); -cpu_relax ();/* allow HT sibling to run */ -__mwait (eax, ecx); +mwait_idle_with_hints (eax, ecx);start_critical_timings ();atomic_inc (&idle_wakeup_counter); }tick_nohz_idle_exit (); -preempt_enable_no_resched (); +preempt_enable (); }del_timer_sync (&wakeup_timer);clear_bit (cpunr, cpu_clamping_mask);
include/linux/bottom_half.h +29 -3
@@ -1,9 +1,35 @@#ifndef _LINUX_BH_H#define _LINUX_BH_H -extern void local_bh_disable (void ); +#include <linux/preempt.h> +#include <linux/preempt_mask.h> + +#ifdef CONFIG_TRACE_IRQFLAGS +extern void __local_bh_disable_ip (unsigned long ip,unsigned int cnt); +#else +static __always_inline void __local_bh_disable_ip(unsigned long ip, unsigned int cnt) +{ +preempt_count_add (cnt); +barrier (); +} +#endif + +static inline void local_bh_disable (void ) +{ +__local_bh_disable_ip (_THIS_IP_,SOFTIRQ_DISABLE_OFFSET ); +} +extern void _local_bh_enable (void ); -extern void local_bh_enable (void ); -extern void local_bh_enable_ip (unsigned long ip); +extern void __local_bh_enable_ip (unsigned long ip,unsigned int cnt); + +static inline void local_bh_enable_ip (unsigned long ip) +{ +__local_bh_enable_ip (ip,SOFTIRQ_DISABLE_OFFSET ); +} + +static inline void local_bh_enable (void ) +{ +__local_bh_enable_ip (_THIS_IP_,SOFTIRQ_DISABLE_OFFSET ); +}#endif /* _LINUX_BH_H */
include/linux/hardirq.h +1 -0
@@ -5,6 +5,7 @@#include <linux/lockdep.h> #include <linux/ftrace_irq.h> #include <linux/vtime.h> +#include <asm/hardirq.h> extern void synchronize_irq (unsigned int irq);
include/linux/init_task.h +10 -0
@@ -11,6 +11,7 @@#include <linux/user_namespace.h> #include <linux/securebits.h> #include <linux/seqlock.h> +#include <linux/rbtree.h> #include <net/net_namespace.h> #include <linux/sched/rt.h>
@@ -154,6 +155,14 @@ extern struct task_group root_task_group;#define INIT_TASK_COMM "swapper" +#ifdef CONFIG_RT_MUTEXES +# define INIT_RT_MUTEXES (tsk) \ + .pi_waiters = RB_ROOT, \ + .pi_waiters_leftmost = NULL, +#else +# define INIT_RT_MUTEXES (tsk) +#endif +/* * INIT_TASK is used to set up the first task table, touch at * your own risk!. Base=0, limit=0x1fffff (=2MB)
@@ -221,6 +230,7 @@ extern struct task_group root_task_group; INIT_TRACE_RECURSION \ INIT_TASK_RCU_PREEMPT(tsk) \ INIT_CPUSET_SEQ(tsk) \ + INIT_RT_MUTEXES(tsk) \ INIT_VTIME(tsk) \ }
include/linux/preempt.h +35 -2
@@ -64,7 +64,11 @@ do { \ } while (0)#else -#define preempt_enable () preempt_enable_no_resched() +#define preempt_enable () \ +do { \ + barrier(); \ + preempt_count_dec(); \ +} while (0)#define preempt_check_resched () do { } while (0)#endif
@@ -93,7 +97,11 @@ do { \__preempt_schedule_context (); \ } while (0) #else -#define preempt_enable_notrace () preempt_enable_no_resched_notrace() +#define preempt_enable_notrace () \ +do { \ + barrier(); \ + __preempt_count_dec(); \ +} while (0)#endif #else /* !CONFIG_PREEMPT_COUNT */
@@ -116,6 +124,31 @@ do { \#endif /* CONFIG_PREEMPT_COUNT */ +#ifdef MODULE +/* +* Modules have no business playing preemption tricks. +*/ +#undef sched_preempt_enable_no_resched +#undef preempt_enable_no_resched +#undef preempt_enable_no_resched_notrace +#undef preempt_check_resched +#endif + +#ifdef CONFIG_PREEMPT +#define preempt_set_need_resched () \ +do { \ + set_preempt_need_resched(); \ +} while (0) +#define preempt_fold_need_resched () \ +do { \ + if (tif_need_resched()) \ + set_preempt_need_resched(); \ +} while (0) +#else +#define preempt_set_need_resched () do { } while (0) +#define preempt_fold_need_resched () do { } while (0) +#endif +#ifdef CONFIG_PREEMPT_NOTIFIERS struct preempt_notifier ;
include/linux/preempt_mask.h +15 -1
@@ -2,7 +2,6 @@#define LINUX_PREEMPT_MASK_H #include <linux/preempt.h> -#include <asm/hardirq.h> /* * We put the hardirq and softirq counter into the preemption
@@ -79,6 +78,21 @@#endif /* +* The preempt_count offset needed for things like: +* +* spin_lock_bh() +* +* Which need to disable both preemption (CONFIG_PREEMPT_COUNT) and +* softirqs, such that unlock sequences of: +* +* spin_unlock(); +* local_bh_enable(); +* +* Work as expected. +*/ +#define SOFTIRQ_LOCK_OFFSET (SOFTIRQ_DISABLE_OFFSET + PREEMPT_CHECK_OFFSET) + +/* * Are we running in atomic context? WARNING: this macro cannot * always detect atomic context; in particular, it cannot know about * held spinlocks in non-preemptible kernels. Thus it should not be
include/linux/rtmutex.h +6 -12
@@ -13,7 +13,7 @@#define __LINUX_RT_MUTEX_H#include <linux/linkage.h> -#include <linux/plist.h> +#include <linux/rbtree.h> #include <linux/spinlock_types.h> extern int max_lock_depth;/* for sysctl */
@@ -22,12 +22,14 @@ extern int max_lock_depth; /* for sysctl */* The rt_mutex structure * * @wait_lock: spinlock to protect the structure -* @wait_list: pilist head to enqueue waiters in priority order +* @waiters: rbtree root to enqueue waiters in priority order +* @waiters_leftmost: top waiter * @owner: the mutex owner */ struct rt_mutex {raw_spinlock_t wait_lock; -struct plist_head wait_list; +struct rb_root waiters; +struct rb_node *waiters_leftmost;struct task_struct *owner;#ifdef CONFIG_DEBUG_RT_MUTEXES int save_state;
@@ -66,7 +68,7 @@ struct hrtimer_sleeper;#define __RT_MUTEX_INITIALIZER (mutexname) \ { .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \ - , .wait_list = PLIST_HEAD_INIT(mutexname.wait_list) \ + , .waiters = RB_ROOT \ , .owner = NULL \ __DEBUG_RT_MUTEX_INITIALIZER(mutexname)}
@@ -98,12 +100,4 @@ extern int rt_mutex_trylock(struct rt_mutex *lock);extern void rt_mutex_unlock (struct rt_mutex *lock); -#ifdef CONFIG_RT_MUTEXES -# define INIT_RT_MUTEXES (tsk) \ - .pi_waiters = PLIST_HEAD_INIT(tsk.pi_waiters), \ - INIT_RT_MUTEX_DEBUG(tsk) -#else -# define INIT_RT_MUTEXES (tsk) -#endif -#endif
include/linux/rwlock_api_smp.h +4 -8
@@ -172,8 +172,7 @@ static inline void __raw_read_lock_irq(rwlock_t *lock)static inline void __raw_read_lock_bh (rwlock_t *lock) { -local_bh_disable (); -preempt_disable (); +__local_bh_disable_ip (_RET_IP_,SOFTIRQ_LOCK_OFFSET );rwlock_acquire_read (&lock->dep_map,0 ,0 , _RET_IP_);LOCK_CONTENDED (lock, do_raw_read_trylock, do_raw_read_lock); }
@@ -200,8 +199,7 @@ static inline void __raw_write_lock_irq(rwlock_t *lock)static inline void __raw_write_lock_bh (rwlock_t *lock) { -local_bh_disable (); -preempt_disable (); +__local_bh_disable_ip (_RET_IP_,SOFTIRQ_LOCK_OFFSET );rwlock_acquire (&lock->dep_map,0 ,0 , _RET_IP_);LOCK_CONTENDED (lock, do_raw_write_trylock, do_raw_write_lock); }
@@ -250,8 +248,7 @@ static inline void __raw_read_unlock_bh(rwlock_t *lock) {rwlock_release (&lock->dep_map,1 , _RET_IP_);do_raw_read_unlock (lock); -preempt_enable_no_resched (); -local_bh_enable_ip ((unsigned long )__builtin_return_address (0 )); +__local_bh_enable_ip (_RET_IP_,SOFTIRQ_LOCK_OFFSET ); } static inline void __raw_write_unlock_irqrestore(rwlock_t *lock,
@@ -275,8 +272,7 @@ static inline void __raw_write_unlock_bh(rwlock_t *lock) {rwlock_release (&lock->dep_map,1 , _RET_IP_);do_raw_write_unlock (lock); -preempt_enable_no_resched (); -local_bh_enable_ip ((unsigned long )__builtin_return_address (0 )); +__local_bh_enable_ip (_RET_IP_,SOFTIRQ_LOCK_OFFSET ); }#endif /* __LINUX_RWLOCK_API_SMP_H */
include/linux/sched.h +137 -4
209 lines not on this page · raw message
include/linux/sched/deadline.h new file +24 -0
@@ -0,0 +1,24 @@ +#ifndef _SCHED_DEADLINE_H +#define _SCHED_DEADLINE_H + +/* +* SCHED_DEADLINE tasks has negative priorities, reflecting +* the fact that any of them has higher prio than RT and +* NORMAL/BATCH tasks. +*/ + +#define MAX_DL_PRIO 0 + +static inline int dl_prio (int prio) +{ +if (unlikely (prio <MAX_DL_PRIO )) +return 1 ; +return 0 ; +} + +static inline int dl_task (struct task_struct *p) +{ +return dl_prio (p->prio); +} + +#endif /* _SCHED_DEADLINE_H */
include/linux/sched/rt.h +5 -0
@@ -35,6 +35,7 @@ static inline int rt_task(struct task_struct *p)#ifdef CONFIG_RT_MUTEXES extern int rt_mutex_getprio (struct task_struct *p);extern void rt_mutex_setprio (struct task_struct *p,int prio); +extern struct task_struct *rt_mutex_get_top_task (struct task_struct *task);extern void rt_mutex_adjust_pi (struct task_struct *p);static inline bool tsk_is_pi_blocked (struct task_struct *tsk) {
@@ -45,6 +46,10 @@ static inline int rt_mutex_getprio(struct task_struct *p) {return p->normal_prio; } +static inline struct task_struct *rt_mutex_get_top_task (struct task_struct *task) +{ +return NULL ; +}# define rt_mutex_adjust_pi (p) do { } while (0)static inline bool tsk_is_pi_blocked (struct task_struct *tsk) {
include/linux/sched/sysctl.h +0 -1
@@ -48,7 +48,6 @@ extern unsigned int sysctl_numa_balancing_scan_delay;extern unsigned int sysctl_numa_balancing_scan_period_min;extern unsigned int sysctl_numa_balancing_scan_period_max;extern unsigned int sysctl_numa_balancing_scan_size; -extern unsigned int sysctl_numa_balancing_settle_count;#ifdef CONFIG_SCHED_DEBUG extern unsigned int sysctl_sched_migration_cost;
include/linux/spinlock_api_smp.h +4 -8
@@ -131,8 +131,7 @@ static inline void __raw_spin_lock_irq(raw_spinlock_t *lock)static inline void __raw_spin_lock_bh (raw_spinlock_t *lock) { -local_bh_disable (); -preempt_disable (); +__local_bh_disable_ip (_RET_IP_,SOFTIRQ_LOCK_OFFSET );spin_acquire (&lock->dep_map,0 ,0 , _RET_IP_);LOCK_CONTENDED (lock, do_raw_spin_trylock, do_raw_spin_lock); }
@@ -174,20 +173,17 @@ static inline void __raw_spin_unlock_bh(raw_spinlock_t *lock) {spin_release (&lock->dep_map,1 , _RET_IP_);do_raw_spin_unlock (lock); -preempt_enable_no_resched (); -local_bh_enable_ip ((unsigned long )__builtin_return_address (0 )); +__local_bh_enable_ip (_RET_IP_,SOFTIRQ_LOCK_OFFSET ); }static inline int __raw_spin_trylock_bh (raw_spinlock_t *lock) { -local_bh_disable (); -preempt_disable (); +__local_bh_disable_ip (_RET_IP_,SOFTIRQ_LOCK_OFFSET );if (do_raw_spin_trylock (lock)) {spin_acquire (&lock->dep_map,0 ,1 , _RET_IP_);return 1 ; } -preempt_enable_no_resched (); -local_bh_enable_ip ((unsigned long )__builtin_return_address (0 )); +__local_bh_enable_ip (_RET_IP_,SOFTIRQ_LOCK_OFFSET );return 0 ; }
include/linux/spinlock_api_up.h +11 -5
@@ -24,11 +24,14 @@* flags straight, to suppress compiler warnings of unused lock * variables, and to add the proper checker annotations: */ +#define ___LOCK (lock) \ + do { __acquire(lock); (void)(lock); } while (0) +#define __LOCK (lock) \ - do { preempt_disable(); __acquire(lock); (void)(lock); } while (0) + do { preempt_disable(); ___LOCK(lock); } while (0)#define __LOCK_BH (lock) \ - do { local_bh_disable(); __LOCK(lock); } while (0) + do { __local_bh_disable_ip(_THIS_IP_, SOFTIRQ_LOCK_OFFSET); ___LOCK(lock); } while (0)#define __LOCK_IRQ (lock) \ do { local_irq_disable(); __LOCK(lock); } while (0)
@@ -36,12 +39,15 @@#define __LOCK_IRQSAVE (lock, flags) \ do { local_irq_save(flags); __LOCK(lock); } while (0) +#define ___UNLOCK (lock) \ + do { __release(lock); (void)(lock); } while (0) +#define __UNLOCK (lock) \ - do { preempt_enable(); __release(lock); (void)(lock); } while (0) + do { preempt_enable(); ___UNLOCK(lock); } while (0)#define __UNLOCK_BH (lock) \ - do { preempt_enable_no_resched(); local_bh_enable(); \ - __release(lock); (void)(lock); } while (0) + do { __local_bh_enable_ip(_THIS_IP_, SOFTIRQ_LOCK_OFFSET); \ + ___UNLOCK(lock); } while (0)#define __UNLOCK_IRQ (lock) \ do { local_irq_enable(); __UNLOCK(lock); } while (0)
include/linux/syscalls.h +6 -0
@@ -38,6 +38,7 @@ struct rlimit;struct rlimit64 ;struct rusage ;struct sched_param ; +struct sched_attr ;struct sel_arg_struct ;struct semaphore ;struct sembuf ;
@@ -279,9 +280,14 @@ asmlinkage long sys_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param);asmlinkage long sys_sched_setparam (pid_t pid,struct sched_param __user *param); +asmlinkage long sys_sched_setattr (pid_t pid, +struct sched_attr __user *attr);asmlinkage long sys_sched_getscheduler (pid_t pid);asmlinkage long sys_sched_getparam (pid_t pid,struct sched_param __user *param); +asmlinkage long sys_sched_getattr (pid_t pid, +struct sched_attr __user *attr, +unsigned int size);asmlinkage long sys_sched_setaffinity (pid_t pid,unsigned int len,unsigned long __user *user_mask_ptr); asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len,
include/linux/uaccess.h +4 -1
@@ -25,13 +25,16 @@ static inline void pagefault_disable(void)static inline void pagefault_enable (void ) { +#ifndef CONFIG_PREEMPT /* * make sure to issue those last loads/stores before enabling * the pagefault handler again. */ barrier ();preempt_count_dec (); -preempt_check_resched (); +#else +preempt_enable (); +#endif }#ifndef ARCH_HAS_NOCACHE_UACCESS
include/net/busy_poll.h +1 -18
@@ -42,27 +42,10 @@ static inline bool net_busy_loop_on(void)return sysctl_net_busy_poll; } -/* a wrapper to make debug_smp_processor_id() happy -* we can use sched_clock() because we don't care much about precision -* we only care that the average is bounded -*/ -#ifdef CONFIG_DEBUG_PREEMPT -static inline u64 busy_loop_us_clock (void ) -{ -u64 rc; - -preempt_disable_notrace (); - rc =sched_clock (); -preempt_enable_no_resched_notrace (); - -return rc >>10 ; -} -#else /* CONFIG_DEBUG_PREEMPT */ static inline u64 busy_loop_us_clock (void ) { -return sched_clock () >>10 ; +return local_clock () >>10 ; } -#endif /* CONFIG_DEBUG_PREEMPT */ static inline unsigned long sk_busy_loop_end_time (struct sock *sk) {
include/uapi/linux/sched.h +6 -0
@@ -39,8 +39,14 @@#define SCHED_BATCH 3/* SCHED_ISO: reserved but not implemented yet */ #define SCHED_IDLE 5 +#define SCHED_DEADLINE 6 +/* Can be ORed in to make sure the process is reverted back to SCHED_NORMAL on fork */ #define SCHED_RESET_ON_FORK 0x40000000 +/* +* For the sched_{set,get}attr() calls +*/ +#define SCHED_FLAG_RESET_ON_FORK 0x01#endif /* _UAPI_LINUX_SCHED_H */
kernel/cpu/idle.c +10 -7
@@ -105,14 +105,17 @@ static void cpu_idle_loop(void)__current_set_polling (); }arch_cpu_idle_exit (); -/* -* We need to test and propagate the TIF_NEED_RESCHED -* bit here because we might not have send the -* reschedule IPI to idle tasks. -*/ -if (tif_need_resched ()) -set_preempt_need_resched (); } + +/* +* Since we fell out of the loop above, we know +* TIF_NEED_RESCHED must be set, propagate it into +* PREEMPT_NEED_RESCHED. +* +* This is required because for polling idle loops we will +* not have had an IPI to fold the state for us. +*/ +preempt_set_need_resched ();tick_nohz_idle_exit ();schedule_preempt_disabled (); }
kernel/fork.c +7 -5
@@ -1087,8 +1087,10 @@ static void rt_mutex_init_task(struct task_struct *p) {raw_spin_lock_init (&p->pi_lock);#ifdef CONFIG_RT_MUTEXES -plist_head_init (&p->pi_waiters); + p->pi_waiters =RB_ROOT ; + p->pi_waiters_leftmost =NULL ; p->pi_blocked_on =NULL ; + p->pi_top_task =NULL ;#endif }
@@ -1311,7 +1313,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,#endif /* Perform scheduler related setup. Assign this task to a CPU. */ -sched_fork (clone_flags, p); + retval =sched_fork (clone_flags, p); +if (retval) + goto bad_fork_cleanup_policy; retval =perf_event_init_task (p);if (retval)
@@ -1403,13 +1407,11 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->tgid = p->pid; } - p->pdeath_signal =0 ; - p->exit_state =0 ; - p->nr_dirtied =0 ; p->nr_dirtied_pause =128 >> (PAGE_SHIFT -10 ); p->dirty_paused_when =0 ; + p->pdeath_signal =0 ;INIT_LIST_HEAD (&p->thread_group); p->task_works =NULL ;
kernel/futex.c +2 -0
@@ -2316,6 +2316,8 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,* code while we sleep on uaddr. */ debug_rt_mutex_init_waiter (&rt_waiter); +RB_CLEAR_NODE (&rt_waiter.pi_tree_entry); +RB_CLEAR_NODE (&rt_waiter.tree_entry); rt_waiter.task =NULL ; ret =get_futex_key (uaddr2, flags &FLAGS_SHARED , &key2,VERIFY_WRITE );
kernel/hrtimer.c +2 -1
@@ -46,6 +46,7 @@#include <linux/sched.h> #include <linux/sched/sysctl.h> #include <linux/sched/rt.h> +#include <linux/sched/deadline.h> #include <linux/timer.h> #include <linux/freezer.h>
@@ -1610,7 +1611,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,unsigned long slack; slack = current->timer_slack_ns; -if (rt_task (current)) +if (dl_task (current) ||rt_task (current)) slack =0 ;hrtimer_init_on_stack (&t.timer, clockid, mode);
kernel/locking/rtmutex-debug.c +2 -6
@@ -24,7 +24,7 @@#include <linux/kallsyms.h> #include <linux/syscalls.h> #include <linux/interrupt.h> -#include <linux/plist.h> +#include <linux/rbtree.h> #include <linux/fs.h> #include <linux/debug_locks.h>
@@ -57,7 +57,7 @@ static void printk_lock(struct rt_mutex *lock, int print_owner)void rt_mutex_debug_task_free (struct task_struct *task) { -DEBUG_LOCKS_WARN_ON (!plist_head_empty (&task->pi_waiters)); +DEBUG_LOCKS_WARN_ON (!RB_EMPTY_ROOT (&task->pi_waiters));DEBUG_LOCKS_WARN_ON (task->pi_blocked_on); }
@@ -154,16 +154,12 @@ void debug_rt_mutex_proxy_unlock(struct rt_mutex *lock)void debug_rt_mutex_init_waiter (struct rt_mutex_waiter *waiter) {memset (waiter,0x11 ,sizeof (*waiter)); -plist_node_init (&waiter->list_entry,MAX_PRIO ); -plist_node_init (&waiter->pi_list_entry,MAX_PRIO ); waiter->deadlock_task_pid =NULL ; }void debug_rt_mutex_free_waiter (struct rt_mutex_waiter *waiter) {put_pid (waiter->deadlock_task_pid); -DEBUG_LOCKS_WARN_ON (!plist_node_empty (&waiter->list_entry)); -DEBUG_LOCKS_WARN_ON (!plist_node_empty (&waiter->pi_list_entry));memset (waiter,0x22 ,sizeof (*waiter)); }
kernel/locking/rtmutex.c +135 -31
299 lines not on this page · raw message
kernel/locking/rtmutex_common.h +12 -11
@@ -40,13 +40,13 @@ extern void schedule_rt_mutex_test(struct rt_mutex *lock);* This is the control structure for tasks blocked on a rt_mutex, * which is allocated on the kernel stack on of the blocked task. * -* @list_entry: pi node to enqueue into the mutex waiters list -* @pi_list_entry: pi node to enqueue into the mutex owner waiters list +* @tree_entry: pi node to enqueue into the mutex waiters tree +* @pi_tree_entry: pi node to enqueue into the mutex owner waiters tree * @task: task reference to the blocked task */ struct rt_mutex_waiter { -struct plist_node list_entry; -struct plist_node pi_list_entry; +struct rb_node tree_entry; +struct rb_node pi_tree_entry;struct task_struct *task;struct rt_mutex *lock;#ifdef CONFIG_DEBUG_RT_MUTEXES
@@ -54,14 +54,15 @@ struct rt_mutex_waiter {struct pid *deadlock_task_pid;struct rt_mutex *deadlock_lock;#endif +int prio; };/* -* Various helpers to access the waiters-plist: +* Various helpers to access the waiters-tree: */ static inline int rt_mutex_has_waiters (struct rt_mutex *lock) { -return !plist_head_empty (&lock->wait_list); +return !RB_EMPTY_ROOT (&lock->waiters); } static inline struct rt_mutex_waiter *
@@ -69,8 +70,8 @@ rt_mutex_top_waiter(struct rt_mutex *lock) {struct rt_mutex_waiter *w; - w = plist_first_entry(&lock->wait_list, struct rt_mutex_waiter, - list_entry); + w = rb_entry(lock->waiters_leftmost, struct rt_mutex_waiter, + tree_entry);BUG_ON (w->lock != lock);return w;
@@ -78,14 +79,14 @@ rt_mutex_top_waiter(struct rt_mutex *lock)static inline int task_has_pi_waiters (struct task_struct *p) { -return !plist_head_empty (&p->pi_waiters); +return !RB_EMPTY_ROOT (&p->pi_waiters); }static inline struct rt_mutex_waiter *task_top_pi_waiter (struct task_struct *p) { - return plist_first_entry(&p->pi_waiters, struct rt_mutex_waiter, - pi_list_entry); + return rb_entry(p->pi_waiters_leftmost, struct rt_mutex_waiter, + pi_tree_entry); }/*
kernel/sched/Makefile +3 -2
@@ -11,9 +11,10 @@ ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y) CFLAGS_core.o := $(PROFILING) -fno-omit-frame-pointer endif -obj-y += core.o proc.o clock.o cputime.o idle_task.o fair.o rt.o stop_task.o +obj-y += core.o proc.o clock.o cputime.o +obj-y += idle_task.o fair.o rt.o deadline.o stop_task.o obj-y += wait.o completion.o -obj-$(CONFIG_SMP) += cpupri.o +obj-$(CONFIG_SMP) += cpupri.o cpudeadline.o obj-$(CONFIG_SCHED_AUTOGROUP) += auto_group.o obj-$(CONFIG_SCHEDSTATS) += stats.o obj-$(CONFIG_SCHED_DEBUG) += debug.o
kernel/sched/clock.c +47 -31
151 lines not on this page · raw message
kernel/sched/core.c +708 -114
854 lines not on this page · raw message
kernel/sched/cpudeadline.c new file +216 -0
216 lines not on this page · raw message
kernel/sched/deadline.c new file +1640 -0
1,640 lines not on this page · raw message
kernel/sched/fair.c +36 -47
83 lines not on this page · raw message
kernel/sched/sched.h +140 -6
146 lines not on this page · raw message
kernel/trace/trace_sched_wakeup.c +61 -4
65 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Part of the diff is not shown here. View the raw message.