diff -Nur linux-3.18.8.orig/arch/alpha/mm/fault.c linux-3.18.8/arch/alpha/mm/fault.c --- linux-3.18.8.orig/arch/alpha/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/alpha/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 @@ -107,7 +107,7 @@ /* If we're in an interrupt context, or have no user context, we must not take the fault. */ - if (!mm || in_atomic()) + if (!mm || pagefault_disabled()) goto no_context; #ifdef CONFIG_ALPHA_LARGE_VMALLOC diff -Nur linux-3.18.8.orig/arch/arm/include/asm/cmpxchg.h linux-3.18.8/arch/arm/include/asm/cmpxchg.h --- linux-3.18.8.orig/arch/arm/include/asm/cmpxchg.h 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/include/asm/cmpxchg.h 2015-03-03 08:05:17.000000000 +0100 @@ -129,6 +129,8 @@ #else /* min ARCH >= ARMv6 */ +#define __HAVE_ARCH_CMPXCHG 1 + extern void __bad_cmpxchg(volatile void *ptr, int size); /* diff -Nur linux-3.18.8.orig/arch/arm/include/asm/futex.h linux-3.18.8/arch/arm/include/asm/futex.h --- linux-3.18.8.orig/arch/arm/include/asm/futex.h 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/include/asm/futex.h 2015-03-03 08:05:17.000000000 +0100 @@ -93,6 +93,8 @@ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) return -EFAULT; + preempt_disable_rt(); + __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" "1: " TUSER(ldr) " %1, [%4]\n" " teq %1, %2\n" @@ -104,6 +106,8 @@ : "cc", "memory"); *uval = val; + + preempt_enable_rt(); return ret; } diff -Nur linux-3.18.8.orig/arch/arm/include/asm/switch_to.h linux-3.18.8/arch/arm/include/asm/switch_to.h --- linux-3.18.8.orig/arch/arm/include/asm/switch_to.h 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/include/asm/switch_to.h 2015-03-03 08:05:17.000000000 +0100 @@ -3,6 +3,13 @@ #include +#if defined CONFIG_PREEMPT_RT_FULL && defined CONFIG_HIGHMEM +void switch_kmaps(struct task_struct *prev_p, struct task_struct *next_p); +#else +static inline void +switch_kmaps(struct task_struct *prev_p, struct task_struct *next_p) { } +#endif + /* * For v7 SMP cores running a preemptible kernel we may be pre-empted * during a TLB maintenance operation, so execute an inner-shareable dsb @@ -22,6 +29,7 @@ #define switch_to(prev,next,last) \ do { \ + switch_kmaps(prev, next); \ last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \ } while (0) diff -Nur linux-3.18.8.orig/arch/arm/include/asm/thread_info.h linux-3.18.8/arch/arm/include/asm/thread_info.h --- linux-3.18.8.orig/arch/arm/include/asm/thread_info.h 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/include/asm/thread_info.h 2015-03-03 08:05:17.000000000 +0100 @@ -51,6 +51,7 @@ struct thread_info { unsigned long flags; /* low level flags */ int preempt_count; /* 0 => preemptable, <0 => bug */ + int preempt_lazy_count; /* 0 => preemptable, <0 => bug */ mm_segment_t addr_limit; /* address limit */ struct task_struct *task; /* main task structure */ struct exec_domain *exec_domain; /* execution domain */ @@ -149,6 +150,7 @@ #define TIF_SIGPENDING 0 #define TIF_NEED_RESCHED 1 #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ +#define TIF_NEED_RESCHED_LAZY 3 #define TIF_UPROBE 7 #define TIF_SYSCALL_TRACE 8 #define TIF_SYSCALL_AUDIT 9 @@ -162,6 +164,7 @@ #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) +#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY) #define _TIF_UPROBE (1 << TIF_UPROBE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) diff -Nur linux-3.18.8.orig/arch/arm/Kconfig linux-3.18.8/arch/arm/Kconfig --- linux-3.18.8.orig/arch/arm/Kconfig 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/Kconfig 2015-03-03 08:05:17.000000000 +0100 @@ -62,6 +62,7 @@ select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP + select HAVE_PREEMPT_LAZY select HAVE_RCU_TABLE_FREE if (SMP && ARM_LPAE) select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_SYSCALL_TRACEPOINTS diff -Nur linux-3.18.8.orig/arch/arm/kernel/asm-offsets.c linux-3.18.8/arch/arm/kernel/asm-offsets.c --- linux-3.18.8.orig/arch/arm/kernel/asm-offsets.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/kernel/asm-offsets.c 2015-03-03 08:05:17.000000000 +0100 @@ -64,6 +64,7 @@ BLANK(); DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); + DEFINE(TI_PREEMPT_LAZY, offsetof(struct thread_info, preempt_lazy_count)); DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit)); DEFINE(TI_TASK, offsetof(struct thread_info, task)); DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain)); diff -Nur linux-3.18.8.orig/arch/arm/kernel/entry-armv.S linux-3.18.8/arch/arm/kernel/entry-armv.S --- linux-3.18.8.orig/arch/arm/kernel/entry-armv.S 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/kernel/entry-armv.S 2015-03-03 08:05:17.000000000 +0100 @@ -207,11 +207,18 @@ #ifdef CONFIG_PREEMPT get_thread_info tsk ldr r8, [tsk, #TI_PREEMPT] @ get preempt count - ldr r0, [tsk, #TI_FLAGS] @ get flags teq r8, #0 @ if preempt count != 0 + bne 1f @ return from exeption + ldr r0, [tsk, #TI_FLAGS] @ get flags + tst r0, #_TIF_NEED_RESCHED @ if NEED_RESCHED is set + blne svc_preempt @ preempt! + + ldr r8, [tsk, #TI_PREEMPT_LAZY] @ get preempt lazy count + teq r8, #0 @ if preempt lazy count != 0 movne r0, #0 @ force flags to 0 - tst r0, #_TIF_NEED_RESCHED + tst r0, #_TIF_NEED_RESCHED_LAZY blne svc_preempt +1: #endif svc_exit r5, irq = 1 @ return from exception @@ -226,6 +233,8 @@ 1: bl preempt_schedule_irq @ irq en/disable is done inside ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS tst r0, #_TIF_NEED_RESCHED + bne 1b + tst r0, #_TIF_NEED_RESCHED_LAZY reteq r8 @ go again b 1b #endif diff -Nur linux-3.18.8.orig/arch/arm/kernel/process.c linux-3.18.8/arch/arm/kernel/process.c --- linux-3.18.8.orig/arch/arm/kernel/process.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/kernel/process.c 2015-03-03 08:05:17.000000000 +0100 @@ -431,6 +431,30 @@ } #ifdef CONFIG_MMU +/* + * CONFIG_SPLIT_PTLOCK_CPUS results in a page->ptl lock. If the lock is not + * initialized by pgtable_page_ctor() then a coredump of the vector page will + * fail. + */ +static int __init vectors_user_mapping_init_page(void) +{ + struct page *page; + unsigned long addr = 0xffff0000; + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + + pgd = pgd_offset_k(addr); + pud = pud_offset(pgd, addr); + pmd = pmd_offset(pud, addr); + page = pmd_page(*(pmd)); + + pgtable_page_ctor(page); + + return 0; +} +late_initcall(vectors_user_mapping_init_page); + #ifdef CONFIG_KUSER_HELPERS /* * The vectors page is always readable from user space for the diff -Nur linux-3.18.8.orig/arch/arm/kernel/signal.c linux-3.18.8/arch/arm/kernel/signal.c --- linux-3.18.8.orig/arch/arm/kernel/signal.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/kernel/signal.c 2015-03-03 08:05:17.000000000 +0100 @@ -574,7 +574,8 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall) { do { - if (likely(thread_flags & _TIF_NEED_RESCHED)) { + if (likely(thread_flags & (_TIF_NEED_RESCHED | + _TIF_NEED_RESCHED_LAZY))) { schedule(); } else { if (unlikely(!user_mode(regs))) diff -Nur linux-3.18.8.orig/arch/arm/kernel/smp.c linux-3.18.8/arch/arm/kernel/smp.c --- linux-3.18.8.orig/arch/arm/kernel/smp.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/kernel/smp.c 2015-03-03 08:05:17.000000000 +0100 @@ -506,12 +506,14 @@ } #ifdef CONFIG_IRQ_WORK +#ifndef CONFIG_PREEMPT_RT_FULL void arch_irq_work_raise(void) { if (arch_irq_work_has_interrupt()) smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); } #endif +#endif #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST void tick_broadcast(const struct cpumask *mask) diff -Nur linux-3.18.8.orig/arch/arm/kernel/unwind.c linux-3.18.8/arch/arm/kernel/unwind.c --- linux-3.18.8.orig/arch/arm/kernel/unwind.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/kernel/unwind.c 2015-03-03 08:05:17.000000000 +0100 @@ -93,7 +93,7 @@ static const struct unwind_idx *__origin_unwind_idx; extern const struct unwind_idx __stop_unwind_idx[]; -static DEFINE_SPINLOCK(unwind_lock); +static DEFINE_RAW_SPINLOCK(unwind_lock); static LIST_HEAD(unwind_tables); /* Convert a prel31 symbol to an absolute address */ @@ -201,7 +201,7 @@ /* module unwind tables */ struct unwind_table *table; - spin_lock_irqsave(&unwind_lock, flags); + raw_spin_lock_irqsave(&unwind_lock, flags); list_for_each_entry(table, &unwind_tables, list) { if (addr >= table->begin_addr && addr < table->end_addr) { @@ -213,7 +213,7 @@ break; } } - spin_unlock_irqrestore(&unwind_lock, flags); + raw_spin_unlock_irqrestore(&unwind_lock, flags); } pr_debug("%s: idx = %p\n", __func__, idx); @@ -530,9 +530,9 @@ tab->begin_addr = text_addr; tab->end_addr = text_addr + text_size; - spin_lock_irqsave(&unwind_lock, flags); + raw_spin_lock_irqsave(&unwind_lock, flags); list_add_tail(&tab->list, &unwind_tables); - spin_unlock_irqrestore(&unwind_lock, flags); + raw_spin_unlock_irqrestore(&unwind_lock, flags); return tab; } @@ -544,9 +544,9 @@ if (!tab) return; - spin_lock_irqsave(&unwind_lock, flags); + raw_spin_lock_irqsave(&unwind_lock, flags); list_del(&tab->list); - spin_unlock_irqrestore(&unwind_lock, flags); + raw_spin_unlock_irqrestore(&unwind_lock, flags); kfree(tab); } diff -Nur linux-3.18.8.orig/arch/arm/mach-at91/at91rm9200_time.c linux-3.18.8/arch/arm/mach-at91/at91rm9200_time.c --- linux-3.18.8.orig/arch/arm/mach-at91/at91rm9200_time.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/mach-at91/at91rm9200_time.c 2015-03-03 08:05:17.000000000 +0100 @@ -135,6 +135,7 @@ break; case CLOCK_EVT_MODE_SHUTDOWN: case CLOCK_EVT_MODE_UNUSED: + remove_irq(NR_IRQS_LEGACY + AT91_ID_SYS, &at91rm9200_timer_irq); case CLOCK_EVT_MODE_RESUME: irqmask = 0; break; diff -Nur linux-3.18.8.orig/arch/arm/mach-exynos/platsmp.c linux-3.18.8/arch/arm/mach-exynos/platsmp.c --- linux-3.18.8.orig/arch/arm/mach-exynos/platsmp.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/mach-exynos/platsmp.c 2015-03-03 08:05:17.000000000 +0100 @@ -137,7 +137,7 @@ return (void __iomem *)(S5P_VA_SCU); } -static DEFINE_SPINLOCK(boot_lock); +static DEFINE_RAW_SPINLOCK(boot_lock); static void exynos_secondary_init(unsigned int cpu) { @@ -150,8 +150,8 @@ /* * Synchronise with the boot thread. */ - spin_lock(&boot_lock); - spin_unlock(&boot_lock); + raw_spin_lock(&boot_lock); + raw_spin_unlock(&boot_lock); } static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) @@ -165,7 +165,7 @@ * Set synchronisation state between this boot processor * and the secondary one */ - spin_lock(&boot_lock); + raw_spin_lock(&boot_lock); /* * The secondary processor is waiting to be released from @@ -192,7 +192,7 @@ if (timeout == 0) { printk(KERN_ERR "cpu1 power enable failed"); - spin_unlock(&boot_lock); + raw_spin_unlock(&boot_lock); return -ETIMEDOUT; } } @@ -242,7 +242,7 @@ * calibrations, then wait for it to finish */ fail: - spin_unlock(&boot_lock); + raw_spin_unlock(&boot_lock); return pen_release != -1 ? ret : 0; } diff -Nur linux-3.18.8.orig/arch/arm/mach-hisi/platmcpm.c linux-3.18.8/arch/arm/mach-hisi/platmcpm.c --- linux-3.18.8.orig/arch/arm/mach-hisi/platmcpm.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/mach-hisi/platmcpm.c 2015-03-03 08:05:17.000000000 +0100 @@ -57,7 +57,7 @@ static void __iomem *sysctrl, *fabric; static int hip04_cpu_table[HIP04_MAX_CLUSTERS][HIP04_MAX_CPUS_PER_CLUSTER]; -static DEFINE_SPINLOCK(boot_lock); +static DEFINE_RAW_SPINLOCK(boot_lock); static u32 fabric_phys_addr; /* * [0]: bootwrapper physical address @@ -104,7 +104,7 @@ if (cluster >= HIP04_MAX_CLUSTERS || cpu >= HIP04_MAX_CPUS_PER_CLUSTER) return -EINVAL; - spin_lock_irq(&boot_lock); + raw_spin_lock_irq(&boot_lock); if (hip04_cpu_table[cluster][cpu]) goto out; @@ -133,7 +133,7 @@ udelay(20); out: hip04_cpu_table[cluster][cpu]++; - spin_unlock_irq(&boot_lock); + raw_spin_unlock_irq(&boot_lock); return 0; } @@ -149,7 +149,7 @@ __mcpm_cpu_going_down(cpu, cluster); - spin_lock(&boot_lock); + raw_spin_lock(&boot_lock); BUG_ON(__mcpm_cluster_state(cluster) != CLUSTER_UP); hip04_cpu_table[cluster][cpu]--; if (hip04_cpu_table[cluster][cpu] == 1) { @@ -162,7 +162,7 @@ last_man = hip04_cluster_is_down(cluster); if (last_man && __mcpm_outbound_enter_critical(cpu, cluster)) { - spin_unlock(&boot_lock); + raw_spin_unlock(&boot_lock); /* Since it's Cortex A15, disable L2 prefetching. */ asm volatile( "mcr p15, 1, %0, c15, c0, 3 \n\t" @@ -173,7 +173,7 @@ hip04_set_snoop_filter(cluster, 0); __mcpm_outbound_leave_critical(cluster, CLUSTER_DOWN); } else { - spin_unlock(&boot_lock); + raw_spin_unlock(&boot_lock); v7_exit_coherency_flush(louis); } @@ -192,7 +192,7 @@ cpu >= HIP04_MAX_CPUS_PER_CLUSTER); count = TIMEOUT_MSEC / POLL_MSEC; - spin_lock_irq(&boot_lock); + raw_spin_lock_irq(&boot_lock); for (tries = 0; tries < count; tries++) { if (hip04_cpu_table[cluster][cpu]) { ret = -EBUSY; @@ -202,10 +202,10 @@ data = readl_relaxed(sysctrl + SC_CPU_RESET_STATUS(cluster)); if (data & CORE_WFI_STATUS(cpu)) break; - spin_unlock_irq(&boot_lock); + raw_spin_unlock_irq(&boot_lock); /* Wait for clean L2 when the whole cluster is down. */ msleep(POLL_MSEC); - spin_lock_irq(&boot_lock); + raw_spin_lock_irq(&boot_lock); } if (tries >= count) goto err; @@ -220,10 +220,10 @@ } if (tries >= count) goto err; - spin_unlock_irq(&boot_lock); + raw_spin_unlock_irq(&boot_lock); return 0; err: - spin_unlock_irq(&boot_lock); + raw_spin_unlock_irq(&boot_lock); return ret; } @@ -235,10 +235,10 @@ cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); - spin_lock(&boot_lock); + raw_spin_lock(&boot_lock); if (!hip04_cpu_table[cluster][cpu]) hip04_cpu_table[cluster][cpu] = 1; - spin_unlock(&boot_lock); + raw_spin_unlock(&boot_lock); } static void __naked hip04_mcpm_power_up_setup(unsigned int affinity_level) diff -Nur linux-3.18.8.orig/arch/arm/mach-omap2/omap-smp.c linux-3.18.8/arch/arm/mach-omap2/omap-smp.c --- linux-3.18.8.orig/arch/arm/mach-omap2/omap-smp.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/mach-omap2/omap-smp.c 2015-03-03 08:05:17.000000000 +0100 @@ -43,7 +43,7 @@ /* SCU base address */ static void __iomem *scu_base; -static DEFINE_SPINLOCK(boot_lock); +static DEFINE_RAW_SPINLOCK(boot_lock); void __iomem *omap4_get_scu_base(void) { @@ -74,8 +74,8 @@ /* * Synchronise with the boot thread. */ - spin_lock(&boot_lock); - spin_unlock(&boot_lock); + raw_spin_lock(&boot_lock); + raw_spin_unlock(&boot_lock); } static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle) @@ -89,7 +89,7 @@ * Set synchronisation state between this boot processor * and the secondary one */ - spin_lock(&boot_lock); + raw_spin_lock(&boot_lock); /* * Update the AuxCoreBoot0 with boot state for secondary core. @@ -166,7 +166,7 @@ * Now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ - spin_unlock(&boot_lock); + raw_spin_unlock(&boot_lock); return 0; } diff -Nur linux-3.18.8.orig/arch/arm/mach-prima2/platsmp.c linux-3.18.8/arch/arm/mach-prima2/platsmp.c --- linux-3.18.8.orig/arch/arm/mach-prima2/platsmp.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/mach-prima2/platsmp.c 2015-03-03 08:05:17.000000000 +0100 @@ -23,7 +23,7 @@ static void __iomem *scu_base; static void __iomem *rsc_base; -static DEFINE_SPINLOCK(boot_lock); +static DEFINE_RAW_SPINLOCK(boot_lock); static struct map_desc scu_io_desc __initdata = { .length = SZ_4K, @@ -56,8 +56,8 @@ /* * Synchronise with the boot thread. */ - spin_lock(&boot_lock); - spin_unlock(&boot_lock); + raw_spin_lock(&boot_lock); + raw_spin_unlock(&boot_lock); } static struct of_device_id rsc_ids[] = { @@ -95,7 +95,7 @@ /* make sure write buffer is drained */ mb(); - spin_lock(&boot_lock); + raw_spin_lock(&boot_lock); /* * The secondary processor is waiting to be released from @@ -127,7 +127,7 @@ * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ - spin_unlock(&boot_lock); + raw_spin_unlock(&boot_lock); return pen_release != -1 ? -ENOSYS : 0; } diff -Nur linux-3.18.8.orig/arch/arm/mach-qcom/platsmp.c linux-3.18.8/arch/arm/mach-qcom/platsmp.c --- linux-3.18.8.orig/arch/arm/mach-qcom/platsmp.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/mach-qcom/platsmp.c 2015-03-03 08:05:17.000000000 +0100 @@ -46,7 +46,7 @@ extern void secondary_startup(void); -static DEFINE_SPINLOCK(boot_lock); +static DEFINE_RAW_SPINLOCK(boot_lock); #ifdef CONFIG_HOTPLUG_CPU static void __ref qcom_cpu_die(unsigned int cpu) @@ -60,8 +60,8 @@ /* * Synchronise with the boot thread. */ - spin_lock(&boot_lock); - spin_unlock(&boot_lock); + raw_spin_lock(&boot_lock); + raw_spin_unlock(&boot_lock); } static int scss_release_secondary(unsigned int cpu) @@ -284,7 +284,7 @@ * set synchronisation state between this boot processor * and the secondary one */ - spin_lock(&boot_lock); + raw_spin_lock(&boot_lock); /* * Send the secondary CPU a soft interrupt, thereby causing @@ -297,7 +297,7 @@ * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ - spin_unlock(&boot_lock); + raw_spin_unlock(&boot_lock); return ret; } diff -Nur linux-3.18.8.orig/arch/arm/mach-spear/platsmp.c linux-3.18.8/arch/arm/mach-spear/platsmp.c --- linux-3.18.8.orig/arch/arm/mach-spear/platsmp.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/mach-spear/platsmp.c 2015-03-03 08:05:17.000000000 +0100 @@ -32,7 +32,7 @@ sync_cache_w(&pen_release); } -static DEFINE_SPINLOCK(boot_lock); +static DEFINE_RAW_SPINLOCK(boot_lock); static void __iomem *scu_base = IOMEM(VA_SCU_BASE); @@ -47,8 +47,8 @@ /* * Synchronise with the boot thread. */ - spin_lock(&boot_lock); - spin_unlock(&boot_lock); + raw_spin_lock(&boot_lock); + raw_spin_unlock(&boot_lock); } static int spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle) @@ -59,7 +59,7 @@ * set synchronisation state between this boot processor * and the secondary one */ - spin_lock(&boot_lock); + raw_spin_lock(&boot_lock); /* * The secondary processor is waiting to be released from @@ -84,7 +84,7 @@ * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ - spin_unlock(&boot_lock); + raw_spin_unlock(&boot_lock); return pen_release != -1 ? -ENOSYS : 0; } diff -Nur linux-3.18.8.orig/arch/arm/mach-sti/platsmp.c linux-3.18.8/arch/arm/mach-sti/platsmp.c --- linux-3.18.8.orig/arch/arm/mach-sti/platsmp.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/mach-sti/platsmp.c 2015-03-03 08:05:17.000000000 +0100 @@ -34,7 +34,7 @@ sync_cache_w(&pen_release); } -static DEFINE_SPINLOCK(boot_lock); +static DEFINE_RAW_SPINLOCK(boot_lock); static void sti_secondary_init(unsigned int cpu) { @@ -49,8 +49,8 @@ /* * Synchronise with the boot thread. */ - spin_lock(&boot_lock); - spin_unlock(&boot_lock); + raw_spin_lock(&boot_lock); + raw_spin_unlock(&boot_lock); } static int sti_boot_secondary(unsigned int cpu, struct task_struct *idle) @@ -61,7 +61,7 @@ * set synchronisation state between this boot processor * and the secondary one */ - spin_lock(&boot_lock); + raw_spin_lock(&boot_lock); /* * The secondary processor is waiting to be released from @@ -92,7 +92,7 @@ * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ - spin_unlock(&boot_lock); + raw_spin_unlock(&boot_lock); return pen_release != -1 ? -ENOSYS : 0; } diff -Nur linux-3.18.8.orig/arch/arm/mach-ux500/platsmp.c linux-3.18.8/arch/arm/mach-ux500/platsmp.c --- linux-3.18.8.orig/arch/arm/mach-ux500/platsmp.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/mach-ux500/platsmp.c 2015-03-03 08:05:17.000000000 +0100 @@ -51,7 +51,7 @@ return NULL; } -static DEFINE_SPINLOCK(boot_lock); +static DEFINE_RAW_SPINLOCK(boot_lock); static void ux500_secondary_init(unsigned int cpu) { @@ -64,8 +64,8 @@ /* * Synchronise with the boot thread. */ - spin_lock(&boot_lock); - spin_unlock(&boot_lock); + raw_spin_lock(&boot_lock); + raw_spin_unlock(&boot_lock); } static int ux500_boot_secondary(unsigned int cpu, struct task_struct *idle) @@ -76,7 +76,7 @@ * set synchronisation state between this boot processor * and the secondary one */ - spin_lock(&boot_lock); + raw_spin_lock(&boot_lock); /* * The secondary processor is waiting to be released from @@ -97,7 +97,7 @@ * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ - spin_unlock(&boot_lock); + raw_spin_unlock(&boot_lock); return pen_release != -1 ? -ENOSYS : 0; } diff -Nur linux-3.18.8.orig/arch/arm/mm/fault.c linux-3.18.8/arch/arm/mm/fault.c --- linux-3.18.8.orig/arch/arm/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 @@ -277,7 +277,7 @@ * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (!mm || pagefault_disabled()) goto no_context; if (user_mode(regs)) @@ -431,6 +431,9 @@ if (addr < TASK_SIZE) return do_page_fault(addr, fsr, regs); + if (interrupts_enabled(regs)) + local_irq_enable(); + if (user_mode(regs)) goto bad_area; @@ -498,6 +501,9 @@ static int do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { + if (interrupts_enabled(regs)) + local_irq_enable(); + do_bad_area(addr, fsr, regs); return 0; } diff -Nur linux-3.18.8.orig/arch/arm/mm/highmem.c linux-3.18.8/arch/arm/mm/highmem.c --- linux-3.18.8.orig/arch/arm/mm/highmem.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/mm/highmem.c 2015-03-03 08:05:17.000000000 +0100 @@ -53,6 +53,7 @@ void *kmap_atomic(struct page *page) { + pte_t pte = mk_pte(page, kmap_prot); unsigned int idx; unsigned long vaddr; void *kmap; @@ -91,7 +92,10 @@ * in place, so the contained TLB flush ensures the TLB is updated * with the new mapping. */ - set_fixmap_pte(idx, mk_pte(page, kmap_prot)); +#ifdef CONFIG_PREEMPT_RT_FULL + current->kmap_pte[type] = pte; +#endif + set_fixmap_pte(idx, pte); return (void *)vaddr; } @@ -108,12 +112,15 @@ if (cache_is_vivt()) __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); +#ifdef CONFIG_PREEMPT_RT_FULL + current->kmap_pte[type] = __pte(0); +#endif #ifdef CONFIG_DEBUG_HIGHMEM BUG_ON(vaddr != __fix_to_virt(idx)); - set_fixmap_pte(idx, __pte(0)); #else (void) idx; /* to kill a warning */ #endif + set_fixmap_pte(idx, __pte(0)); kmap_atomic_idx_pop(); } else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) { /* this address was obtained through kmap_high_get() */ @@ -125,6 +132,7 @@ void *kmap_atomic_pfn(unsigned long pfn) { + pte_t pte = pfn_pte(pfn, kmap_prot); unsigned long vaddr; int idx, type; struct page *page = pfn_to_page(pfn); @@ -139,7 +147,10 @@ #ifdef CONFIG_DEBUG_HIGHMEM BUG_ON(!pte_none(*(fixmap_page_table + idx))); #endif - set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot)); +#ifdef CONFIG_PREEMPT_RT_FULL + current->kmap_pte[type] = pte; +#endif + set_fixmap_pte(idx, pte); return (void *)vaddr; } @@ -153,3 +164,28 @@ return pte_page(get_fixmap_pte(vaddr)); } + +#if defined CONFIG_PREEMPT_RT_FULL +void switch_kmaps(struct task_struct *prev_p, struct task_struct *next_p) +{ + int i; + + /* + * Clear @prev's kmap_atomic mappings + */ + for (i = 0; i < prev_p->kmap_idx; i++) { + int idx = i + KM_TYPE_NR * smp_processor_id(); + + set_fixmap_pte(idx, __pte(0)); + } + /* + * Restore @next_p's kmap_atomic mappings + */ + for (i = 0; i < next_p->kmap_idx; i++) { + int idx = i + KM_TYPE_NR * smp_processor_id(); + + if (!pte_none(next_p->kmap_pte[i])) + set_fixmap_pte(idx, next_p->kmap_pte[i]); + } +} +#endif diff -Nur linux-3.18.8.orig/arch/arm/plat-versatile/platsmp.c linux-3.18.8/arch/arm/plat-versatile/platsmp.c --- linux-3.18.8.orig/arch/arm/plat-versatile/platsmp.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm/plat-versatile/platsmp.c 2015-03-03 08:05:17.000000000 +0100 @@ -30,7 +30,7 @@ sync_cache_w(&pen_release); } -static DEFINE_SPINLOCK(boot_lock); +static DEFINE_RAW_SPINLOCK(boot_lock); void versatile_secondary_init(unsigned int cpu) { @@ -43,8 +43,8 @@ /* * Synchronise with the boot thread. */ - spin_lock(&boot_lock); - spin_unlock(&boot_lock); + raw_spin_lock(&boot_lock); + raw_spin_unlock(&boot_lock); } int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle) @@ -55,7 +55,7 @@ * Set synchronisation state between this boot processor * and the secondary one */ - spin_lock(&boot_lock); + raw_spin_lock(&boot_lock); /* * This is really belt and braces; we hold unintended secondary @@ -85,7 +85,7 @@ * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ - spin_unlock(&boot_lock); + raw_spin_unlock(&boot_lock); return pen_release != -1 ? -ENOSYS : 0; } diff -Nur linux-3.18.8.orig/arch/arm64/kernel/smp.c linux-3.18.8/arch/arm64/kernel/smp.c --- linux-3.18.8.orig/arch/arm64/kernel/smp.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/arm64/kernel/smp.c 2015-03-03 08:05:17.000000000 +0100 @@ -529,12 +529,14 @@ } #ifdef CONFIG_IRQ_WORK +#ifndef CONFIG_PREEMPT_RT_FULL void arch_irq_work_raise(void) { if (__smp_cross_call) smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); } #endif +#endif static DEFINE_RAW_SPINLOCK(stop_lock); diff -Nur linux-3.18.8.orig/arch/avr32/mm/fault.c linux-3.18.8/arch/avr32/mm/fault.c --- linux-3.18.8.orig/arch/avr32/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/avr32/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 @@ -81,7 +81,7 @@ * If we're in an interrupt or have no user context, we must * not take the fault... */ - if (in_atomic() || !mm || regs->sr & SYSREG_BIT(GM)) + if (!mm || regs->sr & SYSREG_BIT(GM) || pagefault_disabled()) goto no_context; local_irq_enable(); diff -Nur linux-3.18.8.orig/arch/cris/mm/fault.c linux-3.18.8/arch/cris/mm/fault.c --- linux-3.18.8.orig/arch/cris/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/cris/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 @@ -113,7 +113,7 @@ * user context, we must not take the fault. */ - if (in_atomic() || !mm) + if (!mm || pagefault_disabled()) goto no_context; if (user_mode(regs)) diff -Nur linux-3.18.8.orig/arch/frv/mm/fault.c linux-3.18.8/arch/frv/mm/fault.c --- linux-3.18.8.orig/arch/frv/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/frv/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 @@ -78,7 +78,7 @@ * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (!mm || pagefault_disabled()) goto no_context; if (user_mode(__frame)) diff -Nur linux-3.18.8.orig/arch/ia64/mm/fault.c linux-3.18.8/arch/ia64/mm/fault.c --- linux-3.18.8.orig/arch/ia64/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/ia64/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 @@ -96,7 +96,7 @@ /* * If we're in an interrupt or have no user context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (!mm || pagefault_disabled()) goto no_context; #ifdef CONFIG_VIRTUAL_MEM_MAP diff -Nur linux-3.18.8.orig/arch/Kconfig linux-3.18.8/arch/Kconfig --- linux-3.18.8.orig/arch/Kconfig 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/Kconfig 2015-03-03 08:05:17.000000000 +0100 @@ -6,6 +6,7 @@ tristate "OProfile system profiling" depends on PROFILING depends on HAVE_OPROFILE + depends on !PREEMPT_RT_FULL select RING_BUFFER select RING_BUFFER_ALLOW_SWAP help diff -Nur linux-3.18.8.orig/arch/m32r/mm/fault.c linux-3.18.8/arch/m32r/mm/fault.c --- linux-3.18.8.orig/arch/m32r/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/m32r/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 @@ -114,7 +114,7 @@ * If we're in an interrupt or have no user context or are running in an * atomic region then we must not take the fault.. */ - if (in_atomic() || !mm) + if (!mm || pagefault_disabled()) goto bad_area_nosemaphore; if (error_code & ACE_USERMODE) diff -Nur linux-3.18.8.orig/arch/m68k/mm/fault.c linux-3.18.8/arch/m68k/mm/fault.c --- linux-3.18.8.orig/arch/m68k/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/m68k/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 @@ -81,7 +81,7 @@ * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (!mm || pagefault_disabled()) goto no_context; if (user_mode(regs)) diff -Nur linux-3.18.8.orig/arch/microblaze/mm/fault.c linux-3.18.8/arch/microblaze/mm/fault.c --- linux-3.18.8.orig/arch/microblaze/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/microblaze/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 @@ -107,7 +107,7 @@ if ((error_code & 0x13) == 0x13 || (error_code & 0x11) == 0x11) is_write = 0; - if (unlikely(in_atomic() || !mm)) { + if (unlikely(!mm || pagefault_disabled())) { if (kernel_mode(regs)) goto bad_area_nosemaphore; diff -Nur linux-3.18.8.orig/arch/mips/Kconfig linux-3.18.8/arch/mips/Kconfig --- linux-3.18.8.orig/arch/mips/Kconfig 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/mips/Kconfig 2015-03-03 08:05:17.000000000 +0100 @@ -2196,7 +2196,7 @@ # config HIGHMEM bool "High Memory Support" - depends on 32BIT && CPU_SUPPORTS_HIGHMEM && SYS_SUPPORTS_HIGHMEM && !CPU_MIPS32_3_5_EVA + depends on 32BIT && CPU_SUPPORTS_HIGHMEM && SYS_SUPPORTS_HIGHMEM && !CPU_MIPS32_3_5_EVA && !PREEMPT_RT_FULL config CPU_SUPPORTS_HIGHMEM bool diff -Nur linux-3.18.8.orig/arch/mips/kernel/signal.c linux-3.18.8/arch/mips/kernel/signal.c --- linux-3.18.8.orig/arch/mips/kernel/signal.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/mips/kernel/signal.c 2015-03-03 08:05:17.000000000 +0100 @@ -613,6 +613,7 @@ __u32 thread_info_flags) { local_irq_enable(); + preempt_check_resched(); user_exit(); diff -Nur linux-3.18.8.orig/arch/mips/mm/fault.c linux-3.18.8/arch/mips/mm/fault.c --- linux-3.18.8.orig/arch/mips/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/mips/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 @@ -89,7 +89,7 @@ * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (!mm || pagefault_disabled()) goto bad_area_nosemaphore; if (user_mode(regs)) diff -Nur linux-3.18.8.orig/arch/mips/mm/init.c linux-3.18.8/arch/mips/mm/init.c --- linux-3.18.8.orig/arch/mips/mm/init.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/mips/mm/init.c 2015-03-03 08:05:17.000000000 +0100 @@ -90,7 +90,7 @@ BUG_ON(Page_dcache_dirty(page)); - pagefault_disable(); + raw_pagefault_disable(); idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); idx += in_interrupt() ? FIX_N_COLOURS : 0; vaddr = __fix_to_virt(FIX_CMAP_END - idx); @@ -146,7 +146,7 @@ tlbw_use_hazard(); write_c0_entryhi(old_ctx); local_irq_restore(flags); - pagefault_enable(); + raw_pagefault_enable(); } void copy_user_highpage(struct page *to, struct page *from, diff -Nur linux-3.18.8.orig/arch/mn10300/mm/fault.c linux-3.18.8/arch/mn10300/mm/fault.c --- linux-3.18.8.orig/arch/mn10300/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/mn10300/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 @@ -168,7 +168,7 @@ * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (!mm || pagefault_disabled()) goto no_context; if ((fault_code & MMUFCR_xFC_ACCESS) == MMUFCR_xFC_ACCESS_USR) diff -Nur linux-3.18.8.orig/arch/parisc/mm/fault.c linux-3.18.8/arch/parisc/mm/fault.c --- linux-3.18.8.orig/arch/parisc/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/parisc/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 @@ -207,7 +207,7 @@ int fault; unsigned int flags; - if (in_atomic()) + if (pagefault_disabled()) goto no_context; tsk = current; diff -Nur linux-3.18.8.orig/arch/powerpc/include/asm/thread_info.h linux-3.18.8/arch/powerpc/include/asm/thread_info.h --- linux-3.18.8.orig/arch/powerpc/include/asm/thread_info.h 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/powerpc/include/asm/thread_info.h 2015-03-03 08:05:17.000000000 +0100 @@ -43,6 +43,8 @@ int cpu; /* cpu we're on */ int preempt_count; /* 0 => preemptable, <0 => BUG */ + int preempt_lazy_count; /* 0 => preemptable, + <0 => BUG */ struct restart_block restart_block; unsigned long local_flags; /* private flags for thread */ @@ -88,8 +90,7 @@ #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ #define TIF_SIGPENDING 1 /* signal pending */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ -#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling - TIF_NEED_RESCHED */ +#define TIF_NEED_RESCHED_LAZY 3 /* lazy rescheduling necessary */ #define TIF_32BIT 4 /* 32 bit binary */ #define TIF_RESTORE_TM 5 /* need to restore TM FP/VEC/VSX */ #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ @@ -107,6 +108,8 @@ #if defined(CONFIG_PPC64) #define TIF_ELF2ABI 18 /* function descriptors must die! */ #endif +#define TIF_POLLING_NRFLAG 19 /* true if poll_idle() is polling + TIF_NEED_RESCHED */ /* as above, but as bit values */ #define _TIF_SYSCALL_TRACE (1<flags) set_bits(irqtp->flags, &curtp->flags); } +#endif irq_hw_number_t virq_to_hw(unsigned int virq) { diff -Nur linux-3.18.8.orig/arch/powerpc/kernel/misc_32.S linux-3.18.8/arch/powerpc/kernel/misc_32.S --- linux-3.18.8.orig/arch/powerpc/kernel/misc_32.S 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/powerpc/kernel/misc_32.S 2015-03-03 08:05:17.000000000 +0100 @@ -40,6 +40,7 @@ * We store the saved ksp_limit in the unused part * of the STACK_FRAME_OVERHEAD */ +#ifndef CONFIG_PREEMPT_RT_FULL _GLOBAL(call_do_softirq) mflr r0 stw r0,4(r1) @@ -56,6 +57,7 @@ stw r10,THREAD+KSP_LIMIT(r2) mtlr r0 blr +#endif /* * void call_do_irq(struct pt_regs *regs, struct thread_info *irqtp); diff -Nur linux-3.18.8.orig/arch/powerpc/kernel/misc_64.S linux-3.18.8/arch/powerpc/kernel/misc_64.S --- linux-3.18.8.orig/arch/powerpc/kernel/misc_64.S 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/powerpc/kernel/misc_64.S 2015-03-03 08:05:17.000000000 +0100 @@ -29,6 +29,7 @@ .text +#ifndef CONFIG_PREEMPT_RT_FULL _GLOBAL(call_do_softirq) mflr r0 std r0,16(r1) @@ -39,6 +40,7 @@ ld r0,16(r1) mtlr r0 blr +#endif _GLOBAL(call_do_irq) mflr r0 diff -Nur linux-3.18.8.orig/arch/powerpc/kernel/time.c linux-3.18.8/arch/powerpc/kernel/time.c --- linux-3.18.8.orig/arch/powerpc/kernel/time.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/powerpc/kernel/time.c 2015-03-03 08:05:17.000000000 +0100 @@ -424,7 +424,7 @@ EXPORT_SYMBOL(profile_pc); #endif -#ifdef CONFIG_IRQ_WORK +#if defined(CONFIG_IRQ_WORK) && !defined(CONFIG_PREEMPT_RT_FULL) /* * 64-bit uses a byte in the PACA, 32-bit uses a per-cpu variable... diff -Nur linux-3.18.8.orig/arch/powerpc/mm/fault.c linux-3.18.8/arch/powerpc/mm/fault.c --- linux-3.18.8.orig/arch/powerpc/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/powerpc/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 @@ -273,7 +273,7 @@ if (!arch_irq_disabled_regs(regs)) local_irq_enable(); - if (in_atomic() || mm == NULL) { + if (in_atomic() || mm == NULL || pagefault_disabled()) { if (!user_mode(regs)) { rc = SIGSEGV; goto bail; diff -Nur linux-3.18.8.orig/arch/s390/mm/fault.c linux-3.18.8/arch/s390/mm/fault.c --- linux-3.18.8.orig/arch/s390/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/s390/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 @@ -435,7 +435,8 @@ * user context. */ fault = VM_FAULT_BADCONTEXT; - if (unlikely(!user_space_fault(regs) || in_atomic() || !mm)) + if (unlikely(!user_space_fault(regs) || !mm || + tsk->pagefault_disabled)) goto out; address = trans_exc_code & __FAIL_ADDR_MASK; diff -Nur linux-3.18.8.orig/arch/score/mm/fault.c linux-3.18.8/arch/score/mm/fault.c --- linux-3.18.8.orig/arch/score/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/score/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 @@ -73,7 +73,7 @@ * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (!mm || pagefault_disabled()) goto bad_area_nosemaphore; if (user_mode(regs)) diff -Nur linux-3.18.8.orig/arch/sh/kernel/irq.c linux-3.18.8/arch/sh/kernel/irq.c --- linux-3.18.8.orig/arch/sh/kernel/irq.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/sh/kernel/irq.c 2015-03-03 08:05:17.000000000 +0100 @@ -149,6 +149,7 @@ hardirq_ctx[cpu] = NULL; } +#ifndef CONFIG_PREEMPT_RT_FULL void do_softirq_own_stack(void) { struct thread_info *curctx; @@ -176,6 +177,7 @@ "r5", "r6", "r7", "r8", "r9", "r15", "t", "pr" ); } +#endif #else static inline void handle_one_irq(unsigned int irq) { diff -Nur linux-3.18.8.orig/arch/sh/mm/fault.c linux-3.18.8/arch/sh/mm/fault.c --- linux-3.18.8.orig/arch/sh/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/sh/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 @@ -440,7 +440,7 @@ * If we're in an interrupt, have no user context or are running * in an atomic region then we must not take the fault: */ - if (unlikely(in_atomic() || !mm)) { + if (unlikely(!mm || pagefault_disabled())) { bad_area_nosemaphore(regs, error_code, address); return; } diff -Nur linux-3.18.8.orig/arch/sparc/Kconfig linux-3.18.8/arch/sparc/Kconfig --- linux-3.18.8.orig/arch/sparc/Kconfig 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/sparc/Kconfig 2015-03-03 08:05:17.000000000 +0100 @@ -182,12 +182,10 @@ source kernel/Kconfig.hz config RWSEM_GENERIC_SPINLOCK - bool - default y if SPARC32 + def_bool PREEMPT_RT_FULL config RWSEM_XCHGADD_ALGORITHM - bool - default y if SPARC64 + def_bool !RWSEM_GENERIC_SPINLOCK && !PREEMPT_RT_FULL config GENERIC_HWEIGHT bool @@ -528,6 +526,10 @@ source "fs/Kconfig.binfmt" +config EARLY_PRINTK + bool + default y + config COMPAT bool depends on SPARC64 diff -Nur linux-3.18.8.orig/arch/sparc/kernel/irq_64.c linux-3.18.8/arch/sparc/kernel/irq_64.c --- linux-3.18.8.orig/arch/sparc/kernel/irq_64.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/sparc/kernel/irq_64.c 2015-03-03 08:05:17.000000000 +0100 @@ -849,6 +849,7 @@ set_irq_regs(old_regs); } +#ifndef CONFIG_PREEMPT_RT_FULL void do_softirq_own_stack(void) { void *orig_sp, *sp = softirq_stack[smp_processor_id()]; @@ -863,6 +864,7 @@ __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp)); } +#endif #ifdef CONFIG_HOTPLUG_CPU void fixup_irqs(void) diff -Nur linux-3.18.8.orig/arch/sparc/kernel/pcr.c linux-3.18.8/arch/sparc/kernel/pcr.c --- linux-3.18.8.orig/arch/sparc/kernel/pcr.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/sparc/kernel/pcr.c 2015-03-03 08:05:17.000000000 +0100 @@ -43,10 +43,12 @@ set_irq_regs(old_regs); } +#ifndef CONFIG_PREEMPT_RT_FULL void arch_irq_work_raise(void) { set_softint(1 << PIL_DEFERRED_PCR_WORK); } +#endif const struct pcr_ops *pcr_ops; EXPORT_SYMBOL_GPL(pcr_ops); diff -Nur linux-3.18.8.orig/arch/sparc/kernel/setup_32.c linux-3.18.8/arch/sparc/kernel/setup_32.c --- linux-3.18.8.orig/arch/sparc/kernel/setup_32.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/sparc/kernel/setup_32.c 2015-03-03 08:05:17.000000000 +0100 @@ -309,6 +309,7 @@ boot_flags_init(*cmdline_p); + early_console = &prom_early_console; register_console(&prom_early_console); printk("ARCH: "); diff -Nur linux-3.18.8.orig/arch/sparc/kernel/setup_64.c linux-3.18.8/arch/sparc/kernel/setup_64.c --- linux-3.18.8.orig/arch/sparc/kernel/setup_64.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/sparc/kernel/setup_64.c 2015-03-03 08:05:17.000000000 +0100 @@ -563,6 +563,12 @@ pause_patch(); } +static inline void register_prom_console(void) +{ + early_console = &prom_early_console; + register_console(&prom_early_console); +} + void __init setup_arch(char **cmdline_p) { /* Initialize PROM console and command line. */ @@ -574,7 +580,7 @@ #ifdef CONFIG_EARLYFB if (btext_find_display()) #endif - register_console(&prom_early_console); + register_prom_console(); if (tlb_type == hypervisor) printk("ARCH: SUN4V\n"); diff -Nur linux-3.18.8.orig/arch/sparc/mm/fault_32.c linux-3.18.8/arch/sparc/mm/fault_32.c --- linux-3.18.8.orig/arch/sparc/mm/fault_32.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/sparc/mm/fault_32.c 2015-03-03 08:05:17.000000000 +0100 @@ -196,7 +196,7 @@ * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (!mm || pagefault_disabled()) goto no_context; perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); diff -Nur linux-3.18.8.orig/arch/sparc/mm/fault_64.c linux-3.18.8/arch/sparc/mm/fault_64.c --- linux-3.18.8.orig/arch/sparc/mm/fault_64.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/sparc/mm/fault_64.c 2015-03-03 08:05:17.000000000 +0100 @@ -330,7 +330,7 @@ * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_atomic() || !mm) + if (!mm || pagefault_disabled()) goto intr_or_no_mm; perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); diff -Nur linux-3.18.8.orig/arch/tile/mm/fault.c linux-3.18.8/arch/tile/mm/fault.c --- linux-3.18.8.orig/arch/tile/mm/fault.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/tile/mm/fault.c 2015-03-03 08:05:17.000000000 +0100 @@ -357,7 +357,7 @@ * If we're in an interrupt, have no user context or are running in an * atomic region then we must not take the fault. */ - if (in_atomic() || !mm) { + if (!mm || pagefault_disabled()) { vma = NULL; /* happy compiler */ goto bad_area_nosemaphore; } diff -Nur linux-3.18.8.orig/arch/um/kernel/trap.c linux-3.18.8/arch/um/kernel/trap.c --- linux-3.18.8.orig/arch/um/kernel/trap.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/um/kernel/trap.c 2015-03-03 08:05:17.000000000 +0100 @@ -38,7 +38,7 @@ * If the fault was during atomic operation, don't take the fault, just * fail. */ - if (in_atomic()) + if (pagefault_disabled()) goto out_nosemaphore; if (is_user) diff -Nur linux-3.18.8.orig/arch/x86/crypto/aesni-intel_glue.c linux-3.18.8/arch/x86/crypto/aesni-intel_glue.c --- linux-3.18.8.orig/arch/x86/crypto/aesni-intel_glue.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/x86/crypto/aesni-intel_glue.c 2015-03-03 08:05:17.000000000 +0100 @@ -381,14 +381,14 @@ err = blkcipher_walk_virt(desc, &walk); desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - kernel_fpu_begin(); while ((nbytes = walk.nbytes)) { + kernel_fpu_begin(); aesni_ecb_enc(ctx, walk.dst.virt.addr, walk.src.virt.addr, - nbytes & AES_BLOCK_MASK); + nbytes & AES_BLOCK_MASK); + kernel_fpu_end(); nbytes &= AES_BLOCK_SIZE - 1; err = blkcipher_walk_done(desc, &walk, nbytes); } - kernel_fpu_end(); return err; } @@ -405,14 +405,14 @@ err = blkcipher_walk_virt(desc, &walk); desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - kernel_fpu_begin(); while ((nbytes = walk.nbytes)) { + kernel_fpu_begin(); aesni_ecb_dec(ctx, walk.dst.virt.addr, walk.src.virt.addr, nbytes & AES_BLOCK_MASK); + kernel_fpu_end(); nbytes &= AES_BLOCK_SIZE - 1; err = blkcipher_walk_done(desc, &walk, nbytes); } - kernel_fpu_end(); return err; } @@ -429,14 +429,14 @@ err = blkcipher_walk_virt(desc, &walk); desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - kernel_fpu_begin(); while ((nbytes = walk.nbytes)) { + kernel_fpu_begin(); aesni_cbc_enc(ctx, walk.dst.virt.addr, walk.src.virt.addr, nbytes & AES_BLOCK_MASK, walk.iv); + kernel_fpu_end(); nbytes &= AES_BLOCK_SIZE - 1; err = blkcipher_walk_done(desc, &walk, nbytes); } - kernel_fpu_end(); return err; } @@ -453,14 +453,14 @@ err = blkcipher_walk_virt(desc, &walk); desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - kernel_fpu_begin(); while ((nbytes = walk.nbytes)) { + kernel_fpu_begin(); aesni_cbc_dec(ctx, walk.dst.virt.addr, walk.src.virt.addr, nbytes & AES_BLOCK_MASK, walk.iv); + kernel_fpu_end(); nbytes &= AES_BLOCK_SIZE - 1; err = blkcipher_walk_done(desc, &walk, nbytes); } - kernel_fpu_end(); return err; } @@ -512,18 +512,20 @@ err = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE); desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - kernel_fpu_begin(); while ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE) { + kernel_fpu_begin(); aesni_ctr_enc_tfm(ctx, walk.dst.virt.addr, walk.src.virt.addr, nbytes & AES_BLOCK_MASK, walk.iv); + kernel_fpu_end(); nbytes &= AES_BLOCK_SIZE - 1; err = blkcipher_walk_done(desc, &walk, nbytes); } if (walk.nbytes) { + kernel_fpu_begin(); ctr_crypt_final(ctx, &walk); + kernel_fpu_end(); err = blkcipher_walk_done(desc, &walk, 0); } - kernel_fpu_end(); return err; } diff -Nur linux-3.18.8.orig/arch/x86/crypto/cast5_avx_glue.c linux-3.18.8/arch/x86/crypto/cast5_avx_glue.c --- linux-3.18.8.orig/arch/x86/crypto/cast5_avx_glue.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/x86/crypto/cast5_avx_glue.c 2015-03-03 08:05:17.000000000 +0100 @@ -60,7 +60,7 @@ static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, bool enc) { - bool fpu_enabled = false; + bool fpu_enabled; struct cast5_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); const unsigned int bsize = CAST5_BLOCK_SIZE; unsigned int nbytes; @@ -76,7 +76,7 @@ u8 *wsrc = walk->src.virt.addr; u8 *wdst = walk->dst.virt.addr; - fpu_enabled = cast5_fpu_begin(fpu_enabled, nbytes); + fpu_enabled = cast5_fpu_begin(false, nbytes); /* Process multi-block batch */ if (nbytes >= bsize * CAST5_PARALLEL_BLOCKS) { @@ -104,10 +104,9 @@ } while (nbytes >= bsize); done: + cast5_fpu_end(fpu_enabled); err = blkcipher_walk_done(desc, walk, nbytes); } - - cast5_fpu_end(fpu_enabled); return err; } @@ -228,7 +227,7 @@ static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes) { - bool fpu_enabled = false; + bool fpu_enabled; struct blkcipher_walk walk; int err; @@ -237,12 +236,11 @@ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; while ((nbytes = walk.nbytes)) { - fpu_enabled = cast5_fpu_begin(fpu_enabled, nbytes); + fpu_enabled = cast5_fpu_begin(false, nbytes); nbytes = __cbc_decrypt(desc, &walk); + cast5_fpu_end(fpu_enabled); err = blkcipher_walk_done(desc, &walk, nbytes); } - - cast5_fpu_end(fpu_enabled); return err; } @@ -312,7 +310,7 @@ static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes) { - bool fpu_enabled = false; + bool fpu_enabled; struct blkcipher_walk walk; int err; @@ -321,13 +319,12 @@ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; while ((nbytes = walk.nbytes) >= CAST5_BLOCK_SIZE) { - fpu_enabled = cast5_fpu_begin(fpu_enabled, nbytes); + fpu_enabled = cast5_fpu_begin(false, nbytes); nbytes = __ctr_crypt(desc, &walk); + cast5_fpu_end(fpu_enabled); err = blkcipher_walk_done(desc, &walk, nbytes); } - cast5_fpu_end(fpu_enabled); - if (walk.nbytes) { ctr_crypt_final(desc, &walk); err = blkcipher_walk_done(desc, &walk, 0); diff -Nur linux-3.18.8.orig/arch/x86/crypto/glue_helper.c linux-3.18.8/arch/x86/crypto/glue_helper.c --- linux-3.18.8.orig/arch/x86/crypto/glue_helper.c 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/x86/crypto/glue_helper.c 2015-03-03 08:05:17.000000000 +0100 @@ -39,7 +39,7 @@ void *ctx = crypto_blkcipher_ctx(desc->tfm); const unsigned int bsize = 128 / 8; unsigned int nbytes, i, func_bytes; - bool fpu_enabled = false; + bool fpu_enabled; int err; err = blkcipher_walk_virt(desc, walk); @@ -49,7 +49,7 @@ u8 *wdst = walk->dst.virt.addr; fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, - desc, fpu_enabled, nbytes); + desc, false, nbytes); for (i = 0; i < gctx->num_funcs; i++) { func_bytes = bsize * gctx->funcs[i].num_blocks; @@ -71,10 +71,10 @@ } done: + glue_fpu_end(fpu_enabled); err = blkcipher_walk_done(desc, walk, nbytes); } - glue_fpu_end(fpu_enabled); return err; } @@ -194,7 +194,7 @@ struct scatterlist *src, unsigned int nbytes) { const unsigned int bsize = 128 / 8; - bool fpu_enabled = false; + bool fpu_enabled; struct blkcipher_walk walk; int err; @@ -203,12 +203,12 @@ while ((nbytes = walk.nbytes)) { fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, - desc, fpu_enabled, nbytes); + desc, false, nbytes); nbytes = __glue_cbc_decrypt_128bit(gctx, desc, &walk); + glue_fpu_end(fpu_enabled); err = blkcipher_walk_done(desc, &walk, nbytes); } - glue_fpu_end(fpu_enabled); return err; } EXPORT_SYMBOL_GPL(glue_cbc_decrypt_128bit); @@ -278,7 +278,7 @@ struct scatterlist *src, unsigned int nbytes) { const unsigned int bsize = 128 / 8; - bool fpu_enabled = false; + bool fpu_enabled; struct blkcipher_walk walk; int err; @@ -287,13 +287,12 @@ while ((nbytes = walk.nbytes) >= bsize) { fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, - desc, fpu_enabled, nbytes); + desc, false, nbytes); nbytes = __glue_ctr_crypt_128bit(gctx, desc, &walk); + glue_fpu_end(fpu_enabled); err = blkcipher_walk_done(desc, &walk, nbytes); } - glue_fpu_end(fpu_enabled); - if (walk.nbytes) { glue_ctr_crypt_final_128bit( gctx->funcs[gctx->num_funcs - 1].fn_u.ctr, desc, &walk); @@ -348,7 +347,7 @@ void *tweak_ctx, void *crypt_ctx) { const unsigned int bsize = 128 / 8; - bool fpu_enabled = false; + bool fpu_enabled; struct blkcipher_walk walk; int err; @@ -361,21 +360,21 @@ /* set minimum length to bsize, for tweak_fn */ fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, - desc, fpu_enabled, + desc, false, nbytes < bsize ? bsize : nbytes); - /* calculate first value of T */ tweak_fn(tweak_ctx, walk.iv, walk.iv); + glue_fpu_end(fpu_enabled); while (nbytes) { + fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, + desc, false, nbytes); nbytes = __glue_xts_crypt_128bit(gctx, crypt_ctx, desc, &walk); + glue_fpu_end(fpu_enabled); err = blkcipher_walk_done(desc, &walk, nbytes); nbytes = walk.nbytes; } - - glue_fpu_end(fpu_enabled); - return err; } EXPORT_SYMBOL_GPL(glue_xts_crypt_128bit); diff -Nur linux-3.18.8.orig/arch/x86/include/asm/preempt.h linux-3.18.8/arch/x86/include/asm/preempt.h --- linux-3.18.8.orig/arch/x86/include/asm/preempt.h 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/x86/include/asm/preempt.h 2015-03-03 08:05:17.000000000 +0100 @@ -85,17 +85,33 @@ * a decrement which hits zero means we have no preempt_count and should * reschedule. */ -static __always_inline bool __preempt_count_dec_and_test(void) +static __always_inline bool ____preempt_count_dec_and_test(void) { GEN_UNARY_RMWcc("decl", __preempt_count, __percpu_arg(0), "e"); } +static __always_inline bool __preempt_count_dec_and_test(void) +{ + if (____preempt_count_dec_and_test()) + return true; +#ifdef CONFIG_PREEMPT_LAZY + return test_thread_flag(TIF_NEED_RESCHED_LAZY); +#else + return false; +#endif +} + /* * Returns true when we need to resched and can (barring IRQ state). */ static __always_inline bool should_resched(void) { +#ifdef CONFIG_PREEMPT_LAZY + return unlikely(!raw_cpu_read_4(__preempt_count) || \ + test_thread_flag(TIF_NEED_RESCHED_LAZY)); +#else return unlikely(!raw_cpu_read_4(__preempt_count)); +#endif } #ifdef CONFIG_PREEMPT diff -Nur linux-3.18.8.orig/arch/x86/include/asm/signal.h linux-3.18.8/arch/x86/include/asm/signal.h --- linux-3.18.8.orig/arch/x86/include/asm/signal.h 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/x86/include/asm/signal.h 2015-03-03 08:05:17.000000000 +0100 @@ -23,6 +23,19 @@ unsigned long sig[_NSIG_WORDS]; } sigset_t; +/* + * Because some traps use the IST stack, we must keep preemption + * disabled while calling do_trap(), but do_trap() may call + * force_sig_info() which will grab the signal spin_locks for the + * task, which in PREEMPT_RT_FULL are mutexes. By defining + * ARCH_RT_DELAYS_SIGNAL_SEND the force_sig_info() will set + * TIF_NOTIFY_RESUME and set up the signal to be sent on exit of the + * trap. + */ +#if defined(CONFIG_PREEMPT_RT_FULL) && defined(CONFIG_X86_64) +#define ARCH_RT_DELAYS_SIGNAL_SEND +#endif + #ifndef CONFIG_COMPAT typedef sigset_t compat_sigset_t; #endif diff -Nur linux-3.18.8.orig/arch/x86/include/asm/stackprotector.h linux-3.18.8/arch/x86/include/asm/stackprotector.h --- linux-3.18.8.orig/arch/x86/include/asm/stackprotector.h 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/x86/include/asm/stackprotector.h 2015-03-03 08:05:17.000000000 +0100 @@ -57,7 +57,7 @@ */ static __always_inline void boot_init_stack_canary(void) { - u64 canary; + u64 uninitialized_var(canary); u64 tsc; #ifdef CONFIG_X86_64 @@ -68,8 +68,16 @@ * of randomness. The TSC only matters for very early init, * there it already has some randomness on most systems. Later * on during the bootup the random pool has true entropy too. + * + * For preempt-rt we need to weaken the randomness a bit, as + * we can't call into the random generator from atomic context + * due to locking constraints. We just leave canary + * uninitialized and use the TSC based randomness on top of + * it. */ +#ifndef CONFIG_PREEMPT_RT_FULL get_random_bytes(&canary, sizeof(canary)); +#endif tsc = __native_read_tsc(); canary += tsc + (tsc << 32UL); diff -Nur linux-3.18.8.orig/arch/x86/include/asm/thread_info.h linux-3.18.8/arch/x86/include/asm/thread_info.h --- linux-3.18.8.orig/arch/x86/include/asm/thread_info.h 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/x86/include/asm/thread_info.h 2015-03-03 08:05:17.000000000 +0100 @@ -30,6 +30,8 @@ __u32 status; /* thread synchronous flags */ __u32 cpu; /* current CPU */ int saved_preempt_count; + int preempt_lazy_count; /* 0 => lazy preemptable + <0 => BUG */ mm_segment_t addr_limit; struct restart_block restart_block; void __user *sysenter_return; @@ -75,6 +77,7 @@ #define TIF_SYSCALL_EMU 6 /* syscall emulation active */ #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ #define TIF_SECCOMP 8 /* secure computing */ +#define TIF_NEED_RESCHED_LAZY 9 /* lazy rescheduling necessary */ #define TIF_MCE_NOTIFY 10 /* notify userspace of an MCE */ #define TIF_USER_RETURN_NOTIFY 11 /* notify kernel of userspace return */ #define TIF_UPROBE 12 /* breakpointed or singlestepping */ @@ -100,6 +103,7 @@ #define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SECCOMP (1 << TIF_SECCOMP) +#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY) #define _TIF_MCE_NOTIFY (1 << TIF_MCE_NOTIFY) #define _TIF_USER_RETURN_NOTIFY (1 << TIF_USER_RETURN_NOTIFY) #define _TIF_UPROBE (1 << TIF_UPROBE) @@ -150,6 +154,8 @@ #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY) #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW) +#define _TIF_NEED_RESCHED_MASK (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY) + #define STACK_WARN (THREAD_SIZE/8) #define KERNEL_STACK_OFFSET (5*(BITS_PER_LONG/8)) diff -Nur linux-3.18.8.orig/arch/x86/include/asm/uv/uv_bau.h linux-3.18.8/arch/x86/include/asm/uv/uv_bau.h --- linux-3.18.8.orig/arch/x86/include/asm/uv/uv_bau.h 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/x86/include/asm/uv/uv_bau.h 2015-03-03 08:05:17.000000000 +0100 @@ -615,9 +615,9 @@ cycles_t send_message; cycles_t period_end; cycles_t period_time; - spinlock_t uvhub_lock; - spinlock_t queue_lock; - spinlock_t disable_lock; + raw_spinlock_t uvhub_lock; + raw_spinlock_t queue_lock; + raw_spinlock_t disable_lock; /* tunables */ int max_concurr; int max_concurr_const; @@ -776,15 +776,15 @@ * to be lowered below the current 'v'. atomic_add_unless can only stop * on equal. */ -static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u) +static inline int atomic_inc_unless_ge(raw_spinlock_t *lock, atomic_t *v, int u) { - spin_lock(lock); + raw_spin_lock(lock); if (atomic_read(v) >= u) { - spin_unlock(lock); + raw_spin_unlock(lock); return 0; } atomic_inc(v); - spin_unlock(lock); + raw_spin_unlock(lock); return 1; } diff -Nur linux-3.18.8.orig/arch/x86/include/asm/uv/uv_hub.h linux-3.18.8/arch/x86/include/asm/uv/uv_hub.h --- linux-3.18.8.orig/arch/x86/include/asm/uv/uv_hub.h 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/x86/include/asm/uv/uv_hub.h 2015-03-03 08:05:17.000000000 +0100 @@ -492,7 +492,7 @@ unsigned short nr_online_cpus; unsigned short pnode; short memory_nid; - spinlock_t nmi_lock; /* obsolete, see uv_hub_nmi */ + raw_spinlock_t nmi_lock; /* obsolete, see uv_hub_nmi */ unsigned long nmi_count; /* obsolete, see uv_hub_nmi */ }; extern struct uv_blade_info *uv_blade_info; diff -Nur linux-3.18.8.orig/arch/x86/Kconfig linux-3.18.8/arch/x86/Kconfig --- linux-3.18.8.orig/arch/x86/Kconfig 2015-02-27 02:49:36.000000000 +0100 +++ linux-3.18.8/arch/x86/Kconfig 2015-03-03 08:05:17.000000000 +0100 @@ -21,6 +21,7 @@ ### Arch settings config X86 def_bool y + select HAVE_PREEMPT_LAZY if X86_32 select ARCH_MIGHT_HAVE_ACPI_PDC if ACPI select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS select ARCH_HAS_FAST_MULTIPLIER @@ -197,8 +198,11 @@ def_bool y depends on ISA_DMA_API +config RWSEM_GENERIC_SPINLOCK + def_bool PREEMPT_RT_FULL + config RWSEM_XCHGADD_ALGORITHM - def_bool y + def_bool !RWSEM_GENERIC_SPINLOCK && !PREEMPT_RT_FULL config GENERIC_CALIBRATE_DELAY def_bool y @@ -811,7 +815,7 @@ config M