Skip to contentSkip to conversation

scheduler changes for v3.13

GIT PULL Ingo Molnar 1 participant 1 message Nov 11, 2013

Subsystems (46)
lore
Share & tools
lore
#0 lore raw

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
index 9d4c1d1..4273b2d 100644
@@ -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
index ea2d35d..bd36598 100644
@@ -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
index 3438384..dcd69cb 100644
@@ -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
index a6e85f44..f01fb50 100644
@@ -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
index d8dd660..5943f7f 100644
@@ -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
index 59ceae8..1a7024b 100644
@@ -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
index 79a642d..519f89f 100644
@@ -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
index fd79807..658001b 100644
@@ -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
index 127826f..f2b4347 100644
@@ -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
index e49f918..fc0b3c3 100644
@@ -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
index c832545..b06caf6 100644
@@ -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
index c5d7670..74742dc 100644
@@ -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
index 8ada3cf..7e0e721 100644
@@ -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
index 1da17ca..67c3450 100644
@@ -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
index a3456f3..f93ee08 100644
@@ -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
\ No newline at end of file
arch/m32r/include/asm/Kbuild +1 -0
index bebdc36..2b58c5f 100644
@@ -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
index 09d77a8..a5d27f2 100644
@@ -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
index 6ae0ccb..84d0c1d 100644
@@ -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
index 23f5118..8e9c0b3 100644
@@ -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
index d3c51a6..ce0bbf8 100644
@@ -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
index 454ddf9..1acbb8b 100644
@@ -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
index d763f11..2c12ea1 100644
@@ -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
index e205ef5..1215617 100644
@@ -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
index c5d7670..74742dc 100644
@@ -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
index 195653e..7840562 100644
@@ -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
index ff4c9fa..a603b9e 100644
@@ -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
index 704e6f1..d8f9d2f 100644
@@ -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
\ No newline at end of file
arch/s390/include/asm/Kbuild +1 -0
index f313f9c..7a5288f 100644
@@ -2,3 +2,4 @@
 
 generic-y += clkdev.h
 generic-y += trace_clock.h
