scheduler changes for v3.13
Subsystems (46)
Linus,
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: e5137b50a0640009fd63a3e65c14bc6e1be8796a ftrace, sched: Add TRACE_FLAG_PREEMPT_RESCHED
Main changes in this cycle are:
- (much) improved CONFIG_NUMA_BALANCING support from Mel Gorman, Rik van Riel, Peter Zijlstra et al. Yay!
- optimize preemption counter handling: merge the NEED_RESCHED flag into the preempt_count variable, by Peter Zijlstra.
- wait.h fixes and code reorganization from Peter Zijlstra
- cfs_bandwidth fixes from Ben Segall
- SMP load-balancer cleanups from Peter Zijstra
- idle balancer improvements from Jason Low
- other fixes and cleanups.
Thanks,
Ingo
------------------>
Ben Segall (4):
sched: Fix race on toggling cfs_bandwidth_used
sched: Fix cfs_bandwidth misuse of hrtimer_expires_remaining
sched: Fix hrtimer_cancel()/rq->lock deadlock
sched: Avoid throttle_cfs_rq() racing with period_timer stopping
Heiko Carstens (1):
sched/wait: Fix __wait_event_interruptible_lock_irq_timeout()
Ingo Molnar (3):
sched/wait: Clean up wait.h details a bit sched/numa: Add debugging
x86: Apply the asm_volatile_goto() compiler quirk
Jason Low (3):
sched: Reduce overestimating rq->avg_idle sched/balancing: Consider max cost of idle balance per sched domain sched/balancing: Periodically decay max cost of idle balance
Kamalesh Babulal (1):
sched/fair: Fix trivial typos in comments
Li Bin (1):
sched/rt: Fix task_tick_rt() comment
Mel Gorman (39):
mm: numa: Document automatic NUMA balancing sysctls
mm: numa: Do not account for a hinting fault if we raced
mm: Wait for THP migrations to complete during NUMA hinting faults
mm: Prevent parallel splits during THP migration
mm: numa: Sanitize task_numa_fault() callsites
mm: Close races between THP migration and PMD numa clearing
mm: Account for a THP NUMA hinting update as one PTE update
mm: Do not flush TLB during protection change if !pte_present && !migration_entry
mm: Only flush TLBs if a transhuge PMD is modified for NUMA pte scanning
mm: numa: Do not migrate or account for hinting faults on the zero page Revert "mm: sched: numa: Delay PTE scanning until a task is scheduled on a new node" sched/numa: Initialise numa_next_scan properly
sched/numa: Set the scan rate proportional to the memory usage of the task being scanned sched/numa: Slow scan rate if no NUMA hinting faults are being recorded sched/numa: Track NUMA hinting faults on per-node basis
sched/numa: Select a preferred node with the most numa hinting faults sched/numa: Update NUMA hinting faults once per scan
sched/numa: Favour moving tasks towards the preferred node
sched/numa: Resist moving tasks towards nodes with fewer hinting faults sched/numa: Reschedule task on preferred NUMA node once selected sched/numa: Add infrastructure for split shared/private accounting of NUMA hinting faults sched/numa: Check current->mm before allocating NUMA faults
mm: numa: Scan pages with elevated page_mapcount
sched/numa: Remove check that skips small VMAs
sched/numa: Set preferred NUMA node based on number of private faults
mm: numa: Limit NUMA scanning to migrate-on-fault VMAs
sched/numa: Avoid overloading CPUs on a preferred NUMA node
sched/numa: Retry migration of tasks to CPU on a preferred node sched/numa: Do not trap hinting faults for shared libraries
mm: numa: Trap pmd hinting faults only if we would otherwise trap PTE faults sched/numa: Use a system-wide search to find swap/migration candidates sched/numa: Favor placing a task on the preferred node
sched/numa: Report a NUMA task group ID
mm: numa: Do not batch handle PMD pages
sched/numa: Use group fault statistics in numa placement
sched/numa: Prevent parallel updates to group stats during placement sched/numa: Take false sharing into account when adapting scan rate sched/numa: Remove the numa_balancing_scan_period_reset sysctl
sched/numa: Use unsigned longs for numa group fault stats
Michael S. Tsirkin (1):
sched: Micro-optimize by dropping unnecessary task_rq() calls
Michael wang (1):
sched: Remove extra put_online_cpus() inside sched_setaffinity()
Oleg Nesterov (2):
sched/wait: Add ___wait_cond_timeout() to wait_event*_timeout() too sched/wait: Introduce prepare_to_wait_event()
Paul Turner (1):
sched: Guarantee new group-entities always have weight
Peter Zijlstra (52):
sched/fair: Rewrite group_imb trigger
sched/fair: Reduce local_group logic
sched/fair: Fix group power_orig computation
sched/fair: Rework and comment the group_capacity code sched/fair: Fix the group_capacity computation
x86: Use asm goto to implement better modify_and_test() functions sched, rcu: Make RCU use resched_cpu()
sched: Remove {set,clear}_need_resched
sched, idle: Fix the idle polling state logic
sched: Introduce preempt_count accessor functions
sched: Add NEED_RESCHED to the preempt_count
sched, arch: Create asm/preempt.h
sched: Create more preempt_count accessors
sched: Extract the basic add/sub preempt_count modifiers
sched: Prepare for per-cpu preempt_count
sched, x86: Provide a per-cpu preempt_count implementation sched, x86: Optimize the preempt_schedule() call
sched: Revert need_resched() to look at TIF_NEED_RESCHED sched/wait: Make the signal_pending() checks consistent sched/wait: Change timeout logic
sched/wait: Change the wait_exclusive control flow sched/wait: Introduce ___wait_event()
sched/wait: Collapse __wait_event()
sched/wait: Collapse __wait_event_timeout()
sched/wait: Collapse __wait_event_interruptible() sched/wait: Collapse __wait_event_interruptible_timeout() sched/wait: Collapse __wait_event_interruptible_exclusive() sched/wait: Collapse __wait_event_lock_irq()
sched/wait: Collapse __wait_event_interruptible_lock_irq() sched/wait: Collapse __wait_event_interruptible_lock_irq_timeout() sched/wait: Collapse __wait_event_interruptible_tty() sched/wait: Collapse __wait_event_killable()
sched/wait: Collapse __wait_event_hrtimeout()
sched/wait: Make the __wait_event*() interface more friendly MAINTAINERS, sched: Update file pattern
sched/numa: Fix comments
sched/numa: Mitigate chance that same task always updates PTEs sched/numa: Continue PTE scanning even if migrate rate limited
stop_machine: Introduce stop_two_cpus()
sched/numa: Introduce migrate_swap()
mm: numa: Change page last {nid,pid} into {cpu,pid} sched/numa: Use {cpu, pid} to create task groups for shared faults
mm: numa: Do not group on RO pages
sched/numa: Avoid migrating tasks that are placed on their preferred node sched/numa: Reflow task_numa_group() to avoid a compiler warning sched/rt: Add missing rmb()
sched: Fix race in migrate_swap_stop()
sched: Remove get_online_cpus() usage
sched: Move wait.c into kernel/sched/
sched: Move wait code from core.c to wait.c
sched: Move completion code from core.c to completion.c ftrace, sched: Add TRACE_FLAG_PREEMPT_RESCHED
Preeti U Murthy (1):
sched: Remove unnecessary iteration over sched domains to update nr_busy_cpus
Ramkumar Ramachandra (1):
sched: Remove bogus parameter in structured comment
Rik van Riel (14):
sched/numa: Do not migrate memory immediately after switching node
sched/numa: Increment numa_migrate_seq when task runs in correct location sched/numa: Fix placement of workloads spread across multiple nodes
mm: numa: Copy cpupid on page migration
sched/numa: Stay on the same node if CLONE_VM
sched/numa: Call task_numa_free() from do_execve()
sched/numa: Decide whether to favour task or group weights based on swap candidate relationships sched/numa: Fix task or group comparison
sched/numa: Be more careful about joining numa groups
sched/numa: Adjust scan rate in task_numa_placement
mm: numa: Revert temporarily disabling of NUMA migration
sched/numa: Skip some page migrations after a shared fault
sched/numa: Retry task_numa_migrate() periodically
stop_machine: Fix race between stop_two_cpus() and stop_cpus()
Shawn Bohrer (1):
sched/rt: Remove redundant nr_cpus_allowed test
Thierry Reding (1):
sched/wait: Fix build breakage
Vaidyanathan Srinivasan (1):
sched: Fix asymmetric scheduling for POWER7
Vladimir Davydov (1):
sched/balancing: Prevent the reselection of a previous env.dst_cpu if some tasks are pinned
Documentation/sysctl/kernel.txt | 76 ++
Documentation/trace/ftrace.txt | 6 +-
MAINTAINERS | 2 +
arch/alpha/include/asm/Kbuild | 1 +
arch/arc/include/asm/Kbuild | 1 +
arch/arm/include/asm/Kbuild | 1 +
arch/arm64/include/asm/Kbuild | 1 +
arch/avr32/include/asm/Kbuild | 1 +
arch/blackfin/include/asm/Kbuild | 1 +
arch/c6x/include/asm/Kbuild | 1 +
arch/cris/include/asm/Kbuild | 1 +
arch/frv/include/asm/Kbuild | 1 +
arch/h8300/include/asm/Kbuild | 1 +
arch/hexagon/include/asm/Kbuild | 1 +
arch/ia64/include/asm/Kbuild | 1 +
arch/m32r/include/asm/Kbuild | 1 +
arch/m68k/include/asm/Kbuild | 1 +
arch/metag/include/asm/Kbuild | 1 +
arch/metag/include/asm/topology.h | 2 +
arch/microblaze/include/asm/Kbuild | 1 +
arch/mips/include/asm/Kbuild | 1 +
arch/mips/kernel/rtlx.c | 19 +-
arch/mips/mm/init.c | 5 +-
arch/mn10300/include/asm/Kbuild | 1 +
arch/openrisc/include/asm/Kbuild | 1 +
arch/parisc/include/asm/Kbuild | 1 +
arch/powerpc/include/asm/Kbuild | 1 +
arch/s390/include/asm/Kbuild | 1 +
arch/score/include/asm/Kbuild | 1 +
arch/sh/include/asm/Kbuild | 1 +
arch/sparc/include/asm/Kbuild | 1 +
arch/tile/include/asm/Kbuild | 1 +
arch/um/include/asm/Kbuild | 1 +
arch/unicore32/include/asm/Kbuild | 1 +
arch/x86/include/asm/atomic.h | 29 +-
arch/x86/include/asm/atomic64_64.h | 28 +-
arch/x86/include/asm/bitops.h | 24 +-
arch/x86/include/asm/calling.h | 50 ++
arch/x86/include/asm/local.h | 28 +-
arch/x86/include/asm/preempt.h | 100 +++
arch/x86/include/asm/rmwcc.h | 41 ++
arch/x86/include/asm/thread_info.h | 5 +-
arch/x86/kernel/Makefile | 2 +
arch/x86/kernel/asm-offsets.c | 1 -
arch/x86/kernel/cpu/common.c | 5 +
arch/x86/kernel/entry_32.S | 7 +-
arch/x86/kernel/entry_64.S | 4 +-
arch/x86/kernel/i386_ksyms_32.c | 7 +
arch/x86/kernel/irq_32.c | 4 -
arch/x86/kernel/preempt.S | 25 +
arch/x86/kernel/process.c | 6 +-
arch/x86/kernel/process_32.c | 8 +
arch/x86/kernel/process_64.c | 8 +
arch/x86/kernel/traps.c | 4 +-
arch/x86/kernel/x8664_ksyms_64.c | 7 +
arch/xtensa/include/asm/Kbuild | 1 +
drivers/acpi/processor_idle.c | 46 +-
drivers/idle/intel_idle.c | 2 +-
fs/exec.c | 1 +
fs/proc/array.c | 2 +
include/asm-generic/preempt.h | 105 +++
include/linux/completion.h | 2 +-
include/linux/hardirq.h | 8 +-
include/linux/mempolicy.h | 1 +
include/linux/migrate.h | 7 +-
include/linux/mm.h | 118 ++-
include/linux/mm_types.h | 17 +-
include/linux/page-flags-layout.h | 28 +-
include/linux/preempt.h | 112 ++-
include/linux/sched.h | 167 ++++-
include/linux/sched/sysctl.h | 1 -
include/linux/stop_machine.h | 1 +
include/linux/thread_info.h | 17 +-
include/linux/topology.h | 6 +
include/linux/tty.h | 28 +-
include/linux/uaccess.h | 8 +-
include/linux/wait.h | 374 ++++------
include/trace/events/sched.h | 2 +-
init/main.c | 2 +-
kernel/Makefile | 2 +-
kernel/bounds.c | 4 +
kernel/context_tracking.c | 2 +-
kernel/cpu.c | 17 +
kernel/cpu/idle.c | 16 +-
kernel/fork.c | 5 +-
kernel/rcutree.c | 15 +-
kernel/sched/Makefile | 1 +
kernel/sched/completion.c | 299 ++++++++
kernel/sched/core.c | 683 ++++++------------
kernel/sched/debug.c | 68 +-
kernel/sched/fair.c | 1397 ++++++++++++++++++++++++++++++------
kernel/sched/features.h | 19 +-
kernel/sched/idle_task.c | 2 +-
kernel/sched/rt.c | 22 +-
kernel/sched/sched.h | 54 +-
kernel/sched/stats.h | 46 +-
kernel/sched/stop_task.c | 2 +-
kernel/{ => sched}/wait.c | 127 ++++
kernel/softirq.c | 16 +-
kernel/stop_machine.c | 303 +++++---
kernel/sysctl.c | 21 +-
kernel/timer.c | 8 +-
kernel/trace/trace.c | 3 +-
kernel/trace/trace.h | 1 +
kernel/trace/trace_output.c | 19 +-
lib/locking-selftest.c | 2 +-
lib/smp_processor_id.c | 3 +-
mm/huge_memory.c | 55 +-
mm/memory.c | 139 ++--
mm/mempolicy.c | 82 ++-
mm/migrate.c | 30 +-
mm/mm_init.c | 18 +-
mm/mmzone.c | 14 +-
mm/mprotect.c | 65 +-
mm/page_alloc.c | 4 +-
net/irda/af_irda.c | 5 +-
net/netfilter/ipvs/ip_vs_sync.c | 7 +-
117 files changed, 3569 insertions(+), 1594 deletions(-)
create mode 100644 arch/x86/include/asm/preempt.h
create mode 100644 arch/x86/include/asm/rmwcc.h
create mode 100644 arch/x86/kernel/preempt.S
create mode 100644 include/asm-generic/preempt.h
create mode 100644 kernel/sched/completion.c
rename kernel/{ => sched}/wait.c (74%)Documentation/sysctl/kernel.txt +76 -0
@@ -355,6 +355,82 @@ utilize. ============================================================== +numa_balancing + +Enables/disables automatic page fault based NUMA memory +balancing. Memory is moved automatically to nodes +that access it often. + +Enables/disables automatic NUMA memory balancing. On NUMA machines, there +is a performance penalty if remote memory is accessed by a CPU. When this +feature is enabled the kernel samples what task thread is accessing memory +by periodically unmapping pages and later trapping a page fault. At the +time of the page fault, it is determined if the data being accessed should +be migrated to a local memory node. + +The unmapping of pages and trapping faults incur additional overhead that +ideally is offset by improved memory locality but there is no universal +guarantee. If the target workload is already bound to NUMA nodes then this +feature should be disabled. Otherwise, if the system overhead from the +feature is too high then the rate the kernel samples for NUMA hinting +faults may be controlled by the numa_balancing_scan_period_min_ms, +numa_balancing_scan_delay_ms, numa_balancing_scan_period_max_ms, +numa_balancing_scan_size_mb, numa_balancing_settle_count sysctls and +numa_balancing_migrate_deferred. + +============================================================== + +numa_balancing_scan_period_min_ms, numa_balancing_scan_delay_ms, +numa_balancing_scan_period_max_ms, numa_balancing_scan_size_mb + +Automatic NUMA balancing scans tasks address space and unmaps pages to +detect if pages are properly placed or if the data should be migrated to a +memory node local to where the task is running. Every "scan delay" the task +scans the next "scan size" number of pages in its address space. When the +end of the address space is reached the scanner restarts from the beginning. + +In combination, the "scan delay" and "scan size" determine the scan rate. +When "scan delay" decreases, the scan rate increases. The scan delay and +hence the scan rate of every task is adaptive and depends on historical +behaviour. If pages are properly placed then the scan delay increases, +otherwise the scan delay decreases. The "scan size" is not adaptive but +the higher the "scan size", the higher the scan rate. + +Higher scan rates incur higher system overhead as page faults must be +trapped and potentially data must be migrated. However, the higher the scan +rate, the more quickly a tasks memory is migrated to a local node if the +workload pattern changes and minimises performance impact due to remote +memory accesses. These sysctls control the thresholds for scan delays and +the number of pages scanned. + +numa_balancing_scan_period_min_ms is the minimum time in milliseconds to +scan a tasks virtual memory. It effectively controls the maximum scanning +rate for each task. + +numa_balancing_scan_delay_ms is the starting "scan delay" used for a task +when it initially forks. + +numa_balancing_scan_period_max_ms is the maximum time in milliseconds to +scan a tasks virtual memory. It effectively controls the minimum scanning +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 +how much stronger the "move task near its memory" policy scheduler becomes, +versus the "move memory near its task" memory management policy, for workloads +with shared memory. + +============================================================== + osrelease, ostype & version: # cat osrelease
Documentation/trace/ftrace.txt +5 -1
@@ -655,7 +655,11 @@ explains which is which. read the irq flags variable, an 'X' will always be printed here. - need-resched: 'N' task need_resched is set, '.' otherwise. + need-resched: + 'N' both TIF_NEED_RESCHED and PREEMPT_NEED_RESCHED is set, + 'n' only TIF_NEED_RESCHED is set, + 'p' only PREEMPT_NEED_RESCHED is set, + '.' otherwise. hardirq/softirq: 'H' - hard irq occurred inside a softirq.
MAINTAINERS +2 -0
@@ -7303,6 +7303,8 @@ S: Maintained F: kernel/sched/ F: include/linux/sched.h F: include/uapi/linux/sched.h +F: kernel/wait.c +F: include/linux/wait.h SCORE ARCHITECTURE M: Chen Liqin <[email protected]>
arch/alpha/include/asm/Kbuild +1 -0
@@ -3,3 +3,4 @@ generic-y += clkdev.h generic-y += exec.h generic-y += trace_clock.h +generic-y += preempt.h
arch/arc/include/asm/Kbuild +1 -0
@@ -46,3 +46,4 @@ generic-y += ucontext.h generic-y += user.h generic-y += vga.h generic-y += xor.h +generic-y += preempt.h
arch/arm/include/asm/Kbuild +1 -0
@@ -32,3 +32,4 @@ generic-y += termios.h generic-y += timex.h generic-y += trace_clock.h generic-y += unaligned.h +generic-y += preempt.h
arch/arm64/include/asm/Kbuild +1 -0
@@ -50,3 +50,4 @@ generic-y += unaligned.h generic-y += user.h generic-y += vga.h generic-y += xor.h +generic-y += preempt.h
arch/avr32/include/asm/Kbuild +1 -0
@@ -7,6 +7,7 @@ generic-y += div64.h generic-y += emergency-restart.h generic-y += exec.h generic-y += futex.h +generic-y += preempt.h generic-y += irq_regs.h generic-y += param.h generic-y += local.h
arch/blackfin/include/asm/Kbuild +1 -0
@@ -44,3 +44,4 @@ generic-y += ucontext.h generic-y += unaligned.h generic-y += user.h generic-y += xor.h +generic-y += preempt.h
arch/c6x/include/asm/Kbuild +1 -0
@@ -56,3 +56,4 @@ generic-y += ucontext.h generic-y += user.h generic-y += vga.h generic-y += xor.h +generic-y += preempt.h
arch/cris/include/asm/Kbuild +1 -0
@@ -11,3 +11,4 @@ generic-y += module.h generic-y += trace_clock.h generic-y += vga.h generic-y += xor.h +generic-y += preempt.h
arch/frv/include/asm/Kbuild +1 -0
@@ -2,3 +2,4 @@ generic-y += clkdev.h generic-y += exec.h generic-y += trace_clock.h +generic-y += preempt.h
arch/h8300/include/asm/Kbuild +1 -0
@@ -6,3 +6,4 @@ generic-y += mmu.h generic-y += module.h generic-y += trace_clock.h generic-y += xor.h +generic-y += preempt.h
arch/hexagon/include/asm/Kbuild +1 -0
@@ -53,3 +53,4 @@ generic-y += types.h generic-y += ucontext.h generic-y += unaligned.h generic-y += xor.h +generic-y += preempt.h
arch/ia64/include/asm/Kbuild +1 -0
@@ -3,4 +3,5 @@ generic-y += clkdev.h generic-y += exec.h generic-y += kvm_para.h generic-y += trace_clock.h +generic-y += preempt.h generic-y += vtime.h
arch/m32r/include/asm/Kbuild +1 -0
@@ -3,3 +3,4 @@ generic-y += clkdev.h generic-y += exec.h generic-y += module.h generic-y += trace_clock.h +generic-y += preempt.h
arch/m68k/include/asm/Kbuild +1 -0
@@ -31,3 +31,4 @@ generic-y += trace_clock.h generic-y += types.h generic-y += word-at-a-time.h generic-y += xor.h +generic-y += preempt.h
arch/metag/include/asm/Kbuild +1 -0
@@ -52,3 +52,4 @@ generic-y += unaligned.h generic-y += user.h generic-y += vga.h generic-y += xor.h +generic-y += preempt.h
arch/metag/include/asm/topology.h +2 -0
@@ -26,6 +26,8 @@ .last_balance = jiffies, \ .balance_interval = 1, \ .nr_balance_failed = 0, \ + .max_newidle_lb_cost = 0, \ + .next_decay_max_lb_cost = jiffies, \ }#define cpu_to_node (cpu) ((void)(cpu), 0)
arch/microblaze/include/asm/Kbuild +1 -0
@@ -3,3 +3,4 @@ generic-y += clkdev.h generic-y += exec.h generic-y += trace_clock.h generic-y += syscalls.h +generic-y += preempt.h
arch/mips/include/asm/Kbuild +1 -0
@@ -11,5 +11,6 @@ generic-y += sections.h generic-y += segment.h generic-y += serial.h generic-y += trace_clock.h +generic-y += preempt.h generic-y += ucontext.h generic-y += xor.h
arch/mips/kernel/rtlx.c +9 -10
@@ -172,8 +172,9 @@ int rtlx_open(int index, int can_sleep)if (rtlx ==NULL ) {if ( (p =vpe_get_shared (tclimit)) ==NULL ) {if (can_sleep) { -__wait_event_interruptible (channel_wqs[index].lx_queue, - (p =vpe_get_shared (tclimit)), ret); + ret =__wait_event_interruptible ( + channel_wqs[index].lx_queue, + (p =vpe_get_shared (tclimit)));if (ret) goto out_fail; }else {
@@ -263,11 +264,10 @@ unsigned int rtlx_read_poll(int index, int can_sleep)/* data available to read? */ if (chan->lx_read == chan->lx_write) {if (can_sleep) { -int ret =0 ; - -__wait_event_interruptible (channel_wqs[index].lx_queue, +int ret =__wait_event_interruptible ( + channel_wqs[index].lx_queue, (chan->lx_read != chan->lx_write) || - sp_stopping, ret); + sp_stopping);if (ret)return ret;
@@ -440,14 +440,13 @@ static ssize_t file_write(struct file *file, const char __user * buffer,/* any space left... */ if (!rtlx_write_poll (minor)) { -int ret =0 ; +int ret;if (file->f_flags &O_NONBLOCK )return -EAGAIN ; -__wait_event_interruptible (channel_wqs[minor].rt_queue, -rtlx_write_poll (minor), - ret); + ret =__wait_event_interruptible (channel_wqs[minor].rt_queue, +rtlx_write_poll (minor));if (ret)return ret; }
arch/mips/mm/init.c +2 -3
@@ -124,7 +124,7 @@ void *kmap_coherent(struct page *page, unsigned long addr)BUG_ON (Page_dcache_dirty (page)); -inc_preempt_count (); +pagefault_disable (); idx = (addr >>PAGE_SHIFT ) & (FIX_N_COLOURS -1 );#ifdef CONFIG_MIPS_MT_SMTC idx += FIX_N_COLOURS * smp_processor_id() +
@@ -193,8 +193,7 @@ void kunmap_coherent(void)write_c0_entryhi (old_ctx);EXIT_CRITICAL (flags);#endif -dec_preempt_count (); -preempt_check_resched (); +pagefault_enable (); } void copy_user_highpage(struct page *to, struct page *from,
arch/mn10300/include/asm/Kbuild +1 -0
@@ -2,3 +2,4 @@ generic-y += clkdev.h generic-y += exec.h generic-y += trace_clock.h +generic-y += preempt.h
arch/openrisc/include/asm/Kbuild +1 -0
@@ -67,3 +67,4 @@ generic-y += ucontext.h generic-y += user.h generic-y += word-at-a-time.h generic-y += xor.h +generic-y += preempt.h
arch/parisc/include/asm/Kbuild +1 -0
@@ -4,3 +4,4 @@ generic-y += word-at-a-time.h auxvec.h user.h cputime.h emergency-restart.h \ div64.h irq_regs.h kdebug.h kvm_para.h local64.h local.h param.h \ poll.h xor.h clkdev.h exec.h generic-y += trace_clock.h +generic-y += preempt.h
arch/powerpc/include/asm/Kbuild +1 -0
@@ -2,4 +2,5 @@ generic-y += clkdev.h generic-y += rwsem.h generic-y += trace_clock.h +generic-y += preempt.h generic-y += vtime.h
arch/s390/include/asm/Kbuild +1 -0
@@ -2,3 +2,4 @@ generic-y += clkdev.h generic-y += trace_clock.h +generic-y += preempt.h
arch/score/include/asm/Kbuild +1 -0
@@ -4,3 +4,4 @@ header-y += generic-y += clkdev.h generic-y += trace_clock.h generic-y += xor.h +generic-y += preempt.h
arch/sh/include/asm/Kbuild +1 -0
@@ -34,3 +34,4 @@ generic-y += termios.h generic-y += trace_clock.h generic-y += ucontext.h generic-y += xor.h +generic-y += preempt.h
arch/sparc/include/asm/Kbuild +1 -0
@@ -16,3 +16,4 @@ generic-y += serial.h generic-y += trace_clock.h generic-y += types.h generic-y += word-at-a-time.h +generic-y += preempt.h
arch/tile/include/asm/Kbuild +1 -0
@@ -38,3 +38,4 @@ generic-y += termios.h generic-y += trace_clock.h generic-y += types.h generic-y += xor.h +generic-y += preempt.h
arch/um/include/asm/Kbuild +1 -0
@@ -3,3 +3,4 @@ generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h generic-y += switch_to.h clkdev.h generic-y += trace_clock.h +generic-y += preempt.h
arch/unicore32/include/asm/Kbuild +1 -0
@@ -60,3 +60,4 @@ generic-y += unaligned.h generic-y += user.h generic-y += vga.h generic-y += xor.h +generic-y += preempt.h
arch/x86/include/asm/atomic.h +5 -24
@@ -6,6 +6,7 @@#include <asm/processor.h> #include <asm/alternative.h> #include <asm/cmpxchg.h> +#include <asm/rmwcc.h> /* * Atomic operations that C can't guarantee us. Useful for
@@ -76,12 +77,7 @@ static inline void atomic_sub(int i, atomic_t *v)*/ static inline int atomic_sub_and_test (int i,atomic_t *v) { -unsigned char c; - - asmvolatile (LOCK_PREFIX "subl %2,%0; sete %1" - :"+m" (v->counter),"=qm" (c) - :"ir" (i) :"memory" ); -return c; +GEN_BINARY_RMWcc (LOCK_PREFIX "subl" , v->counter, i,"%0" ,"e" ); }/**
@@ -118,12 +114,7 @@ static inline void atomic_dec(atomic_t *v)*/ static inline int atomic_dec_and_test (atomic_t *v) { -unsigned char c; - - asmvolatile (LOCK_PREFIX "decl %0; sete %1" - :"+m" (v->counter),"=qm" (c) - : :"memory" ); -return c !=0 ; +GEN_UNARY_RMWcc (LOCK_PREFIX "decl" , v->counter,"%0" ,"e" ); }/**
@@ -136,12 +127,7 @@ static inline int atomic_dec_and_test(atomic_t *v)*/ static inline int atomic_inc_and_test (atomic_t *v) { -unsigned char c; - - asmvolatile (LOCK_PREFIX "incl %0; sete %1" - :"+m" (v->counter),"=qm" (c) - : :"memory" ); -return c !=0 ; +GEN_UNARY_RMWcc (LOCK_PREFIX "incl" , v->counter,"%0" ,"e" ); }/**
@@ -155,12 +141,7 @@ static inline int atomic_inc_and_test(atomic_t *v)*/ static inline int atomic_add_negative (int i,atomic_t *v) { -unsigned char c; - - asmvolatile (LOCK_PREFIX "addl %2,%0; sets %1" - :"+m" (v->counter),"=qm" (c) - :"ir" (i) :"memory" ); -return c; +GEN_BINARY_RMWcc (LOCK_PREFIX "addl" , v->counter, i,"%0" ,"s" ); }/**
arch/x86/include/asm/atomic64_64.h +4 -24
@@ -72,12 +72,7 @@ static inline void atomic64_sub(long i, atomic64_t *v)*/ static inline int atomic64_sub_and_test (long i,atomic64_t *v) { -unsigned char c; - - asmvolatile (LOCK_PREFIX "subq %2,%0; sete %1" - :"=m" (v->counter),"=qm" (c) - :"er" (i),"m" (v->counter) :"memory" ); -return c; +GEN_BINARY_RMWcc (LOCK_PREFIX "subq" , v->counter, i,"%0" ,"e" ); }/**
@@ -116,12 +111,7 @@ static inline void atomic64_dec(atomic64_t *v)*/ static inline int atomic64_dec_and_test (atomic64_t *v) { -unsigned char c; - - asmvolatile (LOCK_PREFIX "decq %0; sete %1" - :"=m" (v->counter),"=qm" (c) - :"m" (v->counter) :"memory" ); -return c !=0 ; +GEN_UNARY_RMWcc (LOCK_PREFIX "decq" , v->counter,"%0" ,"e" ); }/**
@@ -134,12 +124,7 @@ static inline int atomic64_dec_and_test(atomic64_t *v)*/ static inline int atomic64_inc_and_test (atomic64_t *v) { -unsigned char c; - - asmvolatile (LOCK_PREFIX "incq %0; sete %1" - :"=m" (v->counter),"=qm" (c) - :"m" (v->counter) :"memory" ); -return c !=0 ; +GEN_UNARY_RMWcc (LOCK_PREFIX "incq" , v->counter,"%0" ,"e" ); }/**
@@ -153,12 +138,7 @@ static inline int atomic64_inc_and_test(atomic64_t *v)*/ static inline int atomic64_add_negative (long i,atomic64_t *v) { -unsigned char c; - - asmvolatile (LOCK_PREFIX "addq %2,%0; sets %1" - :"=m" (v->counter),"=qm" (c) - :"er" (i),"m" (v->counter) :"memory" ); -return c; +GEN_BINARY_RMWcc (LOCK_PREFIX "addq" , v->counter, i,"%0" ,"s" ); }/**
arch/x86/include/asm/bitops.h +4 -20
@@ -14,6 +14,7 @@#include <linux/compiler.h> #include <asm/alternative.h> +#include <asm/rmwcc.h> #if BITS_PER_LONG ==32 # define _BITOPS_LONG_SHIFT 5
@@ -204,12 +205,7 @@ static inline void change_bit(long nr, volatile unsigned long *addr)*/ static inline int test_and_set_bit (long nr,volatile unsigned long *addr) { -int oldbit; - - asmvolatile (LOCK_PREFIX "bts %2,%1\n\t" - "sbb %0,%0" : "=r" (oldbit), ADDR : "Ir" (nr) : "memory"); - -return oldbit; +GEN_BINARY_RMWcc (LOCK_PREFIX "bts" , *addr, nr,"%0" ,"c" ); }/**
@@ -255,13 +251,7 @@ static inline int __test_and_set_bit(long nr, volatile unsigned long *addr)*/ static inline int test_and_clear_bit (long nr,volatile unsigned long *addr) { -int oldbit; - - asmvolatile (LOCK_PREFIX "btr %2,%1\n\t" -"sbb %0,%0" - : "=r" (oldbit), ADDR : "Ir" (nr) : "memory"); - -return oldbit; +GEN_BINARY_RMWcc (LOCK_PREFIX "btr" , *addr, nr,"%0" ,"c" ); }/**
@@ -314,13 +304,7 @@ static inline int __test_and_change_bit(long nr, volatile unsigned long *addr)*/ static inline int test_and_change_bit (long nr,volatile unsigned long *addr) { -int oldbit; - - asmvolatile (LOCK_PREFIX "btc %2,%1\n\t" -"sbb %0,%0" - : "=r" (oldbit), ADDR : "Ir" (nr) : "memory"); - -return oldbit; +GEN_BINARY_RMWcc (LOCK_PREFIX "btc" , *addr, nr,"%0" ,"c" ); } static __always_inline int constant_test_bit(long nr, const volatile unsigned long *addr)
arch/x86/include/asm/calling.h +50 -0
59 lines not on this page · raw message
arch/x86/include/asm/local.h +4 -24
@@ -52,12 +52,7 @@ static inline void local_sub(long i, local_t *l)*/ static inline int local_sub_and_test (long i,local_t *l) { -unsigned char c; - - asmvolatile (_ASM_SUB"%2,%0; sete %1" - :"+m" (l->a.counter),"=qm" (c) - :"ir" (i) :"memory" ); -return c; +GEN_BINARY_RMWcc (_ASM_SUB, l->a.counter, i,"%0" ,"e" ); }/**
@@ -70,12 +65,7 @@ static inline int local_sub_and_test(long i, local_t *l)*/ static inline int local_dec_and_test (local_t *l) { -unsigned char c; - - asmvolatile (_ASM_DEC"%0; sete %1" - :"+m" (l->a.counter),"=qm" (c) - : :"memory" ); -return c !=0 ; +GEN_UNARY_RMWcc (_ASM_DEC, l->a.counter,"%0" ,"e" ); }/**
@@ -88,12 +78,7 @@ static inline int local_dec_and_test(local_t *l)*/ static inline int local_inc_and_test (local_t *l) { -unsigned char c; - - asmvolatile (_ASM_INC"%0; sete %1" - :"+m" (l->a.counter),"=qm" (c) - : :"memory" ); -return c !=0 ; +GEN_UNARY_RMWcc (_ASM_INC, l->a.counter,"%0" ,"e" ); }/**
@@ -107,12 +92,7 @@ static inline int local_inc_and_test(local_t *l)*/ static inline int local_add_negative (long i,local_t *l) { -unsigned char c; - - asmvolatile (_ASM_ADD"%2,%0; sets %1" - :"+m" (l->a.counter),"=qm" (c) - :"ir" (i) :"memory" ); -return c; +GEN_BINARY_RMWcc (_ASM_ADD, l->a.counter, i,"%0" ,"s" ); }/**
arch/x86/include/asm/preempt.h new file +100 -0
100 lines not on this page · raw message
arch/x86/include/asm/rmwcc.h new file +41 -0
41 lines not on this page · raw message
arch/x86/include/asm/thread_info.h +2 -3
@@ -28,8 +28,7 @@ struct thread_info {__u32 flags;/* low level flags */ __u32 status;/* thread synchronous flags */ __u32 cpu;/* current CPU */ -int preempt_count;/* 0 => preemptable, -<0 => BUG */ +int saved_preempt_count;mm_segment_t addr_limit;struct restart_block restart_block;void __user *sysenter_return;
@@ -49,7 +48,7 @@ struct thread_info { .exec_domain = &default_exec_domain, \ .flags = 0, \ .cpu = 0, \ - .preempt_count = INIT_PREEMPT_COUNT, \ + .saved_preempt_count = INIT_PREEMPT_COUNT, \ .addr_limit = KERNEL_DS, \ .restart_block = { \ .fn = do_no_restart_syscall, \
arch/x86/kernel/Makefile +2 -0
@@ -36,6 +36,8 @@ obj-y += tsc.o io_delay.o rtc.o obj-y += pci-iommu_table.o obj-y += resource.o +obj-$(CONFIG_PREEMPT) += preempt.o + obj-y += process.o obj-y += i387.o xsave.o obj-y += ptrace.o
arch/x86/kernel/asm-offsets.c +0 -1
@@ -32,7 +32,6 @@ void common(void) {OFFSET (TI_flags, thread_info, flags);OFFSET (TI_status, thread_info, status);OFFSET (TI_addr_limit, thread_info, addr_limit); -OFFSET (TI_preempt_count, thread_info, preempt_count);BLANK ();OFFSET (crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
arch/x86/kernel/cpu/common.c +5 -0
@@ -1095,6 +1095,9 @@ DEFINE_PER_CPU(char *, irq_stack_ptr) = DEFINE_PER_CPU(unsigned int, irq_count) __visible = -1; +DEFINE_PER_CPU (int, __preempt_count) =INIT_PREEMPT_COUNT ; +EXPORT_PER_CPU_SYMBOL (__preempt_count); + DEFINE_PER_CPU(struct task_struct *, fpu_owner_task);/*
@@ -1169,6 +1172,8 @@ void debug_stack_reset(void) DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;EXPORT_PER_CPU_SYMBOL (current_task); +DEFINE_PER_CPU (int, __preempt_count) =INIT_PREEMPT_COUNT ; +EXPORT_PER_CPU_SYMBOL (__preempt_count); DEFINE_PER_CPU(struct task_struct *, fpu_owner_task);#ifdef CONFIG_CC_STACKPROTECTOR
arch/x86/kernel/entry_32.S +2 -5
@@ -362,12 +362,9 @@ END(ret_from_exception) #ifdef CONFIG_PREEMPT ENTRY(resume_kernel) DISABLE_INTERRUPTS(CLBR_ANY) - cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? - jnz restore_all need_resched: - movl TI_flags(%ebp), %ecx # need_resched set ? - testb $_TIF_NEED_RESCHED, %cl - jz restore_all + cmpl $0,PER_CPU_VAR(__preempt_count) + jnz restore_all testl $X86_EFLAGS_IF,PT_EFLAGS(%esp) # interrupts off (exception path) ? jz restore_all call preempt_schedule_irq
arch/x86/kernel/entry_64.S +1 -3
@@ -1103,10 +1103,8 @@ retint_signal: /* Returning to kernel space. Check if we need preemption */ /* rcx: threadinfo. interrupts off. */ ENTRY(retint_kernel) - cmpl $0,TI_preempt_count(%rcx) + cmpl $0,PER_CPU_VAR(__preempt_count) jnz retint_restore_args - bt $TIF_NEED_RESCHED,TI_flags(%rcx) - jnc retint_restore_args bt $9,EFLAGS-ARGOFFSET(%rsp) /* interrupts off? */ jnc retint_restore_args call preempt_schedule_irq
arch/x86/kernel/i386_ksyms_32.c +7 -0
@@ -37,3 +37,10 @@ EXPORT_SYMBOL(strstr);EXPORT_SYMBOL (csum_partial);EXPORT_SYMBOL (empty_zero_page); + +#ifdef CONFIG_PREEMPT +EXPORT_SYMBOL (___preempt_schedule); +#ifdef CONFIG_CONTEXT_TRACKING +EXPORT_SYMBOL (___preempt_schedule_context); +#endif +#endif
arch/x86/kernel/irq_32.c +0 -4
@@ -100,9 +100,6 @@ execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq) irqctx->tinfo.task = curctx->tinfo.task; irqctx->tinfo.previous_esp = current_stack_pointer; -/* Copy the preempt_count so that the [soft]irq checks work. */ - irqctx->tinfo.preempt_count = curctx->tinfo.preempt_count; -if (unlikely (overflow))call_on_stack (print_stack_overflow, isp);
@@ -131,7 +128,6 @@ void irq_ctx_init(int cpu) THREAD_SIZE_ORDER));memset (&irqctx->tinfo,0 ,sizeof (struct thread_info )); irqctx->tinfo.cpu = cpu; - irqctx->tinfo.preempt_count =HARDIRQ_OFFSET ; irqctx->tinfo.addr_limit =MAKE_MM_SEG (0 );per_cpu (hardirq_ctx, cpu) = irqctx;
arch/x86/kernel/preempt.S new file +25 -0
@@ -0,0 +1,25 @@ + +#include <linux/linkage.h> +#include <asm/dwarf2.h> +#include <asm/asm.h> +#include <asm/calling.h> + +ENTRY(___preempt_schedule) + CFI_STARTPROC + SAVE_ALL + call preempt_schedule + RESTORE_ALL + ret + CFI_ENDPROC + +#ifdef CONFIG_CONTEXT_TRACKING + +ENTRY(___preempt_schedule_context) + CFI_STARTPROC + SAVE_ALL + call preempt_schedule_context + RESTORE_ALL + ret + CFI_ENDPROC + +#endif
arch/x86/kernel/process.c +3 -3
@@ -391,9 +391,9 @@ static void amd_e400_idle(void)* The switch back from broadcast mode needs to be * called with interrupts disabled. */ -local_irq_disable (); -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_EXIT , &cpu); -local_irq_enable (); +local_irq_disable (); +clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_EXIT , &cpu); +local_irq_enable (); }else default_idle (); }
arch/x86/kernel/process_32.c +8 -0
@@ -292,6 +292,14 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)set_iopl_mask (next->iopl);/* +* If it were not for PREEMPT_ACTIVE we could guarantee that the +* preempt_count of all tasks was equal here and this would not be +* needed. +*/ +task_thread_info (prev_p)->saved_preempt_count =this_cpu_read (__preempt_count); +this_cpu_write (__preempt_count,task_thread_info (next_p)->saved_preempt_count); + +/* * Now maybe handle debug registers and/or IO bitmaps */ if (unlikely(task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV ||
arch/x86/kernel/process_64.c +8 -0
@@ -363,6 +363,14 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)this_cpu_write (old_rsp, next->usersp);this_cpu_write (current_task, next_p); +/* +* If it were not for PREEMPT_ACTIVE we could guarantee that the +* preempt_count of all tasks was equal here and this would not be +* needed. +*/ +task_thread_info (prev_p)->saved_preempt_count =this_cpu_read (__preempt_count); +this_cpu_write (__preempt_count,task_thread_info (next_p)->saved_preempt_count); +this_cpu_write (kernel_stack, (unsigned long )task_stack_page (next_p) +THREAD_SIZE -KERNEL_STACK_OFFSET );
arch/x86/kernel/traps.c +2 -2
@@ -88,7 +88,7 @@ static inline void conditional_sti(struct pt_regs *regs)static inline void preempt_conditional_sti (struct pt_regs *regs) { -inc_preempt_count (); +preempt_count_inc ();if (regs->flags &X86_EFLAGS_IF )local_irq_enable (); }
@@ -103,7 +103,7 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) {if (regs->flags &X86_EFLAGS_IF )local_irq_disable (); -dec_preempt_count (); +preempt_count_dec (); } static int __kprobes
arch/x86/kernel/x8664_ksyms_64.c +7 -0
@@ -66,3 +66,10 @@ EXPORT_SYMBOL(empty_zero_page);#ifndef CONFIG_PARAVIRT EXPORT_SYMBOL (native_load_gs_index);#endif + +#ifdef CONFIG_PREEMPT +EXPORT_SYMBOL (___preempt_schedule); +#ifdef CONFIG_CONTEXT_TRACKING +EXPORT_SYMBOL (___preempt_schedule_context); +#endif +#endif
arch/xtensa/include/asm/Kbuild +1 -0
@@ -28,3 +28,4 @@ generic-y += termios.h generic-y += topology.h generic-y += trace_clock.h generic-y += xor.h +generic-y += preempt.h
drivers/acpi/processor_idle.c +10 -36
87 lines not on this page · raw message
drivers/idle/intel_idle.c +1 -1
@@ -359,7 +359,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 (!need_resched ()) { +if (!current_set_polling_and_test ()) {__monitor ((void *)¤t_thread_info ()->flags,0 ,0 );smp_mb ();
fs/exec.c +1 -0
@@ -1547,6 +1547,7 @@ static int do_execve_common(const char *filename, current->fs->in_exec =0 ; current->in_execve =0 ;acct_update_integrals (current); +task_numa_free (current);free_bprm (bprm);if (displaced)put_files_struct (displaced);
fs/proc/array.c +2 -0
@@ -183,6 +183,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,seq_printf (m,"State:\t%s\n" "Tgid:\t%d\n" +"Ngid:\t%d\n" "Pid:\t%d\n" "PPid:\t%d\n" "TracerPid:\t%d\n"
@@ -190,6 +191,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,"Gid:\t%d\t%d\t%d\t%d\n" ,get_task_state (p),task_tgid_nr_ns (p, ns), +task_numa_group_id (p),pid_nr_ns (pid, ns), ppid, tpid, from_kuid_munged(user_ns, cred->uid),
include/asm-generic/preempt.h new file +105 -0
105 lines not on this page · raw message
include/linux/completion.h +1 -1
@@ -5,7 +5,7 @@* (C) Copyright 2001 Linus Torvalds * * Atomic wait-for-completion handler data structures. -* See kernel/sched/core.c for details. +* See kernel/sched/completion.c for details. */ #include <linux/wait.h>
include/linux/hardirq.h +4 -4
@@ -33,7 +33,7 @@ extern void rcu_nmi_exit(void);#define __irq_enter () \ do { \ account_irq_enter_time(current); \ - add_preempt_count(HARDIRQ_OFFSET); \ + preempt_count_add(HARDIRQ_OFFSET); \ trace_hardirq_enter(); \ } while (0)
@@ -49,7 +49,7 @@ extern void irq_enter(void);do { \trace_hardirq_exit (); \account_irq_exit_time (current); \ -sub_preempt_count (HARDIRQ_OFFSET ); \ +preempt_count_sub (HARDIRQ_OFFSET ); \ }while (0 )/*
@@ -62,7 +62,7 @@ extern void irq_exit(void);lockdep_off (); \ftrace_nmi_enter (); \BUG_ON (in_nmi ()); \ -add_preempt_count (NMI_OFFSET +HARDIRQ_OFFSET ); \ +preempt_count_add (NMI_OFFSET +HARDIRQ_OFFSET ); \rcu_nmi_enter (); \trace_hardirq_enter (); \ }while (0 )
@@ -72,7 +72,7 @@ extern void irq_exit(void);trace_hardirq_exit (); \rcu_nmi_exit (); \BUG_ON (!in_nmi ()); \ -sub_preempt_count (NMI_OFFSET +HARDIRQ_OFFSET ); \ +preempt_count_sub (NMI_OFFSET +HARDIRQ_OFFSET ); \ftrace_nmi_exit (); \lockdep_on (); \ }while (0 )
include/linux/mempolicy.h +1 -0
@@ -136,6 +136,7 @@ struct mempolicy *mpol_shared_policy_lookup(struct shared_policy *sp,struct mempolicy *get_vma_policy (struct task_struct *tsk,struct vm_area_struct *vma,unsigned long addr); +bool vma_policy_mof (struct task_struct *task,struct vm_area_struct *vma);extern void numa_default_policy (void );extern void numa_policy_init (void );
include/linux/migrate.h +4 -3
@@ -90,11 +90,12 @@ static inline int migrate_huge_page_move_mapping(struct address_space *mapping,#endif /* CONFIG_MIGRATION */ #ifdef CONFIG_NUMA_BALANCING -extern int migrate_misplaced_page (struct page *page,int node); -extern int migrate_misplaced_page (struct page *page,int node); +extern int migrate_misplaced_page (struct page *page, +struct vm_area_struct *vma,int node);extern bool migrate_ratelimited (int node);#else -static inline int migrate_misplaced_page (struct page *page,int node) +static inline int migrate_misplaced_page (struct page *page, +struct vm_area_struct *vma,int node) {return -EAGAIN ;/* can't migrate now */ }
include/linux/mm.h +92 -26
168 lines not on this page · raw message
include/linux/mm_types.h +2 -15
@@ -174,8 +174,8 @@ struct page {void *shadow;#endif -#ifdef LAST_NID_NOT_IN_PAGE_FLAGS -int _last_nid; +#ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS +int _last_cpupid;#endif }/*
@@ -420,28 +420,15 @@ struct mm_struct {*/ unsigned long numa_next_scan; -/* numa_next_reset is when the PTE scanner period will be reset */ -unsigned long numa_next_reset; -/* Restart point for scanning and setting pte_numa */ unsigned long numa_scan_offset;/* numa_scan_seq prevents two threads setting pte_numa */ int numa_scan_seq; - -/* -* The first node a task was scheduled on. If a task runs on -* a different node than Make PTE Scan Go Now. -*/ -int first_nid;#endif struct uprobes_state uprobes_state; }; -/* first nid will either be a valid NID or one of these values */ -#define NUMA_PTE_SCAN_INIT -1 -#define NUMA_PTE_SCAN_ACTIVE -2 -static inline void mm_init_cpumask (struct mm_struct *mm) {#ifdef CONFIG_CPUMASK_OFFSTACK
include/linux/page-flags-layout.h +17 -11
@@ -38,10 +38,10 @@* The last is when there is insufficient space in page->flags and a separate * lookup is necessary. * -* No sparsemem or sparsemem vmemmap: | NODE | ZONE | ... | FLAGS | -* " plus space for last_nid: | NODE | ZONE | LAST_NID ... | FLAGS | -* classic sparse with space for node:| SECTION | NODE | ZONE | ... | FLAGS | -* " plus space for last_nid: | SECTION | NODE | ZONE | LAST_NID ... | FLAGS | +* No sparsemem or sparsemem vmemmap: | NODE | ZONE | ... | FLAGS | +* " plus space for last_cpupid: | NODE | ZONE | LAST_CPUPID ... | FLAGS | +* classic sparse with space for node:| SECTION | NODE | ZONE | ... | FLAGS | +* " plus space for last_cpupid: | SECTION | NODE | ZONE | LAST_CPUPID ... | FLAGS | * classic sparse no space for node: | SECTION | ZONE | ... | FLAGS | */ #if defined(CONFIG_SPARSEMEM ) && !defined(CONFIG_SPARSEMEM_VMEMMAP )
@@ -62,15 +62,21 @@#endif #ifdef CONFIG_NUMA_BALANCING -#define LAST_NID_SHIFT NODES_SHIFT +#define LAST__PID_SHIFT 8 +#define LAST__PID_MASK ((1 << LAST__PID_SHIFT)-1) + +#define LAST__CPU_SHIFT NR_CPUS_BITS +#define LAST__CPU_MASK ((1 << LAST__CPU_SHIFT)-1) + +#define LAST_CPUPID_SHIFT (LAST__PID_SHIFT+LAST__CPU_SHIFT)#else -#define LAST_NID_SHIFT 0 +#define LAST_CPUPID_SHIFT 0#endif -#if SECTIONS_WIDTH +ZONES_WIDTH +NODES_SHIFT +LAST_NID_SHIFT <=BITS_PER_LONG -NR_PAGEFLAGS -#define LAST_NID_WIDTH LAST_NID_SHIFT +#if SECTIONS_WIDTH +ZONES_WIDTH +NODES_SHIFT +LAST_CPUPID_SHIFT <=BITS_PER_LONG -NR_PAGEFLAGS +#define LAST_CPUPID_WIDTH LAST_CPUPID_SHIFT#else -#define LAST_NID_WIDTH 0 +#define LAST_CPUPID_WIDTH 0#endif /*
@@ -81,8 +87,8 @@#define NODE_NOT_IN_PAGE_FLAGS #endif -#if defined(CONFIG_NUMA_BALANCING ) &&LAST_NID_WIDTH ==0 -#define LAST_NID_NOT_IN_PAGE_FLAGS +#if defined(CONFIG_NUMA_BALANCING ) &&LAST_CPUPID_WIDTH ==0 +#define LAST_CPUPID_NOT_IN_PAGE_FLAGS #endif #endif /* _LINUX_PAGE_FLAGS_LAYOUT */
include/linux/preempt.h +51 -61
167 lines not on this page · raw message
include/linux/sched.h +150 -17
273 lines not on this page · raw message
include/linux/sched/sysctl.h +0 -1
@@ -47,7 +47,6 @@ extern enum sched_tunable_scaling sysctl_sched_tunable_scaling;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_period_reset;extern unsigned int sysctl_numa_balancing_scan_size;extern unsigned int sysctl_numa_balancing_settle_count;
include/linux/stop_machine.h +1 -0
@@ -28,6 +28,7 @@ struct cpu_stop_work { };int stop_one_cpu (unsigned int cpu,cpu_stop_fn_t fn,void *arg); +int stop_two_cpus (unsigned int cpu1,unsigned int cpu2,cpu_stop_fn_t fn,void *arg);void stop_one_cpu_nowait (unsigned int cpu,cpu_stop_fn_t fn,void *arg,struct cpu_stop_work *work_buf);int stop_cpus (const struct cpumask *cpumask,cpu_stop_fn_t fn,void *arg);
include/linux/thread_info.h +15 -2
@@ -104,8 +104,21 @@ static inline int test_ti_thread_flag(struct thread_info *ti, int flag)#define test_thread_flag (flag) \ test_ti_thread_flag(current_thread_info(), flag) -#define set_need_resched () set_thread_flag(TIF_NEED_RESCHED) -#define clear_need_resched () clear_thread_flag(TIF_NEED_RESCHED) +static inline __deprecated void set_need_resched (void ) +{ +/* +* Use of this function in deprecated. +* +* As of this writing there are only a few users in the DRM tree left +* all of which are wrong and can be removed without causing too much +* grief. +* +* The DRM people are aware and are working on removing the last few +* instances. +*/ +} + +#define tif_need_resched () test_thread_flag(TIF_NEED_RESCHED)#if definedTIF_RESTORE_SIGMASK && !definedHAVE_SET_RESTORE_SIGMASK /*
include/linux/topology.h +6 -0
@@ -106,6 +106,8 @@ int arch_update_cpu_topology(void); .last_balance = jiffies, \ .balance_interval = 1, \ .smt_gain = 1178, /* 15% */ \ + .max_newidle_lb_cost = 0, \ + .next_decay_max_lb_cost = jiffies, \ }#endif #endif /* CONFIG_SCHED_SMT */
@@ -135,6 +137,8 @@ int arch_update_cpu_topology(void); , \ .last_balance = jiffies, \ .balance_interval = 1, \ + .max_newidle_lb_cost = 0, \ + .next_decay_max_lb_cost = jiffies, \ }#endif #endif /* CONFIG_SCHED_MC */
@@ -166,6 +170,8 @@ int arch_update_cpu_topology(void); , \ .last_balance = jiffies, \ .balance_interval = 1, \ + .max_newidle_lb_cost = 0, \ + .next_decay_max_lb_cost = jiffies, \ }#endif
include/linux/tty.h +7 -21
@@ -672,31 +672,17 @@ static inline void tty_wait_until_sent_from_close(struct tty_struct *tty,#define wait_event_interruptible_tty (tty, wq, condition) \ ({ \ int __ret = 0; \ - if (!(condition)) { \ - __wait_event_interruptible_tty(tty, wq, condition, __ret); \ - } \ + if (!(condition)) \ + __ret = __wait_event_interruptible_tty(tty, wq, \ + condition); \ __ret; \ }) -#define __wait_event_interruptible_tty (tty, wq, condition, ret) \ -do { \ - DEFINE_WAIT(__wait); \ - \ - for (;;) { \ - prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE); \ - if (condition) \ - break; \ - if (!signal_pending(current)) { \ - tty_unlock(tty); \ +#define __wait_event_interruptible_tty (tty, wq, condition) \ + ___wait_event(wq, condition, TASK_INTERRUPTIBLE, 0, 0, \ + tty_unlock(tty); \ schedule(); \ - tty_lock(tty); \ - continue; \ - } \ - ret = -ERESTARTSYS; \ - break; \ - } \ - finish_wait(&wq, &__wait); \ -} while (0) + tty_lock(tty))#ifdef CONFIG_PROC_FS extern void proc_tty_register_driver (struct tty_driver *);
include/linux/uaccess.h +2 -6
@@ -15,7 +15,7 @@*/ static inline void pagefault_disable (void ) { -inc_preempt_count (); +preempt_count_inc ();/* * make sure to have issued the store before a pagefault * can hit.
@@ -30,11 +30,7 @@ static inline void pagefault_enable(void)* the pagefault handler again. */ barrier (); -dec_preempt_count (); -/* -* make sure we do.. -*/ -barrier (); +preempt_count_dec ();preempt_check_resched (); }
include/linux/wait.h +141 -233
588 lines not on this page · raw message
include/trace/events/sched.h +1 -1
@@ -100,7 +100,7 @@ static inline long __trace_sched_switch_state(struct task_struct *p)/* * For all intents and purposes a preempted task is a running task. */ -if (task_thread_info (p)->preempt_count &PREEMPT_ACTIVE ) +if (task_preempt_count (p) &PREEMPT_ACTIVE ) state =TASK_RUNNING |TASK_STATE_MAX ;#endif
init/main.c +1 -1
@@ -693,7 +693,7 @@ int __init_or_module do_one_initcall(initcall_t fn)if (preempt_count () != count) {sprintf (msgbuf,"preemption imbalance " ); -preempt_count () = count; +preempt_count_set (count); }if (irqs_disabled ()) {strlcat (msgbuf,"disabled interrupts " ,sizeof (msgbuf));
kernel/Makefile +1 -1
@@ -7,7 +7,7 @@ obj-y = fork.o exec_domain.o panic.o \ sysctl.o sysctl_binary.o capability.o ptrace.o timer.o user.o \ signal.o sys.o kmod.o workqueue.o pid.o task_work.o \ rcupdate.o extable.o params.o posix-timers.o \ - kthread.o wait.o sys_ni.o posix-cpu-timers.o mutex.o \ + kthread.o sys_ni.o posix-cpu-timers.o mutex.o \ hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ notifier.o ksysfs.o cred.o reboot.o \ async.o range.o groups.o lglock.o smpboot.o
kernel/bounds.c +4 -0
@@ -10,6 +10,7 @@#include <linux/mmzone.h> #include <linux/kbuild.h> #include <linux/page_cgroup.h> +#include <linux/log2.h> void foo (void ) {
@@ -17,5 +18,8 @@ void foo(void)DEFINE (NR_PAGEFLAGS , __NR_PAGEFLAGS);DEFINE (MAX_NR_ZONES , __MAX_NR_ZONES);DEFINE (NR_PCG_FLAGS , __NR_PCG_FLAGS); +#ifdef CONFIG_SMP +DEFINE (NR_CPUS_BITS ,ilog2 (CONFIG_NR_CPUS )); +#endif /* End of constants */ }
kernel/context_tracking.c +1 -1
@@ -120,7 +120,7 @@ void context_tracking_user_enter(void)* instead of preempt_schedule() to exit user context if needed before * calling the scheduler. */ -void __sched notrace preempt_schedule_context(void) +asmlinkage void __sched notrace preempt_schedule_context(void) {enum ctx_state prev_ctx;
kernel/cpu.c +17 -0
@@ -308,6 +308,23 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) }smpboot_park_threads (cpu); +/* +* By now we've cleared cpu_active_mask, wait for all preempt-disabled +* and RCU users of this state to go away such that all new such users +* will observe it. +* +* For CONFIG_PREEMPT we have preemptible RCU and its sync_rcu() might +* not imply sync_sched(), so explicitly call both. +*/ +#ifdef CONFIG_PREEMPT +synchronize_sched (); +#endif +synchronize_rcu (); + +/* +* So now all preempt/rcu users must observe !cpu_active(). +*/ + err =__stop_machine (take_cpu_down, &tcd_param,cpumask_of (cpu));if (err) {/* CPU didn't die: tell everyone. Can't complain. */
kernel/cpu/idle.c +11 -5
@@ -44,7 +44,7 @@ static inline int cpu_idle_poll(void)rcu_idle_enter ();trace_cpu_idle_rcuidle (0 ,smp_processor_id ());local_irq_enable (); -while (!need_resched ()) +while (!tif_need_resched ())cpu_relax ();trace_cpu_idle_rcuidle (PWR_EVENT_EXIT ,smp_processor_id ());rcu_idle_exit ();
@@ -92,8 +92,7 @@ static void cpu_idle_loop(void)if (cpu_idle_force_poll ||tick_check_broadcast_expired ()) {cpu_idle_poll (); }else { -current_clr_polling (); -if (!need_resched ()) { +if (!current_clr_polling_and_test ()) {stop_critical_timings ();rcu_idle_enter ();arch_cpu_idle ();
@@ -103,9 +102,16 @@ static void cpu_idle_loop(void) }else {local_irq_enable (); } -current_set_polling (); +__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 (); }tick_nohz_idle_exit ();schedule_preempt_disabled ();
@@ -129,7 +135,7 @@ void cpu_startup_entry(enum cpuhp_state state)*/ boot_init_stack_canary ();#endif -current_set_polling (); +__current_set_polling ();arch_cpu_idle_prepare ();cpu_idle_loop (); }
kernel/fork.c +1 -4
@@ -817,9 +817,6 @@ struct mm_struct *dup_mm(struct task_struct *tsk)#ifdef CONFIG_TRANSPARENT_HUGEPAGE mm->pmd_huge_pte =NULL ;#endif -#ifdef CONFIG_NUMA_BALANCING - mm->first_nid =NUMA_PTE_SCAN_INIT ; -#endif if (!mm_init (mm, tsk)) goto fail_nomem;
@@ -1313,7 +1310,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,#endif /* Perform scheduler related setup. Assign this task to a CPU. */ -sched_fork (p); +sched_fork (clone_flags, p); retval =perf_event_init_task (p);if (retval)
kernel/rcutree.c +14 -1
@@ -898,6 +898,12 @@ static void print_other_cpu_stall(struct rcu_state *rsp)force_quiescent_state (rsp);/* Kick them all. */ } +/* +* This function really isn't for public consumption, but RCU is special in +* that context switches can allow the state machine to make progress. +*/ +extern void resched_cpu (int cpu); +static void print_cpu_stall (struct rcu_state *rsp) {int cpu;
@@ -927,7 +933,14 @@ static void print_cpu_stall(struct rcu_state *rsp)3 *rcu_jiffies_till_stall_check () +3 ;raw_spin_unlock_irqrestore (&rnp->lock, flags); -set_need_resched ();/* kick ourselves to get things going. */ +/* +* Attempt to revive the RCU machinery by forcing a context switch. +* +* A context switch would normally allow the RCU state machine to make +* progress and it could be we're stuck in kernel space without context +* switches for an entirely unreasonable amount of time. +*/ +resched_cpu (smp_processor_id ()); }static void check_cpu_stall (struct rcu_state *rsp,struct rcu_data *rdp)
kernel/sched/Makefile +1 -0
@@ -12,6 +12,7 @@ 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 += wait.o completion.o obj-$(CONFIG_SMP) += cpupri.o obj-$(CONFIG_SCHED_AUTOGROUP) += auto_group.o obj-$(CONFIG_SCHEDSTATS) += stats.o
kernel/sched/completion.c new file +299 -0
255 lines not on this page · raw message
kernel/sched/core.c +234 -449
683 lines not on this page · raw message
kernel/sched/debug.c +66 -2
68 lines not on this page · raw message
kernel/sched/fair.c +1193 -204
1,397 lines not on this page · raw message
kernel/sched/sched.h +52 -2
54 lines not on this page · raw message
kernel/sched/stats.h +24 -22
46 lines not on this page · raw message
kernel/sched/wait.c renamed from kernel/wait.c +127 -0
127 lines not on this page · raw message
kernel/stop_machine.c +203 -100
303 lines not on this page · raw message
mm/huge_memory.c +44 -11
55 lines not on this page · raw message
mm/memory.c +42 -97
139 lines not on this page · raw message
mm/mempolicy.c +78 -4
82 lines not on this page · raw message
mm/mprotect.c +19 -46
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.