diff --git a/debian/changelog b/debian/changelog index f7b07c82d..dc7960fd7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -28,9 +28,9 @@ linux-2.6 (3.0.0-4) UNRELEASED; urgency=low [ Moritz Muehlenhoff ] * Update German Debconf translation. Thanks to Holger Wansing (Closes: #641487) - + [ Uwe Kleine-König ] - * [amd64] Update rt featureset to 3.0.4-rt13 + * [amd64] Update rt featureset to 3.0.4-rt14 -- Ben Hutchings Sun, 28 Aug 2011 17:07:47 +0100 diff --git a/debian/patches/features/all/rt/patch-3.0.4-rt13.patch b/debian/patches/features/all/rt/patch-3.0.4-rt14.patch similarity index 99% rename from debian/patches/features/all/rt/patch-3.0.4-rt13.patch rename to debian/patches/features/all/rt/patch-3.0.4-rt14.patch index fc40dc5a2..30a6248ad 100644 --- a/debian/patches/features/all/rt/patch-3.0.4-rt13.patch +++ b/debian/patches/features/all/rt/patch-3.0.4-rt14.patch @@ -1,3 +1,23 @@ +Index: linux-2.6/arch/arm/plat-mxc/include/mach/iomux-v3.h +=================================================================== +--- linux-2.6.orig/arch/arm/plat-mxc/include/mach/iomux-v3.h ++++ linux-2.6/arch/arm/plat-mxc/include/mach/iomux-v3.h +@@ -66,7 +66,6 @@ typedef u64 iomux_v3_cfg_t; + #define MUX_MODE_MASK ((iomux_v3_cfg_t)0x1f << MUX_MODE_SHIFT) + #define MUX_PAD_CTRL_SHIFT 41 + #define MUX_PAD_CTRL_MASK ((iomux_v3_cfg_t)0x1ffff << MUX_PAD_CTRL_SHIFT) +-#define NO_PAD_CTRL ((iomux_v3_cfg_t)1 << (MUX_PAD_CTRL_SHIFT + 16)) + #define MUX_SEL_INPUT_SHIFT 58 + #define MUX_SEL_INPUT_MASK ((iomux_v3_cfg_t)0xf << MUX_SEL_INPUT_SHIFT) + +@@ -85,6 +84,7 @@ typedef u64 iomux_v3_cfg_t; + * Use to set PAD control + */ + ++#define NO_PAD_CTRL (1 << 16) + #define PAD_CTL_DVS (1 << 13) + #define PAD_CTL_HYS (1 << 8) + Index: linux-2.6/mm/memory.c =================================================================== --- linux-2.6.orig/mm/memory.c @@ -965,6 +985,198 @@ Index: linux-2.6/kernel/lockdep.c if (!debug_locks) print_irqtrace_events(current); +Index: linux-2.6/drivers/pci/dmar.c +=================================================================== +--- linux-2.6.orig/drivers/pci/dmar.c ++++ linux-2.6/drivers/pci/dmar.c +@@ -800,7 +800,7 @@ int alloc_iommu(struct dmar_drhd_unit *d + (unsigned long long)iommu->cap, + (unsigned long long)iommu->ecap); + +- spin_lock_init(&iommu->register_lock); ++ raw_spin_lock_init(&iommu->register_lock); + + drhd->iommu = iommu; + return 0; +@@ -921,11 +921,11 @@ int qi_submit_sync(struct qi_desc *desc, + restart: + rc = 0; + +- spin_lock_irqsave(&qi->q_lock, flags); ++ raw_spin_lock_irqsave(&qi->q_lock, flags); + while (qi->free_cnt < 3) { +- spin_unlock_irqrestore(&qi->q_lock, flags); ++ raw_spin_unlock_irqrestore(&qi->q_lock, flags); + cpu_relax(); +- spin_lock_irqsave(&qi->q_lock, flags); ++ raw_spin_lock_irqsave(&qi->q_lock, flags); + } + + index = qi->free_head; +@@ -965,15 +965,15 @@ restart: + if (rc) + break; + +- spin_unlock(&qi->q_lock); ++ raw_spin_unlock(&qi->q_lock); + cpu_relax(); +- spin_lock(&qi->q_lock); ++ raw_spin_lock(&qi->q_lock); + } + + qi->desc_status[index] = QI_DONE; + + reclaim_free_desc(qi); +- spin_unlock_irqrestore(&qi->q_lock, flags); ++ raw_spin_unlock_irqrestore(&qi->q_lock, flags); + + if (rc == -EAGAIN) + goto restart; +@@ -1062,7 +1062,7 @@ void dmar_disable_qi(struct intel_iommu + if (!ecap_qis(iommu->ecap)) + return; + +- spin_lock_irqsave(&iommu->register_lock, flags); ++ raw_spin_lock_irqsave(&iommu->register_lock, flags); + + sts = dmar_readq(iommu->reg + DMAR_GSTS_REG); + if (!(sts & DMA_GSTS_QIES)) +@@ -1082,7 +1082,7 @@ void dmar_disable_qi(struct intel_iommu + IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl, + !(sts & DMA_GSTS_QIES), sts); + end: +- spin_unlock_irqrestore(&iommu->register_lock, flags); ++ raw_spin_unlock_irqrestore(&iommu->register_lock, flags); + } + + /* +@@ -1097,7 +1097,7 @@ static void __dmar_enable_qi(struct inte + qi->free_head = qi->free_tail = 0; + qi->free_cnt = QI_LENGTH; + +- spin_lock_irqsave(&iommu->register_lock, flags); ++ raw_spin_lock_irqsave(&iommu->register_lock, flags); + + /* write zero to the tail reg */ + writel(0, iommu->reg + DMAR_IQT_REG); +@@ -1110,7 +1110,7 @@ static void __dmar_enable_qi(struct inte + /* Make sure hardware complete it */ + IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl, (sts & DMA_GSTS_QIES), sts); + +- spin_unlock_irqrestore(&iommu->register_lock, flags); ++ raw_spin_unlock_irqrestore(&iommu->register_lock, flags); + } + + /* +@@ -1159,7 +1159,7 @@ int dmar_enable_qi(struct intel_iommu *i + qi->free_head = qi->free_tail = 0; + qi->free_cnt = QI_LENGTH; + +- spin_lock_init(&qi->q_lock); ++ raw_spin_lock_init(&qi->q_lock); + + __dmar_enable_qi(iommu); + +@@ -1225,11 +1225,11 @@ void dmar_msi_unmask(struct irq_data *da + unsigned long flag; + + /* unmask it */ +- spin_lock_irqsave(&iommu->register_lock, flag); ++ raw_spin_lock_irqsave(&iommu->register_lock, flag); + writel(0, iommu->reg + DMAR_FECTL_REG); + /* Read a reg to force flush the post write */ + readl(iommu->reg + DMAR_FECTL_REG); +- spin_unlock_irqrestore(&iommu->register_lock, flag); ++ raw_spin_unlock_irqrestore(&iommu->register_lock, flag); + } + + void dmar_msi_mask(struct irq_data *data) +@@ -1238,11 +1238,11 @@ void dmar_msi_mask(struct irq_data *data + struct intel_iommu *iommu = irq_data_get_irq_handler_data(data); + + /* mask it */ +- spin_lock_irqsave(&iommu->register_lock, flag); ++ raw_spin_lock_irqsave(&iommu->register_lock, flag); + writel(DMA_FECTL_IM, iommu->reg + DMAR_FECTL_REG); + /* Read a reg to force flush the post write */ + readl(iommu->reg + DMAR_FECTL_REG); +- spin_unlock_irqrestore(&iommu->register_lock, flag); ++ raw_spin_unlock_irqrestore(&iommu->register_lock, flag); + } + + void dmar_msi_write(int irq, struct msi_msg *msg) +@@ -1250,11 +1250,11 @@ void dmar_msi_write(int irq, struct msi_ + struct intel_iommu *iommu = irq_get_handler_data(irq); + unsigned long flag; + +- spin_lock_irqsave(&iommu->register_lock, flag); ++ raw_spin_lock_irqsave(&iommu->register_lock, flag); + writel(msg->data, iommu->reg + DMAR_FEDATA_REG); + writel(msg->address_lo, iommu->reg + DMAR_FEADDR_REG); + writel(msg->address_hi, iommu->reg + DMAR_FEUADDR_REG); +- spin_unlock_irqrestore(&iommu->register_lock, flag); ++ raw_spin_unlock_irqrestore(&iommu->register_lock, flag); + } + + void dmar_msi_read(int irq, struct msi_msg *msg) +@@ -1262,11 +1262,11 @@ void dmar_msi_read(int irq, struct msi_m + struct intel_iommu *iommu = irq_get_handler_data(irq); + unsigned long flag; + +- spin_lock_irqsave(&iommu->register_lock, flag); ++ raw_spin_lock_irqsave(&iommu->register_lock, flag); + msg->data = readl(iommu->reg + DMAR_FEDATA_REG); + msg->address_lo = readl(iommu->reg + DMAR_FEADDR_REG); + msg->address_hi = readl(iommu->reg + DMAR_FEUADDR_REG); +- spin_unlock_irqrestore(&iommu->register_lock, flag); ++ raw_spin_unlock_irqrestore(&iommu->register_lock, flag); + } + + static int dmar_fault_do_one(struct intel_iommu *iommu, int type, +@@ -1303,7 +1303,7 @@ irqreturn_t dmar_fault(int irq, void *de + u32 fault_status; + unsigned long flag; + +- spin_lock_irqsave(&iommu->register_lock, flag); ++ raw_spin_lock_irqsave(&iommu->register_lock, flag); + fault_status = readl(iommu->reg + DMAR_FSTS_REG); + if (fault_status) + printk(KERN_ERR "DRHD: handling fault status reg %x\n", +@@ -1342,7 +1342,7 @@ irqreturn_t dmar_fault(int irq, void *de + writel(DMA_FRCD_F, iommu->reg + reg + + fault_index * PRIMARY_FAULT_REG_LEN + 12); + +- spin_unlock_irqrestore(&iommu->register_lock, flag); ++ raw_spin_unlock_irqrestore(&iommu->register_lock, flag); + + dmar_fault_do_one(iommu, type, fault_reason, + source_id, guest_addr); +@@ -1350,14 +1350,14 @@ irqreturn_t dmar_fault(int irq, void *de + fault_index++; + if (fault_index >= cap_num_fault_regs(iommu->cap)) + fault_index = 0; +- spin_lock_irqsave(&iommu->register_lock, flag); ++ raw_spin_lock_irqsave(&iommu->register_lock, flag); + } + clear_rest: + /* clear all the other faults */ + fault_status = readl(iommu->reg + DMAR_FSTS_REG); + writel(fault_status, iommu->reg + DMAR_FSTS_REG); + +- spin_unlock_irqrestore(&iommu->register_lock, flag); ++ raw_spin_unlock_irqrestore(&iommu->register_lock, flag); + return IRQ_HANDLED; + } + +@@ -1388,7 +1388,7 @@ int dmar_set_interrupt(struct intel_iomm + return ret; + } + +- ret = request_irq(irq, dmar_fault, 0, iommu->name, iommu); ++ ret = request_irq(irq, dmar_fault, IRQF_NO_THREAD, iommu->name, iommu); + if (ret) + printk(KERN_ERR "IOMMU: can't request irq\n"); + return ret; Index: linux-2.6/kernel/trace/ftrace.c =================================================================== --- linux-2.6.orig/kernel/trace/ftrace.c @@ -1557,7 +1769,22 @@ Index: linux-2.6/kernel/sched.c #endif void set_user_nice(struct task_struct *p, long nice) -@@ -5543,7 +5588,7 @@ SYSCALL_DEFINE0(sched_yield) +@@ -5009,7 +5054,13 @@ EXPORT_SYMBOL(task_nice); + */ + int idle_cpu(int cpu) + { +- return cpu_curr(cpu) == cpu_rq(cpu)->idle; ++ struct rq *rq = cpu_rq(cpu); ++ ++#ifdef CONFIG_SMP ++ return rq->curr == rq->idle && !rq->nr_running && !rq->wake_list; ++#else ++ return rq->curr == rq->idle && !rq->nr_running; ++#endif + } + + /** +@@ -5543,7 +5594,7 @@ SYSCALL_DEFINE0(sched_yield) __release(rq->lock); spin_release(&rq->lock.dep_map, 1, _THIS_IP_); do_raw_spin_unlock(&rq->lock); @@ -1566,7 +1793,7 @@ Index: linux-2.6/kernel/sched.c schedule(); -@@ -5557,9 +5602,17 @@ static inline int should_resched(void) +@@ -5557,9 +5608,17 @@ static inline int should_resched(void) static void __cond_resched(void) { @@ -1587,7 +1814,7 @@ Index: linux-2.6/kernel/sched.c } int __sched _cond_resched(void) -@@ -5600,6 +5653,7 @@ int __cond_resched_lock(spinlock_t *lock +@@ -5600,6 +5659,7 @@ int __cond_resched_lock(spinlock_t *lock } EXPORT_SYMBOL(__cond_resched_lock); @@ -1595,7 +1822,7 @@ Index: linux-2.6/kernel/sched.c int __sched __cond_resched_softirq(void) { BUG_ON(!in_softirq()); -@@ -5613,6 +5667,7 @@ int __sched __cond_resched_softirq(void) +@@ -5613,6 +5673,7 @@ int __sched __cond_resched_softirq(void) return 0; } EXPORT_SYMBOL(__cond_resched_softirq); @@ -1603,7 +1830,7 @@ Index: linux-2.6/kernel/sched.c /** * yield - yield the current processor to other threads. -@@ -5859,7 +5914,7 @@ void show_state_filter(unsigned long sta +@@ -5859,7 +5920,7 @@ void show_state_filter(unsigned long sta printk(KERN_INFO " task PC stack pid father\n"); #endif @@ -1612,7 +1839,7 @@ Index: linux-2.6/kernel/sched.c do_each_thread(g, p) { /* * reset the NMI-timeout, listing all files on a slow -@@ -5875,7 +5930,7 @@ void show_state_filter(unsigned long sta +@@ -5875,7 +5936,7 @@ void show_state_filter(unsigned long sta #ifdef CONFIG_SCHED_DEBUG sysrq_sched_debug_show(); #endif @@ -1621,7 +1848,7 @@ Index: linux-2.6/kernel/sched.c /* * Only show locks if all tasks are dumped: */ -@@ -5997,12 +6052,12 @@ static inline void sched_init_granularit +@@ -5997,12 +6058,12 @@ static inline void sched_init_granularit #ifdef CONFIG_SMP void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask) { @@ -1638,7 +1865,7 @@ Index: linux-2.6/kernel/sched.c } /* -@@ -6053,7 +6108,7 @@ int set_cpus_allowed_ptr(struct task_str +@@ -6053,7 +6114,7 @@ int set_cpus_allowed_ptr(struct task_str do_set_cpus_allowed(p, new_mask); /* Can the task run on the task's current CPU? If so, we're done */ @@ -1647,7 +1874,7 @@ Index: linux-2.6/kernel/sched.c goto out; dest_cpu = cpumask_any_and(cpu_active_mask, new_mask); -@@ -6072,6 +6127,124 @@ out: +@@ -6072,6 +6133,124 @@ out: } EXPORT_SYMBOL_GPL(set_cpus_allowed_ptr); @@ -1772,7 +1999,7 @@ Index: linux-2.6/kernel/sched.c /* * Move (not current) task off this cpu, onto dest cpu. We're doing * this because either it can't run here any more (set_cpus_allowed() -@@ -6100,7 +6273,7 @@ static int __migrate_task(struct task_st +@@ -6100,7 +6279,7 @@ static int __migrate_task(struct task_st if (task_cpu(p) != src_cpu) goto done; /* Affinity changed (again). */ @@ -1781,7 +2008,7 @@ Index: linux-2.6/kernel/sched.c goto fail; /* -@@ -6142,6 +6315,8 @@ static int migration_cpu_stop(void *data +@@ -6142,6 +6321,8 @@ static int migration_cpu_stop(void *data #ifdef CONFIG_HOTPLUG_CPU @@ -1790,7 +2017,7 @@ Index: linux-2.6/kernel/sched.c /* * Ensures that the idle task is using init_mm right before its cpu goes * offline. -@@ -6154,7 +6329,12 @@ void idle_task_exit(void) +@@ -6154,7 +6335,12 @@ void idle_task_exit(void) if (mm != &init_mm) switch_mm(mm, &init_mm, current); @@ -1804,7 +2031,7 @@ Index: linux-2.6/kernel/sched.c } /* -@@ -6472,6 +6652,12 @@ migration_call(struct notifier_block *nf +@@ -6472,6 +6658,12 @@ migration_call(struct notifier_block *nf migrate_nr_uninterruptible(rq); calc_global_load_remove(rq); break; @@ -1817,7 +2044,7 @@ Index: linux-2.6/kernel/sched.c #endif } -@@ -8188,7 +8374,8 @@ void __init sched_init(void) +@@ -8188,7 +8380,8 @@ void __init sched_init(void) #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP static inline int preempt_count_equals(int preempt_offset) { @@ -2089,327 +2316,6 @@ Index: linux-2.6/kernel/workqueue_sched.h - unsigned int cpu); +void wq_worker_running(struct task_struct *task); +void wq_worker_sleeping(struct task_struct *task); -Index: linux-2.6/arch/x86/kernel/cpu/intel_cacheinfo.c -=================================================================== ---- linux-2.6.orig/arch/x86/kernel/cpu/intel_cacheinfo.c -+++ linux-2.6/arch/x86/kernel/cpu/intel_cacheinfo.c -@@ -151,28 +151,17 @@ union _cpuid4_leaf_ecx { - u32 full; - }; - --struct amd_l3_cache { -- struct amd_northbridge *nb; -- unsigned indices; -- u8 subcaches[4]; --}; -- --struct _cpuid4_info { -+struct _cpuid4_info_regs { - union _cpuid4_leaf_eax eax; - union _cpuid4_leaf_ebx ebx; - union _cpuid4_leaf_ecx ecx; - unsigned long size; -- struct amd_l3_cache *l3; -- DECLARE_BITMAP(shared_cpu_map, NR_CPUS); -+ struct amd_northbridge *nb; - }; - --/* subset of above _cpuid4_info w/o shared_cpu_map */ --struct _cpuid4_info_regs { -- union _cpuid4_leaf_eax eax; -- union _cpuid4_leaf_ebx ebx; -- union _cpuid4_leaf_ecx ecx; -- unsigned long size; -- struct amd_l3_cache *l3; -+struct _cpuid4_info { -+ struct _cpuid4_info_regs base; -+ DECLARE_BITMAP(shared_cpu_map, NR_CPUS); - }; - - unsigned short num_cache_leaves; -@@ -314,12 +303,13 @@ struct _cache_attr { - /* - * L3 cache descriptors - */ --static void __cpuinit amd_calc_l3_indices(struct amd_l3_cache *l3) -+static void __cpuinit amd_calc_l3_indices(struct amd_northbridge *nb) - { -+ struct amd_l3_cache *l3 = &nb->l3_cache; - unsigned int sc0, sc1, sc2, sc3; - u32 val = 0; - -- pci_read_config_dword(l3->nb->misc, 0x1C4, &val); -+ pci_read_config_dword(nb->misc, 0x1C4, &val); - - /* calculate subcache sizes */ - l3->subcaches[0] = sc0 = !(val & BIT(0)); -@@ -333,33 +323,16 @@ static void __cpuinit amd_calc_l3_indice - static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, - int index) - { -- static struct amd_l3_cache *__cpuinitdata l3_caches; - int node; - - /* only for L3, and not in virtualized environments */ -- if (index < 3 || amd_nb_num() == 0) -+ if (index < 3) - return; - -- /* -- * Strictly speaking, the amount in @size below is leaked since it is -- * never freed but this is done only on shutdown so it doesn't matter. -- */ -- if (!l3_caches) { -- int size = amd_nb_num() * sizeof(struct amd_l3_cache); -- -- l3_caches = kzalloc(size, GFP_ATOMIC); -- if (!l3_caches) -- return; -- } -- - node = amd_get_nb_id(smp_processor_id()); -- -- if (!l3_caches[node].nb) { -- l3_caches[node].nb = node_to_amd_nb(node); -- amd_calc_l3_indices(&l3_caches[node]); -- } -- -- this_leaf->l3 = &l3_caches[node]; -+ this_leaf->nb = node_to_amd_nb(node); -+ if (this_leaf->nb && !this_leaf->nb->l3_cache.indices) -+ amd_calc_l3_indices(this_leaf->nb); - } - - /* -@@ -369,11 +342,11 @@ static void __cpuinit amd_init_l3_cache( - * - * @returns: the disabled index if used or negative value if slot free. - */ --int amd_get_l3_disable_slot(struct amd_l3_cache *l3, unsigned slot) -+int amd_get_l3_disable_slot(struct amd_northbridge *nb, unsigned slot) - { - unsigned int reg = 0; - -- pci_read_config_dword(l3->nb->misc, 0x1BC + slot * 4, ®); -+ pci_read_config_dword(nb->misc, 0x1BC + slot * 4, ®); - - /* check whether this slot is activated already */ - if (reg & (3UL << 30)) -@@ -387,11 +360,10 @@ static ssize_t show_cache_disable(struct - { - int index; - -- if (!this_leaf->l3 || -- !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) -+ if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) - return -EINVAL; - -- index = amd_get_l3_disable_slot(this_leaf->l3, slot); -+ index = amd_get_l3_disable_slot(this_leaf->base.nb, slot); - if (index >= 0) - return sprintf(buf, "%d\n", index); - -@@ -408,7 +380,7 @@ show_cache_disable_##slot(struct _cpuid4 - SHOW_CACHE_DISABLE(0) - SHOW_CACHE_DISABLE(1) - --static void amd_l3_disable_index(struct amd_l3_cache *l3, int cpu, -+static void amd_l3_disable_index(struct amd_northbridge *nb, int cpu, - unsigned slot, unsigned long idx) - { - int i; -@@ -421,10 +393,10 @@ static void amd_l3_disable_index(struct - for (i = 0; i < 4; i++) { - u32 reg = idx | (i << 20); - -- if (!l3->subcaches[i]) -+ if (!nb->l3_cache.subcaches[i]) - continue; - -- pci_write_config_dword(l3->nb->misc, 0x1BC + slot * 4, reg); -+ pci_write_config_dword(nb->misc, 0x1BC + slot * 4, reg); - - /* - * We need to WBINVD on a core on the node containing the L3 -@@ -434,7 +406,7 @@ static void amd_l3_disable_index(struct - wbinvd_on_cpu(cpu); - - reg |= BIT(31); -- pci_write_config_dword(l3->nb->misc, 0x1BC + slot * 4, reg); -+ pci_write_config_dword(nb->misc, 0x1BC + slot * 4, reg); - } - } - -@@ -448,24 +420,24 @@ static void amd_l3_disable_index(struct - * - * @return: 0 on success, error status on failure - */ --int amd_set_l3_disable_slot(struct amd_l3_cache *l3, int cpu, unsigned slot, -+int amd_set_l3_disable_slot(struct amd_northbridge *nb, int cpu, unsigned slot, - unsigned long index) - { - int ret = 0; - - /* check if @slot is already used or the index is already disabled */ -- ret = amd_get_l3_disable_slot(l3, slot); -+ ret = amd_get_l3_disable_slot(nb, slot); - if (ret >= 0) - return -EINVAL; - -- if (index > l3->indices) -+ if (index > nb->l3_cache.indices) - return -EINVAL; - - /* check whether the other slot has disabled the same index already */ -- if (index == amd_get_l3_disable_slot(l3, !slot)) -+ if (index == amd_get_l3_disable_slot(nb, !slot)) - return -EINVAL; - -- amd_l3_disable_index(l3, cpu, slot, index); -+ amd_l3_disable_index(nb, cpu, slot, index); - - return 0; - } -@@ -480,8 +452,7 @@ static ssize_t store_cache_disable(struc - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - -- if (!this_leaf->l3 || -- !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) -+ if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) - return -EINVAL; - - cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map)); -@@ -489,7 +460,7 @@ static ssize_t store_cache_disable(struc - if (strict_strtoul(buf, 10, &val) < 0) - return -EINVAL; - -- err = amd_set_l3_disable_slot(this_leaf->l3, cpu, slot, val); -+ err = amd_set_l3_disable_slot(this_leaf->base.nb, cpu, slot, val); - if (err) { - if (err == -EEXIST) - printk(KERN_WARNING "L3 disable slot %d in use!\n", -@@ -518,7 +489,7 @@ static struct _cache_attr cache_disable_ - static ssize_t - show_subcaches(struct _cpuid4_info *this_leaf, char *buf, unsigned int cpu) - { -- if (!this_leaf->l3 || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) -+ if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) - return -EINVAL; - - return sprintf(buf, "%x\n", amd_get_subcaches(cpu)); -@@ -533,7 +504,7 @@ store_subcaches(struct _cpuid4_info *thi - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - -- if (!this_leaf->l3 || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) -+ if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) - return -EINVAL; - - if (strict_strtoul(buf, 16, &val) < 0) -@@ -769,7 +740,7 @@ static void __cpuinit cache_shared_cpu_m - return; - } - this_leaf = CPUID4_INFO_IDX(cpu, index); -- num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing; -+ num_threads_sharing = 1 + this_leaf->base.eax.split.num_threads_sharing; - - if (num_threads_sharing == 1) - cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map)); -@@ -820,29 +791,19 @@ static void __cpuinit free_cache_attribu - for (i = 0; i < num_cache_leaves; i++) - cache_remove_shared_cpu_map(cpu, i); - -- kfree(per_cpu(ici_cpuid4_info, cpu)->l3); - kfree(per_cpu(ici_cpuid4_info, cpu)); - per_cpu(ici_cpuid4_info, cpu) = NULL; - } - --static int --__cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) --{ -- struct _cpuid4_info_regs *leaf_regs = -- (struct _cpuid4_info_regs *)this_leaf; -- -- return cpuid4_cache_lookup_regs(index, leaf_regs); --} -- - static void __cpuinit get_cpu_leaves(void *_retval) - { - int j, *retval = _retval, cpu = smp_processor_id(); - - /* Do cpuid and store the results */ - for (j = 0; j < num_cache_leaves; j++) { -- struct _cpuid4_info *this_leaf; -- this_leaf = CPUID4_INFO_IDX(cpu, j); -- *retval = cpuid4_cache_lookup(j, this_leaf); -+ struct _cpuid4_info *this_leaf = CPUID4_INFO_IDX(cpu, j); -+ -+ *retval = cpuid4_cache_lookup_regs(j, &this_leaf->base); - if (unlikely(*retval < 0)) { - int i; - -@@ -900,16 +861,16 @@ static ssize_t show_##file_name(struct _ - return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \ - } - --show_one_plus(level, eax.split.level, 0); --show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1); --show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1); --show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1); --show_one_plus(number_of_sets, ecx.split.number_of_sets, 1); -+show_one_plus(level, base.eax.split.level, 0); -+show_one_plus(coherency_line_size, base.ebx.split.coherency_line_size, 1); -+show_one_plus(physical_line_partition, base.ebx.split.physical_line_partition, 1); -+show_one_plus(ways_of_associativity, base.ebx.split.ways_of_associativity, 1); -+show_one_plus(number_of_sets, base.ecx.split.number_of_sets, 1); - - static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf, - unsigned int cpu) - { -- return sprintf(buf, "%luK\n", this_leaf->size / 1024); -+ return sprintf(buf, "%luK\n", this_leaf->base.size / 1024); - } - - static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf, -@@ -946,7 +907,7 @@ static inline ssize_t show_shared_cpu_li - static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf, - unsigned int cpu) - { -- switch (this_leaf->eax.split.type) { -+ switch (this_leaf->base.eax.split.type) { - case CACHE_TYPE_DATA: - return sprintf(buf, "Data\n"); - case CACHE_TYPE_INST: -@@ -1135,7 +1096,7 @@ static int __cpuinit cache_add_dev(struc - - ktype_cache.default_attrs = default_attrs; - #ifdef CONFIG_AMD_NB -- if (this_leaf->l3) -+ if (this_leaf->base.nb) - ktype_cache.default_attrs = amd_l3_attrs(); - #endif - retval = kobject_init_and_add(&(this_object->kobj), -Index: linux-2.6/arch/x86/include/asm/amd_nb.h -=================================================================== ---- linux-2.6.orig/arch/x86/include/asm/amd_nb.h -+++ linux-2.6/arch/x86/include/asm/amd_nb.h -@@ -19,9 +19,15 @@ extern int amd_numa_init(void); - extern int amd_get_subcaches(int); - extern int amd_set_subcaches(int, int); - -+struct amd_l3_cache { -+ unsigned indices; -+ u8 subcaches[4]; -+}; -+ - struct amd_northbridge { - struct pci_dev *misc; - struct pci_dev *link; -+ struct amd_l3_cache l3_cache; - }; - - struct amd_northbridge_info { Index: linux-2.6/arch/mips/sibyte/sb1250/irq.c =================================================================== --- linux-2.6.orig/arch/mips/sibyte/sb1250/irq.c @@ -2794,6 +2700,18 @@ Index: linux-2.6/arch/mips/kernel/signal.c if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else +Index: linux-2.6/arch/mips/kernel/i8259.c +=================================================================== +--- linux-2.6.orig/arch/mips/kernel/i8259.c ++++ linux-2.6/arch/mips/kernel/i8259.c +@@ -295,6 +295,7 @@ static void init_8259A(int auto_eoi) + static struct irqaction irq2 = { + .handler = no_action, + .name = "cascade", ++ .flags = IRQF_NO_THREAD, + }; + + static struct resource pic1_io_resource = { Index: linux-2.6/arch/arm/kernel/signal.c =================================================================== --- linux-2.6.orig/arch/arm/kernel/signal.c @@ -2869,18 +2787,68 @@ Index: linux-2.6/arch/arm/kernel/smp.c } set_cpu_online(cpu, false); -Index: linux-2.6/arch/mips/kernel/i8259.c +Index: linux-2.6/kernel/watchdog.c =================================================================== ---- linux-2.6.orig/arch/mips/kernel/i8259.c -+++ linux-2.6/arch/mips/kernel/i8259.c -@@ -295,6 +295,7 @@ static void init_8259A(int auto_eoi) - static struct irqaction irq2 = { - .handler = no_action, - .name = "cascade", -+ .flags = IRQF_NO_THREAD, +--- linux-2.6.orig/kernel/watchdog.c ++++ linux-2.6/kernel/watchdog.c +@@ -208,6 +208,8 @@ static struct perf_event_attr wd_hw_attr + .disabled = 1, }; - static struct resource pic1_io_resource = { ++static DEFINE_RAW_SPINLOCK(watchdog_output_lock); ++ + /* Callback function for perf event subsystem */ + static void watchdog_overflow_callback(struct perf_event *event, int nmi, + struct perf_sample_data *data, +@@ -234,10 +236,19 @@ static void watchdog_overflow_callback(s + if (__this_cpu_read(hard_watchdog_warn) == true) + return; + +- if (hardlockup_panic) ++ /* ++ * If early-printk is enabled then make sure we do not ++ * lock up in printk() and kill console logging: ++ */ ++ printk_kill(); ++ ++ if (hardlockup_panic) { + panic("Watchdog detected hard LOCKUP on cpu %d", this_cpu); +- else ++ } else { ++ raw_spin_lock(&watchdog_output_lock); + WARN(1, "Watchdog detected hard LOCKUP on cpu %d", this_cpu); ++ raw_spin_unlock(&watchdog_output_lock); ++ } + + __this_cpu_write(hard_watchdog_warn, true); + return; +@@ -320,7 +331,7 @@ static enum hrtimer_restart watchdog_tim + */ + static int watchdog(void *unused) + { +- static struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; ++ struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; + struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer); + + sched_setscheduler(current, SCHED_FIFO, ¶m); +@@ -349,7 +360,8 @@ static int watchdog(void *unused) + set_current_state(TASK_INTERRUPTIBLE); + } + __set_current_state(TASK_RUNNING); +- ++ param.sched_priority = 0; ++ sched_setscheduler(current, SCHED_NORMAL, ¶m); + return 0; + } + +@@ -422,6 +434,7 @@ static void watchdog_prepare_cpu(int cpu + WARN_ON(per_cpu(softlockup_watchdog, cpu)); + hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer->function = watchdog_timer_fn; ++ hrtimer->irqsafe = 1; + } + + static int watchdog_enable(int cpu) Index: linux-2.6/kernel/time/clocksource.c =================================================================== --- linux-2.6.orig/kernel/time/clocksource.c @@ -2971,68 +2939,6 @@ Index: linux-2.6/kernel/time/clocksource.c } static void clocksource_enqueue_watchdog(struct clocksource *cs) -Index: linux-2.6/kernel/watchdog.c -=================================================================== ---- linux-2.6.orig/kernel/watchdog.c -+++ linux-2.6/kernel/watchdog.c -@@ -208,6 +208,8 @@ static struct perf_event_attr wd_hw_attr - .disabled = 1, - }; - -+static DEFINE_RAW_SPINLOCK(watchdog_output_lock); -+ - /* Callback function for perf event subsystem */ - static void watchdog_overflow_callback(struct perf_event *event, int nmi, - struct perf_sample_data *data, -@@ -234,10 +236,19 @@ static void watchdog_overflow_callback(s - if (__this_cpu_read(hard_watchdog_warn) == true) - return; - -- if (hardlockup_panic) -+ /* -+ * If early-printk is enabled then make sure we do not -+ * lock up in printk() and kill console logging: -+ */ -+ printk_kill(); -+ -+ if (hardlockup_panic) { - panic("Watchdog detected hard LOCKUP on cpu %d", this_cpu); -- else -+ } else { -+ raw_spin_lock(&watchdog_output_lock); - WARN(1, "Watchdog detected hard LOCKUP on cpu %d", this_cpu); -+ raw_spin_unlock(&watchdog_output_lock); -+ } - - __this_cpu_write(hard_watchdog_warn, true); - return; -@@ -320,7 +331,7 @@ static enum hrtimer_restart watchdog_tim - */ - static int watchdog(void *unused) - { -- static struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; -+ struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; - struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer); - - sched_setscheduler(current, SCHED_FIFO, ¶m); -@@ -349,7 +360,8 @@ static int watchdog(void *unused) - set_current_state(TASK_INTERRUPTIBLE); - } - __set_current_state(TASK_RUNNING); -- -+ param.sched_priority = 0; -+ sched_setscheduler(current, SCHED_NORMAL, ¶m); - return 0; - } - -@@ -422,6 +434,7 @@ static void watchdog_prepare_cpu(int cpu - WARN_ON(per_cpu(softlockup_watchdog, cpu)); - hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - hrtimer->function = watchdog_timer_fn; -+ hrtimer->irqsafe = 1; - } - - static int watchdog_enable(int cpu) Index: linux-2.6/kernel/rtmutex-debug.c =================================================================== --- linux-2.6.orig/kernel/rtmutex-debug.c @@ -3175,1369 +3081,6 @@ Index: linux-2.6/kernel/rtmutex-debug.c memset(waiter, 0x22, sizeof(*waiter)); } -Index: linux-2.6/arch/arm/kernel/perf_event.c -=================================================================== ---- linux-2.6.orig/arch/arm/kernel/perf_event.c -+++ linux-2.6/arch/arm/kernel/perf_event.c -@@ -420,7 +420,7 @@ armpmu_reserve_hardware(void) - continue; - - err = request_irq(irq, handle_irq, -- IRQF_DISABLED | IRQF_NOBALANCING, -+ IRQF_DISABLED | IRQF_NOBALANCING | IRQF_NO_THREAD, - "armpmu", NULL); - if (err) { - pr_warning("unable to request IRQ%d for ARM perf " -Index: linux-2.6/arch/arm/Kconfig -=================================================================== ---- linux-2.6.orig/arch/arm/Kconfig -+++ linux-2.6/arch/arm/Kconfig -@@ -29,6 +29,7 @@ config ARM - select HAVE_GENERIC_HARDIRQS - select HAVE_SPARSE_IRQ - select GENERIC_IRQ_SHOW -+ select IRQ_FORCED_THREADING - help - The ARM series is a line of low-power-consumption RISC chip designs - licensed by ARM Ltd and targeted at embedded applications and -@@ -1510,7 +1511,7 @@ config HAVE_ARCH_PFN_VALID - - config HIGHMEM - bool "High Memory Support" -- depends on MMU -+ depends on MMU && !PREEMPT_RT_FULL - help - The address space of ARM processors is only 4 Gigabytes large - and it has to accommodate user address space, kernel address -Index: linux-2.6/arch/powerpc/platforms/85xx/mpc85xx_cds.c -=================================================================== ---- linux-2.6.orig/arch/powerpc/platforms/85xx/mpc85xx_cds.c -+++ linux-2.6/arch/powerpc/platforms/85xx/mpc85xx_cds.c -@@ -178,7 +178,7 @@ static irqreturn_t mpc85xx_8259_cascade_ - - static struct irqaction mpc85xxcds_8259_irqaction = { - .handler = mpc85xx_8259_cascade_action, -- .flags = IRQF_SHARED, -+ .flags = IRQF_SHARED | IRQF_NO_THREAD, - .name = "8259 cascade", - }; - #endif /* PPC_I8259 */ -Index: linux-2.6/arch/powerpc/Kconfig -=================================================================== ---- linux-2.6.orig/arch/powerpc/Kconfig -+++ linux-2.6/arch/powerpc/Kconfig -@@ -69,10 +69,11 @@ config LOCKDEP_SUPPORT - - config RWSEM_GENERIC_SPINLOCK - bool -+ default y if PREEMPT_RT_FULL - - config RWSEM_XCHGADD_ALGORITHM - bool -- default y -+ default y if !PREEMPT_RT_FULL - - config GENERIC_LOCKBREAK - bool -@@ -134,6 +135,7 @@ config PPC - select GENERIC_IRQ_SHOW_LEVEL - select HAVE_RCU_TABLE_FREE if SMP - select HAVE_SYSCALL_TRACEPOINTS -+ select IRQ_FORCED_THREADING - - config EARLY_PRINTK - bool -@@ -271,7 +273,7 @@ menu "Kernel options" - - config HIGHMEM - bool "High memory support" -- depends on PPC32 -+ depends on PPC32 && !PREEMPT_RT_FULL - - source kernel/time/Kconfig - source kernel/Kconfig.hz -Index: linux-2.6/include/linux/sched.h -=================================================================== ---- linux-2.6.orig/include/linux/sched.h -+++ linux-2.6/include/linux/sched.h -@@ -63,6 +63,7 @@ struct sched_param { - #include - #include - -+#include - #include - #include - #include -@@ -90,6 +91,7 @@ struct sched_param { - #include - #include - #include -+#include - - #include - -@@ -359,6 +361,7 @@ extern signed long schedule_timeout_inte - extern signed long schedule_timeout_killable(signed long timeout); - extern signed long schedule_timeout_uninterruptible(signed long timeout); - asmlinkage void schedule(void); -+extern void schedule_preempt_disabled(void); - extern int mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner); - - struct nsproxy; -@@ -510,7 +513,7 @@ struct task_cputime { - struct thread_group_cputimer { - struct task_cputime cputime; - int running; -- spinlock_t lock; -+ raw_spinlock_t lock; - }; - - #include -@@ -1070,6 +1073,7 @@ struct sched_domain; - #define WF_SYNC 0x01 /* waker goes to sleep after wakup */ - #define WF_FORK 0x02 /* child wakeup after fork */ - #define WF_MIGRATED 0x04 /* internal use, task got migrated */ -+#define WF_LOCK_SLEEPER 0x08 /* wakeup spinlock "sleeper" */ - - #define ENQUEUE_WAKEUP 1 - #define ENQUEUE_HEAD 2 -@@ -1219,6 +1223,7 @@ enum perf_event_task_context { - - struct task_struct { - volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ -+ volatile long saved_state; /* saved state for "spinlock sleepers" */ - void *stack; - atomic_t usage; - unsigned int flags; /* per process flags, defined below */ -@@ -1255,14 +1260,17 @@ struct task_struct { - #endif - - unsigned int policy; -+#ifdef CONFIG_PREEMPT_RT_FULL -+ int migrate_disable; -+#ifdef CONFIG_SCHED_DEBUG -+ int migrate_disable_atomic; -+#endif -+#endif - cpumask_t cpus_allowed; - - #ifdef CONFIG_PREEMPT_RCU - int rcu_read_lock_nesting; - char rcu_read_unlock_special; --#if defined(CONFIG_RCU_BOOST) && defined(CONFIG_TREE_PREEMPT_RCU) -- int rcu_boosted; --#endif /* #if defined(CONFIG_RCU_BOOST) && defined(CONFIG_TREE_PREEMPT_RCU) */ - struct list_head rcu_node_entry; - #endif /* #ifdef CONFIG_PREEMPT_RCU */ - #ifdef CONFIG_TREE_PREEMPT_RCU -@@ -1356,6 +1364,9 @@ struct task_struct { - - struct task_cputime cputime_expires; - struct list_head cpu_timers[3]; -+#ifdef CONFIG_PREEMPT_RT_BASE -+ struct task_struct *posix_timer_list; -+#endif - - /* process credentials */ - const struct cred __rcu *real_cred; /* objective and real subjective task -@@ -1389,6 +1400,7 @@ struct task_struct { - /* signal handlers */ - struct signal_struct *signal; - struct sighand_struct *sighand; -+ struct sigqueue *sigqueue_cache; - - sigset_t blocked, real_blocked; - sigset_t saved_sigmask; /* restored if set_restore_sigmask() was used */ -@@ -1432,6 +1444,9 @@ struct task_struct { - /* mutex deadlock detection */ - struct mutex_waiter *blocked_on; - #endif -+#ifdef CONFIG_PREEMPT_RT_FULL -+ int pagefault_disabled; -+#endif - #ifdef CONFIG_TRACE_IRQFLAGS - unsigned int irq_events; - unsigned long hardirq_enable_ip; -@@ -1558,6 +1573,12 @@ struct task_struct { - unsigned long trace; - /* bitmask and counter of trace recursion */ - unsigned long trace_recursion; -+#ifdef CONFIG_WAKEUP_LATENCY_HIST -+ u64 preempt_timestamp_hist; -+#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST -+ unsigned long timer_offset; -+#endif -+#endif - #endif /* CONFIG_TRACING */ - #ifdef CONFIG_CGROUP_MEM_RES_CTLR /* memcg uses this to do batch job */ - struct memcg_batch_info { -@@ -1570,10 +1591,26 @@ struct task_struct { - #ifdef CONFIG_HAVE_HW_BREAKPOINT - atomic_t ptrace_bp_refcnt; - #endif -+#ifdef CONFIG_PREEMPT_RT_BASE -+ struct rcu_head put_rcu; -+ int softirq_nestcnt; -+#endif -+#if defined CONFIG_PREEMPT_RT_FULL && defined CONFIG_HIGHMEM -+ int kmap_idx; -+ pte_t kmap_pte[KM_TYPE_NR]; -+#endif - }; - --/* Future-safe accessor for struct task_struct's cpus_allowed. */ --#define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed) -+#ifdef CONFIG_PREEMPT_RT_FULL -+static inline bool cur_pf_disabled(void) { return current->pagefault_disabled; } -+#else -+static inline bool cur_pf_disabled(void) { return false; } -+#endif -+ -+static inline bool pagefault_disabled(void) -+{ -+ return in_atomic() || cur_pf_disabled(); -+} - - /* - * Priority of a process goes from 0..MAX_PRIO-1, valid RT -@@ -1743,6 +1780,15 @@ extern struct pid *cad_pid; - extern void free_task(struct task_struct *tsk); - #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) - -+#ifdef CONFIG_PREEMPT_RT_BASE -+extern void __put_task_struct_cb(struct rcu_head *rhp); -+ -+static inline void put_task_struct(struct task_struct *t) -+{ -+ if (atomic_dec_and_test(&t->usage)) -+ call_rcu(&t->put_rcu, __put_task_struct_cb); -+} -+#else - extern void __put_task_struct(struct task_struct *t); - - static inline void put_task_struct(struct task_struct *t) -@@ -1750,6 +1796,7 @@ static inline void put_task_struct(struc - if (atomic_dec_and_test(&t->usage)) - __put_task_struct(t); - } -+#endif - - extern void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st); - extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st); -@@ -1774,6 +1821,7 @@ extern void thread_group_times(struct ta - #define PF_FROZEN 0x00010000 /* frozen for system suspend */ - #define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */ - #define PF_KSWAPD 0x00040000 /* I am kswapd */ -+#define PF_STOMPER 0x00080000 /* I am a stomp machine thread */ - #define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */ - #define PF_KTHREAD 0x00200000 /* I am a kernel thread */ - #define PF_RANDOMIZE 0x00400000 /* randomize virtual address space */ -@@ -2022,15 +2070,27 @@ static inline void sched_autogroup_exit( - #endif - - #ifdef CONFIG_RT_MUTEXES -+extern void task_setprio(struct task_struct *p, int prio); - extern int rt_mutex_getprio(struct task_struct *p); --extern void rt_mutex_setprio(struct task_struct *p, int prio); -+static inline void rt_mutex_setprio(struct task_struct *p, int prio) -+{ -+ task_setprio(p, prio); -+} - extern void rt_mutex_adjust_pi(struct task_struct *p); -+static inline bool tsk_is_pi_blocked(struct task_struct *tsk) -+{ -+ return tsk->pi_blocked_on != NULL; -+} - #else - static inline int rt_mutex_getprio(struct task_struct *p) - { - return p->normal_prio; - } - # define rt_mutex_adjust_pi(p) do { } while (0) -+static inline bool tsk_is_pi_blocked(struct task_struct *tsk) -+{ -+ return false; -+} - #endif - - extern bool yield_to(struct task_struct *p, bool preempt); -@@ -2110,6 +2170,7 @@ extern void xtime_update(unsigned long t - - extern int wake_up_state(struct task_struct *tsk, unsigned int state); - extern int wake_up_process(struct task_struct *tsk); -+extern int wake_up_lock_sleeper(struct task_struct * tsk); - extern void wake_up_new_task(struct task_struct *tsk); - #ifdef CONFIG_SMP - extern void kick_process(struct task_struct *tsk); -@@ -2199,12 +2260,24 @@ extern struct mm_struct * mm_alloc(void) - - /* mmdrop drops the mm and the page tables */ - extern void __mmdrop(struct mm_struct *); -+ - static inline void mmdrop(struct mm_struct * mm) - { - if (unlikely(atomic_dec_and_test(&mm->mm_count))) - __mmdrop(mm); - } - -+#ifdef CONFIG_PREEMPT_RT_BASE -+extern void __mmdrop_delayed(struct rcu_head *rhp); -+static inline void mmdrop_delayed(struct mm_struct *mm) -+{ -+ if (atomic_dec_and_test(&mm->mm_count)) -+ call_rcu(&mm->delayed_drop, __mmdrop_delayed); -+} -+#else -+# define mmdrop_delayed(mm) mmdrop(mm) -+#endif -+ - /* mmput gets rid of the mappings and all user-space */ - extern void mmput(struct mm_struct *); - /* Grab a reference to a task's mm, if it is not already going away */ -@@ -2510,7 +2583,7 @@ extern int _cond_resched(void); - - extern int __cond_resched_lock(spinlock_t *lock); - --#ifdef CONFIG_PREEMPT -+#if defined(CONFIG_PREEMPT) && !defined(CONFIG_PREEMPT_RT_FULL) - #define PREEMPT_LOCK_OFFSET PREEMPT_OFFSET - #else - #define PREEMPT_LOCK_OFFSET 0 -@@ -2521,12 +2594,16 @@ extern int __cond_resched_lock(spinlock_ - __cond_resched_lock(lock); \ - }) - -+#ifndef CONFIG_PREEMPT_RT_FULL - extern int __cond_resched_softirq(void); - - #define cond_resched_softirq() ({ \ - __might_sleep(__FILE__, __LINE__, SOFTIRQ_DISABLE_OFFSET); \ - __cond_resched_softirq(); \ - }) -+#else -+# define cond_resched_softirq() cond_resched() -+#endif - - /* - * Does a critical section need to be broken due to another -@@ -2550,7 +2627,7 @@ void thread_group_cputimer(struct task_s - - static inline void thread_group_cputime_init(struct signal_struct *sig) - { -- spin_lock_init(&sig->cputimer.lock); -+ raw_spin_lock_init(&sig->cputimer.lock); - } - - /* -@@ -2589,6 +2666,26 @@ static inline void set_task_cpu(struct t - - #endif /* CONFIG_SMP */ - -+static inline int __migrate_disabled(struct task_struct *p) -+{ -+#ifdef CONFIG_PREEMPT_RT_FULL -+ return p->migrate_disable; -+#else -+ return 0; -+#endif -+} -+ -+/* Future-safe accessor for struct task_struct's cpus_allowed. */ -+static inline const struct cpumask *tsk_cpus_allowed(struct task_struct *p) -+{ -+#ifdef CONFIG_PREEMPT_RT_FULL -+ if (p->migrate_disable) -+ return cpumask_of(task_cpu(p)); -+#endif -+ -+ return &p->cpus_allowed; -+} -+ - extern long sched_setaffinity(pid_t pid, const struct cpumask *new_mask); - extern long sched_getaffinity(pid_t pid, struct cpumask *mask); - -Index: linux-2.6/arch/arm/kernel/process.c -=================================================================== ---- linux-2.6.orig/arch/arm/kernel/process.c -+++ linux-2.6/arch/arm/kernel/process.c -@@ -209,9 +209,7 @@ void cpu_idle(void) - } - leds_event(led_idle_end); - tick_nohz_restart_sched_tick(); -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/avr32/kernel/process.c -=================================================================== ---- linux-2.6.orig/arch/avr32/kernel/process.c -+++ linux-2.6/arch/avr32/kernel/process.c -@@ -38,9 +38,7 @@ void cpu_idle(void) - while (!need_resched()) - cpu_idle_sleep(); - tick_nohz_restart_sched_tick(); -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/blackfin/kernel/process.c -=================================================================== ---- linux-2.6.orig/arch/blackfin/kernel/process.c -+++ linux-2.6/arch/blackfin/kernel/process.c -@@ -92,9 +92,7 @@ void cpu_idle(void) - while (!need_resched()) - idle(); - tick_nohz_restart_sched_tick(); -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/cris/kernel/process.c -=================================================================== ---- linux-2.6.orig/arch/cris/kernel/process.c -+++ linux-2.6/arch/cris/kernel/process.c -@@ -115,9 +115,7 @@ void cpu_idle (void) - idle = default_idle; - idle(); - } -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/frv/kernel/process.c -=================================================================== ---- linux-2.6.orig/arch/frv/kernel/process.c -+++ linux-2.6/arch/frv/kernel/process.c -@@ -92,9 +92,7 @@ void cpu_idle(void) - idle(); - } - -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/h8300/kernel/process.c -=================================================================== ---- linux-2.6.orig/arch/h8300/kernel/process.c -+++ linux-2.6/arch/h8300/kernel/process.c -@@ -81,9 +81,7 @@ void cpu_idle(void) - while (1) { - while (!need_resched()) - idle(); -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/ia64/kernel/process.c -=================================================================== ---- linux-2.6.orig/arch/ia64/kernel/process.c -+++ linux-2.6/arch/ia64/kernel/process.c -@@ -330,9 +330,7 @@ cpu_idle (void) - normal_xtp(); - #endif - } -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - check_pgt_cache(); - if (cpu_is_offline(cpu)) - play_dead(); -Index: linux-2.6/arch/m32r/kernel/process.c -=================================================================== ---- linux-2.6.orig/arch/m32r/kernel/process.c -+++ linux-2.6/arch/m32r/kernel/process.c -@@ -90,9 +90,7 @@ void cpu_idle (void) - - idle(); - } -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/m68k/kernel/process_mm.c -=================================================================== ---- linux-2.6.orig/arch/m68k/kernel/process_mm.c -+++ linux-2.6/arch/m68k/kernel/process_mm.c -@@ -94,9 +94,7 @@ void cpu_idle(void) - while (1) { - while (!need_resched()) - idle(); -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/m68k/kernel/process_no.c -=================================================================== ---- linux-2.6.orig/arch/m68k/kernel/process_no.c -+++ linux-2.6/arch/m68k/kernel/process_no.c -@@ -73,9 +73,7 @@ void cpu_idle(void) - /* endless idle loop with no priority at all */ - while (1) { - idle(); -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/microblaze/kernel/process.c -=================================================================== ---- linux-2.6.orig/arch/microblaze/kernel/process.c -+++ linux-2.6/arch/microblaze/kernel/process.c -@@ -108,9 +108,7 @@ void cpu_idle(void) - idle(); - tick_nohz_restart_sched_tick(); - -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - check_pgt_cache(); - } - } -Index: linux-2.6/arch/mips/kernel/process.c -=================================================================== ---- linux-2.6.orig/arch/mips/kernel/process.c -+++ linux-2.6/arch/mips/kernel/process.c -@@ -78,9 +78,7 @@ void __noreturn cpu_idle(void) - play_dead(); - #endif - tick_nohz_restart_sched_tick(); -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/mn10300/kernel/process.c -=================================================================== ---- linux-2.6.orig/arch/mn10300/kernel/process.c -+++ linux-2.6/arch/mn10300/kernel/process.c -@@ -123,9 +123,7 @@ void cpu_idle(void) - idle(); - } - -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/parisc/kernel/process.c -=================================================================== ---- linux-2.6.orig/arch/parisc/kernel/process.c -+++ linux-2.6/arch/parisc/kernel/process.c -@@ -71,9 +71,7 @@ void cpu_idle(void) - while (1) { - while (!need_resched()) - barrier(); -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - check_pgt_cache(); - } - } -Index: linux-2.6/arch/powerpc/kernel/idle.c -=================================================================== ---- linux-2.6.orig/arch/powerpc/kernel/idle.c -+++ linux-2.6/arch/powerpc/kernel/idle.c -@@ -94,11 +94,11 @@ void cpu_idle(void) - HMT_medium(); - ppc64_runlatch_on(); - tick_nohz_restart_sched_tick(); -- preempt_enable_no_resched(); -- if (cpu_should_die()) -+ if (cpu_should_die()) { -+ __preempt_enable_no_resched(); - cpu_die(); -- schedule(); -- preempt_disable(); -+ } -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/powerpc/platforms/iseries/setup.c -=================================================================== ---- linux-2.6.orig/arch/powerpc/platforms/iseries/setup.c -+++ linux-2.6/arch/powerpc/platforms/iseries/setup.c -@@ -581,9 +581,7 @@ static void iseries_shared_idle(void) - if (hvlpevent_is_pending()) - process_iSeries_events(); - -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -@@ -610,9 +608,7 @@ static void iseries_dedicated_idle(void) - - ppc64_runlatch_on(); - tick_nohz_restart_sched_tick(); -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/s390/kernel/process.c -=================================================================== ---- linux-2.6.orig/arch/s390/kernel/process.c -+++ linux-2.6/arch/s390/kernel/process.c -@@ -94,9 +94,7 @@ void cpu_idle(void) - while (!need_resched()) - default_idle(); - tick_nohz_restart_sched_tick(); -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/score/kernel/process.c -=================================================================== ---- linux-2.6.orig/arch/score/kernel/process.c -+++ linux-2.6/arch/score/kernel/process.c -@@ -53,9 +53,7 @@ void __noreturn cpu_idle(void) - while (!need_resched()) - barrier(); - -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/sh/kernel/idle.c -=================================================================== ---- linux-2.6.orig/arch/sh/kernel/idle.c -+++ linux-2.6/arch/sh/kernel/idle.c -@@ -110,9 +110,7 @@ void cpu_idle(void) - } - - tick_nohz_restart_sched_tick(); -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/sparc/kernel/process_32.c -=================================================================== ---- linux-2.6.orig/arch/sparc/kernel/process_32.c -+++ linux-2.6/arch/sparc/kernel/process_32.c -@@ -113,9 +113,7 @@ void cpu_idle(void) - while (!need_resched()) - cpu_relax(); - } -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - check_pgt_cache(); - } - } -@@ -138,9 +136,7 @@ void cpu_idle(void) - while (!need_resched()) - cpu_relax(); - } -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - check_pgt_cache(); - } - } -Index: linux-2.6/arch/sparc/kernel/process_64.c -=================================================================== ---- linux-2.6.orig/arch/sparc/kernel/process_64.c -+++ linux-2.6/arch/sparc/kernel/process_64.c -@@ -102,15 +102,13 @@ void cpu_idle(void) - - tick_nohz_restart_sched_tick(); - -- preempt_enable_no_resched(); -- - #ifdef CONFIG_HOTPLUG_CPU -- if (cpu_is_offline(cpu)) -+ if (cpu_is_offline(cpu)) { -+ __preempt_enable_no_resched(); - cpu_play_dead(); -+ } - #endif -- -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/tile/kernel/process.c -=================================================================== ---- linux-2.6.orig/arch/tile/kernel/process.c -+++ linux-2.6/arch/tile/kernel/process.c -@@ -106,9 +106,7 @@ void cpu_idle(void) - current_thread_info()->status |= TS_POLLING; - } - tick_nohz_restart_sched_tick(); -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/x86/kernel/process_32.c -=================================================================== ---- linux-2.6.orig/arch/x86/kernel/process_32.c -+++ linux-2.6/arch/x86/kernel/process_32.c -@@ -38,6 +38,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -113,9 +114,7 @@ void cpu_idle(void) - start_critical_timings(); - } - tick_nohz_restart_sched_tick(); -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -@@ -348,6 +347,41 @@ __switch_to(struct task_struct *prev_p, - task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT)) - __switch_to_xtra(prev_p, next_p, tss); - -+#if defined CONFIG_PREEMPT_RT_FULL && defined CONFIG_HIGHMEM -+ /* -+ * Save @prev's kmap_atomic stack -+ */ -+ prev_p->kmap_idx = __this_cpu_read(__kmap_atomic_idx); -+ if (unlikely(prev_p->kmap_idx)) { -+ int i; -+ -+ for (i = 0; i < prev_p->kmap_idx; i++) { -+ int idx = i + KM_TYPE_NR * smp_processor_id(); -+ -+ pte_t *ptep = kmap_pte - idx; -+ prev_p->kmap_pte[i] = *ptep; -+ kpte_clear_flush(ptep, __fix_to_virt(FIX_KMAP_BEGIN + idx)); -+ } -+ -+ __this_cpu_write(__kmap_atomic_idx, 0); -+ } -+ -+ /* -+ * Restore @next_p's kmap_atomic stack -+ */ -+ if (unlikely(next_p->kmap_idx)) { -+ int i; -+ -+ __this_cpu_write(__kmap_atomic_idx, next_p->kmap_idx); -+ -+ for (i = 0; i < next_p->kmap_idx; i++) { -+ int idx = i + KM_TYPE_NR * smp_processor_id(); -+ -+ set_pte(kmap_pte - idx, next_p->kmap_pte[i]); -+ } -+ } -+#endif -+ - /* If we're going to preload the fpu context, make sure clts - is run while we're batching the cpu state updates. */ - if (preload_fpu) -Index: linux-2.6/arch/x86/kernel/process_64.c -=================================================================== ---- linux-2.6.orig/arch/x86/kernel/process_64.c -+++ linux-2.6/arch/x86/kernel/process_64.c -@@ -146,9 +146,7 @@ void cpu_idle(void) - } - - tick_nohz_restart_sched_tick(); -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/arch/xtensa/kernel/process.c -=================================================================== ---- linux-2.6.orig/arch/xtensa/kernel/process.c -+++ linux-2.6/arch/xtensa/kernel/process.c -@@ -113,9 +113,7 @@ void cpu_idle(void) - while (1) { - while (!need_resched()) - platform_idle(); -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - } - } - -Index: linux-2.6/init/main.c -=================================================================== ---- linux-2.6.orig/init/main.c -+++ linux-2.6/init/main.c -@@ -68,6 +68,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -367,9 +368,7 @@ static noinline void __init_refok rest_i - * at least once to get things moving: - */ - init_idle_bootup_task(current); -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - - /* Call into cpu_idle with preempt disabled */ - cpu_idle(); -@@ -501,6 +500,7 @@ asmlinkage void __init start_kernel(void - parse_args("Booting kernel", static_command_line, __start___param, - __stop___param - __start___param, - &unknown_bootoption); -+ softirq_early_init(); - /* - * These use large bootmem allocations and must precede - * kmem_cache_init() -Index: linux-2.6/kernel/mutex.c -=================================================================== ---- linux-2.6.orig/kernel/mutex.c -+++ linux-2.6/kernel/mutex.c -@@ -240,9 +240,7 @@ __mutex_lock_common(struct mutex *lock, - - /* didn't get the lock, go to sleep: */ - spin_unlock_mutex(&lock->wait_lock, flags); -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -+ schedule_preempt_disabled(); - spin_lock_mutex(&lock->wait_lock, flags); - } - -Index: linux-2.6/kernel/softirq.c -=================================================================== ---- linux-2.6.orig/kernel/softirq.c -+++ linux-2.6/kernel/softirq.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - #define CREATE_TRACE_POINTS - #include -@@ -61,6 +62,67 @@ char *softirq_to_name[NR_SOFTIRQS] = { - "TASKLET", "SCHED", "HRTIMER", "RCU" - }; - -+#ifdef CONFIG_NO_HZ -+# ifdef CONFIG_PREEMPT_RT_FULL -+/* -+ * On preempt-rt a softirq might be blocked on a lock. There might be -+ * no other runnable task on this CPU because the lock owner runs on -+ * some other CPU. So we have to go into idle with the pending bit -+ * set. Therefor we need to check this otherwise we warn about false -+ * positives which confuses users and defeats the whole purpose of -+ * this test. -+ * -+ * This code is called with interrupts disabled. -+ */ -+void softirq_check_pending_idle(void) -+{ -+ static int rate_limit; -+ u32 warnpending = 0, pending = local_softirq_pending(); -+ -+ if (rate_limit >= 10) -+ return; -+ -+ if (pending) { -+ struct task_struct *tsk; -+ -+ tsk = __get_cpu_var(ksoftirqd); -+ /* -+ * The wakeup code in rtmutex.c wakes up the task -+ * _before_ it sets pi_blocked_on to NULL under -+ * tsk->pi_lock. So we need to check for both: state -+ * and pi_blocked_on. -+ */ -+ raw_spin_lock(&tsk->pi_lock); -+ -+ if (!tsk->pi_blocked_on && !(tsk->state == TASK_RUNNING)) -+ warnpending = 1; -+ -+ raw_spin_unlock(&tsk->pi_lock); -+ } -+ -+ if (warnpending) { -+ printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n", -+ pending); -+ rate_limit++; -+ } -+} -+# else -+/* -+ * On !PREEMPT_RT we just printk rate limited: -+ */ -+void softirq_check_pending_idle(void) -+{ -+ static int rate_limit; -+ -+ if (rate_limit < 10) { -+ printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n", -+ local_softirq_pending()); -+ rate_limit++; -+ } -+} -+# endif -+#endif -+ - /* - * we cannot loop indefinitely here to avoid userspace starvation, - * but we also don't want to introduce a worst case 1/HZ latency -@@ -76,6 +138,35 @@ static void wakeup_softirqd(void) - wake_up_process(tsk); - } - -+static void handle_pending_softirqs(u32 pending, int cpu) -+{ -+ struct softirq_action *h = softirq_vec; -+ unsigned int prev_count = preempt_count(); -+ -+ local_irq_enable(); -+ for ( ; pending; h++, pending >>= 1) { -+ unsigned int vec_nr = h - softirq_vec; -+ -+ if (!(pending & 1)) -+ continue; -+ -+ kstat_incr_softirqs_this_cpu(vec_nr); -+ trace_softirq_entry(vec_nr); -+ h->action(h); -+ trace_softirq_exit(vec_nr); -+ if (unlikely(prev_count != preempt_count())) { -+ printk(KERN_ERR -+ "huh, entered softirq %u %s %p with preempt_count %08x exited with %08x?\n", -+ vec_nr, softirq_to_name[vec_nr], h->action, -+ prev_count, (unsigned int) preempt_count()); -+ preempt_count() = prev_count; -+ } -+ rcu_bh_qs(cpu); -+ } -+ local_irq_disable(); -+} -+ -+#ifndef CONFIG_PREEMPT_RT_FULL - /* - * preempt_count and SOFTIRQ_OFFSET usage: - * - preempt_count is changed by SOFTIRQ_OFFSET on entering or leaving -@@ -206,7 +297,6 @@ EXPORT_SYMBOL(local_bh_enable_ip); - - asmlinkage void __do_softirq(void) - { -- struct softirq_action *h; - __u32 pending; - int max_restart = MAX_SOFTIRQ_RESTART; - int cpu; -@@ -215,7 +305,7 @@ asmlinkage void __do_softirq(void) - account_system_vtime(current); - - __local_bh_disable((unsigned long)__builtin_return_address(0), -- SOFTIRQ_OFFSET); -+ SOFTIRQ_OFFSET); - lockdep_softirq_enter(); - - cpu = smp_processor_id(); -@@ -223,36 +313,7 @@ restart: - /* Reset the pending bitmask before enabling irqs */ - set_softirq_pending(0); - -- local_irq_enable(); -- -- h = softirq_vec; -- -- do { -- if (pending & 1) { -- unsigned int vec_nr = h - softirq_vec; -- int prev_count = preempt_count(); -- -- kstat_incr_softirqs_this_cpu(vec_nr); -- -- trace_softirq_entry(vec_nr); -- h->action(h); -- trace_softirq_exit(vec_nr); -- if (unlikely(prev_count != preempt_count())) { -- printk(KERN_ERR "huh, entered softirq %u %s %p" -- "with preempt_count %08x," -- " exited with %08x?\n", vec_nr, -- softirq_to_name[vec_nr], h->action, -- prev_count, preempt_count()); -- preempt_count() = prev_count; -- } -- -- rcu_bh_qs(cpu); -- } -- h++; -- pending >>= 1; -- } while (pending); -- -- local_irq_disable(); -+ handle_pending_softirqs(pending, cpu); - - pending = local_softirq_pending(); - if (pending && --max_restart) -@@ -267,6 +328,26 @@ restart: - __local_bh_enable(SOFTIRQ_OFFSET); - } - -+/* -+ * Called with preemption disabled from run_ksoftirqd() -+ */ -+static int ksoftirqd_do_softirq(int cpu) -+{ -+ /* -+ * Preempt disable stops cpu going offline. -+ * If already offline, we'll be on wrong CPU: -+ * don't process. -+ */ -+ if (cpu_is_offline(cpu)) -+ return -1; -+ -+ local_irq_disable(); -+ if (local_softirq_pending()) -+ __do_softirq(); -+ local_irq_enable(); -+ return 0; -+} -+ - #ifndef __ARCH_HAS_DO_SOFTIRQ - - asmlinkage void do_softirq(void) -@@ -289,6 +370,178 @@ asmlinkage void do_softirq(void) - - #endif - -+static inline void local_bh_disable_nort(void) { local_bh_disable(); } -+static inline void _local_bh_enable_nort(void) { _local_bh_enable(); } -+static inline void ksoftirqd_set_sched_params(void) { } -+static inline void ksoftirqd_clr_sched_params(void) { } -+ -+#else /* !PREEMPT_RT_FULL */ -+ -+/* -+ * On RT we serialize softirq execution with a cpu local lock -+ */ -+static DEFINE_LOCAL_IRQ_LOCK(local_softirq_lock); -+static DEFINE_PER_CPU(struct task_struct *, local_softirq_runner); -+ -+static void __do_softirq(void); -+ -+void __init softirq_early_init(void) -+{ -+ local_irq_lock_init(local_softirq_lock); -+} -+ -+void local_bh_disable(void) -+{ -+ migrate_disable(); -+ current->softirq_nestcnt++; -+} -+EXPORT_SYMBOL(local_bh_disable); -+ -+void local_bh_enable(void) -+{ -+ if (WARN_ON(current->softirq_nestcnt == 0)) -+ return; -+ -+ if ((current->softirq_nestcnt == 1) && -+ local_softirq_pending() && -+ local_trylock(local_softirq_lock)) { -+ -+ local_irq_disable(); -+ if (local_softirq_pending()) -+ __do_softirq(); -+ local_unlock(local_softirq_lock); -+ local_irq_enable(); -+ WARN_ON(current->softirq_nestcnt != 1); -+ } -+ current->softirq_nestcnt--; -+ migrate_enable(); -+} -+EXPORT_SYMBOL(local_bh_enable); -+ -+void local_bh_enable_ip(unsigned long ip) -+{ -+ local_bh_enable(); -+} -+EXPORT_SYMBOL(local_bh_enable_ip); -+ -+/* For tracing */ -+int notrace __in_softirq(void) -+{ -+ if (__get_cpu_var(local_softirq_lock).owner == current) -+ return __get_cpu_var(local_softirq_lock).nestcnt; -+ return 0; -+} -+ -+int in_serving_softirq(void) -+{ -+ int res; -+ -+ preempt_disable(); -+ res = __get_cpu_var(local_softirq_runner) == current; -+ preempt_enable(); -+ return res; -+} -+ -+/* -+ * Called with bh and local interrupts disabled. For full RT cpu must -+ * be pinned. -+ */ -+static void __do_softirq(void) -+{ -+ u32 pending = local_softirq_pending(); -+ int cpu = smp_processor_id(); -+ -+ current->softirq_nestcnt++; -+ -+ /* Reset the pending bitmask before enabling irqs */ -+ set_softirq_pending(0); -+ -+ __get_cpu_var(local_softirq_runner) = current; -+ -+ lockdep_softirq_enter(); -+ -+ handle_pending_softirqs(pending, cpu); -+ -+ pending = local_softirq_pending(); -+ if (pending) -+ wakeup_softirqd(); -+ -+ lockdep_softirq_exit(); -+ __get_cpu_var(local_softirq_runner) = NULL; -+ -+ current->softirq_nestcnt--; -+} -+ -+static int __thread_do_softirq(int cpu) -+{ -+ /* -+ * Prevent the current cpu from going offline. -+ * pin_current_cpu() can reenable preemption and block on the -+ * hotplug mutex. When it returns, the current cpu is -+ * pinned. It might be the wrong one, but the offline check -+ * below catches that. -+ */ -+ pin_current_cpu(); -+ /* -+ * If called from ksoftirqd (cpu >= 0) we need to check -+ * whether we are on the wrong cpu due to cpu offlining. If -+ * called via thread_do_softirq() no action required. -+ */ -+ if (cpu >= 0 && cpu_is_offline(cpu)) { -+ unpin_current_cpu(); -+ return -1; -+ } -+ preempt_enable(); -+ local_lock(local_softirq_lock); -+ local_irq_disable(); -+ /* -+ * We cannot switch stacks on RT as we want to be able to -+ * schedule! -+ */ -+ if (local_softirq_pending()) -+ __do_softirq(); -+ local_unlock(local_softirq_lock); -+ unpin_current_cpu(); -+ preempt_disable(); -+ local_irq_enable(); -+ return 0; -+} -+ -+/* -+ * Called from netif_rx_ni(). Preemption enabled. -+ */ -+void thread_do_softirq(void) -+{ -+ if (!in_serving_softirq()) { -+ preempt_disable(); -+ __thread_do_softirq(-1); -+ preempt_enable(); -+ } -+} -+ -+static int ksoftirqd_do_softirq(int cpu) -+{ -+ return __thread_do_softirq(cpu); -+} -+ -+static inline void local_bh_disable_nort(void) { } -+static inline void _local_bh_enable_nort(void) { } -+ -+static inline void ksoftirqd_set_sched_params(void) -+{ -+ struct sched_param param = { .sched_priority = 1 }; -+ -+ sched_setscheduler(current, SCHED_FIFO, ¶m); -+} -+ -+static inline void ksoftirqd_clr_sched_params(void) -+{ -+ struct sched_param param = { .sched_priority = 0 }; -+ -+ sched_setscheduler(current, SCHED_NORMAL, ¶m); -+} -+ -+#endif /* PREEMPT_RT_FULL */ - /* - * Enter an interrupt context. - */ -@@ -302,9 +555,9 @@ void irq_enter(void) - * Prevent raise_softirq from needlessly waking up ksoftirqd - * here, as softirq will be serviced on return from interrupt. - */ -- local_bh_disable(); -+ local_bh_disable_nort(); - tick_check_idle(cpu); -- _local_bh_enable(); -+ _local_bh_enable_nort(); - } - - __irq_enter(); -@@ -313,6 +566,7 @@ void irq_enter(void) - #ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED - static inline void invoke_softirq(void) - { -+#ifndef CONFIG_PREEMPT_RT_FULL - if (!force_irqthreads) - __do_softirq(); - else { -@@ -321,10 +575,14 @@ static inline void invoke_softirq(void) - wakeup_softirqd(); - __local_bh_enable(SOFTIRQ_OFFSET); - } -+#else -+ wakeup_softirqd(); -+#endif - } - #else - static inline void invoke_softirq(void) - { -+#ifndef CONFIG_PREEMPT_RT_FULL - if (!force_irqthreads) - do_softirq(); - else { -@@ -333,6 +591,9 @@ static inline void invoke_softirq(void) - wakeup_softirqd(); - __local_bh_enable(SOFTIRQ_OFFSET); - } -+#else -+ wakeup_softirqd(); -+#endif - } - #endif - -@@ -353,7 +614,7 @@ void irq_exit(void) - if (idle_cpu(smp_processor_id()) && !in_interrupt() && !need_resched()) - tick_nohz_stop_sched_tick(0); - #endif -- preempt_enable_no_resched(); -+ __preempt_enable_no_resched(); - } - - /* -@@ -739,29 +1000,21 @@ void __init softirq_init(void) - - static int run_ksoftirqd(void * __bind_cpu) - { -+ ksoftirqd_set_sched_params(); -+ - set_current_state(TASK_INTERRUPTIBLE); - - while (!kthread_should_stop()) { - preempt_disable(); -- if (!local_softirq_pending()) { -- preempt_enable_no_resched(); -- schedule(); -- preempt_disable(); -- } -+ if (!local_softirq_pending()) -+ schedule_preempt_disabled(); - - __set_current_state(TASK_RUNNING); - - while (local_softirq_pending()) { -- /* Preempt disable stops cpu going offline. -- If already offline, we'll be on wrong CPU: -- don't process */ -- if (cpu_is_offline((long)__bind_cpu)) -+ if (ksoftirqd_do_softirq((long) __bind_cpu)) - goto wait_to_die; -- local_irq_disable(); -- if (local_softirq_pending()) -- __do_softirq(); -- local_irq_enable(); -- preempt_enable_no_resched(); -+ __preempt_enable_no_resched(); - cond_resched(); - preempt_disable(); - rcu_note_context_switch((long)__bind_cpu); -@@ -774,6 +1027,7 @@ static int run_ksoftirqd(void * __bind_c - - wait_to_die: - preempt_enable(); -+ ksoftirqd_clr_sched_params(); - /* Wait for kthread_stop */ - set_current_state(TASK_INTERRUPTIBLE); - while (!kthread_should_stop()) { Index: linux-2.6/include/linux/kprobes.h =================================================================== --- linux-2.6.orig/include/linux/kprobes.h @@ -5764,6 +4307,306 @@ Index: linux-2.6/include/linux/init_task.h .pids = { \ [PIDTYPE_PID] = INIT_PID_LINK(PIDTYPE_PID), \ [PIDTYPE_PGID] = INIT_PID_LINK(PIDTYPE_PGID), \ +Index: linux-2.6/include/linux/sched.h +=================================================================== +--- linux-2.6.orig/include/linux/sched.h ++++ linux-2.6/include/linux/sched.h +@@ -63,6 +63,7 @@ struct sched_param { + #include + #include + ++#include + #include + #include + #include +@@ -90,6 +91,7 @@ struct sched_param { + #include + #include + #include ++#include + + #include + +@@ -359,6 +361,7 @@ extern signed long schedule_timeout_inte + extern signed long schedule_timeout_killable(signed long timeout); + extern signed long schedule_timeout_uninterruptible(signed long timeout); + asmlinkage void schedule(void); ++extern void schedule_preempt_disabled(void); + extern int mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner); + + struct nsproxy; +@@ -510,7 +513,7 @@ struct task_cputime { + struct thread_group_cputimer { + struct task_cputime cputime; + int running; +- spinlock_t lock; ++ raw_spinlock_t lock; + }; + + #include +@@ -1070,6 +1073,7 @@ struct sched_domain; + #define WF_SYNC 0x01 /* waker goes to sleep after wakup */ + #define WF_FORK 0x02 /* child wakeup after fork */ + #define WF_MIGRATED 0x04 /* internal use, task got migrated */ ++#define WF_LOCK_SLEEPER 0x08 /* wakeup spinlock "sleeper" */ + + #define ENQUEUE_WAKEUP 1 + #define ENQUEUE_HEAD 2 +@@ -1219,6 +1223,7 @@ enum perf_event_task_context { + + struct task_struct { + volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ ++ volatile long saved_state; /* saved state for "spinlock sleepers" */ + void *stack; + atomic_t usage; + unsigned int flags; /* per process flags, defined below */ +@@ -1255,14 +1260,17 @@ struct task_struct { + #endif + + unsigned int policy; ++#ifdef CONFIG_PREEMPT_RT_FULL ++ int migrate_disable; ++#ifdef CONFIG_SCHED_DEBUG ++ int migrate_disable_atomic; ++#endif ++#endif + cpumask_t cpus_allowed; + + #ifdef CONFIG_PREEMPT_RCU + int rcu_read_lock_nesting; + char rcu_read_unlock_special; +-#if defined(CONFIG_RCU_BOOST) && defined(CONFIG_TREE_PREEMPT_RCU) +- int rcu_boosted; +-#endif /* #if defined(CONFIG_RCU_BOOST) && defined(CONFIG_TREE_PREEMPT_RCU) */ + struct list_head rcu_node_entry; + #endif /* #ifdef CONFIG_PREEMPT_RCU */ + #ifdef CONFIG_TREE_PREEMPT_RCU +@@ -1356,6 +1364,9 @@ struct task_struct { + + struct task_cputime cputime_expires; + struct list_head cpu_timers[3]; ++#ifdef CONFIG_PREEMPT_RT_BASE ++ struct task_struct *posix_timer_list; ++#endif + + /* process credentials */ + const struct cred __rcu *real_cred; /* objective and real subjective task +@@ -1389,6 +1400,7 @@ struct task_struct { + /* signal handlers */ + struct signal_struct *signal; + struct sighand_struct *sighand; ++ struct sigqueue *sigqueue_cache; + + sigset_t blocked, real_blocked; + sigset_t saved_sigmask; /* restored if set_restore_sigmask() was used */ +@@ -1432,6 +1444,9 @@ struct task_struct { + /* mutex deadlock detection */ + struct mutex_waiter *blocked_on; + #endif ++#ifdef CONFIG_PREEMPT_RT_FULL ++ int pagefault_disabled; ++#endif + #ifdef CONFIG_TRACE_IRQFLAGS + unsigned int irq_events; + unsigned long hardirq_enable_ip; +@@ -1558,6 +1573,12 @@ struct task_struct { + unsigned long trace; + /* bitmask and counter of trace recursion */ + unsigned long trace_recursion; ++#ifdef CONFIG_WAKEUP_LATENCY_HIST ++ u64 preempt_timestamp_hist; ++#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST ++ unsigned long timer_offset; ++#endif ++#endif + #endif /* CONFIG_TRACING */ + #ifdef CONFIG_CGROUP_MEM_RES_CTLR /* memcg uses this to do batch job */ + struct memcg_batch_info { +@@ -1570,10 +1591,26 @@ struct task_struct { + #ifdef CONFIG_HAVE_HW_BREAKPOINT + atomic_t ptrace_bp_refcnt; + #endif ++#ifdef CONFIG_PREEMPT_RT_BASE ++ struct rcu_head put_rcu; ++ int softirq_nestcnt; ++#endif ++#if defined CONFIG_PREEMPT_RT_FULL && defined CONFIG_HIGHMEM ++ int kmap_idx; ++ pte_t kmap_pte[KM_TYPE_NR]; ++#endif + }; + +-/* Future-safe accessor for struct task_struct's cpus_allowed. */ +-#define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed) ++#ifdef CONFIG_PREEMPT_RT_FULL ++static inline bool cur_pf_disabled(void) { return current->pagefault_disabled; } ++#else ++static inline bool cur_pf_disabled(void) { return false; } ++#endif ++ ++static inline bool pagefault_disabled(void) ++{ ++ return in_atomic() || cur_pf_disabled(); ++} + + /* + * Priority of a process goes from 0..MAX_PRIO-1, valid RT +@@ -1743,6 +1780,15 @@ extern struct pid *cad_pid; + extern void free_task(struct task_struct *tsk); + #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) + ++#ifdef CONFIG_PREEMPT_RT_BASE ++extern void __put_task_struct_cb(struct rcu_head *rhp); ++ ++static inline void put_task_struct(struct task_struct *t) ++{ ++ if (atomic_dec_and_test(&t->usage)) ++ call_rcu(&t->put_rcu, __put_task_struct_cb); ++} ++#else + extern void __put_task_struct(struct task_struct *t); + + static inline void put_task_struct(struct task_struct *t) +@@ -1750,6 +1796,7 @@ static inline void put_task_struct(struc + if (atomic_dec_and_test(&t->usage)) + __put_task_struct(t); + } ++#endif + + extern void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st); + extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st); +@@ -1774,6 +1821,7 @@ extern void thread_group_times(struct ta + #define PF_FROZEN 0x00010000 /* frozen for system suspend */ + #define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */ + #define PF_KSWAPD 0x00040000 /* I am kswapd */ ++#define PF_STOMPER 0x00080000 /* I am a stomp machine thread */ + #define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */ + #define PF_KTHREAD 0x00200000 /* I am a kernel thread */ + #define PF_RANDOMIZE 0x00400000 /* randomize virtual address space */ +@@ -2022,15 +2070,27 @@ static inline void sched_autogroup_exit( + #endif + + #ifdef CONFIG_RT_MUTEXES ++extern void task_setprio(struct task_struct *p, int prio); + extern int rt_mutex_getprio(struct task_struct *p); +-extern void rt_mutex_setprio(struct task_struct *p, int prio); ++static inline void rt_mutex_setprio(struct task_struct *p, int prio) ++{ ++ task_setprio(p, prio); ++} + extern void rt_mutex_adjust_pi(struct task_struct *p); ++static inline bool tsk_is_pi_blocked(struct task_struct *tsk) ++{ ++ return tsk->pi_blocked_on != NULL; ++} + #else + static inline int rt_mutex_getprio(struct task_struct *p) + { + return p->normal_prio; + } + # define rt_mutex_adjust_pi(p) do { } while (0) ++static inline bool tsk_is_pi_blocked(struct task_struct *tsk) ++{ ++ return false; ++} + #endif + + extern bool yield_to(struct task_struct *p, bool preempt); +@@ -2110,6 +2170,7 @@ extern void xtime_update(unsigned long t + + extern int wake_up_state(struct task_struct *tsk, unsigned int state); + extern int wake_up_process(struct task_struct *tsk); ++extern int wake_up_lock_sleeper(struct task_struct * tsk); + extern void wake_up_new_task(struct task_struct *tsk); + #ifdef CONFIG_SMP + extern void kick_process(struct task_struct *tsk); +@@ -2199,12 +2260,24 @@ extern struct mm_struct * mm_alloc(void) + + /* mmdrop drops the mm and the page tables */ + extern void __mmdrop(struct mm_struct *); ++ + static inline void mmdrop(struct mm_struct * mm) + { + if (unlikely(atomic_dec_and_test(&mm->mm_count))) + __mmdrop(mm); + } + ++#ifdef CONFIG_PREEMPT_RT_BASE ++extern void __mmdrop_delayed(struct rcu_head *rhp); ++static inline void mmdrop_delayed(struct mm_struct *mm) ++{ ++ if (atomic_dec_and_test(&mm->mm_count)) ++ call_rcu(&mm->delayed_drop, __mmdrop_delayed); ++} ++#else ++# define mmdrop_delayed(mm) mmdrop(mm) ++#endif ++ + /* mmput gets rid of the mappings and all user-space */ + extern void mmput(struct mm_struct *); + /* Grab a reference to a task's mm, if it is not already going away */ +@@ -2510,7 +2583,7 @@ extern int _cond_resched(void); + + extern int __cond_resched_lock(spinlock_t *lock); + +-#ifdef CONFIG_PREEMPT ++#if defined(CONFIG_PREEMPT) && !defined(CONFIG_PREEMPT_RT_FULL) + #define PREEMPT_LOCK_OFFSET PREEMPT_OFFSET + #else + #define PREEMPT_LOCK_OFFSET 0 +@@ -2521,12 +2594,16 @@ extern int __cond_resched_lock(spinlock_ + __cond_resched_lock(lock); \ + }) + ++#ifndef CONFIG_PREEMPT_RT_FULL + extern int __cond_resched_softirq(void); + + #define cond_resched_softirq() ({ \ + __might_sleep(__FILE__, __LINE__, SOFTIRQ_DISABLE_OFFSET); \ + __cond_resched_softirq(); \ + }) ++#else ++# define cond_resched_softirq() cond_resched() ++#endif + + /* + * Does a critical section need to be broken due to another +@@ -2550,7 +2627,7 @@ void thread_group_cputimer(struct task_s + + static inline void thread_group_cputime_init(struct signal_struct *sig) + { +- spin_lock_init(&sig->cputimer.lock); ++ raw_spin_lock_init(&sig->cputimer.lock); + } + + /* +@@ -2589,6 +2666,26 @@ static inline void set_task_cpu(struct t + + #endif /* CONFIG_SMP */ + ++static inline int __migrate_disabled(struct task_struct *p) ++{ ++#ifdef CONFIG_PREEMPT_RT_FULL ++ return p->migrate_disable; ++#else ++ return 0; ++#endif ++} ++ ++/* Future-safe accessor for struct task_struct's cpus_allowed. */ ++static inline const struct cpumask *tsk_cpus_allowed(struct task_struct *p) ++{ ++#ifdef CONFIG_PREEMPT_RT_FULL ++ if (p->migrate_disable) ++ return cpumask_of(task_cpu(p)); ++#endif ++ ++ return &p->cpus_allowed; ++} ++ + extern long sched_setaffinity(pid_t pid, const struct cpumask *new_mask); + extern long sched_getaffinity(pid_t pid, struct cpumask *mask); + Index: linux-2.6/kernel/posix-cpu-timers.c =================================================================== --- linux-2.6.orig/kernel/posix-cpu-timers.c @@ -8701,198 +7544,6 @@ Index: linux-2.6/drivers/dma/ipu/ipu_irq.c if (!map) { pr_err("IPU: Interrupt on unmapped source %u bank %d\n", -Index: linux-2.6/drivers/pci/dmar.c -=================================================================== ---- linux-2.6.orig/drivers/pci/dmar.c -+++ linux-2.6/drivers/pci/dmar.c -@@ -800,7 +800,7 @@ int alloc_iommu(struct dmar_drhd_unit *d - (unsigned long long)iommu->cap, - (unsigned long long)iommu->ecap); - -- spin_lock_init(&iommu->register_lock); -+ raw_spin_lock_init(&iommu->register_lock); - - drhd->iommu = iommu; - return 0; -@@ -921,11 +921,11 @@ int qi_submit_sync(struct qi_desc *desc, - restart: - rc = 0; - -- spin_lock_irqsave(&qi->q_lock, flags); -+ raw_spin_lock_irqsave(&qi->q_lock, flags); - while (qi->free_cnt < 3) { -- spin_unlock_irqrestore(&qi->q_lock, flags); -+ raw_spin_unlock_irqrestore(&qi->q_lock, flags); - cpu_relax(); -- spin_lock_irqsave(&qi->q_lock, flags); -+ raw_spin_lock_irqsave(&qi->q_lock, flags); - } - - index = qi->free_head; -@@ -965,15 +965,15 @@ restart: - if (rc) - break; - -- spin_unlock(&qi->q_lock); -+ raw_spin_unlock(&qi->q_lock); - cpu_relax(); -- spin_lock(&qi->q_lock); -+ raw_spin_lock(&qi->q_lock); - } - - qi->desc_status[index] = QI_DONE; - - reclaim_free_desc(qi); -- spin_unlock_irqrestore(&qi->q_lock, flags); -+ raw_spin_unlock_irqrestore(&qi->q_lock, flags); - - if (rc == -EAGAIN) - goto restart; -@@ -1062,7 +1062,7 @@ void dmar_disable_qi(struct intel_iommu - if (!ecap_qis(iommu->ecap)) - return; - -- spin_lock_irqsave(&iommu->register_lock, flags); -+ raw_spin_lock_irqsave(&iommu->register_lock, flags); - - sts = dmar_readq(iommu->reg + DMAR_GSTS_REG); - if (!(sts & DMA_GSTS_QIES)) -@@ -1082,7 +1082,7 @@ void dmar_disable_qi(struct intel_iommu - IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl, - !(sts & DMA_GSTS_QIES), sts); - end: -- spin_unlock_irqrestore(&iommu->register_lock, flags); -+ raw_spin_unlock_irqrestore(&iommu->register_lock, flags); - } - - /* -@@ -1097,7 +1097,7 @@ static void __dmar_enable_qi(struct inte - qi->free_head = qi->free_tail = 0; - qi->free_cnt = QI_LENGTH; - -- spin_lock_irqsave(&iommu->register_lock, flags); -+ raw_spin_lock_irqsave(&iommu->register_lock, flags); - - /* write zero to the tail reg */ - writel(0, iommu->reg + DMAR_IQT_REG); -@@ -1110,7 +1110,7 @@ static void __dmar_enable_qi(struct inte - /* Make sure hardware complete it */ - IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl, (sts & DMA_GSTS_QIES), sts); - -- spin_unlock_irqrestore(&iommu->register_lock, flags); -+ raw_spin_unlock_irqrestore(&iommu->register_lock, flags); - } - - /* -@@ -1159,7 +1159,7 @@ int dmar_enable_qi(struct intel_iommu *i - qi->free_head = qi->free_tail = 0; - qi->free_cnt = QI_LENGTH; - -- spin_lock_init(&qi->q_lock); -+ raw_spin_lock_init(&qi->q_lock); - - __dmar_enable_qi(iommu); - -@@ -1225,11 +1225,11 @@ void dmar_msi_unmask(struct irq_data *da - unsigned long flag; - - /* unmask it */ -- spin_lock_irqsave(&iommu->register_lock, flag); -+ raw_spin_lock_irqsave(&iommu->register_lock, flag); - writel(0, iommu->reg + DMAR_FECTL_REG); - /* Read a reg to force flush the post write */ - readl(iommu->reg + DMAR_FECTL_REG); -- spin_unlock_irqrestore(&iommu->register_lock, flag); -+ raw_spin_unlock_irqrestore(&iommu->register_lock, flag); - } - - void dmar_msi_mask(struct irq_data *data) -@@ -1238,11 +1238,11 @@ void dmar_msi_mask(struct irq_data *data - struct intel_iommu *iommu = irq_data_get_irq_handler_data(data); - - /* mask it */ -- spin_lock_irqsave(&iommu->register_lock, flag); -+ raw_spin_lock_irqsave(&iommu->register_lock, flag); - writel(DMA_FECTL_IM, iommu->reg + DMAR_FECTL_REG); - /* Read a reg to force flush the post write */ - readl(iommu->reg + DMAR_FECTL_REG); -- spin_unlock_irqrestore(&iommu->register_lock, flag); -+ raw_spin_unlock_irqrestore(&iommu->register_lock, flag); - } - - void dmar_msi_write(int irq, struct msi_msg *msg) -@@ -1250,11 +1250,11 @@ void dmar_msi_write(int irq, struct msi_ - struct intel_iommu *iommu = irq_get_handler_data(irq); - unsigned long flag; - -- spin_lock_irqsave(&iommu->register_lock, flag); -+ raw_spin_lock_irqsave(&iommu->register_lock, flag); - writel(msg->data, iommu->reg + DMAR_FEDATA_REG); - writel(msg->address_lo, iommu->reg + DMAR_FEADDR_REG); - writel(msg->address_hi, iommu->reg + DMAR_FEUADDR_REG); -- spin_unlock_irqrestore(&iommu->register_lock, flag); -+ raw_spin_unlock_irqrestore(&iommu->register_lock, flag); - } - - void dmar_msi_read(int irq, struct msi_msg *msg) -@@ -1262,11 +1262,11 @@ void dmar_msi_read(int irq, struct msi_m - struct intel_iommu *iommu = irq_get_handler_data(irq); - unsigned long flag; - -- spin_lock_irqsave(&iommu->register_lock, flag); -+ raw_spin_lock_irqsave(&iommu->register_lock, flag); - msg->data = readl(iommu->reg + DMAR_FEDATA_REG); - msg->address_lo = readl(iommu->reg + DMAR_FEADDR_REG); - msg->address_hi = readl(iommu->reg + DMAR_FEUADDR_REG); -- spin_unlock_irqrestore(&iommu->register_lock, flag); -+ raw_spin_unlock_irqrestore(&iommu->register_lock, flag); - } - - static int dmar_fault_do_one(struct intel_iommu *iommu, int type, -@@ -1303,7 +1303,7 @@ irqreturn_t dmar_fault(int irq, void *de - u32 fault_status; - unsigned long flag; - -- spin_lock_irqsave(&iommu->register_lock, flag); -+ raw_spin_lock_irqsave(&iommu->register_lock, flag); - fault_status = readl(iommu->reg + DMAR_FSTS_REG); - if (fault_status) - printk(KERN_ERR "DRHD: handling fault status reg %x\n", -@@ -1342,7 +1342,7 @@ irqreturn_t dmar_fault(int irq, void *de - writel(DMA_FRCD_F, iommu->reg + reg + - fault_index * PRIMARY_FAULT_REG_LEN + 12); - -- spin_unlock_irqrestore(&iommu->register_lock, flag); -+ raw_spin_unlock_irqrestore(&iommu->register_lock, flag); - - dmar_fault_do_one(iommu, type, fault_reason, - source_id, guest_addr); -@@ -1350,14 +1350,14 @@ irqreturn_t dmar_fault(int irq, void *de - fault_index++; - if (fault_index >= cap_num_fault_regs(iommu->cap)) - fault_index = 0; -- spin_lock_irqsave(&iommu->register_lock, flag); -+ raw_spin_lock_irqsave(&iommu->register_lock, flag); - } - clear_rest: - /* clear all the other faults */ - fault_status = readl(iommu->reg + DMAR_FSTS_REG); - writel(fault_status, iommu->reg + DMAR_FSTS_REG); - -- spin_unlock_irqrestore(&iommu->register_lock, flag); -+ raw_spin_unlock_irqrestore(&iommu->register_lock, flag); - return IRQ_HANDLED; - } - -@@ -1388,7 +1388,7 @@ int dmar_set_interrupt(struct intel_iomm - return ret; - } - -- ret = request_irq(irq, dmar_fault, 0, iommu->name, iommu); -+ ret = request_irq(irq, dmar_fault, IRQF_NO_THREAD, iommu->name, iommu); - if (ret) - printk(KERN_ERR "IOMMU: can't request irq\n"); - return ret; Index: linux-2.6/drivers/pci/intel-iommu.c =================================================================== --- linux-2.6.orig/drivers/pci/intel-iommu.c @@ -9258,7 +7909,7 @@ Index: linux-2.6/lib/atomic64.c =================================================================== --- linux-2.6.orig/lib/atomic64.c +++ linux-2.6/lib/atomic64.c -@@ -29,7 +29,7 @@ +@@ -29,11 +29,11 @@ * Ensure each lock is in a separate cacheline. */ static union { @@ -9267,8 +7918,17 @@ Index: linux-2.6/lib/atomic64.c char pad[L1_CACHE_BYTES]; } atomic64_lock[NR_LOCKS] __cacheline_aligned_in_smp; -@@ -48,9 +48,9 @@ long long atomic64_read(const atomic64_t - spinlock_t *lock = lock_addr(v); +-static inline spinlock_t *lock_addr(const atomic64_t *v) ++static inline raw_spinlock_t *lock_addr(const atomic64_t *v) + { + unsigned long addr = (unsigned long) v; + +@@ -45,12 +45,12 @@ static inline spinlock_t *lock_addr(cons + long long atomic64_read(const atomic64_t *v) + { + unsigned long flags; +- spinlock_t *lock = lock_addr(v); ++ raw_spinlock_t *lock = lock_addr(v); long long val; - spin_lock_irqsave(lock, flags); @@ -9279,9 +7939,12 @@ Index: linux-2.6/lib/atomic64.c return val; } EXPORT_SYMBOL(atomic64_read); -@@ -60,9 +60,9 @@ void atomic64_set(atomic64_t *v, long lo +@@ -58,34 +58,34 @@ EXPORT_SYMBOL(atomic64_read); + void atomic64_set(atomic64_t *v, long long i) + { unsigned long flags; - spinlock_t *lock = lock_addr(v); +- spinlock_t *lock = lock_addr(v); ++ raw_spinlock_t *lock = lock_addr(v); - spin_lock_irqsave(lock, flags); + raw_spin_lock_irqsave(lock, flags); @@ -9291,9 +7954,11 @@ Index: linux-2.6/lib/atomic64.c } EXPORT_SYMBOL(atomic64_set); -@@ -71,9 +71,9 @@ void atomic64_add(long long a, atomic64_ + void atomic64_add(long long a, atomic64_t *v) + { unsigned long flags; - spinlock_t *lock = lock_addr(v); +- spinlock_t *lock = lock_addr(v); ++ raw_spinlock_t *lock = lock_addr(v); - spin_lock_irqsave(lock, flags); + raw_spin_lock_irqsave(lock, flags); @@ -9303,8 +7968,11 @@ Index: linux-2.6/lib/atomic64.c } EXPORT_SYMBOL(atomic64_add); -@@ -83,9 +83,9 @@ long long atomic64_add_return(long long - spinlock_t *lock = lock_addr(v); + long long atomic64_add_return(long long a, atomic64_t *v) + { + unsigned long flags; +- spinlock_t *lock = lock_addr(v); ++ raw_spinlock_t *lock = lock_addr(v); long long val; - spin_lock_irqsave(lock, flags); @@ -9315,9 +7983,12 @@ Index: linux-2.6/lib/atomic64.c return val; } EXPORT_SYMBOL(atomic64_add_return); -@@ -95,9 +95,9 @@ void atomic64_sub(long long a, atomic64_ +@@ -93,23 +93,23 @@ EXPORT_SYMBOL(atomic64_add_return); + void atomic64_sub(long long a, atomic64_t *v) + { unsigned long flags; - spinlock_t *lock = lock_addr(v); +- spinlock_t *lock = lock_addr(v); ++ raw_spinlock_t *lock = lock_addr(v); - spin_lock_irqsave(lock, flags); + raw_spin_lock_irqsave(lock, flags); @@ -9327,8 +7998,11 @@ Index: linux-2.6/lib/atomic64.c } EXPORT_SYMBOL(atomic64_sub); -@@ -107,9 +107,9 @@ long long atomic64_sub_return(long long - spinlock_t *lock = lock_addr(v); + long long atomic64_sub_return(long long a, atomic64_t *v) + { + unsigned long flags; +- spinlock_t *lock = lock_addr(v); ++ raw_spinlock_t *lock = lock_addr(v); long long val; - spin_lock_irqsave(lock, flags); @@ -9339,8 +8013,12 @@ Index: linux-2.6/lib/atomic64.c return val; } EXPORT_SYMBOL(atomic64_sub_return); -@@ -120,11 +120,11 @@ long long atomic64_dec_if_positive(atomi - spinlock_t *lock = lock_addr(v); +@@ -117,14 +117,14 @@ EXPORT_SYMBOL(atomic64_sub_return); + long long atomic64_dec_if_positive(atomic64_t *v) + { + unsigned long flags; +- spinlock_t *lock = lock_addr(v); ++ raw_spinlock_t *lock = lock_addr(v); long long val; - spin_lock_irqsave(lock, flags); @@ -9353,8 +8031,12 @@ Index: linux-2.6/lib/atomic64.c return val; } EXPORT_SYMBOL(atomic64_dec_if_positive); -@@ -135,11 +135,11 @@ long long atomic64_cmpxchg(atomic64_t *v - spinlock_t *lock = lock_addr(v); +@@ -132,14 +132,14 @@ EXPORT_SYMBOL(atomic64_dec_if_positive); + long long atomic64_cmpxchg(atomic64_t *v, long long o, long long n) + { + unsigned long flags; +- spinlock_t *lock = lock_addr(v); ++ raw_spinlock_t *lock = lock_addr(v); long long val; - spin_lock_irqsave(lock, flags); @@ -9367,8 +8049,12 @@ Index: linux-2.6/lib/atomic64.c return val; } EXPORT_SYMBOL(atomic64_cmpxchg); -@@ -150,10 +150,10 @@ long long atomic64_xchg(atomic64_t *v, l - spinlock_t *lock = lock_addr(v); +@@ -147,13 +147,13 @@ EXPORT_SYMBOL(atomic64_cmpxchg); + long long atomic64_xchg(atomic64_t *v, long long new) + { + unsigned long flags; +- spinlock_t *lock = lock_addr(v); ++ raw_spinlock_t *lock = lock_addr(v); long long val; - spin_lock_irqsave(lock, flags); @@ -9380,8 +8066,12 @@ Index: linux-2.6/lib/atomic64.c return val; } EXPORT_SYMBOL(atomic64_xchg); -@@ -164,12 +164,12 @@ int atomic64_add_unless(atomic64_t *v, l - spinlock_t *lock = lock_addr(v); +@@ -161,15 +161,15 @@ EXPORT_SYMBOL(atomic64_xchg); + int atomic64_add_unless(atomic64_t *v, long long a, long long u) + { + unsigned long flags; +- spinlock_t *lock = lock_addr(v); ++ raw_spinlock_t *lock = lock_addr(v); int ret = 0; - spin_lock_irqsave(lock, flags); @@ -9404,6 +8094,1390 @@ Index: linux-2.6/lib/atomic64.c return 0; } +Index: linux-2.6/arch/x86/kernel/cpu/intel_cacheinfo.c +=================================================================== +--- linux-2.6.orig/arch/x86/kernel/cpu/intel_cacheinfo.c ++++ linux-2.6/arch/x86/kernel/cpu/intel_cacheinfo.c +@@ -151,28 +151,17 @@ union _cpuid4_leaf_ecx { + u32 full; + }; + +-struct amd_l3_cache { +- struct amd_northbridge *nb; +- unsigned indices; +- u8 subcaches[4]; +-}; +- +-struct _cpuid4_info { ++struct _cpuid4_info_regs { + union _cpuid4_leaf_eax eax; + union _cpuid4_leaf_ebx ebx; + union _cpuid4_leaf_ecx ecx; + unsigned long size; +- struct amd_l3_cache *l3; +- DECLARE_BITMAP(shared_cpu_map, NR_CPUS); ++ struct amd_northbridge *nb; + }; + +-/* subset of above _cpuid4_info w/o shared_cpu_map */ +-struct _cpuid4_info_regs { +- union _cpuid4_leaf_eax eax; +- union _cpuid4_leaf_ebx ebx; +- union _cpuid4_leaf_ecx ecx; +- unsigned long size; +- struct amd_l3_cache *l3; ++struct _cpuid4_info { ++ struct _cpuid4_info_regs base; ++ DECLARE_BITMAP(shared_cpu_map, NR_CPUS); + }; + + unsigned short num_cache_leaves; +@@ -314,12 +303,13 @@ struct _cache_attr { + /* + * L3 cache descriptors + */ +-static void __cpuinit amd_calc_l3_indices(struct amd_l3_cache *l3) ++static void __cpuinit amd_calc_l3_indices(struct amd_northbridge *nb) + { ++ struct amd_l3_cache *l3 = &nb->l3_cache; + unsigned int sc0, sc1, sc2, sc3; + u32 val = 0; + +- pci_read_config_dword(l3->nb->misc, 0x1C4, &val); ++ pci_read_config_dword(nb->misc, 0x1C4, &val); + + /* calculate subcache sizes */ + l3->subcaches[0] = sc0 = !(val & BIT(0)); +@@ -333,33 +323,16 @@ static void __cpuinit amd_calc_l3_indice + static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, + int index) + { +- static struct amd_l3_cache *__cpuinitdata l3_caches; + int node; + + /* only for L3, and not in virtualized environments */ +- if (index < 3 || amd_nb_num() == 0) ++ if (index < 3) + return; + +- /* +- * Strictly speaking, the amount in @size below is leaked since it is +- * never freed but this is done only on shutdown so it doesn't matter. +- */ +- if (!l3_caches) { +- int size = amd_nb_num() * sizeof(struct amd_l3_cache); +- +- l3_caches = kzalloc(size, GFP_ATOMIC); +- if (!l3_caches) +- return; +- } +- + node = amd_get_nb_id(smp_processor_id()); +- +- if (!l3_caches[node].nb) { +- l3_caches[node].nb = node_to_amd_nb(node); +- amd_calc_l3_indices(&l3_caches[node]); +- } +- +- this_leaf->l3 = &l3_caches[node]; ++ this_leaf->nb = node_to_amd_nb(node); ++ if (this_leaf->nb && !this_leaf->nb->l3_cache.indices) ++ amd_calc_l3_indices(this_leaf->nb); + } + + /* +@@ -369,11 +342,11 @@ static void __cpuinit amd_init_l3_cache( + * + * @returns: the disabled index if used or negative value if slot free. + */ +-int amd_get_l3_disable_slot(struct amd_l3_cache *l3, unsigned slot) ++int amd_get_l3_disable_slot(struct amd_northbridge *nb, unsigned slot) + { + unsigned int reg = 0; + +- pci_read_config_dword(l3->nb->misc, 0x1BC + slot * 4, ®); ++ pci_read_config_dword(nb->misc, 0x1BC + slot * 4, ®); + + /* check whether this slot is activated already */ + if (reg & (3UL << 30)) +@@ -387,11 +360,10 @@ static ssize_t show_cache_disable(struct + { + int index; + +- if (!this_leaf->l3 || +- !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) ++ if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) + return -EINVAL; + +- index = amd_get_l3_disable_slot(this_leaf->l3, slot); ++ index = amd_get_l3_disable_slot(this_leaf->base.nb, slot); + if (index >= 0) + return sprintf(buf, "%d\n", index); + +@@ -408,7 +380,7 @@ show_cache_disable_##slot(struct _cpuid4 + SHOW_CACHE_DISABLE(0) + SHOW_CACHE_DISABLE(1) + +-static void amd_l3_disable_index(struct amd_l3_cache *l3, int cpu, ++static void amd_l3_disable_index(struct amd_northbridge *nb, int cpu, + unsigned slot, unsigned long idx) + { + int i; +@@ -421,10 +393,10 @@ static void amd_l3_disable_index(struct + for (i = 0; i < 4; i++) { + u32 reg = idx | (i << 20); + +- if (!l3->subcaches[i]) ++ if (!nb->l3_cache.subcaches[i]) + continue; + +- pci_write_config_dword(l3->nb->misc, 0x1BC + slot * 4, reg); ++ pci_write_config_dword(nb->misc, 0x1BC + slot * 4, reg); + + /* + * We need to WBINVD on a core on the node containing the L3 +@@ -434,7 +406,7 @@ static void amd_l3_disable_index(struct + wbinvd_on_cpu(cpu); + + reg |= BIT(31); +- pci_write_config_dword(l3->nb->misc, 0x1BC + slot * 4, reg); ++ pci_write_config_dword(nb->misc, 0x1BC + slot * 4, reg); + } + } + +@@ -448,24 +420,24 @@ static void amd_l3_disable_index(struct + * + * @return: 0 on success, error status on failure + */ +-int amd_set_l3_disable_slot(struct amd_l3_cache *l3, int cpu, unsigned slot, ++int amd_set_l3_disable_slot(struct amd_northbridge *nb, int cpu, unsigned slot, + unsigned long index) + { + int ret = 0; + + /* check if @slot is already used or the index is already disabled */ +- ret = amd_get_l3_disable_slot(l3, slot); ++ ret = amd_get_l3_disable_slot(nb, slot); + if (ret >= 0) + return -EINVAL; + +- if (index > l3->indices) ++ if (index > nb->l3_cache.indices) + return -EINVAL; + + /* check whether the other slot has disabled the same index already */ +- if (index == amd_get_l3_disable_slot(l3, !slot)) ++ if (index == amd_get_l3_disable_slot(nb, !slot)) + return -EINVAL; + +- amd_l3_disable_index(l3, cpu, slot, index); ++ amd_l3_disable_index(nb, cpu, slot, index); + + return 0; + } +@@ -480,8 +452,7 @@ static ssize_t store_cache_disable(struc + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- if (!this_leaf->l3 || +- !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) ++ if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) + return -EINVAL; + + cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map)); +@@ -489,7 +460,7 @@ static ssize_t store_cache_disable(struc + if (strict_strtoul(buf, 10, &val) < 0) + return -EINVAL; + +- err = amd_set_l3_disable_slot(this_leaf->l3, cpu, slot, val); ++ err = amd_set_l3_disable_slot(this_leaf->base.nb, cpu, slot, val); + if (err) { + if (err == -EEXIST) + printk(KERN_WARNING "L3 disable slot %d in use!\n", +@@ -518,7 +489,7 @@ static struct _cache_attr cache_disable_ + static ssize_t + show_subcaches(struct _cpuid4_info *this_leaf, char *buf, unsigned int cpu) + { +- if (!this_leaf->l3 || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) ++ if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) + return -EINVAL; + + return sprintf(buf, "%x\n", amd_get_subcaches(cpu)); +@@ -533,7 +504,7 @@ store_subcaches(struct _cpuid4_info *thi + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + +- if (!this_leaf->l3 || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) ++ if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) + return -EINVAL; + + if (strict_strtoul(buf, 16, &val) < 0) +@@ -769,7 +740,7 @@ static void __cpuinit cache_shared_cpu_m + return; + } + this_leaf = CPUID4_INFO_IDX(cpu, index); +- num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing; ++ num_threads_sharing = 1 + this_leaf->base.eax.split.num_threads_sharing; + + if (num_threads_sharing == 1) + cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map)); +@@ -820,29 +791,19 @@ static void __cpuinit free_cache_attribu + for (i = 0; i < num_cache_leaves; i++) + cache_remove_shared_cpu_map(cpu, i); + +- kfree(per_cpu(ici_cpuid4_info, cpu)->l3); + kfree(per_cpu(ici_cpuid4_info, cpu)); + per_cpu(ici_cpuid4_info, cpu) = NULL; + } + +-static int +-__cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) +-{ +- struct _cpuid4_info_regs *leaf_regs = +- (struct _cpuid4_info_regs *)this_leaf; +- +- return cpuid4_cache_lookup_regs(index, leaf_regs); +-} +- + static void __cpuinit get_cpu_leaves(void *_retval) + { + int j, *retval = _retval, cpu = smp_processor_id(); + + /* Do cpuid and store the results */ + for (j = 0; j < num_cache_leaves; j++) { +- struct _cpuid4_info *this_leaf; +- this_leaf = CPUID4_INFO_IDX(cpu, j); +- *retval = cpuid4_cache_lookup(j, this_leaf); ++ struct _cpuid4_info *this_leaf = CPUID4_INFO_IDX(cpu, j); ++ ++ *retval = cpuid4_cache_lookup_regs(j, &this_leaf->base); + if (unlikely(*retval < 0)) { + int i; + +@@ -900,16 +861,16 @@ static ssize_t show_##file_name(struct _ + return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \ + } + +-show_one_plus(level, eax.split.level, 0); +-show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1); +-show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1); +-show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1); +-show_one_plus(number_of_sets, ecx.split.number_of_sets, 1); ++show_one_plus(level, base.eax.split.level, 0); ++show_one_plus(coherency_line_size, base.ebx.split.coherency_line_size, 1); ++show_one_plus(physical_line_partition, base.ebx.split.physical_line_partition, 1); ++show_one_plus(ways_of_associativity, base.ebx.split.ways_of_associativity, 1); ++show_one_plus(number_of_sets, base.ecx.split.number_of_sets, 1); + + static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf, + unsigned int cpu) + { +- return sprintf(buf, "%luK\n", this_leaf->size / 1024); ++ return sprintf(buf, "%luK\n", this_leaf->base.size / 1024); + } + + static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf, +@@ -946,7 +907,7 @@ static inline ssize_t show_shared_cpu_li + static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf, + unsigned int cpu) + { +- switch (this_leaf->eax.split.type) { ++ switch (this_leaf->base.eax.split.type) { + case CACHE_TYPE_DATA: + return sprintf(buf, "Data\n"); + case CACHE_TYPE_INST: +@@ -1135,7 +1096,7 @@ static int __cpuinit cache_add_dev(struc + + ktype_cache.default_attrs = default_attrs; + #ifdef CONFIG_AMD_NB +- if (this_leaf->l3) ++ if (this_leaf->base.nb) + ktype_cache.default_attrs = amd_l3_attrs(); + #endif + retval = kobject_init_and_add(&(this_object->kobj), +Index: linux-2.6/arch/x86/include/asm/amd_nb.h +=================================================================== +--- linux-2.6.orig/arch/x86/include/asm/amd_nb.h ++++ linux-2.6/arch/x86/include/asm/amd_nb.h +@@ -19,9 +19,15 @@ extern int amd_numa_init(void); + extern int amd_get_subcaches(int); + extern int amd_set_subcaches(int, int); + ++struct amd_l3_cache { ++ unsigned indices; ++ u8 subcaches[4]; ++}; ++ + struct amd_northbridge { + struct pci_dev *misc; + struct pci_dev *link; ++ struct amd_l3_cache l3_cache; + }; + + struct amd_northbridge_info { +Index: linux-2.6/arch/arm/kernel/perf_event.c +=================================================================== +--- linux-2.6.orig/arch/arm/kernel/perf_event.c ++++ linux-2.6/arch/arm/kernel/perf_event.c +@@ -420,7 +420,7 @@ armpmu_reserve_hardware(void) + continue; + + err = request_irq(irq, handle_irq, +- IRQF_DISABLED | IRQF_NOBALANCING, ++ IRQF_NOBALANCING | IRQF_NO_THREAD, + "armpmu", NULL); + if (err) { + pr_warning("unable to request IRQ%d for ARM perf " +Index: linux-2.6/arch/arm/Kconfig +=================================================================== +--- linux-2.6.orig/arch/arm/Kconfig ++++ linux-2.6/arch/arm/Kconfig +@@ -29,6 +29,7 @@ config ARM + select HAVE_GENERIC_HARDIRQS + select HAVE_SPARSE_IRQ + select GENERIC_IRQ_SHOW ++ select IRQ_FORCED_THREADING + help + The ARM series is a line of low-power-consumption RISC chip designs + licensed by ARM Ltd and targeted at embedded applications and +@@ -1510,7 +1511,7 @@ config HAVE_ARCH_PFN_VALID + + config HIGHMEM + bool "High Memory Support" +- depends on MMU ++ depends on MMU && !PREEMPT_RT_FULL + help + The address space of ARM processors is only 4 Gigabytes large + and it has to accommodate user address space, kernel address +Index: linux-2.6/arch/powerpc/platforms/85xx/mpc85xx_cds.c +=================================================================== +--- linux-2.6.orig/arch/powerpc/platforms/85xx/mpc85xx_cds.c ++++ linux-2.6/arch/powerpc/platforms/85xx/mpc85xx_cds.c +@@ -178,7 +178,7 @@ static irqreturn_t mpc85xx_8259_cascade_ + + static struct irqaction mpc85xxcds_8259_irqaction = { + .handler = mpc85xx_8259_cascade_action, +- .flags = IRQF_SHARED, ++ .flags = IRQF_SHARED | IRQF_NO_THREAD, + .name = "8259 cascade", + }; + #endif /* PPC_I8259 */ +Index: linux-2.6/arch/powerpc/Kconfig +=================================================================== +--- linux-2.6.orig/arch/powerpc/Kconfig ++++ linux-2.6/arch/powerpc/Kconfig +@@ -69,10 +69,11 @@ config LOCKDEP_SUPPORT + + config RWSEM_GENERIC_SPINLOCK + bool ++ default y if PREEMPT_RT_FULL + + config RWSEM_XCHGADD_ALGORITHM + bool +- default y ++ default y if !PREEMPT_RT_FULL + + config GENERIC_LOCKBREAK + bool +@@ -134,6 +135,7 @@ config PPC + select GENERIC_IRQ_SHOW_LEVEL + select HAVE_RCU_TABLE_FREE if SMP + select HAVE_SYSCALL_TRACEPOINTS ++ select IRQ_FORCED_THREADING + + config EARLY_PRINTK + bool +@@ -271,7 +273,7 @@ menu "Kernel options" + + config HIGHMEM + bool "High memory support" +- depends on PPC32 ++ depends on PPC32 && !PREEMPT_RT_FULL + + source kernel/time/Kconfig + source kernel/Kconfig.hz +Index: linux-2.6/arch/arm/kernel/process.c +=================================================================== +--- linux-2.6.orig/arch/arm/kernel/process.c ++++ linux-2.6/arch/arm/kernel/process.c +@@ -209,9 +209,7 @@ void cpu_idle(void) + } + leds_event(led_idle_end); + tick_nohz_restart_sched_tick(); +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/avr32/kernel/process.c +=================================================================== +--- linux-2.6.orig/arch/avr32/kernel/process.c ++++ linux-2.6/arch/avr32/kernel/process.c +@@ -38,9 +38,7 @@ void cpu_idle(void) + while (!need_resched()) + cpu_idle_sleep(); + tick_nohz_restart_sched_tick(); +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/blackfin/kernel/process.c +=================================================================== +--- linux-2.6.orig/arch/blackfin/kernel/process.c ++++ linux-2.6/arch/blackfin/kernel/process.c +@@ -92,9 +92,7 @@ void cpu_idle(void) + while (!need_resched()) + idle(); + tick_nohz_restart_sched_tick(); +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/cris/kernel/process.c +=================================================================== +--- linux-2.6.orig/arch/cris/kernel/process.c ++++ linux-2.6/arch/cris/kernel/process.c +@@ -115,9 +115,7 @@ void cpu_idle (void) + idle = default_idle; + idle(); + } +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/frv/kernel/process.c +=================================================================== +--- linux-2.6.orig/arch/frv/kernel/process.c ++++ linux-2.6/arch/frv/kernel/process.c +@@ -92,9 +92,7 @@ void cpu_idle(void) + idle(); + } + +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/h8300/kernel/process.c +=================================================================== +--- linux-2.6.orig/arch/h8300/kernel/process.c ++++ linux-2.6/arch/h8300/kernel/process.c +@@ -81,9 +81,7 @@ void cpu_idle(void) + while (1) { + while (!need_resched()) + idle(); +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/ia64/kernel/process.c +=================================================================== +--- linux-2.6.orig/arch/ia64/kernel/process.c ++++ linux-2.6/arch/ia64/kernel/process.c +@@ -330,9 +330,7 @@ cpu_idle (void) + normal_xtp(); + #endif + } +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + check_pgt_cache(); + if (cpu_is_offline(cpu)) + play_dead(); +Index: linux-2.6/arch/m32r/kernel/process.c +=================================================================== +--- linux-2.6.orig/arch/m32r/kernel/process.c ++++ linux-2.6/arch/m32r/kernel/process.c +@@ -90,9 +90,7 @@ void cpu_idle (void) + + idle(); + } +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/m68k/kernel/process_mm.c +=================================================================== +--- linux-2.6.orig/arch/m68k/kernel/process_mm.c ++++ linux-2.6/arch/m68k/kernel/process_mm.c +@@ -94,9 +94,7 @@ void cpu_idle(void) + while (1) { + while (!need_resched()) + idle(); +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/m68k/kernel/process_no.c +=================================================================== +--- linux-2.6.orig/arch/m68k/kernel/process_no.c ++++ linux-2.6/arch/m68k/kernel/process_no.c +@@ -73,9 +73,7 @@ void cpu_idle(void) + /* endless idle loop with no priority at all */ + while (1) { + idle(); +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/microblaze/kernel/process.c +=================================================================== +--- linux-2.6.orig/arch/microblaze/kernel/process.c ++++ linux-2.6/arch/microblaze/kernel/process.c +@@ -108,9 +108,7 @@ void cpu_idle(void) + idle(); + tick_nohz_restart_sched_tick(); + +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + check_pgt_cache(); + } + } +Index: linux-2.6/arch/mips/kernel/process.c +=================================================================== +--- linux-2.6.orig/arch/mips/kernel/process.c ++++ linux-2.6/arch/mips/kernel/process.c +@@ -78,9 +78,7 @@ void __noreturn cpu_idle(void) + play_dead(); + #endif + tick_nohz_restart_sched_tick(); +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/mn10300/kernel/process.c +=================================================================== +--- linux-2.6.orig/arch/mn10300/kernel/process.c ++++ linux-2.6/arch/mn10300/kernel/process.c +@@ -123,9 +123,7 @@ void cpu_idle(void) + idle(); + } + +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/parisc/kernel/process.c +=================================================================== +--- linux-2.6.orig/arch/parisc/kernel/process.c ++++ linux-2.6/arch/parisc/kernel/process.c +@@ -71,9 +71,7 @@ void cpu_idle(void) + while (1) { + while (!need_resched()) + barrier(); +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + check_pgt_cache(); + } + } +Index: linux-2.6/arch/powerpc/kernel/idle.c +=================================================================== +--- linux-2.6.orig/arch/powerpc/kernel/idle.c ++++ linux-2.6/arch/powerpc/kernel/idle.c +@@ -94,11 +94,11 @@ void cpu_idle(void) + HMT_medium(); + ppc64_runlatch_on(); + tick_nohz_restart_sched_tick(); +- preempt_enable_no_resched(); +- if (cpu_should_die()) ++ if (cpu_should_die()) { ++ __preempt_enable_no_resched(); + cpu_die(); +- schedule(); +- preempt_disable(); ++ } ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/powerpc/platforms/iseries/setup.c +=================================================================== +--- linux-2.6.orig/arch/powerpc/platforms/iseries/setup.c ++++ linux-2.6/arch/powerpc/platforms/iseries/setup.c +@@ -581,9 +581,7 @@ static void iseries_shared_idle(void) + if (hvlpevent_is_pending()) + process_iSeries_events(); + +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +@@ -610,9 +608,7 @@ static void iseries_dedicated_idle(void) + + ppc64_runlatch_on(); + tick_nohz_restart_sched_tick(); +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/s390/kernel/process.c +=================================================================== +--- linux-2.6.orig/arch/s390/kernel/process.c ++++ linux-2.6/arch/s390/kernel/process.c +@@ -94,9 +94,7 @@ void cpu_idle(void) + while (!need_resched()) + default_idle(); + tick_nohz_restart_sched_tick(); +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/score/kernel/process.c +=================================================================== +--- linux-2.6.orig/arch/score/kernel/process.c ++++ linux-2.6/arch/score/kernel/process.c +@@ -53,9 +53,7 @@ void __noreturn cpu_idle(void) + while (!need_resched()) + barrier(); + +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/sh/kernel/idle.c +=================================================================== +--- linux-2.6.orig/arch/sh/kernel/idle.c ++++ linux-2.6/arch/sh/kernel/idle.c +@@ -110,9 +110,7 @@ void cpu_idle(void) + } + + tick_nohz_restart_sched_tick(); +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/sparc/kernel/process_32.c +=================================================================== +--- linux-2.6.orig/arch/sparc/kernel/process_32.c ++++ linux-2.6/arch/sparc/kernel/process_32.c +@@ -113,9 +113,7 @@ void cpu_idle(void) + while (!need_resched()) + cpu_relax(); + } +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + check_pgt_cache(); + } + } +@@ -138,9 +136,7 @@ void cpu_idle(void) + while (!need_resched()) + cpu_relax(); + } +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + check_pgt_cache(); + } + } +Index: linux-2.6/arch/sparc/kernel/process_64.c +=================================================================== +--- linux-2.6.orig/arch/sparc/kernel/process_64.c ++++ linux-2.6/arch/sparc/kernel/process_64.c +@@ -102,15 +102,13 @@ void cpu_idle(void) + + tick_nohz_restart_sched_tick(); + +- preempt_enable_no_resched(); +- + #ifdef CONFIG_HOTPLUG_CPU +- if (cpu_is_offline(cpu)) ++ if (cpu_is_offline(cpu)) { ++ __preempt_enable_no_resched(); + cpu_play_dead(); ++ } + #endif +- +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/tile/kernel/process.c +=================================================================== +--- linux-2.6.orig/arch/tile/kernel/process.c ++++ linux-2.6/arch/tile/kernel/process.c +@@ -106,9 +106,7 @@ void cpu_idle(void) + current_thread_info()->status |= TS_POLLING; + } + tick_nohz_restart_sched_tick(); +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/x86/kernel/process_32.c +=================================================================== +--- linux-2.6.orig/arch/x86/kernel/process_32.c ++++ linux-2.6/arch/x86/kernel/process_32.c +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -113,9 +114,7 @@ void cpu_idle(void) + start_critical_timings(); + } + tick_nohz_restart_sched_tick(); +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +@@ -348,6 +347,41 @@ __switch_to(struct task_struct *prev_p, + task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT)) + __switch_to_xtra(prev_p, next_p, tss); + ++#if defined CONFIG_PREEMPT_RT_FULL && defined CONFIG_HIGHMEM ++ /* ++ * Save @prev's kmap_atomic stack ++ */ ++ prev_p->kmap_idx = __this_cpu_read(__kmap_atomic_idx); ++ if (unlikely(prev_p->kmap_idx)) { ++ int i; ++ ++ for (i = 0; i < prev_p->kmap_idx; i++) { ++ int idx = i + KM_TYPE_NR * smp_processor_id(); ++ ++ pte_t *ptep = kmap_pte - idx; ++ prev_p->kmap_pte[i] = *ptep; ++ kpte_clear_flush(ptep, __fix_to_virt(FIX_KMAP_BEGIN + idx)); ++ } ++ ++ __this_cpu_write(__kmap_atomic_idx, 0); ++ } ++ ++ /* ++ * Restore @next_p's kmap_atomic stack ++ */ ++ if (unlikely(next_p->kmap_idx)) { ++ int i; ++ ++ __this_cpu_write(__kmap_atomic_idx, next_p->kmap_idx); ++ ++ for (i = 0; i < next_p->kmap_idx; i++) { ++ int idx = i + KM_TYPE_NR * smp_processor_id(); ++ ++ set_pte(kmap_pte - idx, next_p->kmap_pte[i]); ++ } ++ } ++#endif ++ + /* If we're going to preload the fpu context, make sure clts + is run while we're batching the cpu state updates. */ + if (preload_fpu) +Index: linux-2.6/arch/x86/kernel/process_64.c +=================================================================== +--- linux-2.6.orig/arch/x86/kernel/process_64.c ++++ linux-2.6/arch/x86/kernel/process_64.c +@@ -146,9 +146,7 @@ void cpu_idle(void) + } + + tick_nohz_restart_sched_tick(); +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/arch/xtensa/kernel/process.c +=================================================================== +--- linux-2.6.orig/arch/xtensa/kernel/process.c ++++ linux-2.6/arch/xtensa/kernel/process.c +@@ -113,9 +113,7 @@ void cpu_idle(void) + while (1) { + while (!need_resched()) + platform_idle(); +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + } + } + +Index: linux-2.6/init/main.c +=================================================================== +--- linux-2.6.orig/init/main.c ++++ linux-2.6/init/main.c +@@ -68,6 +68,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -367,9 +368,7 @@ static noinline void __init_refok rest_i + * at least once to get things moving: + */ + init_idle_bootup_task(current); +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + + /* Call into cpu_idle with preempt disabled */ + cpu_idle(); +@@ -501,6 +500,7 @@ asmlinkage void __init start_kernel(void + parse_args("Booting kernel", static_command_line, __start___param, + __stop___param - __start___param, + &unknown_bootoption); ++ softirq_early_init(); + /* + * These use large bootmem allocations and must precede + * kmem_cache_init() +Index: linux-2.6/kernel/mutex.c +=================================================================== +--- linux-2.6.orig/kernel/mutex.c ++++ linux-2.6/kernel/mutex.c +@@ -240,9 +240,7 @@ __mutex_lock_common(struct mutex *lock, + + /* didn't get the lock, go to sleep: */ + spin_unlock_mutex(&lock->wait_lock, flags); +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); ++ schedule_preempt_disabled(); + spin_lock_mutex(&lock->wait_lock, flags); + } + +Index: linux-2.6/kernel/softirq.c +=================================================================== +--- linux-2.6.orig/kernel/softirq.c ++++ linux-2.6/kernel/softirq.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #define CREATE_TRACE_POINTS + #include +@@ -61,6 +62,67 @@ char *softirq_to_name[NR_SOFTIRQS] = { + "TASKLET", "SCHED", "HRTIMER", "RCU" + }; + ++#ifdef CONFIG_NO_HZ ++# ifdef CONFIG_PREEMPT_RT_FULL ++/* ++ * On preempt-rt a softirq might be blocked on a lock. There might be ++ * no other runnable task on this CPU because the lock owner runs on ++ * some other CPU. So we have to go into idle with the pending bit ++ * set. Therefor we need to check this otherwise we warn about false ++ * positives which confuses users and defeats the whole purpose of ++ * this test. ++ * ++ * This code is called with interrupts disabled. ++ */ ++void softirq_check_pending_idle(void) ++{ ++ static int rate_limit; ++ u32 warnpending = 0, pending = local_softirq_pending(); ++ ++ if (rate_limit >= 10) ++ return; ++ ++ if (pending) { ++ struct task_struct *tsk; ++ ++ tsk = __get_cpu_var(ksoftirqd); ++ /* ++ * The wakeup code in rtmutex.c wakes up the task ++ * _before_ it sets pi_blocked_on to NULL under ++ * tsk->pi_lock. So we need to check for both: state ++ * and pi_blocked_on. ++ */ ++ raw_spin_lock(&tsk->pi_lock); ++ ++ if (!tsk->pi_blocked_on && !(tsk->state == TASK_RUNNING)) ++ warnpending = 1; ++ ++ raw_spin_unlock(&tsk->pi_lock); ++ } ++ ++ if (warnpending) { ++ printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n", ++ pending); ++ rate_limit++; ++ } ++} ++# else ++/* ++ * On !PREEMPT_RT we just printk rate limited: ++ */ ++void softirq_check_pending_idle(void) ++{ ++ static int rate_limit; ++ ++ if (rate_limit < 10) { ++ printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n", ++ local_softirq_pending()); ++ rate_limit++; ++ } ++} ++# endif ++#endif ++ + /* + * we cannot loop indefinitely here to avoid userspace starvation, + * but we also don't want to introduce a worst case 1/HZ latency +@@ -76,6 +138,35 @@ static void wakeup_softirqd(void) + wake_up_process(tsk); + } + ++static void handle_pending_softirqs(u32 pending, int cpu) ++{ ++ struct softirq_action *h = softirq_vec; ++ unsigned int prev_count = preempt_count(); ++ ++ local_irq_enable(); ++ for ( ; pending; h++, pending >>= 1) { ++ unsigned int vec_nr = h - softirq_vec; ++ ++ if (!(pending & 1)) ++ continue; ++ ++ kstat_incr_softirqs_this_cpu(vec_nr); ++ trace_softirq_entry(vec_nr); ++ h->action(h); ++ trace_softirq_exit(vec_nr); ++ if (unlikely(prev_count != preempt_count())) { ++ printk(KERN_ERR ++ "huh, entered softirq %u %s %p with preempt_count %08x exited with %08x?\n", ++ vec_nr, softirq_to_name[vec_nr], h->action, ++ prev_count, (unsigned int) preempt_count()); ++ preempt_count() = prev_count; ++ } ++ rcu_bh_qs(cpu); ++ } ++ local_irq_disable(); ++} ++ ++#ifndef CONFIG_PREEMPT_RT_FULL + /* + * preempt_count and SOFTIRQ_OFFSET usage: + * - preempt_count is changed by SOFTIRQ_OFFSET on entering or leaving +@@ -206,7 +297,6 @@ EXPORT_SYMBOL(local_bh_enable_ip); + + asmlinkage void __do_softirq(void) + { +- struct softirq_action *h; + __u32 pending; + int max_restart = MAX_SOFTIRQ_RESTART; + int cpu; +@@ -215,7 +305,7 @@ asmlinkage void __do_softirq(void) + account_system_vtime(current); + + __local_bh_disable((unsigned long)__builtin_return_address(0), +- SOFTIRQ_OFFSET); ++ SOFTIRQ_OFFSET); + lockdep_softirq_enter(); + + cpu = smp_processor_id(); +@@ -223,36 +313,7 @@ restart: + /* Reset the pending bitmask before enabling irqs */ + set_softirq_pending(0); + +- local_irq_enable(); +- +- h = softirq_vec; +- +- do { +- if (pending & 1) { +- unsigned int vec_nr = h - softirq_vec; +- int prev_count = preempt_count(); +- +- kstat_incr_softirqs_this_cpu(vec_nr); +- +- trace_softirq_entry(vec_nr); +- h->action(h); +- trace_softirq_exit(vec_nr); +- if (unlikely(prev_count != preempt_count())) { +- printk(KERN_ERR "huh, entered softirq %u %s %p" +- "with preempt_count %08x," +- " exited with %08x?\n", vec_nr, +- softirq_to_name[vec_nr], h->action, +- prev_count, preempt_count()); +- preempt_count() = prev_count; +- } +- +- rcu_bh_qs(cpu); +- } +- h++; +- pending >>= 1; +- } while (pending); +- +- local_irq_disable(); ++ handle_pending_softirqs(pending, cpu); + + pending = local_softirq_pending(); + if (pending && --max_restart) +@@ -267,6 +328,26 @@ restart: + __local_bh_enable(SOFTIRQ_OFFSET); + } + ++/* ++ * Called with preemption disabled from run_ksoftirqd() ++ */ ++static int ksoftirqd_do_softirq(int cpu) ++{ ++ /* ++ * Preempt disable stops cpu going offline. ++ * If already offline, we'll be on wrong CPU: ++ * don't process. ++ */ ++ if (cpu_is_offline(cpu)) ++ return -1; ++ ++ local_irq_disable(); ++ if (local_softirq_pending()) ++ __do_softirq(); ++ local_irq_enable(); ++ return 0; ++} ++ + #ifndef __ARCH_HAS_DO_SOFTIRQ + + asmlinkage void do_softirq(void) +@@ -289,6 +370,178 @@ asmlinkage void do_softirq(void) + + #endif + ++static inline void local_bh_disable_nort(void) { local_bh_disable(); } ++static inline void _local_bh_enable_nort(void) { _local_bh_enable(); } ++static inline void ksoftirqd_set_sched_params(void) { } ++static inline void ksoftirqd_clr_sched_params(void) { } ++ ++#else /* !PREEMPT_RT_FULL */ ++ ++/* ++ * On RT we serialize softirq execution with a cpu local lock ++ */ ++static DEFINE_LOCAL_IRQ_LOCK(local_softirq_lock); ++static DEFINE_PER_CPU(struct task_struct *, local_softirq_runner); ++ ++static void __do_softirq(void); ++ ++void __init softirq_early_init(void) ++{ ++ local_irq_lock_init(local_softirq_lock); ++} ++ ++void local_bh_disable(void) ++{ ++ migrate_disable(); ++ current->softirq_nestcnt++; ++} ++EXPORT_SYMBOL(local_bh_disable); ++ ++void local_bh_enable(void) ++{ ++ if (WARN_ON(current->softirq_nestcnt == 0)) ++ return; ++ ++ if ((current->softirq_nestcnt == 1) && ++ local_softirq_pending() && ++ local_trylock(local_softirq_lock)) { ++ ++ local_irq_disable(); ++ if (local_softirq_pending()) ++ __do_softirq(); ++ local_unlock(local_softirq_lock); ++ local_irq_enable(); ++ WARN_ON(current->softirq_nestcnt != 1); ++ } ++ current->softirq_nestcnt--; ++ migrate_enable(); ++} ++EXPORT_SYMBOL(local_bh_enable); ++ ++void local_bh_enable_ip(unsigned long ip) ++{ ++ local_bh_enable(); ++} ++EXPORT_SYMBOL(local_bh_enable_ip); ++ ++/* For tracing */ ++int notrace __in_softirq(void) ++{ ++ if (__get_cpu_var(local_softirq_lock).owner == current) ++ return __get_cpu_var(local_softirq_lock).nestcnt; ++ return 0; ++} ++ ++int in_serving_softirq(void) ++{ ++ int res; ++ ++ preempt_disable(); ++ res = __get_cpu_var(local_softirq_runner) == current; ++ preempt_enable(); ++ return res; ++} ++ ++/* ++ * Called with bh and local interrupts disabled. For full RT cpu must ++ * be pinned. ++ */ ++static void __do_softirq(void) ++{ ++ u32 pending = local_softirq_pending(); ++ int cpu = smp_processor_id(); ++ ++ current->softirq_nestcnt++; ++ ++ /* Reset the pending bitmask before enabling irqs */ ++ set_softirq_pending(0); ++ ++ __get_cpu_var(local_softirq_runner) = current; ++ ++ lockdep_softirq_enter(); ++ ++ handle_pending_softirqs(pending, cpu); ++ ++ pending = local_softirq_pending(); ++ if (pending) ++ wakeup_softirqd(); ++ ++ lockdep_softirq_exit(); ++ __get_cpu_var(local_softirq_runner) = NULL; ++ ++ current->softirq_nestcnt--; ++} ++ ++static int __thread_do_softirq(int cpu) ++{ ++ /* ++ * Prevent the current cpu from going offline. ++ * pin_current_cpu() can reenable preemption and block on the ++ * hotplug mutex. When it returns, the current cpu is ++ * pinned. It might be the wrong one, but the offline check ++ * below catches that. ++ */ ++ pin_current_cpu(); ++ /* ++ * If called from ksoftirqd (cpu >= 0) we need to check ++ * whether we are on the wrong cpu due to cpu offlining. If ++ * called via thread_do_softirq() no action required. ++ */ ++ if (cpu >= 0 && cpu_is_offline(cpu)) { ++ unpin_current_cpu(); ++ return -1; ++ } ++ preempt_enable(); ++ local_lock(local_softirq_lock); ++ local_irq_disable(); ++ /* ++ * We cannot switch stacks on RT as we want to be able to ++ * schedule! ++ */ ++ if (local_softirq_pending()) ++ __do_softirq(); ++ local_unlock(local_softirq_lock); ++ unpin_current_cpu(); ++ preempt_disable(); ++ local_irq_enable(); ++ return 0; ++} ++ ++/* ++ * Called from netif_rx_ni(). Preemption enabled. ++ */ ++void thread_do_softirq(void) ++{ ++ if (!in_serving_softirq()) { ++ preempt_disable(); ++ __thread_do_softirq(-1); ++ preempt_enable(); ++ } ++} ++ ++static int ksoftirqd_do_softirq(int cpu) ++{ ++ return __thread_do_softirq(cpu); ++} ++ ++static inline void local_bh_disable_nort(void) { } ++static inline void _local_bh_enable_nort(void) { } ++ ++static inline void ksoftirqd_set_sched_params(void) ++{ ++ struct sched_param param = { .sched_priority = 1 }; ++ ++ sched_setscheduler(current, SCHED_FIFO, ¶m); ++} ++ ++static inline void ksoftirqd_clr_sched_params(void) ++{ ++ struct sched_param param = { .sched_priority = 0 }; ++ ++ sched_setscheduler(current, SCHED_NORMAL, ¶m); ++} ++ ++#endif /* PREEMPT_RT_FULL */ + /* + * Enter an interrupt context. + */ +@@ -302,9 +555,9 @@ void irq_enter(void) + * Prevent raise_softirq from needlessly waking up ksoftirqd + * here, as softirq will be serviced on return from interrupt. + */ +- local_bh_disable(); ++ local_bh_disable_nort(); + tick_check_idle(cpu); +- _local_bh_enable(); ++ _local_bh_enable_nort(); + } + + __irq_enter(); +@@ -313,6 +566,7 @@ void irq_enter(void) + #ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED + static inline void invoke_softirq(void) + { ++#ifndef CONFIG_PREEMPT_RT_FULL + if (!force_irqthreads) + __do_softirq(); + else { +@@ -321,10 +575,14 @@ static inline void invoke_softirq(void) + wakeup_softirqd(); + __local_bh_enable(SOFTIRQ_OFFSET); + } ++#else ++ wakeup_softirqd(); ++#endif + } + #else + static inline void invoke_softirq(void) + { ++#ifndef CONFIG_PREEMPT_RT_FULL + if (!force_irqthreads) + do_softirq(); + else { +@@ -333,6 +591,9 @@ static inline void invoke_softirq(void) + wakeup_softirqd(); + __local_bh_enable(SOFTIRQ_OFFSET); + } ++#else ++ wakeup_softirqd(); ++#endif + } + #endif + +@@ -353,7 +614,7 @@ void irq_exit(void) + if (idle_cpu(smp_processor_id()) && !in_interrupt() && !need_resched()) + tick_nohz_stop_sched_tick(0); + #endif +- preempt_enable_no_resched(); ++ __preempt_enable_no_resched(); + } + + /* +@@ -739,29 +1000,21 @@ void __init softirq_init(void) + + static int run_ksoftirqd(void * __bind_cpu) + { ++ ksoftirqd_set_sched_params(); ++ + set_current_state(TASK_INTERRUPTIBLE); + + while (!kthread_should_stop()) { + preempt_disable(); +- if (!local_softirq_pending()) { +- preempt_enable_no_resched(); +- schedule(); +- preempt_disable(); +- } ++ if (!local_softirq_pending()) ++ schedule_preempt_disabled(); + + __set_current_state(TASK_RUNNING); + + while (local_softirq_pending()) { +- /* Preempt disable stops cpu going offline. +- If already offline, we'll be on wrong CPU: +- don't process */ +- if (cpu_is_offline((long)__bind_cpu)) ++ if (ksoftirqd_do_softirq((long) __bind_cpu)) + goto wait_to_die; +- local_irq_disable(); +- if (local_softirq_pending()) +- __do_softirq(); +- local_irq_enable(); +- preempt_enable_no_resched(); ++ __preempt_enable_no_resched(); + cond_resched(); + preempt_disable(); + rcu_note_context_switch((long)__bind_cpu); +@@ -774,6 +1027,7 @@ static int run_ksoftirqd(void * __bind_c + + wait_to_die: + preempt_enable(); ++ ksoftirqd_clr_sched_params(); + /* Wait for kthread_stop */ + set_current_state(TASK_INTERRUPTIBLE); + while (!kthread_should_stop()) { Index: linux-2.6/kernel/signal.c =================================================================== --- linux-2.6.orig/kernel/signal.c @@ -9803,6 +9877,15 @@ Index: linux-2.6/kernel/sched_rt.c if (rt_rq_throttled(rt_rq)) { sched_rt_rq_dequeue(rt_rq); return 1; +@@ -1038,7 +1039,7 @@ select_task_rq_rt(struct task_struct *p, + */ + if (curr && unlikely(rt_task(curr)) && + (curr->rt.nr_cpus_allowed < 2 || +- curr->prio < p->prio) && ++ curr->prio <= p->prio) && + (p->rt.nr_cpus_allowed > 1)) { + int target = find_lowest_rq(p); + @@ -1186,7 +1187,7 @@ static void deactivate_task(struct rq *r static int pick_rt_task(struct rq *rq, struct task_struct *p, int cpu) { @@ -9821,6 +9904,15 @@ Index: linux-2.6/kernel/sched_rt.c task_running(rq, task) || !task->on_rq)) { +@@ -1569,7 +1570,7 @@ static void task_woken_rt(struct rq *rq, + p->rt.nr_cpus_allowed > 1 && + rt_task(rq->curr) && + (rq->curr->rt.nr_cpus_allowed < 2 || +- rq->curr->prio < p->prio)) ++ rq->curr->prio <= p->prio)) + push_rt_tasks(rq); + } + @@ -1614,9 +1615,6 @@ static void set_cpus_allowed_rt(struct t update_rt_migration(&rq->rt); @@ -15148,7 +15240,7 @@ Index: linux-2.6/kernel/hrtimer.c timerqueue_init(&timer->node); #ifdef CONFIG_TIMER_STATS -@@ -1232,6 +1292,116 @@ static void __run_hrtimer(struct hrtimer +@@ -1232,6 +1292,122 @@ static void __run_hrtimer(struct hrtimer timer->state &= ~HRTIMER_STATE_CALLBACK; } @@ -15174,7 +15266,11 @@ Index: linux-2.6/kernel/hrtimer.c + if (!enqueue_hrtimer(timer, base)) + return; + -+ if (hrtimer_reprogram(timer, base)) ++#ifndef CONFIG_HIGH_RES_TIMERS ++ } ++#else ++ if (base->cpu_base->hres_active && ++ hrtimer_reprogram(timer, base)) + goto requeue; + + } else if (hrtimer_active(timer)) { @@ -15183,6 +15279,7 @@ Index: linux-2.6/kernel/hrtimer.c + * the event device. + */ + if (&timer->node == base->active.next && ++ base->cpu_base->hres_active && + hrtimer_reprogram(timer, base)) + goto requeue; + } @@ -15195,6 +15292,7 @@ Index: linux-2.6/kernel/hrtimer.c + */ + __remove_hrtimer(timer, base, timer->state, 0); + list_add_tail(&timer->cb_entry, &base->expired); ++#endif +} + +/* @@ -15265,7 +15363,7 @@ Index: linux-2.6/kernel/hrtimer.c #ifdef CONFIG_HIGH_RES_TIMERS /* -@@ -1242,7 +1412,7 @@ void hrtimer_interrupt(struct clock_even +@@ -1242,7 +1418,7 @@ void hrtimer_interrupt(struct clock_even { struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases); ktime_t expires_next, now, entry_time, delta; @@ -15274,7 +15372,7 @@ Index: linux-2.6/kernel/hrtimer.c BUG_ON(!cpu_base->hres_active); cpu_base->nr_events++; -@@ -1278,6 +1448,14 @@ retry: +@@ -1278,6 +1454,14 @@ retry: timer = container_of(node, struct hrtimer, node); @@ -15289,7 +15387,7 @@ Index: linux-2.6/kernel/hrtimer.c /* * The immediate goal for using the softexpires is * minimizing wakeups, not running timers at the -@@ -1301,7 +1479,10 @@ retry: +@@ -1301,7 +1485,10 @@ retry: break; } @@ -15301,7 +15399,7 @@ Index: linux-2.6/kernel/hrtimer.c } } -@@ -1316,6 +1497,10 @@ retry: +@@ -1316,6 +1503,10 @@ retry: if (expires_next.tv64 == KTIME_MAX || !tick_program_event(expires_next, 0)) { cpu_base->hang_detected = 0; @@ -15312,7 +15410,7 @@ Index: linux-2.6/kernel/hrtimer.c return; } -@@ -1391,17 +1576,17 @@ void hrtimer_peek_ahead_timers(void) +@@ -1391,17 +1582,17 @@ void hrtimer_peek_ahead_timers(void) local_irq_restore(flags); } @@ -15335,7 +15433,7 @@ Index: linux-2.6/kernel/hrtimer.c /* * Called from timer softirq every jiffy, expire hrtimers: * -@@ -1434,7 +1619,7 @@ void hrtimer_run_queues(void) +@@ -1434,7 +1625,7 @@ void hrtimer_run_queues(void) struct timerqueue_node *node; struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases); struct hrtimer_clock_base *base; @@ -15344,7 +15442,7 @@ Index: linux-2.6/kernel/hrtimer.c if (hrtimer_hres_active()) return; -@@ -1459,10 +1644,16 @@ void hrtimer_run_queues(void) +@@ -1459,10 +1650,16 @@ void hrtimer_run_queues(void) hrtimer_get_expires_tv64(timer)) break; @@ -15362,7 +15460,7 @@ Index: linux-2.6/kernel/hrtimer.c } /* -@@ -1484,6 +1675,7 @@ static enum hrtimer_restart hrtimer_wake +@@ -1484,6 +1681,7 @@ static enum hrtimer_restart hrtimer_wake void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *task) { sl->timer.function = hrtimer_wakeup; @@ -15370,7 +15468,7 @@ Index: linux-2.6/kernel/hrtimer.c sl->task = task; } EXPORT_SYMBOL_GPL(hrtimer_init_sleeper); -@@ -1622,9 +1814,13 @@ static void __cpuinit init_hrtimers_cpu( +@@ -1622,9 +1820,13 @@ static void __cpuinit init_hrtimers_cpu( for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { cpu_base->clock_base[i].cpu_base = cpu_base; timerqueue_init_head(&cpu_base->clock_base[i].active); @@ -15384,7 +15482,7 @@ Index: linux-2.6/kernel/hrtimer.c } #ifdef CONFIG_HOTPLUG_CPU -@@ -1737,9 +1933,7 @@ void __init hrtimers_init(void) +@@ -1737,9 +1939,7 @@ void __init hrtimers_init(void) hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE, (void *)(long)smp_processor_id()); register_cpu_notifier(&hrtimers_nb); @@ -18033,7 +18131,7 @@ Index: linux-2.6/localversion-rt --- /dev/null +++ linux-2.6/localversion-rt @@ -0,0 +1 @@ -+-rt13 ++-rt14 Index: linux-2.6/arch/arm/kernel/early_printk.c =================================================================== --- linux-2.6.orig/arch/arm/kernel/early_printk.c @@ -20896,6 +20994,25 @@ Index: linux-2.6/include/linux/rcupdate.h /* * debug_rcu_head_queue()/debug_rcu_head_unqueue() are used internally +Index: linux-2.6/kernel/sched_features.h +=================================================================== +--- linux-2.6.orig/kernel/sched_features.h ++++ linux-2.6/kernel/sched_features.h +@@ -65,10 +65,14 @@ SCHED_FEAT(OWNER_SPIN, 1) + */ + SCHED_FEAT(NONIRQ_POWER, 1) + ++#ifndef CONFIG_PREEMPT_RT_FULL + /* + * Queue remote wakeups on the target CPU and process them + * using the scheduler IPI. Reduces rq->lock contention/bounces. + */ + SCHED_FEAT(TTWU_QUEUE, 1) ++#else ++SCHED_FEAT(TTWU_QUEUE, 0) ++#endif + + SCHED_FEAT(FORCE_SD_OVERLAP, 0) Index: linux-2.6/kernel/stop_machine.c =================================================================== --- linux-2.6.orig/kernel/stop_machine.c @@ -21343,15 +21460,17 @@ Index: linux-2.6/kernel/sched_debug.c =================================================================== --- linux-2.6.orig/kernel/sched_debug.c +++ linux-2.6/kernel/sched_debug.c -@@ -235,6 +235,7 @@ void print_rt_rq(struct seq_file *m, int +@@ -235,6 +235,9 @@ void print_rt_rq(struct seq_file *m, int P(rt_throttled); PN(rt_time); PN(rt_runtime); ++#ifdef CONFIG_SMP + P(rt_nr_migratory); ++#endif #undef PN #undef P -@@ -484,6 +485,10 @@ void proc_sched_show_task(struct task_st +@@ -484,6 +487,10 @@ void proc_sched_show_task(struct task_st P(se.load.weight); P(policy); P(prio); @@ -25079,6 +25198,48 @@ Index: linux-2.6/kernel/ksysfs.c NULL }; +Index: linux-2.6/ipc/sem.c +=================================================================== +--- linux-2.6.orig/ipc/sem.c ++++ linux-2.6/ipc/sem.c +@@ -415,6 +415,13 @@ undo: + static void wake_up_sem_queue_prepare(struct list_head *pt, + struct sem_queue *q, int error) + { ++#ifdef CONFIG_PREEMPT_RT_BASE ++ struct task_struct *p = q->sleeper; ++ get_task_struct(p); ++ q->status = error; ++ wake_up_process(p); ++ put_task_struct(p); ++#else + if (list_empty(pt)) { + /* + * Hold preempt off so that we don't get preempted and have the +@@ -426,6 +433,7 @@ static void wake_up_sem_queue_prepare(st + q->pid = error; + + list_add_tail(&q->simple_list, pt); ++#endif + } + + /** +@@ -439,6 +447,7 @@ static void wake_up_sem_queue_prepare(st + */ + static void wake_up_sem_queue_do(struct list_head *pt) + { ++#ifndef CONFIG_PREEMPT_RT_BASE + struct sem_queue *q, *t; + int did_something; + +@@ -451,6 +460,7 @@ static void wake_up_sem_queue_do(struct + } + if (did_something) + preempt_enable(); ++#endif + } + + static void unlink_queue(struct sem_array *sma, struct sem_queue *q) Index: linux-2.6/arch/Kconfig =================================================================== --- linux-2.6.orig/arch/Kconfig diff --git a/debian/patches/series/4-extra b/debian/patches/series/4-extra index a50d2dd76..756ae97b2 100644 --- a/debian/patches/series/4-extra +++ b/debian/patches/series/4-extra @@ -1 +1 @@ -+ features/all/rt/patch-3.0.4-rt13.patch featureset=rt ++ features/all/rt/patch-3.0.4-rt14.patch featureset=rt