]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'stable/for-linus-3.12-rc0-tag-two' of git://git.kernel.org/pub/scm/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 11 Sep 2013 03:07:04 +0000 (20:07 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 11 Sep 2013 03:07:04 +0000 (20:07 -0700)
Pull Xen bug-fixes from Konrad Rzeszutek Wilk:
 "This pull I usually do after rc1 is out but because we have a nice
  amount of fixes, some bootup related fixes for ARM, and it is early in
  the cycle we figured to do it now to help with tracking of potential
  regressions.

  The simple ones are the ARM ones - one of the patches fell through the
  cracks, other fixes a bootup issue (unconditionally using Xen
  functions).  Then a fix for a regression causing preempt count being
  off (patch causing this went in v3.12).

  Lastly are the fixes to make Xen PVHVM guests use PV ticketlocks (Xen
  PV already does).

  The enablement of that was supposed to be part of the x86 spinlock
  merge in commit 816434ec4a67 ("The biggest change here are
  paravirtualized ticket spinlocks (PV spinlocks), which bring a nice
  speedup on various benchmarks...") but unfortunatly it would cause
  hang when booting Xen PVHVM guests.  Yours truly got all of the bugs
  fixed last week and they (six of them) are included in this pull.

  Bug-fixes:
   - Boot on ARM without using Xen unconditionally
   - On Xen ARM don't run cpuidle/cpufreq
   - Fix regression in balloon driver, preempt count warnings
   - Fixes to make PVHVM able to use pv ticketlock.
   - Revert Xen PVHVM disabling pv ticketlock (aka, re-enable pv ticketlocks)"

* tag 'stable/for-linus-3.12-rc0-tag-two' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
  xen/spinlock: Don't use __initdate for xen_pv_spin
  Revert "xen/spinlock: Disable IRQ spinlock (PV) allocation on PVHVM"
  xen/spinlock: Don't setup xen spinlock IPI kicker if disabled.
  xen/smp: Update pv_lock_ops functions before alternative code starts under PVHVM
  xen/spinlock: We don't need the old structure anymore
  xen/spinlock: Fix locking path engaging too soon under PVHVM.
  xen/arm: disable cpuidle and cpufreq when linux is running as dom0
  xen/p2m: Don't call get_balloon_scratch_page() twice, keep interrupts disabled for multicalls
  ARM: xen: only set pm function ptrs for Xen guests

arch/arm/xen/enlighten.c
arch/x86/xen/enlighten.c
arch/x86/xen/p2m.c
arch/x86/xen/smp.c
arch/x86/xen/spinlock.c

index 8a6295c86209cd982076a8f79662bd20c2c0f02b..83e4f959ee47c6b9b18a77d9f50995b7b4fc5ab0 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
+#include <linux/cpuidle.h>
+#include <linux/cpufreq.h>
 
 #include <linux/mm.h>
 
@@ -267,18 +269,28 @@ static int __init xen_guest_init(void)
        if (!xen_initial_domain())
                xenbus_probe(NULL);
 
+       /*
+        * Making sure board specific code will not set up ops for
+        * cpu idle and cpu freq.
+        */
+       disable_cpuidle();
+       disable_cpufreq();
+
        return 0;
 }
 core_initcall(xen_guest_init);
 
 static int __init xen_pm_init(void)
 {
+       if (!xen_domain())
+               return -ENODEV;
+
        pm_power_off = xen_power_off;
        arm_pm_restart = xen_restart;
 
        return 0;
 }