+generic-y += preempt.h
arch/score/include/asm/Kbuild +1 -0
index e1c7bb9..f3414ad 100644
@@ -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
index 280bea9..231efbb 100644
@@ -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
index 7e4a97f..bf39066 100644
@@ -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
index 664d6ad..22f3bd1 100644
@@ -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
index b30f34a..fdde187 100644
@@ -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
index 89d8b6c..00045cb 100644
@@ -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
index 722aa3b..da31c8b 100644
@@ -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;
-
-	asm volatile(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;
-
-	asm volatile(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;
-
-	asm volatile(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;
-
-	asm volatile(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
index 0e1cbfc..3f065c9 100644
@@ -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;
-
-	asm volatile(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;
-
-	asm volatile(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;
-
-	asm volatile(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;
-
-	asm volatile(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
index 41639ce..6d76d09 100644
@@ -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;
-
-	asm volatile(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;
-
-	asm volatile(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;
-
-	asm volatile(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
index 2d89e39..5b23e60 100644
@@ -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;
-
-	asm volatile(_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;
-
-	asm volatile(_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;
-
-	asm volatile(_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;
-
-	asm volatile(_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
index 2781119..c46a46b 100644
@@ -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
index a5408b9..9b0a34e 100644
@@ -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
index 2861082..9f6b934 100644
@@ -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
index 2793d1f..5223fe6 100644
@@ -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
index f0dcb0c..fd1bc1b 100644
@@ -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
index b077f4c..1a2cc64 100644
@@ -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
index 0fa6912..05fd74f 100644
@@ -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
index 4186755..3fe0663 100644
@@ -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
new file mode 100644
index 0000000..ca7f0d5
@@ -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
index c83516b..3fb8d95 100644
@@ -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
index 884f98f..c2ec1aa 100644
@@ -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
index bb1dc51..45ab4d6 100644
@@ -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
index 8c8093b..729aa77 100644
@@ -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
index b014d94..0406819 100644
@@ -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
index 1b98264..228d6ae 100644
@@ -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
index fa6964d..f116d66 100644
@@ -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 *)&current_thread_info()->flags, 0, 0);
 		smp_mb();
fs/exec.c +1 -0
index 8875dd1..2ea437e 100644
@@ -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
index cbd0f1b..1bd2077 100644
@@ -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
index 3cd574d..22c33e3 100644
@@ -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
index 1e04106..d9cf963 100644
@@ -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
index da6716b..ea4d249 100644
@@ -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
index 8d3c57f..f5096b5 100644
@@ -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
index d9851ee..a3198e5 100644
@@ -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
index 93506a1..da52366 100644
@@ -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
index bf8086b..10d16c4f 100644
@@ -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
index 3b5e910..d2abbdb 100644
@@ -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
index e7e0473..fddbe20 100644
@@ -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 defined TIF_RESTORE_SIGMASK && !defined HAVE_SET_RESTORE_SIGMASK
 /*
include/linux/topology.h +6 -0
index d3cf0d6..12ae6ce 100644
@@ -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
index 64f8646..633cac7 100644
@@ -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
index 5ca0951..9d8cf05 100644
@@ -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
index 2e7d994..613381b 100644
@@ -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
index 63d3e8f..379090f 100644
@@ -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
index 1ce4755..b3d51e2 100644
@@ -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
index 0c9b862..e8ca97b 100644
@@ -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
index 859c8df..e5f3917 100644
@@ -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
index d7f07a2..63aa50d 100644
@@ -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
index e695c0a..988573a 100644
@@ -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
index 086fe73..c93be06 100644
@@ -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
index 32618b3..1dc9f36 100644
@@ -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
index 54adcf3..7b62140 100644
@@ -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/features.h +16 -3
index 99399f8..5716929 100644

Lines of this file are not shown. View the raw message.

kernel/sched/idle_task.c +1 -1
index d8da010..516c3d9 100644

Lines of this file are not shown. View the raw message.

kernel/sched/rt.c +13 -9
index 01970c8..7d57275 100644

Lines of this file are not shown. View the 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/stop_task.c +1 -1
index e08fbee..47197de 100644

Lines of this file are not shown. View the raw message.

kernel/sched/wait.c renamed from kernel/wait.c +127 -0

127 lines not on this page · raw message

kernel/softirq.c +8 -8
index d7d498d..dcab1d3 100644

Lines of this file are not shown. View the raw message.

kernel/stop_machine.c +203 -100

303 lines not on this page · raw message

kernel/sysctl.c +14 -7
index b2f06f3..a159e1f 100644

Lines of this file are not shown. View the raw message.

kernel/timer.c +4 -4
index 4296d13..6582b82 100644

Lines of this file are not shown. View the raw message.

kernel/trace/trace.c +2 -1
index 7974ba2..d9fea7d 100644

Lines of this file are not shown. View the raw message.

kernel/trace/trace.h +1 -0
index 10c86fb..73d08aa 100644

Lines of this file are not shown. View the raw message.

kernel/trace/trace_output.c +17 -2
index 34e7cba..ed32284 100644

Lines of this file are not shown. View the raw message.

lib/locking-selftest.c +1 -1
index 6dc09d8..872a15a 100644

Lines of this file are not shown. View the raw message.

lib/smp_processor_id.c +1 -2
index 4c0d0e5..04abe53 100644

Lines of this file are not shown. View the 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/migrate.c +17 -13
index c046927..dfc8300 100644

Lines of this file are not shown. View the raw message.

mm/mm_init.c +9 -9
index 633c088..68562e9 100644

Lines of this file are not shown. View the raw message.

mm/mmzone.c +7 -7
index 2ac0afb..bf34fb8 100644

Lines of this file are not shown. View the raw message.

mm/mprotect.c +19 -46

65 lines not on this page · raw message

mm/page_alloc.c +2 -2
index dd886fa..73d812f 100644

Lines of this file are not shown. View the raw message.

net/irda/af_irda.c +2 -3
index 0578d4f..0f67690 100644

Lines of this file are not shown. View the raw message.

net/netfilter/ipvs/ip_vs_sync.c +2 -5
index f448471..f63c238 100644

Lines of this file are not shown. View the 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.