-subsys_initcall(xen_pm_init);
+late_initcall(xen_pm_init);
 
 static irqreturn_t xen_arm_callback(int irq, void *arg)
 {
index 2fc216dfbd9c6c8a08dd0a386a621cdb7d2c2b41..fa6ade76ef3fc084c5f4911e145979aebe10c5bb 100644 (file)
@@ -1692,7 +1692,6 @@ static int xen_hvm_cpu_notify(struct notifier_block *self, unsigned long action,
        case CPU_UP_PREPARE:
                xen_vcpu_setup(cpu);
                if (xen_have_vector_callback) {
-                       xen_init_lock_cpu(cpu);
                        if (xen_feature(XENFEAT_hvm_safe_pvclock))
                                xen_setup_timer(cpu);
                }
index 0d4ec35895d425c64567110f9d2285aaae3dc1b4..8b901e8d782dadf00091ac88a6fc859c54c4d1de 100644 (file)
@@ -990,10 +990,13 @@ int m2p_remove_override(struct page *page,
                                printk(KERN_WARNING "m2p_remove_override: "
                                                "pfn %lx mfn %lx, failed to modify kernel mappings",
                                                pfn, mfn);
+                               put_balloon_scratch_page();
                                return -1;
                        }
 
-                       mcs = xen_mc_entry(
+                       xen_mc_batch();
+
+                       mcs = __xen_mc_entry(
                                        sizeof(struct gnttab_unmap_and_replace));
                        unmap_op = mcs.args;
                        unmap_op->host_addr = kmap_op->host_addr;
@@ -1003,12 +1006,11 @@ int m2p_remove_override(struct page *page,
                        MULTI_grant_table_op(mcs.mc,
                                        GNTTABOP_unmap_and_replace, unmap_op, 1);
 
-                       xen_mc_issue(PARAVIRT_LAZY_MMU);
-
                        mcs = __xen_mc_entry(0);
                        MULTI_update_va_mapping(mcs.mc, scratch_page_address,
-                                       pfn_pte(page_to_pfn(get_balloon_scratch_page()),
+                                       pfn_pte(page_to_pfn(scratch_page),
                                        PAGE_KERNEL_RO), 0);
+
                        xen_mc_issue(PARAVIRT_LAZY_MMU);
 
                        kmap_op->host_addr = 0;
index 9235842cd76a14bf39ae61f9e1026754beee9f8a..d1e4777b4e75352fea33ca6a3e3d43a679e19c6d 100644 (file)
@@ -273,12 +273,20 @@ static void __init xen_smp_prepare_boot_cpu(void)
        BUG_ON(smp_processor_id() != 0);
        native_smp_prepare_boot_cpu();
 
-       /* We've switched to the "real" per-cpu gdt, so make sure the
-          old memory can be recycled */
-       make_lowmem_page_readwrite(xen_initial_gdt);
+       if (xen_pv_domain()) {
+               /* We've switched to the "real" per-cpu gdt, so make sure the
+                  old memory can be recycled */
+               make_lowmem_page_readwrite(xen_initial_gdt);
 
-       xen_filter_cpu_maps();
-       xen_setup_vcpu_info_placement();
+               xen_filter_cpu_maps();
+               xen_setup_vcpu_info_placement();
+       }
+       /*
+        * The alternative logic (which patches the unlock/lock) runs before
+        * the smp bootup up code is activated. Hence we need to set this up
+        * the core kernel is being patched. Otherwise we will have only
+        * modules patched but not core code.
+        */
        xen_init_spinlocks();
 }
 
@@ -709,6 +717,15 @@ static int xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle)
        WARN_ON(rc);
        if (!rc)
                rc =  native_cpu_up(cpu, tidle);
+
+       /*
+        * We must initialize the slowpath CPU kicker _after_ the native
+        * path has executed. If we initialized it before none of the
+        * unlocker IPI kicks would reach the booting CPU as the booting
+        * CPU had not set itself 'online' in cpu_online_mask. That mask
+        * is checked when IPIs are sent (on HVM at least).
+        */
+       xen_init_lock_cpu(cpu);
        return rc;
 }
 
@@ -728,4 +745,5 @@ void __init xen_hvm_smp_init(void)
        smp_ops.cpu_die = xen_hvm_cpu_die;
        smp_ops.send_call_func_ipi = xen_smp_send_call_function_ipi;
        smp_ops.send_call_func_single_ipi = xen_smp_send_call_function_single_ipi;
+       smp_ops.smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu;
 }
index 0438b9324a72175cad44f55eb44f841e5b268322..253f63fceea104978c6e5d1f54ba81e1e3581b20 100644 (file)
@@ -81,7 +81,6 @@ static inline void spin_time_accum_blocked(u64 start)
        spinlock_stats.time_blocked += delta;
 }
 #else  /* !CONFIG_XEN_DEBUG_FS */
-#define TIMEOUT                        (1 << 10)
 static inline void add_stats(enum xen_contention_stat var, u32 val)
 {
 }
@@ -96,23 +95,6 @@ static inline void spin_time_accum_blocked(u64 start)
 }
 #endif  /* CONFIG_XEN_DEBUG_FS */
 
-/*
- * Size struct xen_spinlock so it's the same as arch_spinlock_t.
- */
-#if NR_CPUS < 256
-typedef u8 xen_spinners_t;
-# define inc_spinners(xl) \
-       asm(LOCK_PREFIX " incb %0" : "+m" ((xl)->spinners) : : "memory");
-# define dec_spinners(xl) \
-       asm(LOCK_PREFIX " decb %0" : "+m" ((xl)->spinners) : : "memory");
-#else
-typedef u16 xen_spinners_t;
-# define inc_spinners(xl) \
-       asm(LOCK_PREFIX " incw %0" : "+m" ((xl)->spinners) : : "memory");
-# define dec_spinners(xl) \
-       asm(LOCK_PREFIX " decw %0" : "+m" ((xl)->spinners) : : "memory");
-#endif
-
 struct xen_lock_waiting {
        struct arch_spinlock *lock;
        __ticket_t want;
@@ -123,6 +105,7 @@ static DEFINE_PER_CPU(char *, irq_name);
 static DEFINE_PER_CPU(struct xen_lock_waiting, lock_waiting);
 static cpumask_t waiting_cpus;
 
+static bool xen_pvspin = true;
 static void xen_lock_spinning(struct arch_spinlock *lock, __ticket_t want)
 {
        int irq = __this_cpu_read(lock_kicker_irq);
@@ -241,16 +224,12 @@ void xen_init_lock_cpu(int cpu)
        int irq;
        char *name;
 
+       if (!xen_pvspin)
+               return;
+
        WARN(per_cpu(lock_kicker_irq, cpu) >= 0, "spinlock on CPU%d exists on IRQ%d!\n",
             cpu, per_cpu(lock_kicker_irq, cpu));
 
-       /*
-        * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23
-        * (xen: disable PV spinlocks on HVM)
-        */
-       if (xen_hvm_domain())
-               return;
-
        name = kasprintf(GFP_KERNEL, "spinlock%d", cpu);
        irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR,
                                     cpu,
@@ -270,11 +249,7 @@ void xen_init_lock_cpu(int cpu)
 
 void xen_uninit_lock_cpu(int cpu)
 {
-       /*
-        * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23
-        * (xen: disable PV spinlocks on HVM)
-        */
-       if (xen_hvm_domain())
+       if (!xen_pvspin)
                return;
 
        unbind_from_irqhandler(per_cpu(lock_kicker_irq, cpu), NULL);
@@ -283,16 +258,9 @@ void xen_uninit_lock_cpu(int cpu)
        per_cpu(irq_name, cpu) = NULL;
 }
 
-static bool xen_pvspin __initdata = true;
 
 void __init xen_init_spinlocks(void)
 {
-       /*
-        * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23
-        * (xen: disable PV spinlocks on HVM)
-        */
-       if (xen_hvm_domain())
-               return;
 
        if (!xen_pvspin) {
                printk(KERN_DEBUG "xen: PV spinlocks disabled\n");
@@ -323,6 +291,9 @@ static int __init xen_spinlock_debugfs(void)
        if (d_xen == NULL)
                return -ENOMEM;
 
+       if (!xen_pvspin)
+               return 0;
+
        d_spin_debug = debugfs_create_dir("spinlocks", d_xen);
 
        debugfs_create_u8("zero_stats", 0644, d_spin_debug, &zero_stats);